Lines 1-701
Link Here
|
1 |
/* |
|
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. |
5 |
* |
6 |
* The contents of this file are subject to the terms of either the GNU |
7 |
* General Public License Version 2 only ("GPL") or the Common |
8 |
* Development and Distribution License("CDDL") (collectively, the |
9 |
* "License"). You may not use this file except in compliance with the |
10 |
* License. You can obtain a copy of the License at |
11 |
* http://www.netbeans.org/cddl-gplv2.html |
12 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
13 |
* specific language governing permissions and limitations under the |
14 |
* License. When distributing the software, include this License Header |
15 |
* Notice in each file and include the License file at |
16 |
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this |
17 |
* particular file as subject to the "Classpath" exception as provided |
18 |
* by Sun in the GPL Version 2 section of the License file that |
19 |
* accompanied this code. If applicable, add the following below the |
20 |
* License Header, with the fields enclosed by brackets [] replaced by |
21 |
* your own identifying information: |
22 |
* "Portions Copyrighted [year] [name of copyright owner]" |
23 |
* |
24 |
* Contributor(s): |
25 |
* |
26 |
* The Original Software is NetBeans. The Initial Developer of the Original |
27 |
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun |
28 |
* Microsystems, Inc. All Rights Reserved. |
29 |
* |
30 |
* If you wish your version of this file to be governed by only the CDDL |
31 |
* or only the GPL Version 2, indicate your decision by adding |
32 |
* "[Contributor] elects to include this software in this distribution |
33 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
34 |
* single choice of license, a recipient has the option to distribute |
35 |
* your version of this file under either the CDDL, the GPL Version 2 or |
36 |
* to extend the choice of license to its licensees as provided above. |
37 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
38 |
* Version 2 license, then the option applies only if the new code is |
39 |
* made subject to such option by the copyright holder. |
40 |
*/ |
41 |
|
42 |
package org.netbeans.api.java.classpath; |
43 |
|
44 |
import java.io.File; |
45 |
import java.beans.PropertyChangeEvent; |
46 |
import java.beans.PropertyChangeListener; |
47 |
import java.beans.PropertyChangeSupport; |
48 |
import java.io.FileOutputStream; |
49 |
import java.lang.ref.Reference; |
50 |
import java.lang.ref.WeakReference; |
51 |
import java.net.URL; |
52 |
import java.net.URLClassLoader; |
53 |
import java.util.ArrayList; |
54 |
import java.util.Arrays; |
55 |
import java.util.Collections; |
56 |
import java.util.Enumeration; |
57 |
import java.util.HashSet; |
58 |
import java.util.Iterator; |
59 |
import java.util.List; |
60 |
import java.util.Set; |
61 |
import java.util.SortedSet; |
62 |
import java.util.StringTokenizer; |
63 |
import java.util.TreeSet; |
64 |
import java.util.jar.JarOutputStream; |
65 |
import java.util.logging.Level; |
66 |
import java.util.zip.ZipEntry; |
67 |
import org.netbeans.junit.Log; |
68 |
import org.netbeans.junit.NbTestCase; |
69 |
import org.netbeans.spi.java.classpath.support.ClassPathSupport; |
70 |
import org.netbeans.spi.java.classpath.ClassPathImplementation; |
71 |
import org.netbeans.spi.java.classpath.ClassPathFactory; |
72 |
import org.netbeans.spi.java.classpath.FilteringPathResourceImplementation; |
73 |
import org.netbeans.spi.java.classpath.PathResourceImplementation; |
74 |
import org.openide.filesystems.FileObject; |
75 |
import org.openide.filesystems.FileUtil; |
76 |
|
77 |
public class ClassPathTest extends NbTestCase { |
78 |
|
79 |
public ClassPathTest(String testName) { |
80 |
super(testName); |
81 |
} |
82 |
|
83 |
protected @Override void setUp() throws Exception { |
84 |
super.setUp(); |
85 |
clearWorkDir(); |
86 |
} |
87 |
|
88 |
private File getBaseDir() throws Exception { |
89 |
return FileUtil.normalizeFile(getWorkDir()); |
90 |
} |
91 |
|
92 |
/** |
93 |
* Tests ClassPath.getResourceName (); |
94 |
*/ |
95 |
public void testGetResourceName() throws Exception { |
96 |
File f = getBaseDir(); |
97 |
f = new File(f.getPath()+"/w.e.i.r.d/f o l d e r"); |
98 |
f.mkdirs(); |
99 |
File f2 = new File(f, "org/netbeans/test"); |
100 |
f2.mkdirs(); |
101 |
File f3 = new File(f2, "Main.java"); |
102 |
f3.createNewFile(); |
103 |
|
104 |
FileObject cpRoot = FileUtil.toFileObject(f); |
105 |
FileObject cpItem = FileUtil.toFileObject(f2); |
106 |
FileObject clazz = FileUtil.toFileObject(f3); |
107 |
ClassPath cp = ClassPathSupport.createClassPath(new FileObject[]{cpRoot}); |
108 |
String pkg = cp.getResourceName(cpItem); |
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(cpItem, '#', true); |
118 |
assertEquals("org#netbeans#test", pkg); |
119 |
|
120 |
pkg = cp.getResourceName(cpItem, '#', false); |
121 |
assertEquals("org#netbeans#test", pkg); |
122 |
|
123 |
pkg = cp.getResourceName(clazz); |
124 |
assertEquals("org/netbeans/test/Main.java", 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 |
pkg = cp.getResourceName(clazz, '@', true); |
133 |
assertEquals("org@netbeans@test@Main.java", pkg); |
134 |
|
135 |
pkg = cp.getResourceName(clazz, '@', false); |
136 |
assertEquals("org@netbeans@test@Main", pkg); |
137 |
} |
138 |
|
139 |
/** |
140 |
* Tests ClassPath.findAllResources(), ClassPath.findResoruce(), |
141 |
* ClassPath.contains (), ClassPath.findOwnerRoot(), |
142 |
* ClassPath.isResourceVisible () |
143 |
*/ |
144 |
public void testGetResource () throws Exception { |
145 |
File root_1 = new File (getBaseDir(),"root_1"); |
146 |
root_1.mkdir(); |
147 |
File root_2 = new File (getBaseDir(),"root_2"); |
148 |
root_2.mkdir(); |
149 |
FileObject[] roots = new FileObject [] { |
150 |
FileUtil.toFileObject(root_1), |
151 |
FileUtil.toFileObject(root_2), |
152 |
}; |
153 |
|
154 |
FileObject tmp = roots[0].createFolder("org"); |
155 |
tmp = tmp.createFolder("me"); |
156 |
FileObject testFo_1 = tmp.createData("Foo","txt"); |
157 |
tmp = roots[1].createFolder("org"); |
158 |
tmp = tmp.createFolder("me"); |
159 |
FileObject testFo_2 = tmp.createData("Foo","txt"); |
160 |
ClassPath cp = ClassPathSupport.createClassPath(roots); |
161 |
|
162 |
//findResource |
163 |
assertTrue(cp.findResource ("org/me/Foo.txt")==testFo_1); |
164 |
assertTrue (cp.findResource("org/me/None.txt")==null); |
165 |
|
166 |
//findAllResources |
167 |
List res = cp.findAllResources ("org/me/Foo.txt"); |
168 |
assertTrue (res.size() == 2); |
169 |
assertTrue (res.contains(testFo_1)); |
170 |
assertTrue (res.contains(testFo_2)); |
171 |
|
172 |
//contains |
173 |
assertTrue (cp.contains (testFo_1)); |
174 |
assertTrue (cp.contains (testFo_2)); |
175 |
assertFalse (cp.contains (roots[0].getParent())); |
176 |
|
177 |
//findOwnerRoot |
178 |
assertTrue (cp.findOwnerRoot(testFo_1)==roots[0]); |
179 |
assertTrue (cp.findOwnerRoot(testFo_2)==roots[1]); |
180 |
|
181 |
/* |
182 |
//isResourceVisible |
183 |
assertTrue (cp.isResourceVisible(testFo_1)); |
184 |
assertFalse (cp.isResourceVisible(testFo_2)); |
185 |
*/ |
186 |
|
187 |
cp = null; |
188 |
roots[0].delete(); |
189 |
roots[1].delete(); |
190 |
} |
191 |
|
192 |
/** |
193 |
* Test ClassPath.getRoots(), ClassPath.addPropertyChangeListener (), |
194 |
* ClassPath.entries () and classpath SPI. |
195 |
*/ |
196 |
public void testListening() throws Exception { |
197 |
// XXX unreliable, would be improved by usage of TestFileUtils methods: |
198 |
|
199 |
File root_1 = new File (getBaseDir(),"root_1"); |
200 |
root_1.mkdir(); |
201 |
File root_2 = new File (getBaseDir(),"root_2"); |
202 |
root_2.mkdir(); |
203 |
File root_3 = new File (getBaseDir(),"root_3.jar"); |
204 |
JarOutputStream out = new JarOutputStream ( new FileOutputStream (root_3)); |
205 |
try { |
206 |
out.putNextEntry(new ZipEntry("test.txt")); |
207 |
out.write ("test".getBytes()); |
208 |
} finally { |
209 |
out.close (); |
210 |
} |
211 |
assertNotNull("Cannot find file",FileUtil.toFileObject(root_1)); |
212 |
assertNotNull("Cannot find file",FileUtil.toFileObject(root_2)); |
213 |
assertNotNull("Cannot find file",FileUtil.toFileObject(root_3)); |
214 |
TestClassPathImplementation impl = new TestClassPathImplementation(); |
215 |
ClassPath cp = ClassPathFactory.createClassPath (impl); |
216 |
impl.addResource(root_1.toURI().toURL()); |
217 |
cp.addPropertyChangeListener (impl); |
218 |
impl.addResource (root_2.toURI().toURL()); |
219 |
impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); |
220 |
assertTrue (cp.getRoots().length==2); |
221 |
impl.removeResource (root_2.toURI().toURL()); |
222 |
impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); |
223 |
assertTrue (cp.getRoots().length==1); |
224 |
FileObject fo = cp.getRoots()[0]; |
225 |
FileObject parentFolder = fo.getParent(); |
226 |
fo.delete(); |
227 |
impl.assertEvents(ClassPath.PROP_ROOTS); |
228 |
assertTrue (cp.getRoots().length==0); |
229 |
parentFolder.createFolder("root_1"); |
230 |
assertTrue (cp.getRoots().length==1); |
231 |
impl.assertEvents(ClassPath.PROP_ROOTS); |
232 |
FileObject archiveFile = FileUtil.toFileObject(root_3); |
233 |
impl.addResource(FileUtil.getArchiveRoot(archiveFile.getURL())); |
234 |
assertEquals (cp.getRoots().length,2); |
235 |
impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); |
236 |
root_3.delete(); |
237 |
root_3 = new File (getBaseDir(),"root_3.jar"); |
238 |
Thread.sleep(1000); |
239 |
out = new JarOutputStream ( new FileOutputStream (root_3)); |
240 |
try { |
241 |
out.putNextEntry(new ZipEntry("test2.txt")); |
242 |
out.write ("test2".getBytes()); |
243 |
} finally { |
244 |
out.close (); |
245 |
} |
246 |
archiveFile.refresh(); |
247 |
impl.assertEvents(ClassPath.PROP_ROOTS); |
248 |
root_1.delete(); |
249 |
root_2.delete(); |
250 |
root_3.delete(); |
251 |
cp = null; |
252 |
} |
253 |
|
254 |
public void testListening2() throws Exception { |
255 |
// Checks that changes in PathResourceImplementation.PROP_ROOTS matter. |
256 |
class FiringPRI implements PathResourceImplementation { |
257 |
private URL[] roots = new URL[0]; |
258 |
public URL[] getRoots() { |
259 |
return roots; |
260 |
} |
261 |
void changeRoots(URL[] nue) { |
262 |
roots = nue; |
263 |
pcs.firePropertyChange(PROP_ROOTS, null, null); |
264 |
} |
265 |
public ClassPathImplementation getContent() { |
266 |
return null; |
267 |
} |
268 |
PropertyChangeSupport pcs = new PropertyChangeSupport(this); |
269 |
public void addPropertyChangeListener(PropertyChangeListener listener) { |
270 |
pcs.addPropertyChangeListener(listener); |
271 |
} |
272 |
public void removePropertyChangeListener(PropertyChangeListener listener) { |
273 |
pcs.removePropertyChangeListener(listener); |
274 |
} |
275 |
} |
276 |
FiringPRI pri = new FiringPRI(); |
277 |
TestClassPathImplementation impl = new TestClassPathImplementation(); |
278 |
impl.addResource(pri); |
279 |
ClassPath cp = ClassPathFactory.createClassPath(impl); |
280 |
assertEquals(Collections.emptyList(), Arrays.asList(cp.getRoots())); |
281 |
cp.addPropertyChangeListener(impl); |
282 |
File d = new File(getBaseDir(), "d"); |
283 |
d.mkdir(); |
284 |
pri.changeRoots(new URL[] {d.toURI().toURL()}); |
285 |
impl.assertEvents(ClassPath.PROP_ENTRIES, ClassPath.PROP_ROOTS); |
286 |
assertEquals(Collections.singletonList(FileUtil.toFileObject(d)), Arrays.asList(cp.getRoots())); |
287 |
} |
288 |
|
289 |
public void testChangesAcknowledgedWithoutListener() throws Exception { |
290 |
// Discovered in #72573. |
291 |
clearWorkDir(); |
292 |
File root = new File(getWorkDir(), "root"); |
293 |
URL rootU = root.toURI().toURL(); |
294 |
if (!rootU.toExternalForm().endsWith("/")) { |
295 |
rootU = new URL(rootU.toExternalForm() + "/"); |
296 |
} |
297 |
ClassPath cp = ClassPathSupport.createClassPath(new URL[] {rootU}); |
298 |
assertEquals("nothing there yet", null, cp.findResource("f")); |
299 |
FileObject f = FileUtil.createData(FileUtil.toFileObject(getWorkDir()), "root/f"); |
300 |
assertEquals("found new file", f, cp.findResource("f")); |
301 |
f.delete(); |
302 |
assertEquals("again empty", null, cp.findResource("f")); |
303 |
} |
304 |
|
305 |
static final class TestClassPathImplementation implements ClassPathImplementation, PropertyChangeListener { |
306 |
|
307 |
private final PropertyChangeSupport support = new PropertyChangeSupport (this); |
308 |
private final List<PathResourceImplementation> resources = new ArrayList<PathResourceImplementation> (); |
309 |
private final SortedSet<String> events = new TreeSet<String>(); |
310 |
|
311 |
public synchronized void addResource (URL resource) { |
312 |
PathResourceImplementation pr = ClassPathSupport.createResource (resource); |
313 |
addResource(pr); |
314 |
} |
315 |
|
316 |
public synchronized void addResource(PathResourceImplementation pr) { |
317 |
this.resources.add (pr); |
318 |
this.support.firePropertyChange (ClassPathImplementation.PROP_RESOURCES,null,null); |
319 |
} |
320 |
|
321 |
public synchronized void removeResource (URL resource) { |
322 |
for (Iterator it = this.resources.iterator(); it.hasNext();) { |
323 |
PathResourceImplementation pr = (PathResourceImplementation) it.next (); |
324 |
if (Arrays.asList(pr.getRoots()).contains (resource)) { |
325 |
this.resources.remove (pr); |
326 |
this.support.firePropertyChange (ClassPathImplementation.PROP_RESOURCES,null,null); |
327 |
break; |
328 |
} |
329 |
} |
330 |
} |
331 |
|
332 |
public synchronized List<? extends PathResourceImplementation> getResources() { |
333 |
return this.resources; |
334 |
} |
335 |
|
336 |
public void addPropertyChangeListener(PropertyChangeListener listener) { |
337 |
this.support.addPropertyChangeListener (listener); |
338 |
} |
339 |
|
340 |
public void removePropertyChangeListener(PropertyChangeListener listener) { |
341 |
this.support.removePropertyChangeListener (listener); |
342 |
} |
343 |
|
344 |
public void propertyChange (PropertyChangeEvent event) { |
345 |
events.add(event.getPropertyName()); |
346 |
} |
347 |
|
348 |
void assertEvents(String... events) { |
349 |
assertEquals(new TreeSet<String>(Arrays.asList(events)), this.events); |
350 |
this.events.clear(); |
351 |
} |
352 |
} |
353 |
|
354 |
public void testFilteredClassPaths() throws Exception { |
355 |
FileObject bd = FileUtil.toFileObject(getBaseDir()); |
356 |
FileObject u1fo = bd.createFolder("u1"); |
357 |
FileObject u2fo = bd.createFolder("u2"); |
358 |
final URL u1 = u1fo.getURL(); |
359 |
final URL u2 = u2fo.getURL(); |
360 |
class FPRI implements FilteringPathResourceImplementation { |
361 |
private int modulus = 2; |
362 |
public void changeIncludes(int modulus) { |
363 |
this.modulus = modulus; |
364 |
pcs.firePropertyChange(PROP_INCLUDES, null, null); |
365 |
} |
366 |
public URL[] getRoots() { |
367 |
return new URL[] {u1, u2}; |
368 |
} |
369 |
public boolean includes(URL root, String resource) { |
370 |
int offset; |
371 |
if (root.equals(u1)) { |
372 |
offset = 0; |
373 |
} else if (root.equals(u2)) { |
374 |
offset = 1; |
375 |
} else { |
376 |
throw new IllegalArgumentException(root.toString()); |
377 |
} |
378 |
return (offset + resource.length()) % modulus == 0; |
379 |
} |
380 |
public ClassPathImplementation getContent() { |
381 |
return null; |
382 |
} |
383 |
private PropertyChangeSupport pcs = new PropertyChangeSupport(this); |
384 |
public void addPropertyChangeListener(PropertyChangeListener listener) { |
385 |
pcs.addPropertyChangeListener(listener); |
386 |
} |
387 |
public void removePropertyChangeListener(PropertyChangeListener listener) { |
388 |
pcs.removePropertyChangeListener(listener); |
389 |
} |
390 |
} |
391 |
FPRI pr = new FPRI(); |
392 |
TestClassPathImplementation impl = new TestClassPathImplementation(); |
393 |
impl.addResource(pr); |
394 |
ClassPath cp = ClassPathFactory.createClassPath(impl); |
395 |
FileObject xx1 = u1fo.createData("xx"); |
396 |
FileObject xxx1 = u1fo.createData("xxx"); |
397 |
FileObject xy1 = FileUtil.createData(u1fo, "x/y"); |
398 |
FileObject x_1 = u1fo.createData("x "); |
399 |
String cau = "\u010Dau"; |
400 |
FileObject cau1 = u1fo.createData(cau); |
401 |
FileObject folder = u1fo.createFolder("folder"); |
402 |
FileObject foldr = u1fo.createFolder("foldr"); |
403 |
FileObject xx2 = u2fo.createData("xx"); |
404 |
FileObject xxx2 = u2fo.createData("xxx"); |
405 |
FileObject xy2 = FileUtil.createData(u2fo, "x/y"); |
406 |
FileObject x_2 = u2fo.createData("x "); |
407 |
FileObject cau2 = u2fo.createData(cau); |
408 |
assertEquals(Arrays.asList(u1fo, u2fo), Arrays.asList(cp.getRoots())); |
409 |
assertTrue(cp.contains(xx1)); |
410 |
assertTrue(cp.contains(x_1)); |
411 |
assertFalse(cp.contains(xxx1)); |
412 |
assertFalse(cp.contains(cau1)); |
413 |
assertFalse(cp.contains(xy1)); |
414 |
assertFalse(cp.contains(xx2)); |
415 |
assertFalse(cp.contains(x_2)); |
416 |
assertTrue(cp.contains(xxx2)); |
417 |
assertTrue(cp.contains(cau2)); |
418 |
assertTrue(cp.contains(xy2)); |
419 |
assertFalse(cp.contains(folder)); |
420 |
assertTrue(cp.contains(foldr)); |
421 |
assertEquals(xx1, cp.findResource("xx")); |
422 |
assertEquals(x_1, cp.findResource("x ")); |
423 |
assertEquals(xxx2, cp.findResource("xxx")); |
424 |
assertEquals(cau2, cp.findResource(cau)); |
425 |
assertEquals(xy2, cp.findResource("x/y")); |
426 |
assertEquals(null, cp.findResource("folder")); |
427 |
assertEquals(foldr, cp.findResource("foldr")); |
428 |
assertEquals(Collections.singletonList(xx1), cp.findAllResources("xx")); |
429 |
assertEquals(Collections.singletonList(x_1), cp.findAllResources("x ")); |
430 |
assertEquals(Collections.singletonList(xxx2), cp.findAllResources("xxx")); |
431 |
assertEquals(Collections.singletonList(cau2), cp.findAllResources(cau)); |
432 |
assertEquals(Collections.singletonList(xy2), cp.findAllResources("x/y")); |
433 |
assertEquals(Collections.emptyList(), cp.findAllResources("folder")); |
434 |
assertEquals(Collections.singletonList(foldr), cp.findAllResources("foldr")); |
435 |
assertEquals("xx", cp.getResourceName(xx1)); |
436 |
assertEquals("x ", cp.getResourceName(x_1)); |
437 |
assertEquals("xxx", cp.getResourceName(xxx1)); |
438 |
assertEquals(cau, cp.getResourceName(cau1)); |
439 |
assertEquals("x/y", cp.getResourceName(xy1)); |
440 |
assertEquals("folder", cp.getResourceName(folder)); |
441 |
assertEquals("foldr", cp.getResourceName(foldr)); |
442 |
assertEquals(u1fo, cp.findOwnerRoot(xx1)); |
443 |
assertEquals(u1fo, cp.findOwnerRoot(x_1)); |
444 |
assertEquals(u1fo, cp.findOwnerRoot(xxx1)); |
445 |
assertEquals(u1fo, cp.findOwnerRoot(cau1)); |
446 |
assertEquals(u1fo, cp.findOwnerRoot(xy1)); |
447 |
assertEquals(u1fo, cp.findOwnerRoot(folder)); |
448 |
assertEquals(u1fo, cp.findOwnerRoot(foldr)); |
449 |
assertTrue(cp.isResourceVisible(xx1)); |
450 |
assertTrue(cp.isResourceVisible(x_1)); |
451 |
assertFalse(cp.isResourceVisible(xxx1)); |
452 |
assertFalse(cp.isResourceVisible(cau1)); |
453 |
assertFalse(cp.isResourceVisible(xy1)); |
454 |
assertFalse(cp.isResourceVisible(folder)); |
455 |
assertTrue(cp.isResourceVisible(foldr)); |
456 |
ClassPath.Entry e1 = cp.entries().get(0); |
457 |
assertTrue(e1.includes("xx")); |
458 |
assertTrue(e1.includes("x ")); |
459 |
assertFalse(e1.includes("xxx")); |
460 |
assertFalse(e1.includes(cau)); |
461 |
assertFalse(e1.includes("x/y")); |
462 |
assertFalse(e1.includes("folder/")); |
463 |
assertTrue(e1.includes("foldr/")); |
464 |
assertTrue(e1.includes(xx1)); |
465 |
assertTrue(e1.includes(x_1)); |
466 |
assertFalse(e1.includes(xxx1)); |
467 |
assertFalse(e1.includes(cau1)); |
468 |
assertFalse(e1.includes(xy1)); |
469 |
assertFalse(e1.includes(folder)); |
470 |
assertTrue(e1.includes(foldr)); |
471 |
try { |
472 |
e1.includes(xx2); |
473 |
fail(); |
474 |
} catch (IllegalArgumentException iae) {} |
475 |
assertTrue(e1.includes(xx1.getURL())); |
476 |
assertTrue(e1.includes(x_1.getURL())); |
477 |
assertFalse(e1.includes(xxx1.getURL())); |
478 |
assertFalse(e1.includes(cau1.getURL())); |
479 |
assertFalse(e1.includes(xy1.getURL())); |
480 |
assertFalse(e1.includes(folder.getURL())); |
481 |
assertTrue(e1.includes(foldr.getURL())); |
482 |
try { |
483 |
e1.includes(xx2.getURL()); |
484 |
fail(); |
485 |
} catch (IllegalArgumentException iae) {} |
486 |
cp.addPropertyChangeListener(impl); |
487 |
pr.changeIncludes(3); |
488 |
impl.assertEvents(ClassPath.PROP_INCLUDES); |
489 |
assertFalse(cp.contains(xx1)); |
490 |
assertFalse(cp.contains(x_1)); |
491 |
assertTrue(cp.contains(xxx1)); |
492 |
assertTrue(cp.contains(cau1)); |
493 |
assertTrue(cp.contains(xy1)); |
494 |
assertTrue(cp.contains(xx2)); |
495 |
assertTrue(cp.contains(x_2)); |
496 |
assertFalse(cp.contains(xxx2)); |
497 |
assertFalse(cp.contains(cau2)); |
498 |
assertFalse(cp.contains(xy2)); |
499 |
assertEquals(xx2, cp.findResource("xx")); |
500 |
assertEquals(x_2, cp.findResource("x ")); |
501 |
assertEquals(xxx1, cp.findResource("xxx")); |
502 |
assertEquals(cau1, cp.findResource(cau)); |
503 |
assertEquals(xy1, cp.findResource("x/y")); |
504 |
e1 = cp.entries().get(0); |
505 |
assertFalse(e1.includes("xx")); |
506 |
assertFalse(e1.includes("x ")); |
507 |
assertTrue(e1.includes("xxx")); |
508 |
assertTrue(e1.includes(cau)); |
509 |
assertTrue(e1.includes("x/y")); |
510 |
assertFalse(e1.includes(xx1)); |
511 |
assertFalse(e1.includes(x_1)); |
512 |
assertTrue(e1.includes(xxx1)); |
513 |
assertTrue(e1.includes(cau1)); |
514 |
assertTrue(e1.includes(xy1)); |
515 |
assertFalse(e1.includes(xx1.getURL())); |
516 |
assertFalse(e1.includes(x_1.getURL())); |
517 |
assertTrue(e1.includes(xxx1.getURL())); |
518 |
assertTrue(e1.includes(cau1.getURL())); |
519 |
assertTrue(e1.includes(xy1.getURL())); |
520 |
} |
521 |
|
522 |
public void testFpriChangeFiring() throws Exception { |
523 |
class FPRI implements FilteringPathResourceImplementation { |
524 |
URL root; |
525 |
PropertyChangeSupport pcs = new PropertyChangeSupport(this); |
526 |
FPRI(URL root) { |
527 |
this.root = root; |
528 |
} |
529 |
public boolean includes(URL root, String resource) { |
530 |
return true; |
531 |
} |
532 |
public URL[] getRoots() { |
533 |
return new URL[] {root}; |
534 |
} |
535 |
public ClassPathImplementation getContent() { |
536 |
return null; |
537 |
} |
538 |
public void addPropertyChangeListener(PropertyChangeListener listener) { |
539 |
pcs.addPropertyChangeListener(listener); |
540 |
} |
541 |
public void removePropertyChangeListener(PropertyChangeListener listener) { |
542 |
pcs.removePropertyChangeListener(listener); |
543 |
} |
544 |
void fire(Object propid) { |
545 |
PropertyChangeEvent e = new PropertyChangeEvent(this, FilteringPathResourceImplementation.PROP_INCLUDES, null, null); |
546 |
e.setPropagationId(propid); |
547 |
pcs.firePropertyChange(e); |
548 |
} |
549 |
} |
550 |
FPRI fpri1 = new FPRI(new File(getWorkDir(), "src1").toURI().toURL()); |
551 |
FPRI fpri2 = new FPRI(new File(getWorkDir(), "src2").toURI().toURL()); |
552 |
class L implements PropertyChangeListener { |
553 |
int cnt; |
554 |
public void propertyChange(PropertyChangeEvent e) { |
555 |
if (ClassPath.PROP_INCLUDES.equals(e.getPropertyName())) { |
556 |
cnt++; |
557 |
} |
558 |
} |
559 |
} |
560 |
ClassPath cp = ClassPathSupport.createClassPath(Arrays.asList(fpri1, fpri2)); |
561 |
L l = new L(); |
562 |
cp.addPropertyChangeListener(l); |
563 |
//No events fired before cp.entries() called |
564 |
fpri1.fire(null); |
565 |
assertEquals(0, l.cnt); |
566 |
cp.entries(); |
567 |
fpri1.fire(null); |
568 |
assertEquals(1, l.cnt); |
569 |
fpri2.fire(null); |
570 |
assertEquals(2, l.cnt); |
571 |
fpri1.fire("hello"); |
572 |
assertEquals(3, l.cnt); |
573 |
fpri2.fire("goodbye"); |
574 |
assertEquals(4, l.cnt); |
575 |
fpri1.fire("fixed"); |
576 |
assertEquals(5, l.cnt); |
577 |
fpri2.fire("fixed"); |
578 |
assertEquals(5, l.cnt); |
579 |
fpri1.fire("new"); |
580 |
assertEquals(6, l.cnt); |
581 |
} |
582 |
|
583 |
public void testLeakingClassPath() throws Exception { |
584 |
ClassPath cp = ClassPathSupport.createClassPath(new URL("file:///a/"), new URL("file:///b/")); |
585 |
ClassPath proxyCP = ClassPathSupport.createProxyClassPath(cp); |
586 |
Reference<ClassPath> proxy = new WeakReference<ClassPath>(proxyCP); |
587 |
|
588 |
proxyCP.entries(); |
589 |
|
590 |
proxyCP = null; |
591 |
|
592 |
assertGC("the proxy classpath needs to GCable", proxy); |
593 |
} |
594 |
|
595 |
public void testGetClassLoaderPerf () throws Exception { |
596 |
final String bootPathProp = System.getProperty("sun.boot.class.path"); //NOI18N |
597 |
List<URL> roots = new ArrayList<URL> (); |
598 |
StringTokenizer tk = new StringTokenizer (bootPathProp,File.pathSeparator); |
599 |
if (tk.hasMoreTokens()) { |
600 |
final String path = tk.nextToken(); |
601 |
final File f = FileUtil.normalizeFile(new File (path)); |
602 |
if (f.canRead()) { |
603 |
roots.add(f.toURI().toURL()); |
604 |
} |
605 |
} |
606 |
final ClassLoader bootLoader = new URLClassLoader(roots.toArray(new URL[roots.size()]), null); |
607 |
|
608 |
final String classPathProp = System.getProperty("java.class.path"); //NOI18N |
609 |
roots = new ArrayList<URL> (); |
610 |
List<URL> roots2 = new ArrayList<URL>(); |
611 |
tk = new StringTokenizer (classPathProp,File.pathSeparator); |
612 |
while (tk.hasMoreTokens()) { |
613 |
final String path = tk.nextToken(); |
614 |
final File f = FileUtil.normalizeFile(new File (path)); |
615 |
if (!f.canRead()) { |
616 |
continue; |
617 |
} |
618 |
URL url = f.toURI().toURL(); |
619 |
roots2.add(url); |
620 |
if (FileUtil.isArchiveFile(url)) { |
621 |
url = FileUtil.getArchiveRoot(url); |
622 |
} |
623 |
roots.add(url); |
624 |
} |
625 |
|
626 |
final ClassPath cp = ClassPathSupport.createClassPath(roots.toArray(new URL[roots.size()])); |
627 |
// final ClassLoader loader = ClassLoaderSupport.create(cp,bootLoader); |
628 |
// final ClassLoader loader = new URLClassLoader(roots.toArray(new URL[roots.size()]),bootLoader); |
629 |
final ClassLoader loader = new URLClassLoader(roots2.toArray(new URL[roots2.size()]),bootLoader); |
630 |
|
631 |
final Set<String> classNames = getClassNames (cp); |
632 |
int noLoaded = 0; |
633 |
int noFailed = 0; |
634 |
long st = System.currentTimeMillis(); |
635 |
for (String className : classNames) { |
636 |
try { |
637 |
final Class<?> c = loader.loadClass(className); |
638 |
noLoaded++; |
639 |
} catch (ClassNotFoundException e) { |
640 |
noFailed++; |
641 |
} |
642 |
catch (NoClassDefFoundError e) { |
643 |
noFailed++; |
644 |
} |
645 |
} |
646 |
long et = System.currentTimeMillis(); |
647 |
System.out.println("Loaded: " + noLoaded + " in: " + (et-st)+"ms"); |
648 |
} |
649 |
|
650 |
private Set<String> getClassNames (final ClassPath cp) { |
651 |
Set<String> classNames = new HashSet<String> (); |
652 |
for (FileObject root : cp.getRoots()) { |
653 |
Enumeration<? extends FileObject> fos = root.getChildren(true); |
654 |
while (fos.hasMoreElements()) { |
655 |
FileObject fo = fos.nextElement(); |
656 |
if (isImportant (fo)) { |
657 |
classNames.add(cp.getResourceName(fo, '.', false)); |
658 |
} |
659 |
} |
660 |
} |
661 |
return classNames; |
662 |
} |
663 |
|
664 |
private boolean isImportant (final FileObject fo) { |
665 |
if (fo.isFolder()) { |
666 |
return false; |
667 |
} |
668 |
if (!"class".equals(fo.getExt())) { //NOI18N |
669 |
return false; |
670 |
} |
671 |
return !fo.getName().contains("$"); //NOI18N |
672 |
|
673 |
} |
674 |
|
675 |
public void testJVMPathConversion() throws Exception { |
676 |
String root = getWorkDir().toURI().toString(); |
677 |
ClassPath cp = ClassPathSupport.createClassPath( |
678 |
new URL(root + "folder/"), |
679 |
new URL("jar:" + root + "file.zip!/"), |
680 |
new URL("jar:" + root + "file.zip!/subdir/")); |
681 |
assertEquals(massagePath("<root>/folder:<root>/file.zip"), cp.toString(ClassPath.PathConversionMode.SKIP)); |
682 |
assertEquals(massagePath("<root>/folder:<root>/file.zip:") + "jar:" + root + "file.zip!/subdir/", cp.toString(ClassPath.PathConversionMode.PRINT)); |
683 |
try { |
684 |
cp.toString(ClassPath.PathConversionMode.FAIL); |
685 |
fail(); |
686 |
} catch (IllegalArgumentException x) {/* OK */} |
687 |
CharSequence warnings = Log.enable(ClassPath.class.getName(), Level.WARNING); |
688 |
assertEquals(massagePath("<root>/folder:<root>/file.zip"), cp.toString(ClassPath.PathConversionMode.WARN)); |
689 |
assertTrue(warnings.toString(), warnings.toString().contains("subdir")); |
690 |
|
691 |
cp = ClassPathSupport.createClassPath( |
692 |
new URL(root + "folder/"), |
693 |
new URL("jar:" + root + "file.zip!/")); |
694 |
assertEquals(cp.toString(), ClassPathSupport.createClassPath(cp.toString()).toString()); |
695 |
// XXX could also test IAE (tricky - need to have a URLMapper in Lookup, etc.) |
696 |
} |
697 |
private String massagePath(String path) throws Exception { |
698 |
return path.replace('/', File.separatorChar).replace(':', File.pathSeparatorChar).replace("<root>", getWorkDir().getAbsolutePath()); |
699 |
} |
700 |
|
701 |
} |