1 19 package org.netbeans.api.java.source; 20 21 import com.sun.source.util.JavacTask; 22 import java.beans.PropertyVetoException ; 23 import java.io.File ; 24 import java.io.IOException ; 25 import java.net.URL ; 26 import java.util.ArrayList ; 27 import java.util.Arrays ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.WeakHashMap ; 32 import java.util.concurrent.CountDownLatch ; 33 import java.util.concurrent.TimeUnit ; 34 import java.util.regex.Pattern ; 35 import javax.swing.event.ChangeListener ; 36 import junit.framework.Assert; 37 import org.netbeans.api.java.classpath.ClassPath; 38 import org.netbeans.api.java.queries.SourceForBinaryQuery; 39 import org.netbeans.api.java.source.JavaSource.Phase; 40 import org.netbeans.junit.NbTestCase; 41 import org.netbeans.modules.java.JavaDataLoader; 42 import org.netbeans.modules.java.source.ActivatedDocumentListener; 43 import org.netbeans.modules.java.source.usages.IndexUtil; 44 import org.netbeans.modules.java.source.usages.RepositoryUpdater; 45 import org.netbeans.spi.java.classpath.ClassPathProvider; 46 import org.netbeans.spi.java.classpath.support.ClassPathSupport; 47 import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation; 48 import org.netbeans.spi.java.queries.SourceLevelQueryImplementation; 49 import org.openide.ErrorManager; 50 import org.openide.filesystems.FileObject; 51 import org.openide.filesystems.FileStateInvalidException; 52 import org.openide.filesystems.FileSystem; 53 import org.openide.filesystems.FileUtil; 54 import org.openide.filesystems.LocalFileSystem; 55 import org.openide.filesystems.MultiFileSystem; 56 import org.openide.filesystems.Repository; 57 import org.openide.filesystems.URLMapper; 58 import org.openide.filesystems.XMLFileSystem; 59 import org.openide.util.Lookup; 60 import org.openide.util.Utilities; 61 import org.openide.util.lookup.Lookups; 62 import org.openide.util.lookup.ProxyLookup; 63 import org.xml.sax.SAXException ; 64 65 69 public final class SourceUtilsTestUtil extends ProxyLookup { 70 71 private static SourceUtilsTestUtil DEFAULT_LOOKUP = null; 72 73 public SourceUtilsTestUtil() { 74 Assert.assertNull(DEFAULT_LOOKUP); 75 DEFAULT_LOOKUP = this; 76 } 77 78 81 84 public static void setLookup(Object [] instances, ClassLoader cl) { 85 DEFAULT_LOOKUP.setLookups(new Lookup[] { 86 Lookups.fixed(instances), 87 Lookups.metaInfServices(cl), 88 Lookups.singleton(cl), 89 }); 90 } 91 92 private static Object [] extraLookupContent = null; 93 94 public static void prepareTest(String [] additionalLayers, Object [] additionalLookupContent) throws IOException , SAXException , PropertyVetoException { 95 URL [] layers = new URL [additionalLayers.length]; 96 97 for (int cntr = 0; cntr < additionalLayers.length; cntr++) { 98 layers[cntr] = Thread.currentThread().getContextClassLoader().getResource(additionalLayers[cntr]); 99 } 100 101 XMLFileSystem xmlFS = new XMLFileSystem(); 102 xmlFS.setXmlUrls(layers); 103 104 FileSystem system = new MultiFileSystem(new FileSystem[] {FileUtil.createMemoryFileSystem(), xmlFS}); 105 106 Repository repository = new Repository(system); 107 extraLookupContent = new Object [additionalLookupContent.length + 1]; 108 109 System.arraycopy(additionalLookupContent, 0, extraLookupContent, 1, additionalLookupContent.length); 110 111 extraLookupContent[0] = repository; 112 113 DEFAULT_LOOKUP.setLookup(extraLookupContent, SourceUtilsTestUtil.class.getClassLoader()); 114 115 SourceUtilsTestUtil2.disableLocks(); 116 } 117 118 static { 119 SourceUtilsTestUtil.class.getClassLoader().setDefaultAssertionStatus(true); 120 System.setProperty("org.openide.util.Lookup", SourceUtilsTestUtil.class.getName()); 121 Assert.assertEquals(SourceUtilsTestUtil.class, Lookup.getDefault().getClass()); 122 } 123 124 public static void prepareTest(FileObject sourceRoot, FileObject buildRoot, FileObject cache) throws Exception { 125 prepareTest(sourceRoot, buildRoot, cache, new FileObject[0]); 126 } 127 128 public static void prepareTest(FileObject sourceRoot, FileObject buildRoot, FileObject cache, FileObject[] classPathElements) throws Exception { 129 if (extraLookupContent == null) 130 prepareTest(new String [0], new Object [0]); 131 132 Object [] lookupContent = new Object [extraLookupContent.length + 4]; 133 134 System.arraycopy(extraLookupContent, 0, lookupContent, 4, extraLookupContent.length); 135 136 lookupContent[0] = new TestProxyClassPathProvider(sourceRoot, buildRoot, classPathElements); 137 lookupContent[1] = new TestSourceForBinaryQuery(sourceRoot, classPathElements); 138 lookupContent[2] = new TestSourceLevelQueryImplementation(); 139 lookupContent[3] = JavaDataLoader.findObject(JavaDataLoader.class, true); 140 141 setLookup(lookupContent, SourceUtilsTestUtil.class.getClassLoader()); 142 143 IndexUtil.setCacheFolder(FileUtil.toFile(cache)); 144 } 145 146 private static Map <FileObject, String > file2SourceLevel = new WeakHashMap <FileObject, String >(); 147 148 public static void setSourceLevel(FileObject file, String level) { 149 file2SourceLevel.put(file, level); 150 } 151 152 155 public static void compileRecursively(FileObject sourceRoot) throws Exception { 156 List <FileObject> queue = new LinkedList (); 157 158 queue.add(sourceRoot); 159 160 while (!queue.isEmpty()) { 161 FileObject file = queue.remove(0); 162 163 if (file.isData()) { 164 CountDownLatch l = RepositoryUpdater.getDefault().scheduleCompilationAndWait(file, sourceRoot); 165 166 l.await(60, TimeUnit.SECONDS); 167 } else { 168 queue.addAll(Arrays.asList(file.getChildren())); 169 } 170 } 171 } 172 173 private static List <URL > bootClassPath; 174 175 public static synchronized List <URL > getBootClassPath() { 176 if (bootClassPath == null) { 177 try { 178 String cp = System.getProperty("sun.boot.class.path"); 179 List <URL > urls = new ArrayList <URL >(); 180 String [] paths = cp.split(Pattern.quote(System.getProperty("path.separator"))); 181 182 for (String path : paths) { 183 File f = new File (path); 184 185 if (!f.canRead()) 186 continue; 187 188 FileObject fo = FileUtil.toFileObject(f); 189 190 if (FileUtil.isArchiveFile(fo)) { 191 fo = FileUtil.getArchiveRoot(fo); 192 } 193 194 if (fo != null) { 195 urls.add(fo.getURL()); 196 } 197 } 198 199 bootClassPath = urls; 200 } catch (FileStateInvalidException e) { 201 ErrorManager.getDefault().notify(e); 202 } 203 } 204 205 return bootClassPath; 206 } 207 208 private static class TestSourceForBinaryQuery implements SourceForBinaryQueryImplementation { 209 210 private FileObject sourceRoot; 211 private List <FileObject> classPathElements; 212 213 public TestSourceForBinaryQuery(FileObject sourceRoot, FileObject[] classPathElements) { 214 this.sourceRoot = sourceRoot; 215 this.classPathElements = Arrays.asList(classPathElements); 216 } 217 218 public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) { 219 if (getBootClassPath().contains(binaryRoot)) 220 return null; 221 222 if (classPathElements.contains(URLMapper.findFileObject(binaryRoot))) 223 return null; 224 225 return new SourceForBinaryQuery.Result() { 226 public FileObject[] getRoots() { 227 return new FileObject[] { 228 sourceRoot, 229 }; 230 } 231 232 public void addChangeListener(ChangeListener l) { 233 } 234 235 public void removeChangeListener(ChangeListener l) { 236 } 237 }; 238 } 239 240 } 241 242 private static class TestProxyClassPathProvider implements ClassPathProvider { 243 244 private FileObject sourceRoot; 245 private FileObject buildRoot; 246 private FileObject[] classPathElements; 247 248 public TestProxyClassPathProvider(FileObject sourceRoot, FileObject buildRoot, FileObject[] classPathElements) { 249 this.sourceRoot = sourceRoot; 250 this.buildRoot = buildRoot; 251 this.classPathElements = classPathElements; 252 } 253 254 public ClassPath findClassPath(FileObject file, String type) { 255 try { 256 if (ClassPath.BOOT == type) { 257 return ClassPathSupport.createClassPath(getBootClassPath().toArray(new URL [0])); 258 } 259 260 if (ClassPath.SOURCE == type) { 261 return ClassPathSupport.createClassPath(new FileObject[] { 262 sourceRoot 263 }); 264 } 265 266 if (ClassPath.COMPILE == type) { 267 return ClassPathSupport.createClassPath(classPathElements); 268 } 269 270 if (ClassPath.EXECUTE == type) { 271 return ClassPathSupport.createClassPath(new FileObject[] { 272 buildRoot 273 }); 274 } 275 } catch (Exception e) { 276 e.printStackTrace(); 277 } 278 return null; 279 } 280 281 } 282 283 private static class TestSourceLevelQueryImplementation implements SourceLevelQueryImplementation { 284 285 public String getSourceLevel(FileObject javaFile) { 286 String level = file2SourceLevel.get(javaFile); 287 288 if (level == null) 289 return "1.5"; 290 else 291 return level; 292 } 293 294 } 295 296 301 public static FileObject makeScratchDir(NbTestCase test) throws IOException { 302 test.clearWorkDir(); 303 File root = test.getWorkDir(); 304 assert root.isDirectory() && root.list().length == 0; 305 FileObject fo = FileUtil.toFileObject(root); 306 if (fo != null) { 307 return fo; 309 } else { 310 LocalFileSystem lfs = new LocalFileSystem(); 312 try { 313 lfs.setRootDirectory(root); 314 } catch (PropertyVetoException e) { 315 assert false : e; 316 } 317 Repository.getDefault().addFileSystem(lfs); 318 return lfs.getRoot(); 319 } 320 } 321 322 public static JavacTask getJavacTaskFor(CompilationInfo info) { 323 return info.getJavacTask(); 324 } 325 326 331 public static CompilationInfo getCompilationInfo(JavaSource js, Phase phase ) throws IOException { 332 if (phase == null || phase == Phase.MODIFIED) { 333 throw new IllegalArgumentException (String.format("The %s is not a legal value of phase",phase)); } 335 final DeadlockTask bt = new DeadlockTask(phase); 336 js.runUserActionTask(bt,true); 337 return bt.info; 338 } 339 340 341 private static class DeadlockTask implements CancellableTask<CompilationController> { 342 343 private final Phase phase; 344 private CompilationInfo info; 345 346 public DeadlockTask(Phase phase) { 347 assert phase != null; 348 this.phase = phase; 349 } 350 351 public void run( CompilationController info ) { 352 try { 353 info.toPhase(this.phase); 354 this.info = info; 355 } catch (IOException ioe) { 356 ErrorManager.getDefault().notify(ioe); 357 } 358 } 359 360 public void cancel() { 361 } 362 363 } 364 365 } 366 | Popular Tags |