001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.api.java.classpath;
043:
044: import java.io.File;
045: import java.beans.PropertyChangeEvent;
046: import java.beans.PropertyChangeListener;
047: import java.beans.PropertyChangeSupport;
048: import java.io.FileOutputStream;
049: import java.lang.ref.Reference;
050: import java.lang.ref.WeakReference;
051: import java.net.URL;
052: import java.util.ArrayList;
053: import java.util.Arrays;
054: import java.util.Collections;
055: import java.util.Iterator;
056: import java.util.List;
057: import java.util.SortedSet;
058: import java.util.TreeSet;
059: import java.util.jar.JarOutputStream;
060: import java.util.zip.ZipEntry;
061: import org.netbeans.junit.NbTestCase;
062: import org.netbeans.spi.java.classpath.support.ClassPathSupport;
063: import org.netbeans.spi.java.classpath.ClassPathImplementation;
064: import org.netbeans.spi.java.classpath.ClassPathFactory;
065: import org.netbeans.spi.java.classpath.FilteringPathResourceImplementation;
066: import org.netbeans.spi.java.classpath.PathResourceImplementation;
067: import org.openide.filesystems.FileObject;
068: import org.openide.filesystems.FileUtil;
069:
070: public class ClassPathTest extends NbTestCase {
071:
072: public ClassPathTest(String testName) {
073: super (testName);
074: }
075:
076: protected void setUp() throws Exception {
077: super .setUp();
078: clearWorkDir();
079: }
080:
081: private File getBaseDir() throws Exception {
082: return FileUtil.normalizeFile(getWorkDir());
083: }
084:
085: /**
086: * Tests ClassPath.getResourceName ();
087: */
088: public void testGetResourceName() throws Exception {
089: File f = getBaseDir();
090: f = new File(f.getPath() + "/w.e.i.r.d/f o l d e r");
091: f.mkdirs();
092: File f2 = new File(f, "org/netbeans/test");
093: f2.mkdirs();
094: File f3 = new File(f2, "Main.java");
095: f3.createNewFile();
096:
097: FileObject cpRoot = FileUtil.toFileObject(f);
098: FileObject cpItem = FileUtil.toFileObject(f2);
099: FileObject clazz = FileUtil.toFileObject(f3);
100: ClassPath cp = ClassPathSupport
101: .createClassPath(new FileObject[] { cpRoot });
102: String pkg = cp.getResourceName(cpItem);
103: assertEquals("org/netbeans/test", pkg);
104:
105: pkg = cp.getResourceName(cpItem, '.', true);
106: assertEquals("org.netbeans.test", pkg);
107:
108: pkg = cp.getResourceName(cpItem, '.', false);
109: assertEquals("org.netbeans.test", pkg);
110:
111: pkg = cp.getResourceName(cpItem, '#', true);
112: assertEquals("org#netbeans#test", pkg);
113:
114: pkg = cp.getResourceName(cpItem, '#', false);
115: assertEquals("org#netbeans#test", pkg);
116:
117: pkg = cp.getResourceName(clazz);
118: assertEquals("org/netbeans/test/Main.java", pkg);
119:
120: pkg = cp.getResourceName(clazz, '.', true);
121: assertEquals("org.netbeans.test.Main.java", pkg);
122:
123: pkg = cp.getResourceName(clazz, '.', false);
124: assertEquals("org.netbeans.test.Main", pkg);
125:
126: pkg = cp.getResourceName(clazz, '@', true);
127: assertEquals("org@netbeans@test@Main.java", pkg);
128:
129: pkg = cp.getResourceName(clazz, '@', false);
130: assertEquals("org@netbeans@test@Main", pkg);
131: }
132:
133: /**
134: * Tests ClassPath.findAllResources(), ClassPath.findResoruce(),
135: * ClassPath.contains (), ClassPath.findOwnerRoot(),
136: * ClassPath.isResourceVisible ()
137: */
138: public void testGetResource() throws Exception {
139: File root_1 = new File(getBaseDir(), "root_1");
140: root_1.mkdir();
141: File root_2 = new File(getBaseDir(), "root_2");
142: root_2.mkdir();
143: FileObject[] roots = new FileObject[] {
144: FileUtil.toFileObject(root_1),
145: FileUtil.toFileObject(root_2), };
146:
147: FileObject tmp = roots[0].createFolder("org");
148: tmp = tmp.createFolder("me");
149: FileObject testFo_1 = tmp.createData("Foo", "txt");
150: tmp = roots[1].createFolder("org");
151: tmp = tmp.createFolder("me");
152: FileObject testFo_2 = tmp.createData("Foo", "txt");
153: ClassPath cp = ClassPathSupport.createClassPath(roots);
154:
155: //findResource
156: assertTrue(cp.findResource("org/me/Foo.txt") == testFo_1);
157: assertTrue(cp.findResource("org/me/None.txt") == null);
158:
159: //findAllResources
160: List res = cp.findAllResources("org/me/Foo.txt");
161: assertTrue(res.size() == 2);
162: assertTrue(res.contains(testFo_1));
163: assertTrue(res.contains(testFo_2));
164:
165: //contains
166: assertTrue(cp.contains(testFo_1));
167: assertTrue(cp.contains(testFo_2));
168: assertFalse(cp.contains(roots[0].getParent()));
169:
170: //findOwnerRoot
171: assertTrue(cp.findOwnerRoot(testFo_1) == roots[0]);
172: assertTrue(cp.findOwnerRoot(testFo_2) == roots[1]);
173:
174: /*
175: //isResourceVisible
176: assertTrue (cp.isResourceVisible(testFo_1));
177: assertFalse (cp.isResourceVisible(testFo_2));
178: */
179:
180: cp = null;
181: roots[0].delete();
182: roots[1].delete();
183: }
184:
185: /**
186: * Test ClassPath.getRoots(), ClassPath.addPropertyChangeListener (),
187: * ClassPath.entries () and classpath SPI.
188: */
189: public void testListening() throws Exception {
190:
191: File root_1 = new File(getBaseDir(), "root_1");
192: root_1.mkdir();
193: File root_2 = new File(getBaseDir(), "root_2");
194: root_2.mkdir();
195: File root_3 = new File(getBaseDir(), "root_3.jar");
196: JarOutputStream out = new JarOutputStream(new FileOutputStream(
197: root_3));
198: try {
199: out.putNextEntry(new ZipEntry("test.txt"));
200: out.write("test".getBytes());
201: } finally {
202: out.close();
203: }
204: assertNotNull("Cannot find file", FileUtil.toFileObject(root_1));
205: assertNotNull("Cannot find file", FileUtil.toFileObject(root_2));
206: assertNotNull("Cannot find file", FileUtil.toFileObject(root_3));
207: TestClassPathImplementation impl = new TestClassPathImplementation();
208: ClassPath cp = ClassPathFactory.createClassPath(impl);
209: impl.addResource(root_1.toURI().toURL());
210: cp.addPropertyChangeListener(impl);
211: impl.addResource(root_2.toURI().toURL());
212: impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS);
213: assertTrue(cp.getRoots().length == 2);
214: impl.removeResource(root_2.toURI().toURL());
215: impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS);
216: assertTrue(cp.getRoots().length == 1);
217: FileObject fo = cp.getRoots()[0];
218: FileObject parentFolder = fo.getParent();
219: fo.delete();
220: impl.assertEvents(ClassPath.PROP_ROOTS);
221: assertTrue(cp.getRoots().length == 0);
222: parentFolder.createFolder("root_1");
223: assertTrue(cp.getRoots().length == 1);
224: impl.assertEvents(ClassPath.PROP_ROOTS);
225: FileObject archiveFile = FileUtil.toFileObject(root_3);
226: impl.addResource(FileUtil.getArchiveRoot(archiveFile.getURL()));
227: assertEquals(cp.getRoots().length, 2);
228: impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS);
229: root_3.delete();
230: root_3 = new File(getBaseDir(), "root_3.jar");
231: Thread.sleep(1000);
232: out = new JarOutputStream(new FileOutputStream(root_3));
233: try {
234: out.putNextEntry(new ZipEntry("test2.txt"));
235: out.write("test2".getBytes());
236: } finally {
237: out.close();
238: }
239: archiveFile.refresh();
240: impl.assertEvents(ClassPath.PROP_ROOTS);
241: root_1.delete();
242: root_2.delete();
243: root_3.delete();
244: cp = null;
245: }
246:
247: public void testListening2() throws Exception {
248: // Checks that changes in PathResourceImplementation.PROP_ROOTS matter.
249: class FiringPRI implements PathResourceImplementation {
250: private URL[] roots = new URL[0];
251:
252: public URL[] getRoots() {
253: return roots;
254: }
255:
256: void changeRoots(URL[] nue) {
257: roots = nue;
258: pcs.firePropertyChange(PROP_ROOTS, null, null);
259: }
260:
261: public ClassPathImplementation getContent() {
262: return null;
263: }
264:
265: PropertyChangeSupport pcs = new PropertyChangeSupport(this );
266:
267: public void addPropertyChangeListener(
268: PropertyChangeListener listener) {
269: pcs.addPropertyChangeListener(listener);
270: }
271:
272: public void removePropertyChangeListener(
273: PropertyChangeListener listener) {
274: pcs.removePropertyChangeListener(listener);
275: }
276: }
277: FiringPRI pri = new FiringPRI();
278: TestClassPathImplementation impl = new TestClassPathImplementation();
279: impl.addResource(pri);
280: ClassPath cp = ClassPathFactory.createClassPath(impl);
281: assertEquals(Collections.emptyList(), Arrays.asList(cp
282: .getRoots()));
283: cp.addPropertyChangeListener(impl);
284: File d = new File(getBaseDir(), "d");
285: d.mkdir();
286: pri.changeRoots(new URL[] { d.toURI().toURL() });
287: impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS);
288: assertEquals(Collections
289: .singletonList(FileUtil.toFileObject(d)), Arrays
290: .asList(cp.getRoots()));
291: }
292:
293: public void testChangesAcknowledgedWithoutListener()
294: throws Exception {
295: // Discovered in #72573.
296: clearWorkDir();
297: File root = new File(getWorkDir(), "root");
298: URL rootU = root.toURI().toURL();
299: if (!rootU.toExternalForm().endsWith("/")) {
300: rootU = new URL(rootU.toExternalForm() + "/");
301: }
302: ClassPath cp = ClassPathSupport
303: .createClassPath(new URL[] { rootU });
304: assertEquals("nothing there yet", null, cp.findResource("f"));
305: FileObject f = FileUtil.createData(FileUtil
306: .toFileObject(getWorkDir()), "root/f");
307: assertEquals("found new file", f, cp.findResource("f"));
308: f.delete();
309: assertEquals("again empty", null, cp.findResource("f"));
310: }
311:
312: static final class TestClassPathImplementation implements
313: ClassPathImplementation, PropertyChangeListener {
314:
315: private final PropertyChangeSupport support = new PropertyChangeSupport(
316: this );
317: private final List<PathResourceImplementation> resources = new ArrayList<PathResourceImplementation>();
318: private final SortedSet<String> events = new TreeSet<String>();
319:
320: public synchronized void addResource(URL resource) {
321: PathResourceImplementation pr = ClassPathSupport
322: .createResource(resource);
323: addResource(pr);
324: }
325:
326: public synchronized void addResource(
327: PathResourceImplementation pr) {
328: this .resources.add(pr);
329: this .support.firePropertyChange(
330: ClassPathImplementation.PROP_RESOURCES, null, null);
331: }
332:
333: public synchronized void removeResource(URL resource) {
334: for (Iterator it = this .resources.iterator(); it.hasNext();) {
335: PathResourceImplementation pr = (PathResourceImplementation) it
336: .next();
337: if (Arrays.asList(pr.getRoots()).contains(resource)) {
338: this .resources.remove(pr);
339: this .support.firePropertyChange(
340: ClassPathImplementation.PROP_RESOURCES,
341: null, null);
342: break;
343: }
344: }
345: }
346:
347: public synchronized List<? extends PathResourceImplementation> getResources() {
348: return this .resources;
349: }
350:
351: public void addPropertyChangeListener(
352: PropertyChangeListener listener) {
353: this .support.addPropertyChangeListener(listener);
354: }
355:
356: public void removePropertyChangeListener(
357: PropertyChangeListener listener) {
358: this .support.removePropertyChangeListener(listener);
359: }
360:
361: public void propertyChange(PropertyChangeEvent event) {
362: events.add(event.getPropertyName());
363: }
364:
365: void assertEvents(String... events) {
366: assertEquals(new TreeSet<String>(Arrays.asList(events)),
367: this .events);
368: this .events.clear();
369: }
370: }
371:
372: public void testFilteredClassPaths() throws Exception {
373: FileObject bd = FileUtil.toFileObject(getBaseDir());
374: FileObject u1fo = bd.createFolder("u1");
375: FileObject u2fo = bd.createFolder("u2");
376: final URL u1 = u1fo.getURL();
377: final URL u2 = u2fo.getURL();
378: class FPRI implements FilteringPathResourceImplementation {
379: private int modulus = 2;
380:
381: public void changeIncludes(int modulus) {
382: this .modulus = modulus;
383: pcs.firePropertyChange(PROP_INCLUDES, null, null);
384: }
385:
386: public URL[] getRoots() {
387: return new URL[] { u1, u2 };
388: }
389:
390: public boolean includes(URL root, String resource) {
391: int offset;
392: if (root.equals(u1)) {
393: offset = 0;
394: } else if (root.equals(u2)) {
395: offset = 1;
396: } else {
397: throw new IllegalArgumentException(root.toString());
398: }
399: return (offset + resource.length()) % modulus == 0;
400: }
401:
402: public ClassPathImplementation getContent() {
403: return null;
404: }
405:
406: private PropertyChangeSupport pcs = new PropertyChangeSupport(
407: this );
408:
409: public void addPropertyChangeListener(
410: PropertyChangeListener listener) {
411: pcs.addPropertyChangeListener(listener);
412: }
413:
414: public void removePropertyChangeListener(
415: PropertyChangeListener listener) {
416: pcs.removePropertyChangeListener(listener);
417: }
418: }
419: FPRI pr = new FPRI();
420: TestClassPathImplementation impl = new TestClassPathImplementation();
421: impl.addResource(pr);
422: ClassPath cp = ClassPathFactory.createClassPath(impl);
423: FileObject xx1 = u1fo.createData("xx");
424: FileObject xxx1 = u1fo.createData("xxx");
425: FileObject xy1 = FileUtil.createData(u1fo, "x/y");
426: FileObject x_1 = u1fo.createData("x ");
427: String cau = "\u010Dau";
428: FileObject cau1 = u1fo.createData(cau);
429: FileObject folder = u1fo.createFolder("folder");
430: FileObject foldr = u1fo.createFolder("foldr");
431: FileObject xx2 = u2fo.createData("xx");
432: FileObject xxx2 = u2fo.createData("xxx");
433: FileObject xy2 = FileUtil.createData(u2fo, "x/y");
434: FileObject x_2 = u2fo.createData("x ");
435: FileObject cau2 = u2fo.createData(cau);
436: assertEquals(Arrays.asList(u1fo, u2fo), Arrays.asList(cp
437: .getRoots()));
438: assertTrue(cp.contains(xx1));
439: assertTrue(cp.contains(x_1));
440: assertFalse(cp.contains(xxx1));
441: assertFalse(cp.contains(cau1));
442: assertFalse(cp.contains(xy1));
443: assertFalse(cp.contains(xx2));
444: assertFalse(cp.contains(x_2));
445: assertTrue(cp.contains(xxx2));
446: assertTrue(cp.contains(cau2));
447: assertTrue(cp.contains(xy2));
448: assertFalse(cp.contains(folder));
449: assertTrue(cp.contains(foldr));
450: assertEquals(xx1, cp.findResource("xx"));
451: assertEquals(x_1, cp.findResource("x "));
452: assertEquals(xxx2, cp.findResource("xxx"));
453: assertEquals(cau2, cp.findResource(cau));
454: assertEquals(xy2, cp.findResource("x/y"));
455: assertEquals(null, cp.findResource("folder"));
456: assertEquals(foldr, cp.findResource("foldr"));
457: assertEquals(Collections.singletonList(xx1), cp
458: .findAllResources("xx"));
459: assertEquals(Collections.singletonList(x_1), cp
460: .findAllResources("x "));
461: assertEquals(Collections.singletonList(xxx2), cp
462: .findAllResources("xxx"));
463: assertEquals(Collections.singletonList(cau2), cp
464: .findAllResources(cau));
465: assertEquals(Collections.singletonList(xy2), cp
466: .findAllResources("x/y"));
467: assertEquals(Collections.emptyList(), cp
468: .findAllResources("folder"));
469: assertEquals(Collections.singletonList(foldr), cp
470: .findAllResources("foldr"));
471: assertEquals("xx", cp.getResourceName(xx1));
472: assertEquals("x ", cp.getResourceName(x_1));
473: assertEquals("xxx", cp.getResourceName(xxx1));
474: assertEquals(cau, cp.getResourceName(cau1));
475: assertEquals("x/y", cp.getResourceName(xy1));
476: assertEquals("folder", cp.getResourceName(folder));
477: assertEquals("foldr", cp.getResourceName(foldr));
478: assertEquals(u1fo, cp.findOwnerRoot(xx1));
479: assertEquals(u1fo, cp.findOwnerRoot(x_1));
480: assertEquals(u1fo, cp.findOwnerRoot(xxx1));
481: assertEquals(u1fo, cp.findOwnerRoot(cau1));
482: assertEquals(u1fo, cp.findOwnerRoot(xy1));
483: assertEquals(u1fo, cp.findOwnerRoot(folder));
484: assertEquals(u1fo, cp.findOwnerRoot(foldr));
485: assertTrue(cp.isResourceVisible(xx1));
486: assertTrue(cp.isResourceVisible(x_1));
487: assertFalse(cp.isResourceVisible(xxx1));
488: assertFalse(cp.isResourceVisible(cau1));
489: assertFalse(cp.isResourceVisible(xy1));
490: assertFalse(cp.isResourceVisible(folder));
491: assertTrue(cp.isResourceVisible(foldr));
492: ClassPath.Entry e1 = cp.entries().get(0);
493: assertTrue(e1.includes("xx"));
494: assertTrue(e1.includes("x "));
495: assertFalse(e1.includes("xxx"));
496: assertFalse(e1.includes(cau));
497: assertFalse(e1.includes("x/y"));
498: assertFalse(e1.includes("folder/"));
499: assertTrue(e1.includes("foldr/"));
500: assertTrue(e1.includes(xx1));
501: assertTrue(e1.includes(x_1));
502: assertFalse(e1.includes(xxx1));
503: assertFalse(e1.includes(cau1));
504: assertFalse(e1.includes(xy1));
505: assertFalse(e1.includes(folder));
506: assertTrue(e1.includes(foldr));
507: try {
508: e1.includes(xx2);
509: fail();
510: } catch (IllegalArgumentException iae) {
511: }
512: assertTrue(e1.includes(xx1.getURL()));
513: assertTrue(e1.includes(x_1.getURL()));
514: assertFalse(e1.includes(xxx1.getURL()));
515: assertFalse(e1.includes(cau1.getURL()));
516: assertFalse(e1.includes(xy1.getURL()));
517: assertFalse(e1.includes(folder.getURL()));
518: assertTrue(e1.includes(foldr.getURL()));
519: try {
520: e1.includes(xx2.getURL());
521: fail();
522: } catch (IllegalArgumentException iae) {
523: }
524: cp.addPropertyChangeListener(impl);
525: pr.changeIncludes(3);
526: impl.assertEvents(ClassPath.PROP_INCLUDES);
527: assertFalse(cp.contains(xx1));
528: assertFalse(cp.contains(x_1));
529: assertTrue(cp.contains(xxx1));
530: assertTrue(cp.contains(cau1));
531: assertTrue(cp.contains(xy1));
532: assertTrue(cp.contains(xx2));
533: assertTrue(cp.contains(x_2));
534: assertFalse(cp.contains(xxx2));
535: assertFalse(cp.contains(cau2));
536: assertFalse(cp.contains(xy2));
537: assertEquals(xx2, cp.findResource("xx"));
538: assertEquals(x_2, cp.findResource("x "));
539: assertEquals(xxx1, cp.findResource("xxx"));
540: assertEquals(cau1, cp.findResource(cau));
541: assertEquals(xy1, cp.findResource("x/y"));
542: e1 = cp.entries().get(0);
543: assertFalse(e1.includes("xx"));
544: assertFalse(e1.includes("x "));
545: assertTrue(e1.includes("xxx"));
546: assertTrue(e1.includes(cau));
547: assertTrue(e1.includes("x/y"));
548: assertFalse(e1.includes(xx1));
549: assertFalse(e1.includes(x_1));
550: assertTrue(e1.includes(xxx1));
551: assertTrue(e1.includes(cau1));
552: assertTrue(e1.includes(xy1));
553: assertFalse(e1.includes(xx1.getURL()));
554: assertFalse(e1.includes(x_1.getURL()));
555: assertTrue(e1.includes(xxx1.getURL()));
556: assertTrue(e1.includes(cau1.getURL()));
557: assertTrue(e1.includes(xy1.getURL()));
558: }
559:
560: public void testFpriChangeFiring() throws Exception {
561: class FPRI implements FilteringPathResourceImplementation {
562: URL root;
563: PropertyChangeSupport pcs = new PropertyChangeSupport(this );
564:
565: FPRI(URL root) {
566: this .root = root;
567: }
568:
569: public boolean includes(URL root, String resource) {
570: return true;
571: }
572:
573: public URL[] getRoots() {
574: return new URL[] { root };
575: }
576:
577: public ClassPathImplementation getContent() {
578: return null;
579: }
580:
581: public void addPropertyChangeListener(
582: PropertyChangeListener listener) {
583: pcs.addPropertyChangeListener(listener);
584: }
585:
586: public void removePropertyChangeListener(
587: PropertyChangeListener listener) {
588: pcs.removePropertyChangeListener(listener);
589: }
590:
591: void fire(Object propid) {
592: PropertyChangeEvent e = new PropertyChangeEvent(
593: this ,
594: FilteringPathResourceImplementation.PROP_INCLUDES,
595: null, null);
596: e.setPropagationId(propid);
597: pcs.firePropertyChange(e);
598: }
599: }
600: FPRI fpri1 = new FPRI(new File(getWorkDir(), "src1").toURI()
601: .toURL());
602: FPRI fpri2 = new FPRI(new File(getWorkDir(), "src2").toURI()
603: .toURL());
604: class L implements PropertyChangeListener {
605: int cnt;
606:
607: public void propertyChange(PropertyChangeEvent e) {
608: if (ClassPath.PROP_INCLUDES.equals(e.getPropertyName())) {
609: cnt++;
610: }
611: }
612: }
613: ClassPath cp = ClassPathSupport.createClassPath(Arrays.asList(
614: fpri1, fpri2));
615: L l = new L();
616: cp.addPropertyChangeListener(l);
617: //No events fired before cp.entries() called
618: fpri1.fire(null);
619: assertEquals(0, l.cnt);
620: cp.entries();
621: fpri1.fire(null);
622: assertEquals(1, l.cnt);
623: fpri2.fire(null);
624: assertEquals(2, l.cnt);
625: fpri1.fire("hello");
626: assertEquals(3, l.cnt);
627: fpri2.fire("goodbye");
628: assertEquals(4, l.cnt);
629: fpri1.fire("fixed");
630: assertEquals(5, l.cnt);
631: fpri2.fire("fixed");
632: assertEquals(5, l.cnt);
633: fpri1.fire("new");
634: assertEquals(6, l.cnt);
635: }
636:
637: public void testLeakingClassPath() throws Exception {
638: ClassPath cp = ClassPathSupport.createClassPath(new URL(
639: "file:///a/"), new URL("file:///b/"));
640: ClassPath proxyCP = ClassPathSupport.createProxyClassPath(cp);
641: Reference<ClassPath> proxy = new WeakReference<ClassPath>(
642: proxyCP);
643:
644: proxyCP.entries();
645:
646: proxyCP = null;
647:
648: assertGC("the proxy classpath needs to GCable", proxy);
649: }
650:
651: }
|