1 19 20 package org.netbeans.modules.javacore.scanning; 21 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.util.*; 25 import java.net.URL ; 26 import java.net.URI ; 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 48 public class FileScanner { 49 50 private ClassUpdater classUpdater; 51 private JavaUpdater javaUpdater; 52 private File root; 53 private String 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 77 public FileScanner(URL _root, String sourceLevel, Codebase cb) throws IllegalArgumentException { 78 this(_root, sourceLevel, cb, false); 79 } 80 81 91 public FileScanner(URL _root, String sourceLevel, Codebase cb, boolean isRescan) throws IllegalArgumentException { 92 synchronized (FileScanner.class) { 93 if (ignoredPackages == null) { 94 ignoredPackages = parseSet("org.netbeans.javacore.ignorePackages", "sun sunw"); ignoredDirectories = parseSet("org.netbeans.javacore.ignoreDirectories", "SCCS CVS"); eagerlyParse = parseSet("org.netbeans.javacore.eagerlyParse", "javax/swing/JFrame.java"); } 98 } 99 100 this.isRescan = isRescan; 101 102 if ("jar".equals(_root.getProtocol())) { String strUrl = _root.toExternalForm(); 104 int index = strUrl.lastIndexOf("!/")+2; assert index > 0 && index<=strUrl.length() :"Invalid jar protocol URL"; offset = index == strUrl.length() ? null : strUrl.substring (index); 107 _root = FileUtil.getArchiveFile (_root); 108 zipFile=true; 109 } 110 if (!"file".equals (_root.getProtocol())) { throw new IllegalArgumentException ("The URL: "+_root.toExternalForm()+" has no file protocol."); } 113 URI uri = URI.create (_root.toExternalForm()); 114 root = new File (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 propertyName, String 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 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]; } 163 } 164 try { 165 zipInfo = new ZipArchiveInfo(root, offset); 166 rootInfo = zipInfo.getRootFileInfo(); 167 }catch (IOException 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 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 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 pack, Set visited) { 207 if (ignoredPackages.contains(pack)) return; 208 209 String 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 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."); rep.endTrans(); 230 while (mutex.isSwingWaiting()) { 231 Thread.sleep(100); 232 } 233 } catch (InterruptedException e) { 234 } finally { 236 rep.beginTrans(true); 237 if (DEBUG) System.err.println("FileScanner: Re-acquiring transaction lock to continue with scanning."); if (!isRescan) { 239 rep.disableEvents(); 240 } 241 } 242 } 243 String newpack=pack; 244 245 if (pack.length()!=0) { 246 newpack=pack.concat("."); } 248 newpack=newpack.concat(name); 249 scanPackage(fo,newpack,visited); 250 } else if (name!=null) { 251 if (name.endsWith(".java")) { javaFiles.put(name,fo); 253 } else if (name.endsWith(".class")) classFiles.put(name,fo); 255 } 256 } 257 if (!(javaFiles.isEmpty() && classFiles.isEmpty())) { 258 if (isRescan) { 259 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 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 ex) { 281 ErrorManager.getDefault().notify(ex); 282 } 283 } 284 } else { 285 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 |