KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > javacore > scanning > FileScanner


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 package org.netbeans.modules.javacore.scanning;
21
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.util.*;
25 import java.net.URL JavaDoc;
26 import java.net.URI JavaDoc;
27
28 import org.netbeans.jmi.javamodel.Codebase;
29 import org.netbeans.jmi.javamodel.JavaModelPackage;
30 import org.netbeans.jmi.javamodel.Resource;
31 import org.netbeans.mdr.NBMDRepositoryImpl;
32 import org.netbeans.modules.javacore.ClassIndex;
33 import org.netbeans.modules.javacore.ExclusiveMutex;
34 import org.netbeans.modules.javacore.JMManager;
35 import org.netbeans.modules.javacore.ProgressDisplayer;
36 import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
37 import org.netbeans.modules.javacore.jmiimpl.javamodel.ResourceClassImpl;
38 import org.netbeans.modules.javacore.jmiimpl.javamodel.ResourceImpl;
39 import org.openide.ErrorManager;
40 import org.openide.filesystems.FileObject;
41 import org.openide.filesystems.FileUtil;
42 import org.openide.util.Utilities;
43
44 /**
45  *
46  * @author Pavel Flaska
47  */

48 public class FileScanner {
49     
50     private ClassUpdater classUpdater;
51     private JavaUpdater javaUpdater;
52     private File JavaDoc root;
53     private String JavaDoc offset;
54     private Codebase codebase;
55     private JavaModelPackage mofPackage;
56     private Collection resources;
57     private Collection resourcesToScan;
58     private boolean zipFile;
59     private final ExclusiveMutex mutex;
60     private static HashSet ignoredDirectories;
61     private static HashSet ignoredPackages;
62     private static HashSet eagerlyParse;
63     private final boolean isRescan;
64     
65     private static final boolean DEBUG = false;
66     
67     /**
68      * Creates new FileScanner
69      * @param _root the URL of root which should be scanned, must be either
70      * file protocol of jar protocol with file path
71      * @param sourceLevel
72      * @param cb codebase
73      * @throws IllegalArgumentException when _root is not file protocol or jar protocol
74      * with file path URL
75      *
76      */

77     public FileScanner(URL JavaDoc _root, String JavaDoc sourceLevel, Codebase cb) throws IllegalArgumentException JavaDoc {
78         this(_root, sourceLevel, cb, false);
79     }
80     
81     /**
82      * Creates new FileScanner
83      * @param _root the URL of root which should be scanned, must be either
84      * file protocol of jar protocol with file path
85      * @param sourceLevel
86      * @param cb codebase
87      * @throws IllegalArgumentException when _root is not file protocol or jar protocol
88      * with file path URL
89      *
90      */

91     public FileScanner(URL JavaDoc _root, String JavaDoc sourceLevel, Codebase cb, boolean isRescan) throws IllegalArgumentException JavaDoc {
92         synchronized (FileScanner.class) {
93             if (ignoredPackages == null) {
94                 ignoredPackages = parseSet("org.netbeans.javacore.ignorePackages", "sun sunw"); // NOI18N
95
ignoredDirectories = parseSet("org.netbeans.javacore.ignoreDirectories", "SCCS CVS"); // NOI18N
96
eagerlyParse = parseSet("org.netbeans.javacore.eagerlyParse", "javax/swing/JFrame.java"); // NOI18N
97
}
98         }
99
100         this.isRescan = isRescan;
101         
102         if ("jar".equals(_root.getProtocol())) { //NOI18N
103
String JavaDoc strUrl = _root.toExternalForm();
104             int index = strUrl.lastIndexOf("!/")+2; //NOI18N
105
assert index > 0 && index<=strUrl.length() :"Invalid jar protocol URL"; //NOI18N
106
offset = index == strUrl.length() ? null : strUrl.substring (index);
107             _root = FileUtil.getArchiveFile (_root);
108             zipFile=true;
109         }
110         if (!"file".equals (_root.getProtocol())) { //NOI18N
111
throw new IllegalArgumentException JavaDoc ("The URL: "+_root.toExternalForm()+" has no file protocol."); //NOI18N
112
}
113         URI JavaDoc uri = URI.create (_root.toExternalForm());
114         root = new File JavaDoc (uri);
115         codebase = cb;
116         mofPackage=(JavaModelPackage)codebase.refImmediatePackage();
117         mutex = JMManager.getTransactionMutex();
118         if (!isRescan) {
119             javaUpdater=new JavaUpdater(mofPackage,sourceLevel, this);
120         }
121         classUpdater=new ClassUpdater(mofPackage);
122     }
123     
124     private static HashSet parseSet(String JavaDoc propertyName, String JavaDoc defaultValue) {
125         StringTokenizer st = new StringTokenizer(System.getProperty(propertyName, defaultValue), " \t\n\r\f,-:+!");
126         HashSet result = new HashSet();
127         while (st.hasMoreTokens()) {
128             result.add(st.nextToken());
129         }
130         return result;
131     }
132     
133     void checkParseEagerly(Resource resource) {
134         if (eagerlyParse.contains(resource.getName())) {
135             if (resourcesToScan == null) {
136                 resourcesToScan = new ArrayList(eagerlyParse.size());
137             }
138             resourcesToScan.add(resource);
139         }
140     }
141     
142     public Resource[] scan() {
143         NBMDRepositoryImpl repository = (NBMDRepositoryImpl)JavaMetamodel.getDefaultRepository();
144         FileInfo rootInfo;
145         // turn off events only in case it is not a rescan
146
if (!isRescan) {
147             repository.disableEvents();
148         }
149         resourcesToScan = null;
150         ZipArchiveInfo zipInfo = null;
151         try {
152             ClassIndex index = null;
153             if (zipFile) {
154                 long oldTime=codebase.getTimestamp();
155                 index = ClassIndex.getIndex(mofPackage);
156
157                 if (oldTime!=0) {
158                     long jarTime=root.lastModified();
159
160                     if (oldTime == jarTime && index.getTimestamp() >= jarTime) {
161                         return new Resource[0]; // Jar is up to date
162
}
163                 }
164                 try {
165                     zipInfo = new ZipArchiveInfo(root, offset);
166                     rootInfo = zipInfo.getRootFileInfo();
167                 }catch (IOException JavaDoc ex) {
168                     ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
169                     return null;
170                 }
171             } else {
172                 rootInfo=new FileEntry(root,"");
173             }
174             resources = new HashSet(mofPackage.getResource().refAllOfClass());
175             
176             // get all subfolders (recursively) of filesystem root
177
scanPackage(rootInfo, "", new HashSet());
178             if (zipFile) {
179                 if (index != null) {
180                     index.setTimestamp();
181                 }
182                 codebase.setTimestamp(root.lastModified());
183                 codebase.setLibrary(true);
184             }
185             removeFromRepository();
186             return resourcesToScan == null ? new Resource[0] : (Resource[]) resourcesToScan.toArray(new Resource[resourcesToScan.size()]);
187         } finally {
188             try {
189                 if (zipInfo != null) zipInfo.close();
190             } catch (IOException JavaDoc e) {
191                 ErrorManager.getDefault().notify(e);
192             }
193         }
194     }
195     
196     private void removeFromRepository() {
197         Iterator i = resources.iterator();
198         
199         while (i.hasNext()) {
200             ((Resource) i.next()).refDelete();
201         }
202     }
203     
204     private static ProgressDisplayer progress;
205     
206     private void scanPackage(FileInfo directory, String JavaDoc pack, Set visited) {
207         if (ignoredPackages.contains(pack)) return;
208         
209         String JavaDoc canonicalName = directory.getCanonicalName();
210         if (canonicalName != null && !visited.add(canonicalName)) {
211             return;
212         }
213         
214         FileInfo files[] = directory.listFiles();
215         Map javaFiles=new HashMap();
216         Map classFiles=new HashMap();
217         
218         for(int i=0;i<files.length;i++) {
219             FileInfo fo=files[i];
220             String JavaDoc name=fo.getName();
221             
222             if (fo.isDirectory()) {
223         if (ignoredDirectories.contains(name) || !Utilities.isJavaIdentifier(name))
224             continue;
225                 if (mutex.isSwingWaiting()) {
226                     NBMDRepositoryImpl rep = (NBMDRepositoryImpl) JMManager.getDefaultRepository();
227                     try {
228                         if (DEBUG) System.err.println("FileScanner: Releasing transaction lock to allow event thread to continue."); // NOI18N
229
rep.endTrans();
230                         while (mutex.isSwingWaiting()) {
231                             Thread.sleep(100);
232                         }
233                     } catch (InterruptedException JavaDoc e) {
234                         // ignore
235
} finally {
236                         rep.beginTrans(true);
237                         if (DEBUG) System.err.println("FileScanner: Re-acquiring transaction lock to continue with scanning."); //NOI18N
238
if (!isRescan) {
239                             rep.disableEvents();
240                         }
241                     }
242                 }
243                 String JavaDoc newpack=pack;
244                 
245                 if (pack.length()!=0) {
246                     newpack=pack.concat("."); // NOI18N
247
}
248                 newpack=newpack.concat(name);
249                 scanPackage(fo,newpack,visited);
250             } else if (name!=null) {
251                 if (name.endsWith(".java")) { //NOI18N
252
javaFiles.put(name,fo);
253                 } else if (name.endsWith(".class")) //NOI18N
254
classFiles.put(name,fo);
255             }
256         }
257         if (!(javaFiles.isEmpty() && classFiles.isEmpty())) {
258             if (isRescan) {
259                 // rescan
260
Iterator resIt = javaFiles.values().iterator();
261                 List resList = new ArrayList();
262                 long indexTimestamp;
263
264                 while (resIt.hasNext()) {
265                     FileInfo file = (FileInfo) resIt.next();
266                     try {
267                         String JavaDoc name = file.getPath();
268                         long timestamp = file.lastModified();
269                         ResourceImpl resource = (ResourceImpl) ((ResourceClassImpl) mofPackage.getResource()).resolveResource(name, true, false);
270
271                         if (resource.getTimestamp() != timestamp) {
272                             FileObject fobj = JavaMetamodel.getManager().getFileObject(resource);
273                             if (fobj != null && fobj.isValid()) {
274                                 resources.remove(resource);
275                                 resource.updateFromFileObject(fobj, true);
276                             }
277                         } else {
278                             resources.remove(resource);
279                         }
280                     } catch (Exception JavaDoc ex) {
281                         ErrorManager.getDefault().notify(ex);
282                     }
283                 }
284             } else {
285                 // normal scan
286
progress = ProgressDisplayer.getVisibleProgressDisplayer();
287                 if (progress != null) {
288                     progress.updatePackage(pack);
289                 }
290                 resources.removeAll(javaUpdater.updateResources(javaFiles));
291             }
292             resources.removeAll(classUpdater.updateResources(javaFiles, classFiles));
293         }
294     }
295 }
296
Popular Tags