KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > javacore > RepositoryUpdater


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 /*
21  * RepositoryUpdater.java
22  *
23  * Created on 17. leden 2004, 14:17
24  */

25
26 package org.netbeans.modules.javacore;
27 import java.net.MalformedURLException JavaDoc;
28 import java.net.URL JavaDoc;
29 import java.util.Arrays JavaDoc;
30 import java.util.Collections JavaDoc;
31 import java.util.Date JavaDoc;
32 import java.util.Enumeration JavaDoc;
33 import java.util.HashSet JavaDoc;
34 import java.util.Locale JavaDoc;
35 import java.util.Set JavaDoc;
36 import org.netbeans.jmi.javamodel.JavaModelPackage;
37 import org.netbeans.jmi.javamodel.Resource;
38 import org.netbeans.jmi.javamodel.ResourceClass;
39 import org.netbeans.modules.javacore.api.JavaModel;
40 import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
41 import org.netbeans.modules.javacore.jmiimpl.javamodel.ResourceClassImpl;
42 import org.netbeans.modules.javacore.jmiimpl.javamodel.ResourceImpl;
43 import org.netbeans.modules.javacore.jmiimpl.javamodel.GeneralException;
44 import org.openide.ErrorManager;
45 import org.openide.filesystems.*;
46 import org.openide.filesystems.FileStateInvalidException;
47
48
49 /**
50  *
51  * @author Jan Becicka
52  */

53 public class RepositoryUpdater implements FileChangeListener {
54     private static final boolean DEBUG = false;
55     
56     private static RepositoryUpdater updater = null;
57     private final Set JavaDoc nonArchiveExts;
58     private final JMManager manager = (JMManager) JavaMetamodel.getManager();
59     private final Set JavaDoc fileObjectsToSave = Collections.synchronizedSet(new HashSet JavaDoc());
60
61     
62     /** Creates a new instance of RepositoryUpdater */
63     private RepositoryUpdater() {
64         Set JavaDoc exts = new HashSet JavaDoc(Arrays.asList(new String JavaDoc[] {
65             "JAVA",
66             "CLASS",
67             "LOG",
68             "TXT",
69             "XML",
70             "HTML",
71             "FORM",
72             "PROPERTIES",
73         }));
74         nonArchiveExts = Collections.unmodifiableSet(exts);
75         //--- This will be replaced with master = MasterFileSystem.getDefault()
76
Util.addFileSystemsListener(this);
77     }
78     
79     public static RepositoryUpdater getDefault() {
80         if (updater == null) {
81             updater = new RepositoryUpdater();
82         }
83         return updater;
84     }
85     
86     public void fileAttributeChanged(FileAttributeEvent fe) {
87         //fileChanged(fe);
88
}
89     
90     public void fileChanged(FileEvent fe) {
91         try {
92             if (changesDisabled)
93                 return ;
94             if (DEBUG) System.out.println("file changed: " + fe.getFile().getPath()); // NOI18N
95
if (!isJavaFile(fe)) {
96                 try {
97                     URL JavaDoc rootURL = getRootURL(fe);
98                     if (rootURL != null) {
99                         manager.getMergedClassPathImpl().updateRoot(rootURL);
100                     }
101                 } catch (Exception JavaDoc e) {
102                     JMManager.getLog().notify(ErrorManager.INFORMATIONAL, e);
103                 }
104                 return;
105             }
106             updateResource(fe.getFile());
107         } catch (Exception JavaDoc e) {
108             ErrorManager.getDefault().notify(e);
109         }
110     }
111     
112     // this method never returns a URL which does not end by slash
113
private URL JavaDoc getRootURL(FileEvent fe) throws FileStateInvalidException, MalformedURLException JavaDoc {
114         return getRootURL(fe.getFile());
115     }
116     
117     private URL JavaDoc getRootURL(FileObject fo) throws FileStateInvalidException, MalformedURLException JavaDoc {
118         URL JavaDoc result;
119         if (fo.isFolder()) {
120             result = fo.getURL();
121         } else if (mayBeArchiveFile(fo) && FileUtil.isArchiveFile(fo)) {
122             result = FileUtil.getArchiveRoot(fo.getURL());
123         } else {
124             return null;
125         }
126         assert result.toExternalForm().endsWith("/") : // NOI18N
127
"Bogus URL: " + result + " returned for FileObject: " + fo.getName() // NOI18N
128
+ " (isArchiveFile = " + FileUtil.isArchiveFile(fo) + ", isFolder = " + fo.isFolder() + ", isValid = " + fo.isValid() + ")"; // NOI18N
129
return result;
130     }
131
132     private boolean changesDisabled = false;
133     public void setListenOnChanges(boolean listen) {
134         changesDisabled = !listen;
135     }
136     
137     public void addFileObjectToSave(FileObject file) {
138         fileObjectsToSave.add(file);
139     }
140     
141     static void updateTimeStamp(FileObject fo) {
142         if (fo != null) {
143             ResourceImpl r = (ResourceImpl) JavaMetamodel.getManager().getResource(fo);
144             if (r != null) {
145                 Date JavaDoc lm = fo.lastModified();
146                 assert lm != null : "FileObject.lastModified() returned null for " + fo; // NOI18N
147
r.setTimestamp(lm.getTime(), false);
148             }
149         }
150     }
151     
152     private void updateResource(final FileObject fo) {
153         boolean isSave = fileObjectsToSave.remove(fo);
154         boolean synchronous = Thread.currentThread() == manager.getTransactionMutex().getThread();
155         if (isSave) {
156             if (synchronous) {
157                 updateTimeStamp(fo);
158             } else {
159                 manager.getTransactionMutex().addUpdateTS(fo);
160             }
161         } else {
162             if (synchronous) {
163                 createOrUpdateResource(fo);
164             } else {
165                 manager.getTransactionMutex().addModifiedRW(fo);
166             }
167         }
168     }
169     
170     public void fileDataCreated(FileEvent fe) {
171         FileObject fo = fe.getFile();
172         try {
173             if (DEBUG) System.out.println("file created: " + fo.getPath()); // NOI18N
174

175             if (!Util.isJavaFile(fo)) {
176                 fileCreated(fo);
177                 return;
178             }
179             
180             updateResource(fo);
181         } catch (Exception JavaDoc e) {
182             ErrorManager.getDefault().notify(e);
183         }
184     }
185
186     private void fileCreated(FileObject fo) {
187         try {
188             URL JavaDoc rootURL = getRootURL(fo);
189             if (rootURL != null) {
190                 manager.getMergedClassPathImpl().removeMissingRoot(rootURL);
191             }
192         } catch (Exception JavaDoc e) {
193             JMManager.getLog().notify(ErrorManager.INFORMATIONAL, e);
194         }
195     }
196     
197     void createOrUpdateResource(FileObject fo) {
198         if (!fo.isValid())
199             return ;
200         FileObject cpRoot = manager.getMergedClassPathImpl().findOwnerRoot(fo);
201         if (cpRoot == null) return;
202         boolean failed = true;
203         JavaModel.getJavaRepository().beginTrans(true);
204         try {
205             String JavaDoc name = manager.getResourceName(fo);
206             if (name == null) {
207                 failed = false;
208                 return;
209             }
210             JavaModelPackage modelPckg = manager.resolveJavaExtent(cpRoot);
211             if (modelPckg==null) {
212                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, new GeneralException(fo.getPath() + " was not found in any extent. There is no resource to update.")); //NOI18N
213
failed = false;
214                 return;
215             }
216             ResourceClass resClass=modelPckg.getResource();
217             Resource r = resClass.resolveResource(name, false);
218             if (r == null || !name.equals(r.getName())) {
219                 //resource does not exist - create it
220

221                 if (name.endsWith(".java")) { // NOI18N
222
String JavaDoc clsName = name.substring(0, name.length() - ".java".length()) + ".class"; // NOI18N
223
r = resClass.resolveResource(clsName, false);
224                     if (r != null) {
225                         r.refDelete();
226                     }
227                 } else if (name.endsWith(".class")) { // NOI18N
228
String JavaDoc jName = name.substring(0, name.length() - ".class".length()) + ".java"; //NOI18N
229
if (resClass.resolveResource(jName, false) != null) {
230                         failed = false;
231                         return;
232                     }
233                 }
234                 r = ((ResourceClassImpl) resClass).resolveResource(name, true, false);
235             }
236             ((ResourceImpl)r).updateFromFileObject(fo, true);
237             failed = false;
238         } finally {
239             JavaModel.getJavaRepository().endTrans(failed);
240         }
241     }
242     
243     public void fileDeleted(FileEvent fe) {
244         try {
245             if (DEBUG) System.out.println("file deleted: " + fe.getFile().getPath()); // NOI18N
246
if (!Util.isJavaFile(fe.getFile(), true)) {
247                 try {
248                     URL JavaDoc rootURL = getRootURL(fe);
249                     if (rootURL != null) {
250                         manager.getMergedClassPathImpl().addMissingRoot(rootURL);
251                     }
252                 } catch (Exception JavaDoc e) {
253                     JMManager.getLog().notify(ErrorManager.INFORMATIONAL, e);
254                 }
255                 return;
256             }
257             manager.getTransactionMutex().addDeleted(fe.getFile());
258         } catch (Exception JavaDoc e) {
259             ErrorManager.getDefault().notify(e);
260         }
261         }
262
263     private boolean isJavaFile(FileEvent fe) {
264         return Util.isJavaFile(fe.getFile());
265     }
266
267     public void fileFolderCreated(FileEvent fe) {
268         folderCreated(fe.getFile());
269     }
270     
271     public void folderCreated(FileObject fo) {
272         FileObject cpRoot = Util.getCPRoot(fo);
273         if (cpRoot == null) {
274             try {
275                 URL JavaDoc rootURL = getRootURL(fo);
276                 if (rootURL != null) {
277                     if (manager.getMergedClassPathImpl().removeMissingRoot(rootURL)) {
278                         return;
279                     }
280                 }
281             } catch (Exception JavaDoc e) {
282                 JMManager.getLog().notify(ErrorManager.INFORMATIONAL, e);
283             }
284             FileObject[] children = fo.getChildren();
285             for (int i = 0; i < children.length; i++) {
286                 if (children[i].isFolder()) {
287                     folderCreated(children[i]);
288                 } else {
289                     fileCreated(children[i]);
290                 }
291             }
292             return;
293         }
294         Enumeration JavaDoc en = fo.getChildren(true);
295         while (en.hasMoreElements()) {
296             FileObject f = (FileObject) en.nextElement();
297             if (Util.isJavaFile(f)) {
298                 updateResource(f);
299             }
300         }
301     }
302     
303     public void fileRenamed(FileRenameEvent fe) {
304         try {
305             if (isJavaFile(fe)) {
306                 javaFileRenamed(fe);
307             } else {
308                 try {
309                     URL JavaDoc rootURL = getRootURL(fe);
310                     if (rootURL != null) {
311                         if (manager.getMergedClassPathImpl().removeMissingRoot(rootURL)) {
312                             return;
313                         }
314                     }
315                 } catch (Exception JavaDoc e) {
316                     JMManager.getLog().notify(ErrorManager.INFORMATIONAL, e);
317                 }
318                 if (fe.getFile().isFolder()) {
319                     folderRenamed(fe);
320                 }
321             }
322         } catch (Exception JavaDoc e) {
323             ErrorManager.getDefault().notify(e);
324         }
325     }
326     
327     private void javaFileRenamed(FileRenameEvent fe) {
328         FileObject oldFo = fe.getFile();
329         boolean failed = true;
330         JavaModel.getJavaRepository().beginTrans(true);
331         try {
332             String JavaDoc oldName = fe.getName();
333             FileObject cpRoot = Util.getCPRoot(oldFo);
334             if (cpRoot == null) {
335                 failed = false;
336                 return; // ignore fileobjects that are not visible from our merged classpath
337
}
338             JavaModelPackage model = manager.getJavaExtent(cpRoot);
339             if (model != null) {
340                 String JavaDoc path = manager.getResourceName(oldFo.getParent());
341                 String JavaDoc lookForName = oldName + '.' + fe.getExt(); // file name with extension
342
if (path.length() > 0) {
343                     path += '/';
344                     // put the path to the string if the file is located in package
345
lookForName = path + lookForName;
346                 }
347                 Resource oldRes = model.getResource().resolveResource(lookForName, false);
348                 if (oldRes != null) {
349                     oldRes.setName(path + oldFo.getNameExt());
350                 } else {
351                     ((ResourceClassImpl) model.getResource()).resolveResource(path + oldFo.getNameExt(), true, false);
352                 }
353             }
354
355             failed = false;
356         } finally {
357             JavaModel.getJavaRepository().endTrans(failed);
358         }
359     }
360     
361     private void folderRenamed(FileRenameEvent fe) {
362         FileObject oldFo = fe.getFile();
363         boolean failed = true;
364         
365         JavaModel.getJavaRepository().beginTrans(true);
366         try {
367             Enumeration JavaDoc children = oldFo.getChildren(true);
368             FileObject cpRoot = Util.getCPRoot(oldFo);
369             if (cpRoot == null || cpRoot.equals(oldFo)) {
370                 // ignore rename of cp root
371
// ignore folders that are not visible from our merged classpath
372
failed = false;
373                 return;
374             }
375             String JavaDoc dirName = JMManager.getResourceName(cpRoot, oldFo);
376             while (children.hasMoreElements()) {
377                 FileObject f = (FileObject) children.nextElement();
378                 if ("java".equals(f.getExt()) && !f.isVirtual()) { // NOI18N
379
String JavaDoc newName = JMManager.getResourceName(cpRoot, f);
380                     String JavaDoc oldName = replaceStart(newName, dirName, fe.getName());
381                     oldName = replaceEnd(dirName, fe.getName());
382                     oldName = replaceStart(newName, dirName, oldName);
383                     if (DEBUG)
384                         System.out.println("Folder renamed: Resource " + oldName + " renamed to " + newName); // NOI18N
385
manager.getResource(cpRoot, oldName).setName(newName);
386                 }
387             }
388             failed = false;
389         } finally {
390             JavaModel.getJavaRepository().endTrans(failed);
391         }
392     }
393     
394     /**
395      * example: where = "examples/colorpicker/ColorPreview.java"
396      * what = "examples/colorpicker"
397      * withWhat = "examples/xxx
398      * returns "examples/xxx/ColorPreview.java"
399      */

400     
401     private static final String JavaDoc replaceStart(String JavaDoc where, String JavaDoc what, String JavaDoc withWhat) {
402         return withWhat.concat(where.substring(what.length()));
403     }
404     
405     /**
406      * example: where = "examples/colorpicker"
407      * what = "xxx"
408      * returns "examples/xxx"
409      */

410     
411     private static final String JavaDoc replaceEnd(String JavaDoc where, String JavaDoc what) {
412         int i = where.lastIndexOf('/');
413         if (i>0) {
414             return where.substring(0,i+1).concat(what);
415         } else {
416             return what;
417         }
418     }
419
420     private boolean mayBeArchiveFile(FileObject fileObject) {
421         return !nonArchiveExts.contains(fileObject.getExt().toUpperCase(Locale.US));
422     }
423 }
424
Popular Tags