1 19 20 package org.netbeans.modules.j2ee.metadata; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.beans.PropertyChangeSupport ; 25 import java.lang.ref.WeakReference ; 26 import java.net.URL ; 27 import java.util.ArrayList ; 28 import java.util.Arrays ; 29 import java.util.HashSet ; 30 import java.util.List ; 31 import java.util.Set ; 32 import javax.swing.event.ChangeListener ; 33 import org.netbeans.api.java.classpath.ClassPath; 34 import org.netbeans.api.java.queries.SourceForBinaryQuery; 35 import org.netbeans.modules.j2ee.persistence.wizard.fromdb.ChangeSupport; 36 import org.netbeans.spi.java.classpath.ClassPathFactory; 37 import org.netbeans.spi.java.classpath.ClassPathImplementation; 38 import org.netbeans.spi.java.classpath.PathResourceImplementation; 39 import org.netbeans.spi.java.classpath.support.ClassPathSupport; 40 import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation; 41 import org.openide.filesystems.FileObject; 42 import org.openide.filesystems.FileUtil; 43 import org.openide.filesystems.URLMapper; 44 45 49 public class ClassPathSourceCacheTest extends TestBase { 50 51 private FileObject root1FO; 52 private FileObject root2FO; 53 private URL root1URL; 54 private URL root2URL; 55 56 private URL binary1URL; 57 private FileObject src1; 58 59 private URL binary2URL; 60 private FileObject src2; 61 62 private SourceForBinaryQueryImpl s4bq1; 63 private SourceForBinaryQueryImpl s4bq2; 64 65 public ClassPathSourceCacheTest(String testName) { 66 super(testName); 67 } 68 69 public void setUp() throws Exception { 70 clearWorkDir(); 71 FileObject workDir = FileUtil.toFileObject(getWorkDir()); 72 73 root1FO = workDir.createFolder("root1"); 74 root2FO = workDir.createFolder("root2"); 75 76 root1URL = URLMapper.findURL(root1FO, URLMapper.INTERNAL); 77 root2URL = URLMapper.findURL(root2FO, URLMapper.INTERNAL); 78 79 binary1URL = FileUtil.getArchiveRoot(URLMapper.findURL(workDir.createData("binary1.jar"), URLMapper.INTERNAL)); 80 src1 = workDir.createFolder("src1"); 81 82 binary2URL = FileUtil.getArchiveRoot(URLMapper.findURL(workDir.createData("binary2.jar"), URLMapper.INTERNAL)); 83 src2 = workDir.createFolder("src2"); 84 85 s4bq1 = new SourceForBinaryQueryImpl(binary1URL, new FileObject[] { src1 }); 86 s4bq2 = new SourceForBinaryQueryImpl(binary2URL, new FileObject[] { src2 }); 87 setLookups(new Object [] { s4bq1, s4bq2 }); 88 } 89 90 public void testClassPathSourceCache() throws Exception { 91 ClassPathImpl classPathImpl = new ClassPathImpl(new URL [] { root1URL, root2URL, binary1URL }); 92 ClassPath classPath = ClassPathFactory.createClassPath(classPathImpl); 93 ClassPathSourceCache cache = ClassPathSourceCache.newInstance(classPath, true); 94 PCL pcl = new PCL(); 95 cache.addPropertyChangeListener(pcl); 96 97 assertFalse(pcl.testChangeAndReset()); 98 assertTrue(cache.contains(src1)); 99 assertFalse(cache.contains(src2)); 100 assertRoots(new FileObject[] { root1FO, root2FO, src1 }, cache.getRoots()); 101 102 104 classPathImpl.changeResources(new URL [] { root1URL, root2URL, binary1URL, binary2URL }); 105 106 assertTrue(pcl.testChangeAndReset()); 107 assertTrue(cache.contains(src1)); 108 assertTrue(cache.contains(src2)); 109 assertRoots(new FileObject[] { root1FO, root2FO, src1, src2 }, cache.getRoots()); 110 111 113 s4bq1.getResult().changeRoots(new FileObject[0]); 114 115 assertTrue(pcl.testChangeAndReset()); 116 assertFalse(cache.contains(src1)); 117 assertTrue(cache.contains(src2)); 118 assertRoots(new FileObject[] { root1FO, root2FO, src2 }, cache.getRoots()); 119 assertTrue(cache.contains(root1FO)); 121 assertTrue(cache.contains(root2FO)); 122 assertFalse(cache.contains(src1)); 123 assertTrue(cache.contains(src2)); 124 125 127 root2FO.delete(); 128 129 assertTrue(pcl.testChangeAndReset()); 130 assertFalse(cache.contains(src1)); 131 assertTrue(cache.contains(src2)); 132 assertRoots(new FileObject[] { root1FO, src2 }, cache.getRoots()); 133 assertTrue(cache.contains(root1FO)); 134 assertFalse(cache.contains(root2FO)); 135 assertFalse(cache.contains(src1)); 136 assertTrue(cache.contains(src2)); 137 138 140 FileObject foo = src2.createFolder("foo"); 141 FileObject bar = foo.createData("bar"); 142 143 assertTrue(cache.contains(foo)); 144 assertTrue(cache.contains(bar)); 145 146 148 WeakReference <ClassPath> classPathRef = new WeakReference <ClassPath>(classPath); 149 classPathImpl = null; classPath = null; 151 152 assertGC("Should be able to GC classPath", classPathRef); 153 154 synchronized (cache) { 155 assertTrue("The cache should be deinitialized", cache.deinitialized); 156 assertEquals("The cache source roots should have deinitialized", 0, cache.sourceRoots.size()); 157 assertEquals("The cache SFBQ results should have deinitialized", 0, cache.results.size()); 158 } 159 160 assertEquals("Should have unregistered any SFBQ result listeners", 0, s4bq1.getResult().getListenerCount()); 161 assertEquals("Should have unregistered any SFBQ result listeners", 0, s4bq2.getResult().getListenerCount()); 162 } 163 164 public void testNoResolveSources() throws Exception { 165 ClassPathImpl classPathImpl = new ClassPathImpl(new URL [] { root1URL, root2URL, binary1URL }); 166 ClassPath classPath = ClassPathFactory.createClassPath(classPathImpl); 167 ClassPathSourceCache cache = ClassPathSourceCache.newInstance(classPath, false); 168 169 assertRoots(new FileObject[] { root1FO, root2FO }, cache.getRoots()); 170 171 174 classPathImpl.changeResources(new URL [] { root1URL, root2URL, binary1URL, binary2URL }); 175 176 assertRoots(new FileObject[] { root1FO, root2FO }, cache.getRoots()); 177 } 178 179 private static void assertRoots(FileObject[] expected, FileObject[] actual) { 180 Set <FileObject> expectedSet = new HashSet <FileObject>(Arrays.asList(expected)); 181 Set <FileObject> actualSet = new HashSet <FileObject>(Arrays.asList(actual)); 182 assertEquals("The expected array contains duplicates", expected.length, expectedSet.size()); 183 assertEquals("The actual array contains duplicates", actual.length, actualSet.size()); 184 assertEquals(expectedSet, actualSet); 185 } 186 187 private static final class SourceForBinaryQueryImpl implements SourceForBinaryQueryImplementation { 188 189 private final URL url; 190 private final FileObject[] roots; 191 192 private ResultImpl result; 193 194 public SourceForBinaryQueryImpl(URL url, FileObject[] roots) { 195 this.url = url; 196 this.roots = roots; 197 } 198 199 public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) { 200 if (url.equals(binaryRoot)) { 201 synchronized (this) { 202 if (result == null) { 203 result = new ResultImpl(roots); 204 } 205 return result; 206 } 207 } 208 return null; 209 } 210 211 public synchronized ResultImpl getResult() { 212 return result; 213 } 214 } 215 216 private static final class ResultImpl implements SourceForBinaryQuery.Result { 217 218 private final ChangeSupport changeSupport = new ChangeSupport (this); 219 220 private FileObject[] roots; 221 222 public ResultImpl(FileObject[] roots) { 223 this.roots = roots; 224 } 225 226 public synchronized void changeRoots(FileObject[] roots) { 227 this.roots = roots; 228 changeSupport.fireChange(); 229 } 230 231 public synchronized FileObject[] getRoots() { 232 return roots; 233 } 234 235 public void addChangeListener(ChangeListener listener) { 236 changeSupport.addChangeListener(listener); 237 } 238 239 public void removeChangeListener(ChangeListener listener) { 240 changeSupport.removeChangeListener(listener); 241 } 242 243 public int getListenerCount() { 244 return changeSupport.getListenerCount(); 245 } 246 } 247 248 private static final class ClassPathImpl implements ClassPathImplementation { 249 250 private final PropertyChangeSupport propChangeSupport = new PropertyChangeSupport (this); 251 private List <PathResourceImplementation> resources; 252 253 public ClassPathImpl(URL [] urls) { 254 computeResources(urls); 255 } 256 257 public synchronized void changeResources(URL [] urls) { 258 computeResources(urls); 259 propChangeSupport.firePropertyChange(ClassPathImplementation.PROP_RESOURCES, null, null); 260 } 261 262 private synchronized void computeResources(URL [] urls) { 263 resources = new ArrayList <PathResourceImplementation>(); 264 for (URL url : urls) { 265 resources.add(ClassPathSupport.createResource(url)); 266 } 267 } 268 269 public synchronized List getResources() { 270 return resources; 271 } 272 273 public void addPropertyChangeListener(PropertyChangeListener listener) { 274 propChangeSupport.addPropertyChangeListener(listener); 275 } 276 277 public void removePropertyChangeListener(PropertyChangeListener listener) { 278 propChangeSupport.removePropertyChangeListener(listener); 279 } 280 } 281 282 private static final class PCL implements PropertyChangeListener { 283 284 private int changeCount; 285 286 public void propertyChange(PropertyChangeEvent event) { 287 if (ClassPathSourceCache.PROP_ROOTS.equals(event.getPropertyName())) { 288 changeCount++; 289 } 290 } 291 292 private boolean testChangeAndReset() { 293 boolean result = changeCount > 0; 294 changeCount = 0; 295 return result; 296 } 297 } 298 } 299 | Popular Tags |