KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > startup > ModuleManagerTest


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.core.startup;
21
22 import java.io.ByteArrayInputStream JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.FileOutputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.lang.ref.WeakReference JavaDoc;
28 import java.lang.reflect.Field JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30 import java.net.JarURLConnection JavaDoc;
31 import java.net.URL JavaDoc;
32 import java.net.URLClassLoader JavaDoc;
33 import java.net.URLConnection JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.Arrays JavaDoc;
36 import java.util.Collection JavaDoc;
37 import java.util.Collections JavaDoc;
38 import java.util.Enumeration JavaDoc;
39 import java.util.HashMap JavaDoc;
40 import java.util.HashSet JavaDoc;
41 import java.util.Iterator JavaDoc;
42 import java.util.LinkedHashSet JavaDoc;
43 import java.util.List JavaDoc;
44 import java.util.Locale JavaDoc;
45 import java.util.Map JavaDoc;
46 import java.util.Random JavaDoc;
47 import java.util.Set JavaDoc;
48 import java.util.jar.JarEntry JavaDoc;
49 import java.util.jar.JarFile JavaDoc;
50 import java.util.jar.JarOutputStream JavaDoc;
51 import java.util.jar.Manifest JavaDoc;
52 import java.util.logging.Level JavaDoc;
53 import org.netbeans.InvalidException;
54 import org.netbeans.Module;
55 import org.netbeans.ModuleManager;
56 import org.netbeans.Util;
57 import org.netbeans.core.startup.SetupHid.FakeEvents;
58 import org.netbeans.core.startup.SetupHid.FakeModuleInstaller;
59 import org.netbeans.core.startup.SetupHid.LoggedPCListener;
60 import org.openide.filesystems.FileUtil;
61 import org.openide.modules.Dependency;
62 import org.openide.modules.ModuleInfo;
63 import org.openide.util.Lookup;
64 import org.openide.util.LookupEvent;
65 import org.openide.util.LookupListener;
66 import org.openide.util.Utilities;
67
68 /** Test the module manager as well as the Module class.
69  * This means creating modules from JAR as well as from "classpath"
70  * (i.e. rigged-up classloader), and testing that it creates them with
71  * the correct stuff; testing that the various pieces of the manifest
72  * are correctly parsed and made accessible; that dependencies work
73  * when things are done in various orders etc.; that problems (such as
74  * missing dependencies) are accurately reported; that the classloaders
75  * are capable of getting everything listed; that module installer
76  * methods are called at the correct times and with modules in the correct
77  * state; that changes are fired correctly; etc.
78  * Note that since the design of the module manager makes no direct
79  * reference to general IDE classes other than standalone APIs and a couple
80  * of standalone core utilities, this entire test can (and ought to be)
81  * executed in standalone mode.
82  * @author Jesse Glick
83  */

84 public class ModuleManagerTest extends SetupHid {
85
86     static {
87         // To match org.netbeans.Main.execute (cf. #44828):
88
new URLConnection JavaDoc(ModuleManagerTest.class.getResource("ModuleManagerTest.class")) {
89             public void connect() throws IOException JavaDoc {}
90         }.setDefaultUseCaches(false);
91     }
92
93     public ModuleManagerTest(String JavaDoc name) {
94         super(name);
95     }
96
97     /*
98     public static Test suite() {
99         return new ModuleManagerTest("test...");
100     }
101      */

102
103     @Override JavaDoc
104     protected Level JavaDoc logLevel() {
105         return Level.FINE;
106     }
107
108     /** Load simple-module and depends-on-simple-module.
109      * Make sure they can be installed and in a sane order.
110      * Make sure a class from one can depend on a class from another.
111      * Try to disable them too.
112      */

113     public void testSimpleInstallation() throws Exception JavaDoc {
114         FakeModuleInstaller installer = new FakeModuleInstaller();
115         FakeEvents ev = new FakeEvents();
116         ModuleManager mgr = new ModuleManager(installer, ev);
117         mgr.mutexPrivileged().enterWriteAccess();
118         try {
119             Module m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, false);
120             Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, false, false);
121             assertEquals("org.foo", m1.getCodeNameBase());
122             assertEquals("org.bar", m2.getCodeNameBase());
123             assertEquals(Collections.EMPTY_SET, m1.getDependencies());
124             assertEquals(Dependency.create(Dependency.TYPE_MODULE, "org.foo/1"), m2.getDependencies());
125             Map JavaDoc<String JavaDoc,Module> modulesByName = new HashMap JavaDoc<String JavaDoc,Module>();
126             modulesByName.put(m1.getCodeNameBase(), m1);
127             modulesByName.put(m2.getCodeNameBase(), m2);
128             List JavaDoc<Module> m1m2 = Arrays.asList(m1, m2);
129             List JavaDoc<Module> m2m1 = Arrays.asList(m2, m1);
130             Map JavaDoc<Module,List JavaDoc<Module>> deps = Util.moduleDependencies(m1m2, modulesByName, Collections.<String JavaDoc,Set JavaDoc<Module>>emptyMap());
131             assertNull(deps.get(m1));
132             assertEquals(Collections.singletonList(m1), deps.get(m2));
133             assertEquals(m2m1, Utilities.topologicalSort(m1m2, deps));
134             assertEquals(m2m1, Utilities.topologicalSort(m2m1, deps));
135             // Leave commented out since it has a (hopefully clean) mutation effect
136
// and could affect results:
137
/*
138             assertEquals(Collections.EMPTY_SET, m1.getProblems());
139             assertEquals(Collections.EMPTY_SET, m2.getProblems());
140              */

141             Set JavaDoc<Module> m1PlusM2 = new HashSet JavaDoc<Module>();
142             m1PlusM2.add(m1);
143             m1PlusM2.add(m2);
144             List JavaDoc<Module> toEnable = mgr.simulateEnable(m1PlusM2);
145             assertEquals("correct result of simulateEnable", Arrays.asList(m1, m2), toEnable);
146             mgr.enable(m1PlusM2);
147             assertEquals(Arrays.asList(
148                 "prepare",
149                 "prepare",
150                 "load"
151             ), installer.actions);
152             assertEquals(Arrays.asList(
153                 m1,
154                 m2,
155                 Arrays.asList(m1, m2)
156             ), installer.args);
157             Class JavaDoc somethingelse = Class.forName("org.bar.SomethingElse", true, m2.getClassLoader());
158             Method JavaDoc somemethod = somethingelse.getMethod("message");
159             assertEquals("hello", somemethod.invoke(somethingelse.newInstance()));
160             installer.clear();
161             List JavaDoc<Module> toDisable = mgr.simulateDisable(Collections.singleton(m1));
162             assertEquals("correct result of simulateDisable", Arrays.asList(m2, m1), toDisable);
163             toDisable = mgr.simulateDisable(m1PlusM2);
164             assertEquals("correct result of simulateDisable #2", Arrays.asList(m2, m1), toDisable);
165             mgr.disable(m1PlusM2);
166             assertFalse(m1.isEnabled());
167             assertFalse(m2.isEnabled());
168             assertEquals(Collections.EMPTY_SET, mgr.getEnabledModules());
169             assertEquals(m1PlusM2, mgr.getModules());
170             assertEquals(Arrays.asList(
171                 "unload",
172                 "dispose",
173                 "dispose"
174             ), installer.actions);
175             assertEquals(Arrays.asList(
176                 Arrays.asList(m2, m1),
177                 m2,
178                 m1
179             ), installer.args);
180             installer.clear();
181             mgr.enable(m1);
182             mgr.shutDown();
183             assertEquals(Arrays.asList(
184                 "prepare",
185                 "load",
186                 "closing",
187                 "close"
188             ), installer.actions);
189             assertEquals(Arrays.asList(
190                 m1,
191                 Collections.singletonList(m1),
192                 Collections.singletonList(m1),
193                 Collections.singletonList(m1)
194             ), installer.args);
195         } finally {
196             mgr.mutexPrivileged().exitWriteAccess();
197         }
198     }
199
200     public void testInstallAutoload() throws Exception JavaDoc {
201         // Cf. #9779, I think.
202
FakeModuleInstaller installer = new FakeModuleInstaller();
203         FakeEvents ev = new FakeEvents();
204         ModuleManager mgr = new ModuleManager(installer, ev);
205         mgr.mutexPrivileged().enterWriteAccess();
206         try {
207             Module m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, false);
208             // m1 will be an autoload.
209
Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, true, false);
210             try {
211                 mgr.simulateEnable(new HashSet JavaDoc<Module>(Arrays.asList(m1, m2)));
212                 assertTrue("Should not permit you to simulate enablement of an autoload", false);
213             } catch (IllegalArgumentException JavaDoc iae) {
214                 // Good. m1 should not have been passed to it.
215
}
216             assertEquals(Collections.EMPTY_SET, m1.getProblems());
217             assertEquals(Collections.EMPTY_SET, m2.getProblems());
218             List JavaDoc toEnable = mgr.simulateEnable(Collections.singleton(m2));
219             assertEquals("correct result of simulateEnable", Arrays.asList(m1, m2), toEnable);
220             mgr.enable(Collections.singleton(m2));
221             assertEquals(Arrays.asList(
222                 "prepare",
223                 "prepare",
224                 "load"
225             ), installer.actions);
226             assertEquals(Arrays.asList(
227                 m1,
228                 m2,
229                 Arrays.asList(m1, m2)
230             ), installer.args);
231             Class JavaDoc somethingelse = Class.forName("org.bar.SomethingElse", true, m2.getClassLoader());
232             Method JavaDoc somemethod = somethingelse.getMethod("message");
233             assertEquals("hello", somemethod.invoke(somethingelse.newInstance()));
234             // Now try turning off m2 and make sure m1 goes away as well.
235
assertEquals("correct result of simulateDisable", Arrays.asList(m2, m1), mgr.simulateDisable(Collections.singleton(m2)));
236             installer.clear();
237             mgr.disable(Collections.singleton(m2));
238             assertEquals(Arrays.asList(
239                 "unload",
240                 "dispose",
241                 "dispose"
242             ), installer.actions);
243             assertEquals(Arrays.asList(
244                 Arrays.asList(m2, m1),
245                 m2,
246                 m1
247             ), installer.args);
248         } finally {
249             mgr.mutexPrivileged().exitWriteAccess();
250         }
251     }
252
253     public void testInstallEager() throws Exception JavaDoc {
254         // Cf. #17501.
255
FakeModuleInstaller installer = new FakeModuleInstaller();
256         FakeEvents ev = new FakeEvents();
257         ModuleManager mgr = new ModuleManager(installer, ev);
258         mgr.mutexPrivileged().enterWriteAccess();
259         try {
260             Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, false, false);
261             // m2 will be eager.
262
Module m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, true);
263             try {
264                 mgr.simulateEnable(new HashSet JavaDoc<Module>(Arrays.asList(m1, m2)));
265                 fail("Should not permit you to simulate enablement of an eager module");
266             } catch (IllegalArgumentException JavaDoc iae) {
267                 // Good. m2 should not have been passed to it.
268
}
269             assertEquals(Collections.EMPTY_SET, m1.getProblems());
270             assertEquals(Collections.EMPTY_SET, m2.getProblems());
271             List JavaDoc toEnable = mgr.simulateEnable(Collections.singleton(m1));
272             assertEquals("correct result of simulateEnable", Arrays.asList(m1, m2), toEnable);
273             mgr.enable(Collections.singleton(m1));
274             assertEquals(Arrays.asList(
275                 "prepare",
276                 "prepare",
277                 "load"
278             ), installer.actions);
279             assertEquals(Arrays.asList(
280                 m1,
281                 m2,
282                 Arrays.asList(m1, m2)
283             ), installer.args);
284             Class JavaDoc somethingelse = Class.forName("org.bar.SomethingElse", true, m2.getClassLoader());
285             Method JavaDoc somemethod = somethingelse.getMethod("message");
286             assertEquals("hello", somemethod.invoke(somethingelse.newInstance()));
287             // Now try turning off m1 and make sure m2 goes away quietly.
288
assertEquals("correct result of simulateDisable", Arrays.asList(m2, m1), mgr.simulateDisable(Collections.singleton(m1)));
289             installer.clear();
290             mgr.disable(Collections.singleton(m1));
291             assertEquals(Arrays.asList(
292                 "unload",
293                 "dispose",
294                 "dispose"
295             ), installer.actions);
296             assertEquals(Arrays.asList(
297                 Arrays.asList(m2, m1),
298                 m2,
299                 m1
300             ), installer.args);
301         } finally {
302             mgr.mutexPrivileged().exitWriteAccess();
303         }
304     }
305
306     public void testEagerPlusAutoload() throws Exception JavaDoc {
307         FakeModuleInstaller installer = new FakeModuleInstaller();
308         FakeEvents ev = new FakeEvents();
309         ModuleManager mgr = new ModuleManager(installer, ev);
310         mgr.mutexPrivileged().enterWriteAccess();
311         try {
312             // m1 autoload, m2 normal, m3 eager
313
Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, true, false);
314             Module m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, false);
315             Module m3 = mgr.create(new File JavaDoc(jars, "dep-on-dep-on-simple.jar"), null, false, false, true);
316             List JavaDoc toEnable = mgr.simulateEnable(Collections.singleton(m2));
317             assertEquals("correct result of simulateEnable", Arrays.asList(m1, m2, m3), toEnable);
318             mgr.enable(Collections.singleton(m2));
319             assertEquals(Arrays.asList(
320                 "prepare",
321                 "prepare",
322                 "prepare",
323                 "load"
324             ), installer.actions);
325             assertEquals(Arrays.asList(
326                 m1,
327                 m2,
328                 m3,
329                 Arrays.asList(m1, m2, m3)
330             ), installer.args);
331             Class JavaDoc somethingelseagain = Class.forName("org.baz.SomethingElseAgain", true, m3.getClassLoader());
332             Method JavaDoc somemethod = somethingelseagain.getMethod("doit");
333             assertEquals("hello", somemethod.invoke(somethingelseagain.newInstance()));
334             assertEquals("correct result of simulateDisable", Arrays.asList(m3, m2, m1), mgr.simulateDisable(Collections.singleton(m2)));
335             installer.clear();
336             mgr.disable(Collections.singleton(m2));
337             assertEquals(Arrays.asList(
338                 "unload",
339                 "dispose",
340                 "dispose",
341                 "dispose"
342             ), installer.actions);
343             assertEquals(Arrays.asList(
344                 Arrays.asList(m3, m2, m1),
345                 m3,
346                 m2,
347                 m1
348             ), installer.args);
349         } finally {
350             mgr.mutexPrivileged().exitWriteAccess();
351         }
352     }
353
354     /** Test scenario from #22536: when a normal module and an eager module
355      * both depend on the autoload, the eager & autoload modules should
356      * always be on, regardless of the normal module.
357      */

358     public void testEagerPlusAutoload2() throws Exception JavaDoc {
359         FakeModuleInstaller installer = new FakeModuleInstaller();
360         FakeEvents ev = new FakeEvents();
361         ModuleManager mgr = new ModuleManager(installer, ev);
362         mgr.mutexPrivileged().enterWriteAccess();
363         try {
364             // m1 autoload, m2 normal, m3 eager
365
Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, true, false);
366             Module m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, false);
367             Module m3 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module-2.jar"), null, false, false, true);
368             assertTrue(m1.isEnabled());
369             assertFalse(m2.isEnabled());
370             assertTrue(m3.isEnabled());
371             List JavaDoc toEnable = mgr.simulateEnable(Collections.singleton(m2));
372             assertEquals("correct result of simulateEnable", Collections.singletonList(m2), toEnable);
373             mgr.enable(Collections.singleton(m2));
374             assertTrue(m1.isEnabled());
375             assertTrue(m2.isEnabled());
376             assertTrue(m3.isEnabled());
377             List JavaDoc toDisable = mgr.simulateDisable(Collections.singleton(m2));
378             assertEquals("correct result of simulateDisable", Collections.singletonList(m2), toDisable);
379             mgr.disable(Collections.singleton(m2));
380             assertTrue(m1.isEnabled());
381             assertFalse(m2.isEnabled());
382             assertTrue(m3.isEnabled());
383         } finally {
384             mgr.mutexPrivileged().exitWriteAccess();
385         }
386     }
387
388     public void testEagerEnabledImmediately() throws Exception JavaDoc {
389         FakeModuleInstaller installer = new FakeModuleInstaller();
390         FakeEvents ev = new FakeEvents();
391         ModuleManager mgr = new ModuleManager(installer, ev);
392         mgr.mutexPrivileged().enterWriteAccess();
393         try {
394             Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, false, true);
395             assertTrue(m1.isEnabled());
396         } finally {
397             mgr.mutexPrivileged().exitWriteAccess();
398         }
399         mgr = new ModuleManager(installer, ev);
400         mgr.mutexPrivileged().enterWriteAccess();
401         try {
402             Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, false, false);
403             Module m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, true);
404             assertFalse(m1.isEnabled());
405             assertFalse(m2.isEnabled());
406             mgr.enable(m1);
407             assertTrue(m1.isEnabled());
408             assertTrue(m2.isEnabled());
409         } finally {
410             mgr.mutexPrivileged().exitWriteAccess();
411         }
412         mgr = new ModuleManager(installer, ev);
413         mgr.mutexPrivileged().enterWriteAccess();
414         try {
415             Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, true, false);
416             Module m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, true);
417             assertTrue(m1.isEnabled());
418             assertTrue(m2.isEnabled());
419         } finally {
420             mgr.mutexPrivileged().exitWriteAccess();
421         }
422     }
423
424     public void testCyclic() throws Exception JavaDoc {
425         // Cf. #12014.
426
FakeModuleInstaller installer = new FakeModuleInstaller();
427         FakeEvents ev = new FakeEvents();
428         ModuleManager mgr = new ModuleManager(installer, ev);
429         mgr.mutexPrivileged().enterWriteAccess();
430         try {
431             Module cyc1 = mgr.create(new File JavaDoc(jars, "cyclic-1.jar"), null, false, false, false);
432             Module cyc2 = mgr.create(new File JavaDoc(jars, "cyclic-2.jar"), null, false, false, false);
433             Module cycd = mgr.create(new File JavaDoc(jars, "depends-on-cyclic-1.jar"), null, false, false, false);
434             Set JavaDoc<Module> circular = new HashSet JavaDoc<Module>(Arrays.asList(cyc1, cyc2, cycd));
435             assertEquals("correct result of simulateEnable", Collections.EMPTY_LIST, mgr.simulateEnable(circular));
436             assertEquals("cyc1 problems include cyc2", cyc1.getDependencies(), cyc1.getProblems());
437             assertEquals("cyc2 problems include cyc1", cyc2.getDependencies(), cyc2.getProblems());
438             assertEquals("cycd problems include cyc1", cycd.getDependencies(), cycd.getProblems());
439         } finally {
440             mgr.mutexPrivileged().exitWriteAccess();
441         }
442     }
443
444     public void testBuildVersionCanBeReadOrIsDelegated() throws Exception JavaDoc {
445         // Cf. #12014.
446
FakeModuleInstaller installer = new FakeModuleInstaller();
447         FakeEvents ev = new FakeEvents();
448         ModuleManager mgr = new ModuleManager(installer, ev);
449         mgr.mutexPrivileged().enterWriteAccess();
450         try {
451             Module cyc1 = mgr.create(new File JavaDoc(jars, "cyclic-1.jar"), null, false, false, false);
452             Module cyc2 = mgr.create(new File JavaDoc(jars, "cyclic-2.jar"), null, false, false, false);
453
454             String JavaDoc impl1 = cyc1.getImplementationVersion ();
455             String JavaDoc impl2 = cyc2.getImplementationVersion ();
456             String JavaDoc bld1 = cyc1.getBuildVersion ();
457             String JavaDoc bld2 = cyc2.getBuildVersion ();
458
459             assertEquals (
460                 "cyc1 does not define build version and thus it is same as impl",
461                 impl1, bld1
462             );
463
464             assertEquals (
465                 "cyc2 does define build version",
466                 "this_line_is_here_due_to_yarda",
467                 bld2
468             );
469
470             assertTrue ("Impl and build versions are not same",
471                 !bld2.equals (impl2)
472             );
473         } finally {
474             mgr.mutexPrivileged().exitWriteAccess();
475         }
476     }
477
478     public void testLookup() throws Exception JavaDoc {
479         FakeModuleInstaller installer = new FakeModuleInstaller();
480         FakeEvents ev = new FakeEvents();
481         ModuleManager mgr = new ModuleManager(installer, ev);
482         mgr.mutexPrivileged().enterWriteAccess();
483         Module m1, m2;
484         try {
485             m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, false);
486             m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, false, false);
487         } finally {
488             mgr.mutexPrivileged().exitWriteAccess();
489         }
490         Lookup l = mgr.getModuleLookup();
491         assertNull(l.lookup(String JavaDoc.class));
492         Object JavaDoc random = l.lookup(ModuleInfo.class);
493         assertTrue(random == m1 || random == m2);
494         random = l.lookup(Module.class);
495         assertTrue(random == m1 || random == m2);
496         Lookup.Result<ModuleInfo> resultAll = l.lookupResult(ModuleInfo.class);
497         assertEquals("finding all instances works", new HashSet JavaDoc<Module>(Arrays.asList(m1, m2)), new HashSet JavaDoc<ModuleInfo>(resultAll.allInstances()));
498         Lookup.Result<Module> resultInstance2 = l.lookup(new Lookup.Template<Module>(null, null, m2));
499         assertEquals("finding one specific instance works", Collections.singleton(m2), new HashSet JavaDoc<Module>(resultInstance2.allInstances()));
500         Collection JavaDoc<? extends Lookup.Item<Module>> items = resultInstance2.allItems();
501         assertTrue(items.size() == 1);
502         Lookup.Item<Module> item = items.iterator().next();
503         assertEquals(m2, item.getInstance());
504         Util.err.info("Item ID: " + item.getId());
505         assertTrue("Item class is OK: " + item.getType(), item.getType().isAssignableFrom(Module.class));
506         assertEquals("finding by ID works", Collections.singleton(m2), new HashSet JavaDoc<Module>(l.lookup(new Lookup.Template<Module>(null, item.getId(), null)).allInstances()));
507         final boolean[] waiter = new boolean[] {false};
508         resultAll.addLookupListener(new LookupListener() {
509             public void resultChanged(LookupEvent lev) {
510                 Util.err.info("Got event: " + lev);
511                 synchronized (waiter) {
512                     waiter[0] = true;
513                     waiter.notify();
514                 }
515             }
516         });
517         Module m3;
518         mgr.mutexPrivileged().enterWriteAccess();
519         try {
520             m3 = mgr.create(new File JavaDoc(jars, "cyclic-1.jar"), null, false, false, false);
521             mgr.delete(m2);
522         } finally {
523             mgr.mutexPrivileged().exitWriteAccess();
524         }
525         assertEquals("results changed", new HashSet JavaDoc<ModuleInfo>(Arrays.asList(m1, m3)), new HashSet JavaDoc<ModuleInfo>(resultAll.allInstances()));
526         synchronized (waiter) {
527             if (! waiter[0]) {
528                 waiter.wait(5000);
529             }
530         }
531         assertTrue("got lookup changes within 5 seconds", waiter[0]);
532     }
533
534     /** Test that after deletion of a module, problems cache is cleared. */
535     public void test14561() throws Exception JavaDoc {
536         FakeModuleInstaller installer = new FakeModuleInstaller();
537         FakeEvents ev = new FakeEvents();
538         ModuleManager mgr = new ModuleManager(installer, ev);
539         mgr.mutexPrivileged().enterWriteAccess();
540         try {
541             Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, false, false);
542             Module m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, false);
543             Set JavaDoc<Module> m1AndM2 = new HashSet JavaDoc<Module>(Arrays.asList(m1, m2));
544             mgr.enable(m1AndM2);
545             mgr.disable(m1AndM2);
546             assertEquals(Collections.EMPTY_SET, m2.getProblems());
547             mgr.delete(m1);
548             assertEquals(1, m2.getProblems().size());
549             assertEquals(Collections.EMPTY_LIST, mgr.simulateEnable(Collections.singleton(m2)));
550         } finally {
551             mgr.mutexPrivileged().exitWriteAccess();
552         }
553     }
554
555     /** Test that PROP_PROBLEMS is fired reliably after unexpected problems. */
556     public void test14560() throws Exception JavaDoc {
557         FakeModuleInstaller installer = new FakeModuleInstaller();
558         FakeEvents ev = new FakeEvents();
559         ModuleManager mgr = new ModuleManager(installer, ev);
560         LoggedPCListener listener = new LoggedPCListener();
561         mgr.addPropertyChangeListener(listener);
562         mgr.mutexPrivileged().enterWriteAccess();
563         Module m1, m2;
564         try {
565             m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, false, false);
566             m1.addPropertyChangeListener(listener);
567             m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, false);
568             m2.addPropertyChangeListener(listener);
569             installer.delinquents.add(m1);
570             Set JavaDoc<Module> m1AndM2 = new HashSet JavaDoc<Module>(Arrays.asList(m1, m2));
571             try {
572                 mgr.enable(m1AndM2);
573             } catch (InvalidException ie) {
574                 assertEquals(m1, ie.getModule());
575             }
576             assertFalse(m1.isEnabled());
577         } finally {
578             mgr.mutexPrivileged().exitWriteAccess();
579         }
580         assertTrue("Got PROP_PROBLEMS on m1", listener.waitForChange(m1, Module.PROP_PROBLEMS));
581     }
582
583     // #14705: make sure package loading is tested
584
public void testPackageLoading() throws Exception JavaDoc {
585         FakeModuleInstaller installer = new FakeModuleInstaller();
586         FakeEvents ev = new FakeEvents();
587         ModuleManager mgr = new ModuleManager(installer, ev);
588         mgr.mutexPrivileged().enterWriteAccess();
589         try {
590             // Make sure all of these can be turned on:
591
tryEnablingModule(mgr, "depends-on-lib-undecl.jar");
592             tryEnablingModule(mgr, "depends-on-lib-unvers.jar");
593             tryEnablingModule(mgr, "depends-on-lib-vers.jar");
594             tryEnablingModule(mgr, "depends-on-lib-vers-partial.jar");
595             // In fact it is OK to depend on pkg.somepkg[Something] even with
596
// library-undecl.jar, since the classloader will define a package for you.
597
//failToEnableModule(mgr, "fails-on-lib-undecl.jar");
598
// These should not work:
599
failToEnableModule(mgr, "fails-on-lib-unvers.jar");
600             failToEnableModule(mgr, "fails-on-lib-old.jar");
601             // Make sure that classloading is OK:
602
Module m = mgr.create(new File JavaDoc(jars, "depends-on-lib-undecl.jar"), null, false, false, false);
603             mgr.enable(m);
604             Class JavaDoc c = m.getClassLoader().loadClass("org.dol.User");
605             Object JavaDoc o = c.newInstance();
606             Field JavaDoc f = c.getField("val");
607             assertEquals(42, f.getInt(o));
608             mgr.disable(m);
609             mgr.delete(m);
610         } finally {
611             mgr.mutexPrivileged().exitWriteAccess();
612         }
613     }
614
615     private void tryEnablingModule(ModuleManager mgr, String JavaDoc name) throws Exception JavaDoc {
616         Module m = mgr.create(new File JavaDoc(jars, name), null, false, false, false);
617         try {
618             mgr.enable(m);
619             mgr.disable(m);
620         } finally {
621             mgr.delete(m);
622         }
623     }
624
625     private void failToEnableModule(ModuleManager mgr, String JavaDoc name) throws Exception JavaDoc {
626         try {
627             tryEnablingModule(mgr, name);
628             fail("Was able to turn on " + name + " without complaint");
629         } catch (InvalidException ie) {
630             // Fine, expected.
631
}
632     }
633
634     public void testPackageDependencyMayfail() throws Exception JavaDoc {
635         //see #63904:
636
FakeModuleInstaller installer = new FakeModuleInstaller();
637         FakeEvents ev = new FakeEvents();
638         ModuleManager mgr = new ModuleManager(installer, ev);
639         mgr.mutexPrivileged().enterWriteAccess();
640         try {
641             Manifest JavaDoc mani;
642             JarFile JavaDoc jf = new JarFile JavaDoc(new File JavaDoc(jars, "simple-module.jar"));
643             try {
644                 mani = jf.getManifest();
645             } finally {
646                 jf.close();
647             }
648
649             Module toFail = mgr.create(new File JavaDoc(jars, "fails-on-non-existing-package.jar"), null, false, false, false);
650             Module fixed = mgr.createFixed(mani, null, this.getClass().getClassLoader());
651
652             try {
653                 mgr.enable(new HashSet JavaDoc<Module>(Arrays.asList(toFail, fixed)));
654                 fail("Was able to turn on fails-on-non-existing-package.jar without complaint");
655             } catch (InvalidException e) {
656                 assertTrue("fails-on-non-existing-package.jar was not enabled", e.getModule() == toFail);
657             }
658
659             assertTrue("simple-module.jar was enabled", fixed.isEnabled());
660         } finally {
661             mgr.mutexPrivileged().exitWriteAccess();
662         }
663     }
664
665
666     // #12549: check that loading of localized manifest attributes works.
667
public void testLocalizedManifestAttributes() throws Exception JavaDoc {
668         FakeModuleInstaller installer = new FakeModuleInstaller();
669         FakeEvents ev = new FakeEvents();
670         ModuleManager mgr = new ModuleManager(installer, ev);
671         mgr.mutexPrivileged().enterWriteAccess();
672         Locale JavaDoc starting = Locale.getDefault();
673         try {
674             Locale.setDefault(new Locale JavaDoc("en", "US"));
675             File JavaDoc locmanijar = new File JavaDoc(jars, "localized-manifest.jar");
676             assertTrue("test JAR exists: " + locmanijar, locmanijar.isFile()); // #50891
677
Module m = mgr.create(locmanijar, null, false, false, false);
678             // These are defined in the bundle:
679
assertEquals("en_US display name", "Localized Manifest Module", m.getDisplayName());
680             assertEquals("en_US bundle main attr", "value #1", m.getLocalizedAttribute("some-other-key"));
681             assertEquals("en_US bundle sub attr", "value #2", m.getLocalizedAttribute("locmani/something.txt/other-key"));
682             assertEquals("en_US bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans"));
683             assertEquals("en_US bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans"));
684             // These in the manifest itself:
685
assertEquals("en_US manifest main attr", "value #3", m.getLocalizedAttribute("some-key"));
686             assertEquals("en_US manifest sub attr", "value #4", m.getLocalizedAttribute("locmani/something.txt/key"));
687             assertEquals("en_US manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans"));
688             assertEquals("en_US manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans"));
689             mgr.delete(m);
690             // Now try it again, with a different locale this time:
691
Locale.setDefault(new Locale JavaDoc("cs", "CZ"));
692             m = mgr.create(new File JavaDoc(jars, "localized-manifest.jar"), null, false, false, false);
693             // Note Unicode values in the bundle.
694
assertEquals("cs_CZ display name", "Modul s lokalizovan\u00FDm manifestem", m.getDisplayName());
695             assertEquals("cs_CZ bundle main attr", "v\u00FDznam #1", m.getLocalizedAttribute("some-other-key"));
696             assertEquals("cs_CZ bundle sub attr", "v\u00FDznam #2", m.getLocalizedAttribute("locmani/something.txt/other-key"));
697             // These are not translated, see that they fall back to "default" locale:
698
assertEquals("cs_CZ bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans"));
699             assertEquals("cs_CZ bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans"));
700             // The manifest cannot hold non-ASCII characters.
701
assertEquals("cs_CZ manifest main attr", "vyznam #3", m.getLocalizedAttribute("some-key"));
702             assertEquals("cs_CZ manifest sub attr", "vyznam #4", m.getLocalizedAttribute("locmani/something.txt/key"));
703             // Also not translated:
704
assertEquals("cs_CZ manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans"));
705             assertEquals("cs_CZ manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans"));
706         } finally {
707             mgr.mutexPrivileged().exitWriteAccess();
708             Locale.setDefault(starting);
709         }
710     }
711
712     // #19698: check that it also works when the module is enabled (above, module was disabled).
713
public void testLocalizedManifestAttributesWhileEnabled() throws Exception JavaDoc {
714         FakeModuleInstaller installer = new FakeModuleInstaller();
715         FakeEvents ev = new FakeEvents();
716         ModuleManager mgr = new ModuleManager(installer, ev);
717         mgr.mutexPrivileged().enterWriteAccess();
718         Locale JavaDoc starting = Locale.getDefault();
719         try {
720             Locale.setDefault(new Locale JavaDoc("en", "US"));
721             Module m = mgr.create(new File JavaDoc(jars, "localized-manifest.jar"), null, false, false, false);
722             mgr.enable(m);
723             // These are defined in the bundle:
724
assertEquals("en_US display name", "Localized Manifest Module", m.getDisplayName());
725             assertEquals("en_US bundle main attr", "value #1", m.getLocalizedAttribute("some-other-key"));
726             assertEquals("en_US bundle sub attr", "value #2", m.getLocalizedAttribute("locmani/something.txt/other-key"));
727             assertEquals("en_US bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans"));
728             assertEquals("en_US bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans"));
729             // These in the manifest itself:
730
assertEquals("en_US manifest main attr", "value #3", m.getLocalizedAttribute("some-key"));
731             assertEquals("en_US manifest sub attr", "value #4", m.getLocalizedAttribute("locmani/something.txt/key"));
732             assertEquals("en_US manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans"));
733             assertEquals("en_US manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans"));
734             mgr.disable(m);
735             mgr.delete(m);
736             // Now try it again, with a different locale this time:
737
Locale.setDefault(new Locale JavaDoc("cs", "CZ"));
738             m = mgr.create(new File JavaDoc(jars, "localized-manifest.jar"), null, false, false, false);
739             mgr.enable(m);
740             // Note Unicode values in the bundle.
741
assertEquals("cs_CZ display name", "Modul s lokalizovan\u00FDm manifestem", m.getDisplayName());
742             assertEquals("cs_CZ bundle main attr", "v\u00FDznam #1", m.getLocalizedAttribute("some-other-key"));
743             assertEquals("cs_CZ bundle sub attr", "v\u00FDznam #2", m.getLocalizedAttribute("locmani/something.txt/other-key"));
744             // These are not translated, see that they fall back to "default" locale:
745
assertEquals("cs_CZ bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans"));
746             assertEquals("cs_CZ bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans"));
747             // The manifest cannot hold non-ASCII characters.
748
assertEquals("cs_CZ manifest main attr", "vyznam #3", m.getLocalizedAttribute("some-key"));
749             assertEquals("cs_CZ manifest sub attr", "vyznam #4", m.getLocalizedAttribute("locmani/something.txt/key"));
750             // Also not translated:
751
assertEquals("cs_CZ manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans"));
752             assertEquals("cs_CZ manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans"));
753             mgr.disable(m);
754         } finally {
755             mgr.mutexPrivileged().exitWriteAccess();
756             Locale.setDefault(starting);
757         }
758     }
759
760     // There was also a bug that loc mani attrs were not recognized for classpath modules.
761
public void testLocalizedManifestAttributesClasspath() throws Exception JavaDoc {
762         File JavaDoc jar = new File JavaDoc(jars, "localized-manifest.jar");
763         File JavaDoc ljar = new File JavaDoc(new File JavaDoc(jars, "locale"), "localized-manifest_cs.jar");
764         Manifest JavaDoc mani;
765         JarFile JavaDoc jf = new JarFile JavaDoc(jar);
766         try {
767             mani = jf.getManifest();
768         } finally {
769             jf.close();
770         }
771         ClassLoader JavaDoc l = new URLClassLoader JavaDoc(new URL JavaDoc[] {
772             // Order should be irrelevant:
773
jar.toURL(),
774             ljar.toURL(),
775         });
776         FakeModuleInstaller installer = new FakeModuleInstaller();
777         FakeEvents ev = new FakeEvents();
778         Locale JavaDoc starting = Locale.getDefault();
779         try {
780             ModuleManager mgr = new ModuleManager(installer, ev);
781             mgr.mutexPrivileged().enterWriteAccess();
782             try {
783                 Locale.setDefault(new Locale JavaDoc("en", "US"));
784                 Module m = mgr.createFixed(mani, null, l);
785                 // These are defined in the bundle:
786
assertEquals("en_US display name", "Localized Manifest Module", m.getDisplayName());
787                 assertEquals("en_US bundle main attr", "value #1", m.getLocalizedAttribute("some-other-key"));
788                 assertEquals("en_US bundle sub attr", "value #2", m.getLocalizedAttribute("locmani/something.txt/other-key"));
789                 assertEquals("en_US bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans"));
790                 assertEquals("en_US bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans"));
791                 // These in the manifest itself:
792
assertEquals("en_US manifest main attr", "value #3", m.getLocalizedAttribute("some-key"));
793                 assertEquals("en_US manifest sub attr", "value #4", m.getLocalizedAttribute("locmani/something.txt/key"));
794                 assertEquals("en_US manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans"));
795                 assertEquals("en_US manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans"));
796             } finally {
797                 mgr.mutexPrivileged().exitWriteAccess();
798             }
799             // Need to start with a new manager: cannot delete classpath modules, would be a dupe
800
// if we tried to make it again.
801
mgr = new ModuleManager(installer, ev);
802             mgr.mutexPrivileged().enterWriteAccess();
803             try {
804                 // Now try it again, with a different locale this time:
805
Locale.setDefault(new Locale JavaDoc("cs", "CZ"));
806                 Module m = mgr.createFixed(mani, null, l);
807                 // Note Unicode values in the bundle.
808
assertEquals("cs_CZ display name", "Modul s lokalizovan\u00FDm manifestem", m.getDisplayName());
809                 assertEquals("cs_CZ bundle main attr", "v\u00FDznam #1", m.getLocalizedAttribute("some-other-key"));
810                 assertEquals("cs_CZ bundle sub attr", "v\u00FDznam #2", m.getLocalizedAttribute("locmani/something.txt/other-key"));
811                 // These are not translated, see that they fall back to "default" locale:
812
assertEquals("cs_CZ bundle main attr untrans", "value #7", m.getLocalizedAttribute("other-untrans"));
813                 assertEquals("cs_CZ bundle sub attr untrans", "value #8", m.getLocalizedAttribute("locmani/something.txt/other-untrans"));
814                 // The manifest cannot hold non-ASCII characters.
815
assertEquals("cs_CZ manifest main attr", "vyznam #3", m.getLocalizedAttribute("some-key"));
816                 assertEquals("cs_CZ manifest sub attr", "vyznam #4", m.getLocalizedAttribute("locmani/something.txt/key"));
817                 // Also not translated:
818
assertEquals("cs_CZ manifest main attr untrans", "value #5", m.getLocalizedAttribute("untrans"));
819                 assertEquals("cs_CZ manifest sub attr untrans", "value #6", m.getLocalizedAttribute("locmani/something.txt/untrans"));
820             } finally {
821                 mgr.mutexPrivileged().exitWriteAccess();
822             }
823         } finally {
824             Locale.setDefault(starting);
825         }
826     }
827
828     // #9273: test that modules/patches/<<code-name-dashes>>/*.jar function as patches
829
public void testModulePatches() throws Exception JavaDoc {
830         FakeModuleInstaller installer = new FakeModuleInstaller();
831         FakeEvents ev = new FakeEvents();
832         ModuleManager mgr = new ModuleManager(installer, ev);
833         mgr.mutexPrivileged().enterWriteAccess();
834         try {
835             Module m = mgr.create(new File JavaDoc(jars, "patchable.jar"), null, false, false, false);
836             mgr.enable(m);
837             Class JavaDoc c = m.getClassLoader().loadClass("pkg.subpkg.A");
838             Field JavaDoc f = c.getField("val");
839             Object JavaDoc o = c.newInstance();
840             assertEquals(25, f.getInt(o));
841         } finally {
842             mgr.mutexPrivileged().exitWriteAccess();
843         }
844     }
845
846     public void testSimpleProvReq() throws Exception JavaDoc {
847         FakeModuleInstaller installer = new FakeModuleInstaller();
848         FakeEvents ev = new FakeEvents();
849         ModuleManager mgr = new ModuleManager(installer, ev);
850         mgr.mutexPrivileged().enterWriteAccess();
851         try {
852             Module m1 = mgr.create(new File JavaDoc(jars, "prov-foo.jar"), null, false, false, false);
853             Module m2 = mgr.create(new File JavaDoc(jars, "req-foo.jar"), null, false, false, false);
854             assertEquals(Collections.singletonList("foo"), Arrays.asList(m1.getProvides()));
855             assertEquals(Collections.EMPTY_LIST, Arrays.asList(m2.getProvides()));
856             assertEquals(Collections.EMPTY_SET, m1.getDependencies());
857             assertEquals(Dependency.create(Dependency.TYPE_REQUIRES, "foo"), m2.getDependencies());
858             Map JavaDoc<String JavaDoc,Module> modulesByName = new HashMap JavaDoc<String JavaDoc,Module>();
859             modulesByName.put(m1.getCodeNameBase(), m1);
860             modulesByName.put(m2.getCodeNameBase(), m2);
861             Map JavaDoc<String JavaDoc,Set JavaDoc<Module>> providersOf = new HashMap JavaDoc<String JavaDoc,Set JavaDoc<Module>>();
862             providersOf.put("foo", Collections.singleton(m1));
863             List JavaDoc<Module> m1m2 = Arrays.asList(m1, m2);
864             List JavaDoc<Module> m2m1 = Arrays.asList(m2, m1);
865             Map JavaDoc<Module,List JavaDoc<Module>> deps = Util.moduleDependencies(m1m2, modulesByName, providersOf);
866             assertNull(deps.get(m1));
867             assertEquals(Collections.singletonList(m1), deps.get(m2));
868             assertEquals(m2m1, Utilities.topologicalSort(m1m2, deps));
869             assertEquals(m2m1, Utilities.topologicalSort(m2m1, deps));
870             Set JavaDoc<Module> m1PlusM2 = new HashSet JavaDoc<Module>();
871             m1PlusM2.add(m1);
872             m1PlusM2.add(m2);
873             List JavaDoc<Module> toEnable = mgr.simulateEnable(m1PlusM2);
874             assertEquals("correct result of simulateEnable", Arrays.asList(m1, m2), toEnable);
875             toEnable = mgr.simulateEnable(Collections.singleton(m2));
876             assertEquals("correct result of simulateEnable #2", Arrays.asList(m1, m2), toEnable);
877             mgr.enable(m1PlusM2);
878             assertEquals(Arrays.asList(
879                 "prepare",
880                 "prepare",
881                 "load"
882             ), installer.actions);
883             assertEquals(Arrays.asList(
884                 m1,
885                 m2,
886                 Arrays.asList(m1, m2)
887             ), installer.args);
888             Class JavaDoc testclazz = Class.forName("org.prov_foo.Clazz", true, m1.getClassLoader());
889             try {
890                 Class.forName("org.prov_foo.Clazz", true, m2.getClassLoader());
891                 fail("Should not be able to access classes due to prov-req deps only");
892             } catch (ClassNotFoundException JavaDoc cnfe) {
893                 // OK, good.
894
}
895             installer.clear();
896             List JavaDoc<Module> toDisable = mgr.simulateDisable(Collections.singleton(m1));
897             assertEquals("correct result of simulateDisable", Arrays.asList(m2, m1), toDisable);
898             toDisable = mgr.simulateDisable(m1PlusM2);
899             assertEquals("correct result of simulateDisable #2", Arrays.asList(m2, m1), toDisable);
900             mgr.disable(m1PlusM2);
901             assertFalse(m1.isEnabled());
902             assertFalse(m2.isEnabled());
903             assertEquals(Arrays.asList(
904                 "unload",
905                 "dispose",
906                 "dispose"
907             ), installer.actions);
908             assertEquals(Arrays.asList(
909                 Arrays.asList(m2, m1),
910                 m2,
911                 m1
912             ), installer.args);
913         } finally {
914             mgr.mutexPrivileged().exitWriteAccess();
915         }
916     }
917
918     public void testProvReqCycles() throws Exception JavaDoc {
919         FakeModuleInstaller installer = new FakeModuleInstaller();
920         FakeEvents ev = new FakeEvents();
921         ModuleManager mgr = new ModuleManager(installer, ev);
922         mgr.mutexPrivileged().enterWriteAccess();
923         try {
924             Module m1 = mgr.create(new File JavaDoc(jars, "prov-foo-req-bar.jar"), null, false, false, false);
925             Module m2 = mgr.create(new File JavaDoc(jars, "prov-bar-req-foo.jar"), null, false, false, false);
926             assertEquals("m1 cannot be installed because of m2",
927                 Dependency.create(Dependency.TYPE_REQUIRES, "bar"),
928                 m1.getProblems());
929             assertEquals("m2 cannot be installed because of m1",
930                 Dependency.create(Dependency.TYPE_REQUIRES, "foo"),
931                 m2.getProblems());
932             assertEquals("neither m1 nor m2 can be installed",
933                 Collections.EMPTY_LIST,
934                     mgr.simulateEnable(new HashSet JavaDoc<Module>(Arrays.asList(m1, m2))));
935             mgr.delete(m2);
936             Module m3 = mgr.create(new File JavaDoc(jars, "prov-bar-dep-cyclic.jar"), null, false, false, false);
937             assertEquals("m1 cannot be installed because of m3",
938                 Dependency.create(Dependency.TYPE_REQUIRES, "bar"),
939                 m1.getProblems());
940             assertEquals("m3 cannot be installed because of m1",
941                 Dependency.create(Dependency.TYPE_MODULE, "prov_foo_req_bar"),
942                 m3.getProblems());
943             assertEquals("neither m1 nor m3 can be installed",
944                 Collections.EMPTY_LIST,
945                     mgr.simulateEnable(new HashSet JavaDoc<Module>(Arrays.asList(m1, m3))));
946             m2 = mgr.create(new File JavaDoc(jars, "prov-bar-req-foo.jar"), null, false, false, false);
947             assertEquals("m2 cannot be installed because of m1",
948                 Dependency.create(Dependency.TYPE_REQUIRES, "foo"),
949                 m2.getProblems());
950             Module m4 = mgr.create(new File JavaDoc(jars, "prov-foo.jar"), null, false, false, false);
951             assertEquals("m2 is OK with m4 here",
952                 Collections.EMPTY_SET,
953                 m2.getProblems());
954             mgr.delete(m1); // to prevent random failures; see comment in MM.sE
955
assertEquals("m2 and m4 can be enabled together",
956                 Arrays.asList(m4, m2),
957                 mgr.simulateEnable(Collections.singleton(m2)));
958         } finally {
959             mgr.mutexPrivileged().exitWriteAccess();
960         }
961     }
962
963     public void testMultipleProvs() throws Exception JavaDoc {
964         FakeModuleInstaller installer = new FakeModuleInstaller();
965         FakeEvents ev = new FakeEvents();
966         ModuleManager mgr = new ModuleManager(installer, ev);
967         mgr.mutexPrivileged().enterWriteAccess();
968         try {
969             Module m1 = mgr.create(new File JavaDoc(jars, "prov-foo.jar"), null, false, false, false);
970             Module m2 = mgr.create(new File JavaDoc(jars, "prov-foo-bar.jar"), null, false, false, false);
971             Module m3 = mgr.create(new File JavaDoc(jars, "req-foo.jar"), null, false, false, false);
972             Set JavaDoc<Module> m123 = new HashSet JavaDoc<Module>(Arrays.asList(m1, m2, m3));
973             List JavaDoc<Module> toEnable = mgr.simulateEnable(Collections.singleton(m3));
974             // Note order of first two items in toEnable is indeterminate.
975
assertEquals("From start, turn on all providers", m123, new HashSet JavaDoc<Module>(toEnable));
976             assertEquals("m3 last", m3, toEnable.get(2));
977             assertEquals("Could request them all together too", m123, new HashSet JavaDoc<Module>(mgr.simulateEnable(m123)));
978             List JavaDoc<Module> m13 = Arrays.asList(m1, m3);
979             assertEquals("Or just m1 + m3", m13, mgr.simulateEnable(new HashSet JavaDoc<Module>(m13)));
980             List JavaDoc<Module> m23 = Arrays.asList(m2, m3);
981             assertEquals("Or just m2 + m3", m23, mgr.simulateEnable(new HashSet JavaDoc<Module>(m23)));
982             mgr.enable(m123);
983             assertTrue(m1.isEnabled());
984             assertTrue(m2.isEnabled());
985             assertTrue(m3.isEnabled());
986             assertEquals("Can turn off one provider",
987                 Collections.singletonList(m1),
988                 mgr.simulateDisable(Collections.singleton(m1)));
989             Set JavaDoc<Module> m12 = new HashSet JavaDoc<Module>(Arrays.asList(m1, m2));
990             assertEquals("Can't turn off both providers",
991                 m123,
992                 new HashSet JavaDoc<Module>(mgr.simulateDisable(m12)));
993             mgr.disable(m1);
994             assertFalse(m1.isEnabled());
995             assertTrue(m2.isEnabled());
996             assertTrue(m3.isEnabled());
997             List JavaDoc<Module> m32 = Arrays.asList(m3, m2);
998             assertEquals("Can't turn off last provider",
999                 m32,
1000                mgr.simulateDisable(Collections.singleton(m2)));
1001            mgr.disable(new HashSet JavaDoc<Module>(m32));
1002            assertFalse(m1.isEnabled());
1003            assertFalse(m2.isEnabled());
1004            assertFalse(m3.isEnabled());
1005        } finally {
1006            mgr.mutexPrivileged().exitWriteAccess();
1007        }
1008    }
1009
1010    public void testProvReqUnsatisfiable() throws Exception JavaDoc {
1011        FakeModuleInstaller installer = new FakeModuleInstaller();
1012        FakeEvents ev = new FakeEvents();
1013        ModuleManager mgr = new ModuleManager(installer, ev);
1014        mgr.mutexPrivileged().enterWriteAccess();
1015        Module m1 = createModule(mgr, "OpenIDE-Module: m1\nOpenIDE-Module-Needs: tok\n");
1016        Module m2 = createModule(mgr, "OpenIDE-Module: m2\nOpenIDE-Module-Module-Dependencies: m1\n");
1017        assertEquals(Collections.emptyList(), mgr.simulateEnable(Collections.singleton(m2)));
1018        Module m3 = createModule(mgr, "OpenIDE-Module: m3\nOpenIDE-Module-Provides: tok\n");
1019        assertEquals(new HashSet JavaDoc<Module>(Arrays.asList(m1, m2, m3)), new HashSet JavaDoc<Module>(mgr.simulateEnable(Collections.singleton(m2))));
1020        mgr = new ModuleManager(installer, ev);
1021        mgr.mutexPrivileged().enterWriteAccess();
1022        m1 = createModule(mgr, "OpenIDE-Module: m1\nOpenIDE-Module-Requires: tok\n");
1023        m2 = createModule(mgr, "OpenIDE-Module: m2\nOpenIDE-Module-Module-Dependencies: m1\nOpenIDE-Module-Provides: tok\n");
1024        assertEquals(Collections.emptyList(), mgr.simulateEnable(Collections.singleton(m2)));
1025    }
1026    
1027    public void testSimpleProvNeeds() throws Exception JavaDoc {
1028        doSimpleProvNeeds(false, false);
1029    }
1030    
1031    public void testSimpleProvNeedsReversed() throws Exception JavaDoc {
1032        doSimpleProvNeeds(true, false);
1033    }
1034
1035    public void testSimpleSatisfiedProvRecommends() throws Exception JavaDoc {
1036        doSimpleProvNeeds(false, true);
1037    }
1038    
1039    public void testSimpleSatisfiedProvRecommendsReversed() throws Exception JavaDoc {
1040        doSimpleProvNeeds(true, true);
1041    }
1042    
1043    private void doSimpleProvNeeds(boolean reverseOrder, boolean recommends) throws Exception JavaDoc {
1044        FakeModuleInstaller installer = new FakeModuleInstaller();
1045        FakeEvents ev = new FakeEvents();
1046        ModuleManager mgr = new ModuleManager(installer, ev);
1047        mgr.mutexPrivileged().enterWriteAccess();
1048        try {
1049            Module m1 = mgr.create(new File JavaDoc(jars, "prov-foo-depends-needs_foo.jar"), null, false, false, false);
1050            Module m2;
1051            if (recommends) {
1052                m2 = mgr.create(new File JavaDoc(jars, "recommends-foo.jar"), null, false, false, false);
1053            } else {
1054                m2 = mgr.create(new File JavaDoc(jars, "needs-foo.jar"), null, false, false, false);
1055            }
1056            assertEquals(Collections.singletonList("foo"), Arrays.asList(m1.getProvides()));
1057            assertEquals(Collections.EMPTY_LIST, Arrays.asList(m2.getProvides()));
1058            assertEquals(1, m1.getDependencies().size());
1059            int type = recommends ? Dependency.TYPE_RECOMMENDS : Dependency.TYPE_NEEDS;
1060            assertEquals(Dependency.create(type, "foo"), m2.getDependencies());
1061            Map JavaDoc<String JavaDoc,Module> modulesByName = new HashMap JavaDoc<String JavaDoc,Module>();
1062            modulesByName.put(m1.getCodeNameBase(), m1);
1063            modulesByName.put(m2.getCodeNameBase(), m2);
1064            Map JavaDoc<String JavaDoc,Set JavaDoc<Module>> providersOf = new HashMap JavaDoc<String JavaDoc,Set JavaDoc<Module>>();
1065            providersOf.put("foo", Collections.singleton(m1));
1066            List JavaDoc<Module> m1m2 = Arrays.asList(m1, m2);
1067            List JavaDoc<Module> m2m1 = Arrays.asList(m2, m1);
1068            Map JavaDoc<Module,List JavaDoc<Module>> deps = Util.moduleDependencies(m1m2, modulesByName, providersOf);
1069            assertEquals(Collections.singletonList(m2), deps.get(m1));
1070/* assertEquals(Collections.singletonList(m1), deps.get(m2));
1071            
1072            try {
1073                Utilities.topologicalSort(m1m2, deps);
1074            } catch (TopologicalSortException ex) {
1075                Set[] arr = ex.unsortableSets();
1076                assertEquals("One unsortable set", 1, arr.length);
1077                assertEquals("It contains two elements", 2, arr[0].size());
1078                assertTrue("m1 is there", arr[0].contains(m1));
1079                assertTrue("m2 is there", arr[0].contains(m2));
1080            }*/

1081            Set JavaDoc<Module> m1PlusM2 = new LinkedHashSet JavaDoc<Module>();
1082            if (reverseOrder) {
1083                m1PlusM2.add(m2);
1084                m1PlusM2.add(m1);
1085            } else {
1086                m1PlusM2.add(m1);
1087                m1PlusM2.add(m2);
1088            }
1089            List JavaDoc<Module> toEnable = mgr.simulateEnable(m1PlusM2);
1090            assertEquals("correct result of simulateEnable", Arrays.asList(m2, m1), toEnable);
1091            toEnable = mgr.simulateEnable(Collections.singleton(m1));
1092            assertEquals("correct result of simulateEnable #2", Arrays.asList(m2, m1), toEnable);
1093            toEnable = mgr.simulateEnable(Collections.singleton(m2));
1094            assertEquals("correct result of simulateEnable #3", Arrays.asList(m2, m1), toEnable);
1095            mgr.enable(m1PlusM2);
1096            assertEquals(Arrays.asList(
1097                "prepare",
1098                "prepare",
1099                "load"
1100            ), installer.actions);
1101            assertEquals(Arrays.asList(
1102                m2,
1103                m1,
1104                Arrays.asList(m2, m1)
1105            ), installer.args);
1106            Class JavaDoc testclazz = Class.forName("org.prov_foo.Clazz", true, m1.getClassLoader());
1107            try {
1108                Class.forName("org.prov_foo.Clazz", true, m2.getClassLoader());
1109                fail("Should not be able to access classes due to prov-req deps only");
1110            } catch (ClassNotFoundException JavaDoc cnfe) {
1111                // OK, good.
1112
}
1113            installer.clear();
1114            List JavaDoc<Module> toDisable = mgr.simulateDisable(Collections.singleton(m1));
1115            if (!recommends) {
1116                assertEquals("correct result of simulateDisable", Arrays.asList(m1, m2), toDisable);
1117                toDisable = mgr.simulateDisable(m1PlusM2);
1118                assertEquals("correct result of simulateDisable #2", Arrays.asList(m1, m2), toDisable);
1119                mgr.disable(m1PlusM2);
1120                assertFalse(m1.isEnabled());
1121                assertFalse(m2.isEnabled());
1122                assertEquals(Arrays.asList(
1123                    "unload",
1124                    "dispose",
1125                    "dispose"
1126                ), installer.actions);
1127                assertEquals(Arrays.asList(
1128                    Arrays.asList(m1, m2),
1129                    m1,
1130                    m2
1131                ), installer.args);
1132            } else {
1133                assertEquals("correct result of simulateDisable", Collections.singletonList(m1 ), toDisable);
1134                toDisable = mgr.simulateDisable(m1PlusM2);
1135                assertEquals("correct result of simulateDisable #2", Arrays.asList(m1, m2), toDisable);
1136                mgr.disable(m1);
1137                assertFalse(m1.isEnabled());
1138                assertTrue(m2.isEnabled());
1139                mgr.disable(m2);
1140                assertFalse(m2.isEnabled());
1141                assertEquals(Arrays.asList(
1142                    "unload",
1143                    "dispose",
1144                    "unload",
1145                    "dispose"
1146                ), installer.actions);
1147                assertEquals(Arrays.asList(
1148                    Collections.singletonList(m1),
1149                    m1,
1150                    Collections.singletonList(m2),
1151                    m2
1152                ), installer.args);
1153            }
1154        } finally {
1155            mgr.mutexPrivileged().exitWriteAccess();
1156        }
1157    }
1158
1159    public void testComplexProvNeeds() throws Exception JavaDoc {
1160        doComplexProvNeeds(false, false, false);
1161    }
1162    
1163    public void testComplexProvNeedsReversed() throws Exception JavaDoc {
1164        doComplexProvNeeds(true, false, false);
1165    }
1166
1167    public void testComplexSatisfiedProvRecommends() throws Exception JavaDoc {
1168        doComplexProvNeeds(false, true, false);
1169    }
1170    
1171    public void testComplexSatisfiedProvRecommendsReversed() throws Exception JavaDoc {
1172        doComplexProvNeeds(true, true, true);
1173    }
1174
1175    public void testComplexProvNeeds2() throws Exception JavaDoc {
1176        doComplexProvNeeds(false, false, true);
1177    }
1178    
1179    public void testComplexProvNeedsReversed2() throws Exception JavaDoc {
1180        doComplexProvNeeds(true, false, true);
1181    }
1182
1183    public void testComplexSatisfiedProvRecommends2() throws Exception JavaDoc {
1184        doComplexProvNeeds(false, true, true);
1185    }
1186    
1187    public void testComplexSatisfiedProvRecommendsReversed2() throws Exception JavaDoc {
1188        doComplexProvNeeds(true, true, true);
1189    }
1190    
1191    private void doComplexProvNeeds(boolean reverseOrder, boolean recommends, boolean sndRec) throws Exception JavaDoc {
1192        FakeModuleInstaller installer = new FakeModuleInstaller();
1193        FakeEvents ev = new FakeEvents();
1194        ModuleManager mgr = new ModuleManager(installer, ev);
1195        mgr.mutexPrivileged().enterWriteAccess();
1196        try {
1197            Module m1 = mgr.create(new File JavaDoc(jars, "prov-foo-depends-needs_foo.jar"), null, false, true, false);
1198            Module m2;
1199            if (recommends) {
1200                m2 = mgr.create(new File JavaDoc(jars, "recommends-foo.jar"), null, false, false, false);
1201            } else {
1202                m2 = mgr.create(new File JavaDoc(jars, "needs-foo.jar"), null, false, false, false);
1203            }
1204            Module m3 = null;
1205            if (sndRec) {
1206                String JavaDoc manifest = "Manifest-Version: 1.0\n" +
1207"OpenIDE-Module: snd.needs_foo\n" +
1208"OpenIDE-Module-Name: 2nd Needs foo\n" +
1209"OpenIDE-Module-Needs: foo\n";
1210                m3 = mgr.create(copyJar(m2.getJarFile(), manifest), null, false, false, false);
1211            } else {
1212                String JavaDoc manifest = "Manifest-Version: 1.0\n" +
1213"OpenIDE-Module: snd.needs_foo\n" +
1214"OpenIDE-Module-Name: 2nd Needs foo\n" +
1215"OpenIDE-Module-Recommends: foo\n";
1216                m3 = mgr.create(copyJar(m2.getJarFile(), manifest), null, false, false, false);
1217            }
1218            assertEquals(Collections.singletonList("foo"), Arrays.asList(m1.getProvides()));
1219            assertEquals(Collections.EMPTY_LIST, Arrays.asList(m2.getProvides()));
1220            assertEquals(1, m1.getDependencies().size());
1221            int type = recommends ? Dependency.TYPE_RECOMMENDS : Dependency.TYPE_NEEDS;
1222            assertEquals(Dependency.create(type, "foo"), m2.getDependencies());
1223            Map JavaDoc<String JavaDoc,Module> modulesByName = new HashMap JavaDoc<String JavaDoc,Module>();
1224            modulesByName.put(m1.getCodeNameBase(), m1);
1225            modulesByName.put(m2.getCodeNameBase(), m2);
1226            Map JavaDoc<String JavaDoc,Set JavaDoc<Module>> providersOf = new HashMap JavaDoc<String JavaDoc,Set JavaDoc<Module>>();
1227            providersOf.put("foo", Collections.singleton(m1));
1228            List JavaDoc<Module> m1m2 = Arrays.asList(m1, m2);
1229            List JavaDoc<Module> m2m1 = Arrays.asList(m2, m1);
1230            Map JavaDoc<Module,List JavaDoc<Module>> deps = Util.moduleDependencies(m1m2, modulesByName, providersOf);
1231            assertEquals(Collections.singletonList(m2), deps.get(m1));
1232            List JavaDoc<Module> toEnable = mgr.simulateEnable(Collections.singleton(m2));
1233            assertEquals("correct result of simulateEnable", Arrays.asList(m2, m1), toEnable);
1234
1235            mgr.enable(m2);
1236            assertEquals(Arrays.asList(
1237                "prepare",
1238                "prepare",
1239                "load"
1240            ), installer.actions);
1241            assertEquals(Arrays.asList(
1242                m2,
1243                m1,
1244                Arrays.asList(m2, m1)
1245            ), installer.args);
1246            Class JavaDoc testclazz = Class.forName("org.prov_foo.Clazz", true, m1.getClassLoader());
1247            try {
1248                Class.forName("org.prov_foo.Clazz", true, m2.getClassLoader());
1249                fail("Should not be able to access classes due to prov-req deps only");
1250            } catch (ClassNotFoundException JavaDoc cnfe) {
1251                // OK, good.
1252
}
1253            
1254            mgr.enable(m3);
1255            assertTrue("m3 enabled1", m3.isEnabled());
1256            
1257            installer.clear();
1258            List JavaDoc<Module> toDisable = mgr.simulateDisable(Collections.singleton(m3));
1259            if (!recommends) {
1260                mgr.disable(m3);
1261                assertFalse("M3 enabled", m3.isEnabled());
1262                assertTrue("Provider enabled", m1.isEnabled());
1263                assertTrue(m2.isEnabled());
1264                assertEquals(Arrays.asList(
1265                    "unload",
1266                    "dispose"
1267                ), installer.actions);
1268                assertEquals(Arrays.asList(
1269                    Collections.singletonList( m3 ),
1270                    m3
1271                ), installer.args);
1272            } else {
1273                mgr.disable(m3);
1274                assertFalse(m3.isEnabled());
1275                assertTrue(m2.isEnabled());
1276                assertTrue(m1.isEnabled());
1277                assertEquals(Arrays.asList(
1278                    "unload",
1279                    "dispose"
1280                ), installer.actions);
1281                assertEquals(Arrays.asList(
1282                    Collections.singletonList(m3),
1283                    m3
1284                ), installer.args);
1285            }
1286        } finally {
1287            mgr.mutexPrivileged().exitWriteAccess();
1288        }
1289    }
1290    
1291    public void testRecommendsWithoutAProvider() throws Exception JavaDoc {
1292        FakeModuleInstaller installer = new FakeModuleInstaller();
1293        FakeEvents ev = new FakeEvents();
1294        ModuleManager mgr = new ModuleManager(installer, ev);
1295        mgr.mutexPrivileged().enterWriteAccess();
1296        try {
1297            Module m2 = mgr.create(new File JavaDoc(jars, "recommends-foo.jar"), null, false, false, false);
1298            assertEquals(Collections.EMPTY_LIST, Arrays.asList(m2.getProvides()));
1299            assertEquals(Dependency.create(Dependency.TYPE_RECOMMENDS, "foo"), m2.getDependencies());
1300            Map JavaDoc<String JavaDoc,Module> modulesByName = new HashMap JavaDoc<String JavaDoc,Module>();
1301            modulesByName.put(m2.getCodeNameBase(), m2);
1302            Map JavaDoc<String JavaDoc,Set JavaDoc<Module>> providersOf = new HashMap JavaDoc<String JavaDoc,Set JavaDoc<Module>>();
1303            List JavaDoc<Module> m2List = Collections.singletonList( m2 );
1304            Map JavaDoc<Module,List JavaDoc<Module>> deps = Util.moduleDependencies(m2List, modulesByName, providersOf);
1305            assertEquals(null, deps.get(m2));
1306
1307            List JavaDoc<Module> toEnable = mgr.simulateEnable(new HashSet JavaDoc<Module>(m2List));
1308            assertEquals("correct result of simulateEnable", Collections.singletonList(m2), toEnable);
1309            mgr.enable(new HashSet JavaDoc<Module>(m2List));
1310            assertEquals(Arrays.asList(
1311                "prepare",
1312                "load"
1313            ), installer.actions);
1314            assertEquals(Arrays.asList(
1315                m2,
1316// m1,
1317
Collections.singletonList(m2)
1318            ), installer.args);
1319            installer.clear();
1320            List JavaDoc<Module> toDisable = mgr.simulateDisable(Collections.singleton(m2));
1321            assertEquals("correct result of simulateDisable", Collections.singletonList(m2), toDisable);
1322            mgr.disable(m2);
1323            assertFalse(m2.isEnabled());
1324            assertEquals(Arrays.asList(
1325                "unload",
1326                "dispose"
1327            ), installer.actions);
1328            assertEquals(Arrays.asList(
1329                Collections.singletonList(m2),
1330// m1,
1331
m2
1332            ), installer.args);
1333        } finally {
1334            mgr.mutexPrivileged().exitWriteAccess();
1335        }
1336    }
1337
1338    public void testNeedsWithAProviderWithoutAProvider() throws Exception JavaDoc {
1339        doRecommendsWithAProviderWithoutAProvider(false);
1340    }
1341    
1342    public void testRecommendsWithAProviderWithoutAProvider() throws Exception JavaDoc {
1343        doRecommendsWithAProviderWithoutAProvider(true);
1344    }
1345
1346    private void doRecommendsWithAProviderWithoutAProvider(boolean recommends) throws Exception JavaDoc {
1347        // ========= XXX recommends parameter is unused! ===========
1348
FakeModuleInstaller installer = new FakeModuleInstaller();
1349        FakeEvents ev = new FakeEvents();
1350        ModuleManager mgr = new ModuleManager(installer, ev);
1351        mgr.mutexPrivileged().enterWriteAccess();
1352        try {
1353            Module m2 = mgr.create(new File JavaDoc(jars, "recommends-foo.jar"), null, false, false, false);
1354            assertEquals(Collections.EMPTY_LIST, Arrays.asList(m2.getProvides()));
1355            
1356            Module m1;
1357            {
1358                String JavaDoc manifest = "Manifest-Version: 1.0\n" +
1359"OpenIDE-Module: snd.provides.foo\n" +
1360"OpenIDE-Module-Name: Provides foo\n" +
1361"OpenIDE-Module-Provides: foo\n" +
1362"OpenIDE-Module-Needs: bla\n";
1363                m1 = mgr.create(copyJar(m2.getJarFile(), manifest), null, false, true, false);
1364                
1365            }
1366            assertEquals(Dependency.create(Dependency.TYPE_RECOMMENDS, "foo"), m2.getDependencies());
1367            Map JavaDoc<String JavaDoc,Module> modulesByName = new HashMap JavaDoc<String JavaDoc,Module>();
1368            modulesByName.put(m2.getCodeNameBase(), m2);
1369            Map JavaDoc<String JavaDoc,Set JavaDoc<Module>> providersOf = new HashMap JavaDoc<String JavaDoc,Set JavaDoc<Module>>();
1370            List JavaDoc<Module> m2List = Collections.singletonList(m2);
1371            Map JavaDoc<Module,List JavaDoc<Module>> deps = Util.moduleDependencies(m2List, modulesByName, providersOf);
1372            assertEquals(null, deps.get(m2));
1373
1374            List JavaDoc<Module> toEnable = mgr.simulateEnable(new HashSet JavaDoc<Module>(m2List));
1375            assertEquals("cannot enable while provider of bla is missing", Collections.singletonList(m2), toEnable);
1376
1377
1378// try {
1379
// mgr.enable(new HashSet<Module>(m2List));
1380
// fail("Shall not allow enablement as 'bar' is missing");
1381
// } catch (IllegalArgumentException ex) {
1382
// // this cannot be enabled
1383
// }
1384

1385            
1386            Module m3;
1387            {
1388                String JavaDoc manifest = "Manifest-Version: 1.0\n" +
1389"OpenIDE-Module: snd.provides.bar\n" +
1390"OpenIDE-Module-Name: Provides bar\n" +
1391"OpenIDE-Module-Provides: bla\n";
1392                m3 = mgr.create(copyJar(m2.getJarFile(), manifest), null, false, true, false);
1393            }
1394            
1395            Set JavaDoc allThreeModules = new HashSet JavaDoc<Module>(Arrays.asList(m1, m3, m2));
1396            
1397            toEnable = mgr.simulateEnable(new HashSet JavaDoc<Module>(m2List));
1398            assertEquals("all 3 need to be enabled", allThreeModules, new HashSet JavaDoc<Module>(toEnable));
1399            
1400            mgr.enable(new HashSet JavaDoc<Module>(m2List));
1401            assertEquals(Arrays.asList(
1402                "prepare",
1403                "prepare",
1404                "prepare",
1405                "load"
1406            ), installer.actions);
1407            installer.clear();
1408            List JavaDoc<Module> toDisable = mgr.simulateDisable(Collections.singleton(m2));
1409            assertEquals("correct result of simulateDisable", allThreeModules, new HashSet JavaDoc<Module>(toDisable));
1410            mgr.disable(m2);
1411            assertFalse(m2.isEnabled());
1412            assertEquals(Arrays.asList(
1413                "unload",
1414                "dispose",
1415                "dispose",
1416                "dispose"
1417            ), installer.actions);
1418        } finally {
1419            mgr.mutexPrivileged().exitWriteAccess();
1420        }
1421    }
1422    
1423    public void testMultipleReqs() throws Exception JavaDoc {
1424        FakeModuleInstaller installer = new FakeModuleInstaller();
1425        FakeEvents ev = new FakeEvents();
1426        ModuleManager mgr = new ModuleManager(installer, ev);
1427        mgr.mutexPrivileged().enterWriteAccess();
1428        try {
1429            Module m1 = mgr.create(new File JavaDoc(jars, "prov-foo.jar"), null, false, false, false);
1430            Module m2 = mgr.create(new File JavaDoc(jars, "prov-baz.jar"), null, false, false, false);
1431            Module m3 = mgr.create(new File JavaDoc(jars, "req-foo-baz.jar"), null, false, false, false);
1432            Set JavaDoc<Module> m123 = new HashSet JavaDoc<Module>(Arrays.asList(m1, m2, m3));
1433            assertEquals(m123, new HashSet JavaDoc<Module>(mgr.simulateEnable(Collections.singleton(m3))));
1434            mgr.enable(m123);
1435            assertEquals(Arrays.asList(m3, m1), mgr.simulateDisable(Collections.singleton(m1)));
1436            assertEquals(Arrays.asList(m3, m2), mgr.simulateDisable(Collections.singleton(m2)));
1437        } finally {
1438            mgr.mutexPrivileged().exitWriteAccess();
1439        }
1440    }
1441
1442    public void testEagerReq() throws Exception JavaDoc {
1443        FakeModuleInstaller installer = new FakeModuleInstaller();
1444        FakeEvents ev = new FakeEvents();
1445        ModuleManager mgr = new ModuleManager(installer, ev);
1446        mgr.mutexPrivileged().enterWriteAccess();
1447        try {
1448            Module m1 = mgr.create(new File JavaDoc(jars, "prov-foo.jar"), null, false, false, false);
1449            Module m2 = mgr.create(new File JavaDoc(jars, "prov-baz.jar"), null, false, false, false);
1450            Module m3 = mgr.create(new File JavaDoc(jars, "req-foo-baz.jar"), null, false, false, true);
1451            assertEquals(Collections.singletonList(m1),
1452                mgr.simulateEnable(Collections.singleton(m1)));
1453            assertEquals(Collections.singletonList(m2),
1454                mgr.simulateEnable(Collections.singleton(m2)));
1455            Set JavaDoc<Module> m12 = new HashSet JavaDoc<Module>(Arrays.asList(m1, m2));
1456            Set JavaDoc<Module> m123 = new HashSet JavaDoc<Module>(Arrays.asList(m1, m2, m3));
1457            assertEquals(m123, new HashSet JavaDoc<Module>(mgr.simulateEnable(m12)));
1458            mgr.enable(m12);
1459            assertTrue(m3.isEnabled());
1460            assertEquals(Arrays.asList(m3, m1),
1461                mgr.simulateDisable(Collections.singleton(m1)));
1462            assertEquals(Arrays.asList(m3, m2),
1463                mgr.simulateDisable(Collections.singleton(m2)));
1464            assertEquals(m123,
1465                new HashSet JavaDoc<Module>(mgr.simulateDisable(m12)));
1466            mgr.disable(m12);
1467            assertFalse(m3.isEnabled());
1468        } finally {
1469            mgr.mutexPrivileged().exitWriteAccess();
1470        }
1471    }
1472
1473    public void testAutoloadProv() throws Exception JavaDoc {
1474        FakeModuleInstaller installer = new FakeModuleInstaller();
1475        FakeEvents ev = new FakeEvents();
1476        ModuleManager mgr = new ModuleManager(installer, ev);
1477        mgr.mutexPrivileged().enterWriteAccess();
1478        try {
1479            Module m1 = mgr.create(new File JavaDoc(jars, "prov-foo.jar"), null, false, true, false);
1480            Module m2 = mgr.create(new File JavaDoc(jars, "req-foo.jar"), null, false, false, false);
1481            assertEquals(Arrays.asList(m1, m2),
1482                mgr.simulateEnable(Collections.singleton(m2)));
1483            mgr.enable(m2);
1484            assertTrue(m1.isEnabled());
1485            assertEquals(Arrays.asList(m2, m1),
1486                mgr.simulateDisable(Collections.singleton(m2)));
1487            mgr.disable(m2);
1488            assertFalse(m1.isEnabled());
1489        } finally {
1490            mgr.mutexPrivileged().exitWriteAccess();
1491        }
1492    }
1493
1494    public void testWeirdRecursion() throws Exception JavaDoc {
1495        FakeModuleInstaller installer = new FakeModuleInstaller();
1496        FakeEvents ev = new FakeEvents();
1497        ModuleManager mgr = new ModuleManager(installer, ev);
1498        mgr.mutexPrivileged().enterWriteAccess();
1499        try {
1500            //Module m1 = mgr.create(new File(jars, "prov-foo.jar"), null, false, false, false);
1501
Module m2 = mgr.create(new File JavaDoc(jars, "prov-bar-req-foo.jar"), null, false, true, false);
1502            Module m3 = mgr.create(new File JavaDoc(jars, "prov-foo-bar.jar"), null, false, false, false);
1503            Module m4 = mgr.create(new File JavaDoc(jars, "prov-foo-req-bar.jar"), null, false, false, true);
1504            assertEquals("m2 should not be enabled - m4 might ask for it but m3 already has bar",
1505                new HashSet JavaDoc<Module>(Arrays.asList(m3, m4)),
1506                new HashSet JavaDoc<Module>(mgr.simulateEnable(Collections.singleton(m3))));
1507        } finally {
1508            mgr.mutexPrivileged().exitWriteAccess();
1509        }
1510    }
1511
1512    public void testLackOfOrderSensitivity() throws Exception JavaDoc {
1513        String JavaDoc[] moduleNames = new String JavaDoc[] {
1514            "simple-module.jar",
1515            "depends-on-simple-module.jar",
1516            "dep-on-dep-on-simple.jar",
1517            "prov-foo.jar",
1518            "prov-baz.jar",
1519            "prov-foo-bar.jar",
1520            "req-foo.jar",
1521            "req-foo-baz.jar",
1522            "prov-bar-req-foo.jar",
1523            "prov-foo-req-bar.jar",
1524        };
1525        // Never make any of the following eager:
1526
Set JavaDoc<String JavaDoc> noDepsNames = new HashSet JavaDoc<String JavaDoc>(Arrays.asList(
1527            "simple-module.jar",
1528            "prov-foo.jar",
1529            "prov-baz.jar",
1530            "prov-foo-bar.jar"
1531        ));
1532        List JavaDoc<String JavaDoc> freeModules = new ArrayList JavaDoc<String JavaDoc>(Arrays.asList(moduleNames));
1533        int count = 100; // # of things to do in order
1534
Random JavaDoc r = new Random JavaDoc(count * 17 + 113);
1535        FakeModuleInstaller installer = new FakeModuleInstaller();
1536        FakeEvents ev = new FakeEvents();
1537        ModuleManager mgr = new ModuleManager(installer, ev);
1538        mgr.mutexPrivileged().enterWriteAccess();
1539        try {
1540            int i = 0;
1541            while (i < count) {
1542                Util.err.info("testLackOfOrderSensitivity round #" + i);
1543                switch (r.nextInt(11)) {
1544                case 0:
1545                case 1:
1546                case 2:
1547                    Util.err.info("Add a regular module");
1548                    if (!freeModules.isEmpty()) {
1549                        String JavaDoc name = freeModules.remove(r.nextInt(freeModules.size()));
1550                        mgr.create(new File JavaDoc(jars, name), null, false, false, false);
1551                        i++;
1552                    }
1553                    break;
1554                case 3:
1555                    Util.err.info("Add an autoload");
1556                    if (!freeModules.isEmpty()) {
1557                        String JavaDoc name = freeModules.remove(r.nextInt(freeModules.size()));
1558                        mgr.create(new File JavaDoc(jars, name), null, false, true, false);
1559                        i++;
1560                    }
1561                    break;
1562                case 4:
1563                    Util.err.info("Add an eager module");
1564                    if (!freeModules.isEmpty()) {
1565                        String JavaDoc name = freeModules.remove(r.nextInt(freeModules.size()));
1566                        if (!noDepsNames.contains(name)) {
1567                            Module m = mgr.create(new File JavaDoc(jars, name), null, false, false, true);
1568                            i++;
1569                        }
1570                    }
1571                    break;
1572                case 5:
1573                case 6:
1574                    Util.err.info("Remove a disabled module");
1575                    List JavaDoc<Module> disabled = new ArrayList JavaDoc<Module>(moduleNames.length);
1576                    for (Module m : mgr.getModules()) {
1577                        if (!m.isEnabled()) {
1578                            disabled.add(m);
1579                        }
1580                    }
1581                    if (!disabled.isEmpty()) {
1582                        Module m = disabled.get(r.nextInt(disabled.size()));
1583                        mgr.delete(m);
1584                        freeModules.add(m.getJarFile().getName());
1585                        i++;
1586                    }
1587                    break;
1588                case 7:
1589                case 8:
1590                    Util.err.info("Enable some set of modules");
1591                    List JavaDoc<Module> candidates = new ArrayList JavaDoc<Module>(moduleNames.length);
1592                    for (Module m : mgr.getModules()) {
1593                        if (!m.isEnabled() && !m.isAutoload() && !m.isEager() && r.nextBoolean()) {
1594                            candidates.add(m);
1595                        }
1596                    }
1597                    if (!candidates.isEmpty()) {
1598                        Collections.shuffle(candidates, r);
1599                        Set JavaDoc<Module> candidatesSet = new LinkedHashSet JavaDoc<Module>(candidates);
1600                        assertEquals("OrderPreservingSet works", candidates, new ArrayList JavaDoc<Module>(candidatesSet));
1601                        //dumpState(mgr);
1602
//System.err.println("will try to enable: " + candidates);
1603
List JavaDoc<Module> toEnable1 = mgr.simulateEnable(candidatesSet);
1604                        //System.err.println("Enabling " + candidates + " ->\n " + toEnable1);
1605
Collections.shuffle(candidates, r);
1606                        List JavaDoc<Module> toEnable2 = mgr.simulateEnable(new LinkedHashSet JavaDoc<Module>(candidates));
1607                        Set JavaDoc<Module> s1 = new HashSet JavaDoc<Module>(toEnable1);
1608                        Set JavaDoc<Module> s2 = new HashSet JavaDoc<Module>(toEnable2);
1609                        assertEquals("Order preserved", s1, s2);
1610                        Iterator JavaDoc<Module> it = s1.iterator();
1611                        while (it.hasNext()) {
1612                            Module m = it.next();
1613                            if (m.isAutoload() || m.isEager()) {
1614                                it.remove();
1615                            }
1616                        }
1617                        mgr.enable(s1);
1618                        i++;
1619                    }
1620                    break;
1621                case 9:
1622                case 10:
1623                    Util.err.info("Disable some set of modules");
1624                    candidates = new ArrayList JavaDoc<Module>(moduleNames.length);
1625                    for (Module m : mgr.getModules()) {
1626                        if (m.isEnabled() && !m.isAutoload() && !m.isEager() && r.nextBoolean()) {
1627                            candidates.add(m);
1628                        }
1629                    }
1630                    if (!candidates.isEmpty()) {
1631                        Collections.shuffle(candidates, r);
1632                        //dumpState(mgr);
1633
List JavaDoc<Module> toDisable1 = mgr.simulateDisable(new LinkedHashSet JavaDoc<Module>(candidates));
1634                        //System.err.println("Disabling " + candidates + " ->\n " + toDisable1);
1635
Collections.shuffle(candidates, r);
1636                        //System.err.println("candidates #2: " + candidates);
1637
List JavaDoc<Module> toDisable2 = mgr.simulateDisable(new LinkedHashSet JavaDoc<Module>(candidates));
1638                        Set JavaDoc<Module> s1 = new HashSet JavaDoc<Module>(toDisable1);
1639                        Set JavaDoc<Module> s2 = new HashSet JavaDoc<Module>(toDisable2);
1640                        assertEquals("Order preserved", s1, s2);
1641                        Iterator JavaDoc<Module> it = s1.iterator();
1642                        while (it.hasNext()) {
1643                            Module m = it.next();
1644                            if (m.isAutoload() || m.isEager()) {
1645                                it.remove();
1646                            }
1647                        }
1648                        mgr.disable(s1);
1649                        i++;
1650                    }
1651                    break;
1652                default:
1653                    throw new IllegalStateException JavaDoc();
1654                }
1655            }
1656        } finally {
1657            mgr.mutexPrivileged().exitWriteAccess();
1658        }
1659    }
1660    /*
1661    private static void dumpState(ModuleManager mgr) {
1662        SortedSet modules = new TreeSet(Util.displayNameComparator());
1663        modules.addAll(mgr.getModules());
1664        System.err.print("State:");
1665        Iterator it = modules.iterator();
1666        while (it.hasNext()) {
1667            Module m = (Module)it.next();
1668            System.err.print(" " + m.getCodeNameBase());
1669            if (m.isAutoload()) {
1670                System.err.print(" (autoload, ");
1671            } else if (m.isEager()) {
1672                System.err.print(" (eager, ");
1673            } else {
1674                System.err.print(" (normal, ");
1675            }
1676            if (m.isEnabled()) {
1677                System.err.print("on)");
1678            } else {
1679                System.err.print("off)");
1680            }
1681        }
1682        System.err.println();
1683    }
1684     */

1685
1686    public void testRelVersRanges() throws Exception JavaDoc {
1687        FakeModuleInstaller installer = new FakeModuleInstaller();
1688        FakeEvents ev = new FakeEvents();
1689        ModuleManager mgr = new ModuleManager(installer, ev);
1690        mgr.mutexPrivileged().enterWriteAccess();
1691        try {
1692            Module base = mgr.create(new File JavaDoc(jars, "rel-ver-2.jar"), null, false, false, false);
1693            String JavaDoc[] depNames = new String JavaDoc[] {
1694                "dep-on-relvertest-1.jar", // 0
1695
"dep-on-relvertest-1-2.jar", // 1
1696
"dep-on-relvertest-2.jar", // 2
1697
"dep-on-relvertest-2-3.jar", // 3
1698
"dep-on-relvertest-2-3-late.jar", // 4
1699
"dep-on-relvertest-2-impl.jar", // 5
1700
"dep-on-relvertest-2-impl-wrong.jar", // 6
1701
"dep-on-relvertest-2-late.jar", // 7
1702
"dep-on-relvertest-3-4.jar", // 8
1703
"dep-on-relvertest-some.jar", // 9
1704
};
1705            Module[] deps = new Module[depNames.length];
1706            for (int i = 0; i < deps.length; i++) {
1707                deps[i] = mgr.create(new File JavaDoc(jars, depNames[i]), null, false, false, false);
1708            }
1709            Set JavaDoc<Module> all = new HashSet JavaDoc<Module>();
1710            all.add(base);
1711            all.addAll(Arrays.asList(deps));
1712            Set JavaDoc<Module> ok = new HashSet JavaDoc<Module>();
1713            ok.add(base);
1714            // 0 - too early
1715
ok.add(deps[1]);
1716            ok.add(deps[2]);
1717            ok.add(deps[3]);
1718            // 4 - too late
1719
ok.add(deps[5]);
1720            // 6 - wrong impl version
1721
// 7 - too late
1722
// 8 - too late
1723
// 9 - must give some rel vers, else ~ -1
1724
assertEquals(ok, new HashSet JavaDoc<Module>(mgr.simulateEnable(all)));
1725        } finally {
1726            mgr.mutexPrivileged().exitWriteAccess();
1727        }
1728    }
1729
1730    public void testDisableAgainstRelVersRange() throws Exception JavaDoc {
1731        // #41449: org.openidex.util/3 disabled improperly when disable module w/ dep on org.openide.util/2-3
1732
FakeModuleInstaller installer = new FakeModuleInstaller();
1733        FakeEvents ev = new FakeEvents();
1734        ModuleManager mgr = new ModuleManager(installer, ev);
1735        mgr.mutexPrivileged().enterWriteAccess();
1736        try {
1737            Module base = mgr.create(new File JavaDoc(jars, "rel-ver-2.jar"), null, false, true, false);
1738            Module dep1 = mgr.create(new File JavaDoc(jars, "dep-on-relvertest-2.jar"), null, false, false, false);
1739            Module dep2 = mgr.create(new File JavaDoc(jars, "dep-on-relvertest-1-2-nospec.jar"), null, false, false, false);
1740            Set JavaDoc<Module> all = new HashSet JavaDoc<Module>();
1741            all.add(dep1);
1742            all.add(dep2);
1743            mgr.enable(all);
1744            all.add(base);
1745            assertEquals("turn on autoload w/ both deps OK", all, mgr.getEnabledModules());
1746            Set JavaDoc<Module> dep2only = Collections.singleton(dep2);
1747            assertEquals("intend to disable only dep2", dep2only, new HashSet JavaDoc<Module>(mgr.simulateDisable(dep2only)));
1748            mgr.disable(dep2only);
1749            all.remove(dep2);
1750            assertEquals("removed just dep2, not autoload used by dep1", all, mgr.getEnabledModules());
1751            mgr.disable(Collections.singleton(dep1));
1752            assertEquals("now all gone", Collections.EMPTY_SET, mgr.getEnabledModules());
1753        } finally {
1754            mgr.mutexPrivileged().exitWriteAccess();
1755        }
1756    }
1757
1758    /** Test #21114: after deleting a module, its JARs are released.
1759     * Would probably always pass on Unix, but on Windows it matters.
1760     */

1761    public void testModuleDeletion() throws Exception JavaDoc {
1762        FakeModuleInstaller installer = new FakeModuleInstaller();
1763        FakeEvents ev = new FakeEvents();
1764        ModuleManager mgr = new ModuleManager(installer, ev);
1765
1766        clearWorkDir();
1767        File JavaDoc jar = new File JavaDoc(getWorkDir(), "copy-of-simple-module.jar");
1768        copy(new File JavaDoc(jars, "simple-module.jar"), jar);
1769
1770        mgr.mutexPrivileged().enterWriteAccess();
1771        try {
1772            Module m = mgr.create(jar, null, false, false, false);
1773            mgr.enable(m);
1774            Class JavaDoc c = m.getClassLoader().loadClass("org.foo.Something");
1775            URL JavaDoc u = m.getClassLoader().getResource("org/foo/Something.class");
1776            URLConnection JavaDoc uc = u.openConnection();
1777            assertTrue("using JarURLConnection", uc instanceof JarURLConnection JavaDoc);
1778            uc.connect();
1779            mgr.disable(m);
1780            mgr.delete(m);
1781
1782            WeakReference JavaDoc<Class JavaDoc> refC = new WeakReference JavaDoc<Class JavaDoc>(c);
1783            WeakReference JavaDoc<URL JavaDoc> refU = new WeakReference JavaDoc<URL JavaDoc>(u);
1784            WeakReference JavaDoc<URLConnection JavaDoc> refUC = new WeakReference JavaDoc<URLConnection JavaDoc>(uc);
1785
1786            c = null;
1787            u = null;
1788            uc = null;
1789
1790            assertGC ("Module class can go away", refC);
1791            assertGC ("Module url", refU);
1792            assertGC ("Module connection ", refUC);
1793        } finally {
1794            mgr.mutexPrivileged().exitWriteAccess();
1795        }
1796
1797        assertTrue("could delete JAR file", jar.delete());
1798    }
1799
1800    /** Test #20663: the context classloader is set on all threads
1801     * according to the system classloader.
1802     */

1803    public void testContextClassLoader() throws Exception JavaDoc {
1804        FakeModuleInstaller installer = new FakeModuleInstaller();
1805        FakeEvents ev = new FakeEvents();
1806        final ModuleManager mgr = new ModuleManager(installer, ev);
1807        mgr.mutexPrivileged().enterWriteAccess();
1808        // Make sure created threads do not die.
1809
final Object JavaDoc sleepForever = "sleepForever";
1810        try {
1811            final Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, false, false);
1812            Module m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, false);
1813            ClassLoader JavaDoc l1 = mgr.getClassLoader();
1814            assertEquals(l1, Thread.currentThread().getContextClassLoader());
1815            mgr.enable(m1);
1816            ClassLoader JavaDoc l2 = mgr.getClassLoader();
1817            assertTrue(l1 == l2);
1818            assertEquals(l2, Thread.currentThread().getContextClassLoader());
1819            mgr.enable(m2);
1820            ClassLoader JavaDoc l3 = mgr.getClassLoader();
1821            assertTrue(l1 == l3);
1822            assertEquals(l3, Thread.currentThread().getContextClassLoader());
1823            mgr.disable(m2);
1824            ClassLoader JavaDoc l4 = mgr.getClassLoader();
1825            assertTrue(l1 != l4);
1826            assertEquals(l4, Thread.currentThread().getContextClassLoader());
1827            final Thread JavaDoc[] t23 = new Thread JavaDoc[2];
1828            final ClassLoader JavaDoc[] lx = new ClassLoader JavaDoc[] {new URLClassLoader JavaDoc(new URL JavaDoc[0])};
1829            // Make sure t1 runs to completion, though.
1830
final Object JavaDoc finishT1 = "finishT1";
1831            Thread JavaDoc t1 = new Thread JavaDoc("custom thread #1") {
1832                public void run() {
1833                    synchronized (finishT1) {
1834                        t23[0] = new Thread JavaDoc("custom thread #2") {
1835                            public void run() {
1836                                synchronized (sleepForever) {
1837                                    try {
1838                                        sleepForever.wait();
1839                                    } catch (InterruptedException JavaDoc ie) {
1840                                        throw new Error JavaDoc(ie.toString());
1841                                    }
1842                                }
1843                            }
1844                        };
1845                        t23[0].start();
1846                        Thread.currentThread().setContextClassLoader(lx[0]);
1847                        mgr.disable(m1);
1848                        t23[1] = new Thread JavaDoc("custom thread #3") {
1849                            public void run() {
1850                                synchronized (sleepForever) {
1851                                    try {
1852                                        sleepForever.wait();
1853                                    } catch (InterruptedException JavaDoc ie) {
1854                                        throw new Error JavaDoc(ie.toString());
1855                                    }
1856                                }
1857                            }
1858                        };
1859                        t23[1].start();
1860                        finishT1.notify();
1861                    }
1862                    synchronized (sleepForever) {
1863                        try {
1864                            sleepForever.wait();
1865                        } catch (InterruptedException JavaDoc ie) {
1866                            throw new Error JavaDoc(ie.toString());
1867                        }
1868                    }
1869                }
1870            };
1871            t1.start();
1872            synchronized (finishT1) {
1873                if (t23[1] == null) {
1874                    finishT1.wait();
1875                    assertNotNull(t23[1]);
1876                }
1877            }
1878            assertFalse(m1.isEnabled());
1879            ClassLoader JavaDoc l5 = mgr.getClassLoader();
1880            assertTrue(l1 != l5);
1881            assertTrue(l4 != l5);
1882            assertEquals(l5, Thread.currentThread().getContextClassLoader());
1883            // It had a special classloader when we changed modules.
1884
assertTrue(t1.isAlive());
1885            assertEquals(lx[0], t1.getContextClassLoader());
1886            // It was created before the special classloader.
1887
assertTrue(t23[0].isAlive());
1888            assertEquals(l5, t23[0].getContextClassLoader());
1889            // It was created after and should have inherited the special classloader.
1890
assertTrue(t23[1].isAlive());
1891            assertEquals(lx[0], t23[1].getContextClassLoader());
1892            mgr.enable(m1);
1893            mgr.disable(m1);
1894            ClassLoader JavaDoc l6 = mgr.getClassLoader();
1895            assertTrue(l1 != l6);
1896            assertTrue(l4 != l6);
1897            assertTrue(l5 != l6);
1898            assertEquals(l6, Thread.currentThread().getContextClassLoader());
1899            assertEquals(lx[0], t1.getContextClassLoader());
1900            assertEquals(l6, t23[0].getContextClassLoader());
1901            assertEquals(lx[0], t23[1].getContextClassLoader());
1902        } finally {
1903            synchronized (sleepForever) {
1904                sleepForever.notifyAll();
1905            }
1906            mgr.mutexPrivileged().exitWriteAccess();
1907        }
1908    }
1909
1910    /** Make sure classloaders do not overlap.
1911     * @see "#24996"
1912     */

1913    public void testDependOnTwoFixedModules() throws Exception JavaDoc {
1914        FakeModuleInstaller installer = new FakeModuleInstaller();
1915        FakeEvents ev = new FakeEvents();
1916        ModuleManager mgr = new ModuleManager(installer, ev);
1917        mgr.mutexPrivileged().enterWriteAccess();
1918        try {
1919            File JavaDoc j1 = new File JavaDoc(jars, "simple-module.jar");
1920            File JavaDoc j2 = new File JavaDoc(jars, "depends-on-simple-module.jar");
1921            File JavaDoc j3 = new File JavaDoc(jars, "dep-on-two-modules.jar");
1922            URLClassLoader JavaDoc l = new URLClassLoader JavaDoc(new URL JavaDoc[] {j1.toURL(), j2.toURL()});
1923            Manifest JavaDoc mani1, mani2;
1924            JarFile JavaDoc j = new JarFile JavaDoc(j1);
1925            try {
1926                mani1 = j.getManifest();
1927            } finally {
1928                j.close();
1929            }
1930            j = new JarFile JavaDoc(j2);
1931            try {
1932                mani2 = j.getManifest();
1933            } finally {
1934                j.close();
1935            }
1936            Module m1 = mgr.createFixed(mani1, null, l);
1937            Module m2 = mgr.createFixed(mani2, null, l);
1938            Module m3 = mgr.create(j3, null, false, false, false);
1939            mgr.enable(new HashSet JavaDoc<Module>(Arrays.asList(m1, m2, m3)));
1940        } finally {
1941            mgr.mutexPrivileged().exitWriteAccess();
1942        }
1943    }
1944
1945    /** Test exporting selected packages to clients.
1946     * @see "#19621"
1947     */

1948    public void testPackageExports() throws Exception JavaDoc {
1949        ModuleManager mgr = new ModuleManager(new FakeModuleInstaller(), new FakeEvents());
1950        mgr.mutexPrivileged().enterWriteAccess();
1951        try {
1952            Module m1 = mgr.create(new File JavaDoc(jars, "api-mod-export-all.jar"), null, false, false, false);
1953            Module m2 = mgr.create(new File JavaDoc(jars, "uses-api-simple-dep.jar"), null, false, false, false);
1954            mgr.enable(m1);
1955            mgr.enable(m2);
1956            m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance();
1957            m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance();
1958            mgr.disable(m2);
1959            mgr.disable(m1);
1960            mgr.delete(m2);
1961            mgr.delete(m1);
1962            m1 = mgr.create(new File JavaDoc(jars, "api-mod-export-none.jar"), null, false, false, false);
1963            m2 = mgr.create(new File JavaDoc(jars, "uses-api-simple-dep.jar"), null, false, false, false);
1964            mgr.enable(m1);
1965            mgr.enable(m2);
1966            try {
1967                m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance();
1968                fail();
1969            } catch (NoClassDefFoundError JavaDoc e) {}
1970            try {
1971                m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance();
1972                fail();
1973            } catch (NoClassDefFoundError JavaDoc e) {}
1974            assertNotNull(mgr.getClassLoader().getResource("usesapi/UsesImplClass.class"));
1975            assertNotNull(mgr.getClassLoader().getResource("org/netbeans/api/foo/PublicClass.class"));
1976            assertNotNull(mgr.getClassLoader().getResource("org/netbeans/modules/foo/ImplClass.class"));
1977            mgr.disable(m2);
1978            mgr.disable(m1);
1979            mgr.delete(m2);
1980            mgr.delete(m1);
1981            m1 = mgr.create(new File JavaDoc(jars, "api-mod-export-none.jar"), null, false, false, false);
1982            m2 = mgr.create(new File JavaDoc(jars, "uses-api-spec-dep.jar"), null, false, false, false);
1983            mgr.enable(m1);
1984            mgr.enable(m2);
1985            try {
1986                m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance();
1987                fail();
1988            } catch (NoClassDefFoundError JavaDoc e) {}
1989            try {
1990                m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance();
1991                fail();
1992            } catch (NoClassDefFoundError JavaDoc e) {}
1993            mgr.disable(m2);
1994            mgr.disable(m1);
1995            mgr.delete(m2);
1996            mgr.delete(m1);
1997            m1 = mgr.create(new File JavaDoc(jars, "api-mod-export-none.jar"), null, false, false, false);
1998            m2 = mgr.create(new File JavaDoc(jars, "uses-api-impl-dep.jar"), null, false, false, false);
1999            mgr.enable(m1);
2000            mgr.enable(m2);
2001            m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance();
2002            m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance();
2003            mgr.disable(m2);
2004            mgr.disable(m1);
2005            mgr.delete(m2);
2006            mgr.delete(m1);
2007            m1 = mgr.create(new File JavaDoc(jars, "api-mod-export-api.jar"), null, false, false, false);
2008            m2 = mgr.create(new File JavaDoc(jars, "uses-api-simple-dep.jar"), null, false, false, false);
2009            assertEquals("api-mod-export-api.jar can be enabled", Collections.EMPTY_SET, m1.getProblems());
2010            mgr.enable(m1);
2011            assertEquals("uses-api-simple-dep.jar can be enabled", Collections.EMPTY_SET, m2.getProblems());
2012            mgr.enable(m2);
2013            m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance();
2014            try {
2015                m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance();
2016                fail();
2017            } catch (NoClassDefFoundError JavaDoc e) {}
2018            mgr.disable(m2);
2019            mgr.disable(m1);
2020            mgr.delete(m2);
2021            mgr.delete(m1);
2022            m1 = mgr.create(new File JavaDoc(jars, "api-mod-export-api.jar"), null, false, false, false);
2023            m2 = mgr.create(new File JavaDoc(jars, "uses-api-spec-dep.jar"), null, false, false, false);
2024            mgr.enable(m1);
2025            mgr.enable(m2);
2026            m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance();
2027            try {
2028                m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance();
2029                fail();
2030            } catch (NoClassDefFoundError JavaDoc e) {}
2031            mgr.disable(m2);
2032            mgr.disable(m1);
2033            mgr.delete(m2);
2034            mgr.delete(m1);
2035            m1 = mgr.create(new File JavaDoc(jars, "api-mod-export-api.jar"), null, false, false, false);
2036            m2 = mgr.create(new File JavaDoc(jars, "uses-api-impl-dep.jar"), null, false, false, false);
2037            mgr.enable(m1);
2038            mgr.enable(m2);
2039            m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance();
2040            m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance();
2041            mgr.disable(m2);
2042            mgr.disable(m1);
2043            mgr.delete(m2);
2044            mgr.delete(m1);
2045            // XXX test use of .** to export packages recursively
2046
// XXX test misparsing of malformed export lines
2047
// XXX test exporting of >1 package from one module (comma-separated)
2048
} finally {
2049            mgr.mutexPrivileged().exitWriteAccess();
2050        }
2051    }
2052
2053    /** Test that package exports, and package/classloader use generally, is not
2054     * transitively exported from modules - that you need to declare an explicit
2055     * module dependency on every module from which you expect to load classes
2056     * or resources, even if you are already declaring a dependency on an inter-
2057     * mediate module which has such a dependency.
2058     * @see "#27853"
2059     */

2060    public void testIndirectPackageExports() throws Exception JavaDoc {
2061        ModuleManager mgr = new ModuleManager(new FakeModuleInstaller(), new FakeEvents());
2062        mgr.mutexPrivileged().enterWriteAccess();
2063        try {
2064            Module m1 = mgr.create(new File JavaDoc(jars, "api-mod-export-api.jar"), null, false, false, false);
2065            Module m2 = mgr.create(new File JavaDoc(jars, "uses-and-exports-api.jar"), null, false, false, false);
2066            Module m3 = mgr.create(new File JavaDoc(jars, "uses-api-transitively.jar"), null, false, false, false);
2067            Module m4 = mgr.create(new File JavaDoc(jars, "uses-api-directly.jar"), null, false, false, false);
2068            assertEquals("api-mod-export-api.jar had no problems", Collections.EMPTY_SET, m1.getProblems());
2069            assertEquals("uses-and-exports-api.jar had no problems", Collections.EMPTY_SET, m2.getProblems());
2070            assertEquals("uses-api-transitively.jar had no problems", Collections.EMPTY_SET, m3.getProblems());
2071            assertEquals("uses-api-directly.jar had no problems", Collections.EMPTY_SET, m4.getProblems());
2072            mgr.enable(new HashSet JavaDoc<Module>(Arrays.asList(m1, m2, m3, m4)));
2073            m4.getClassLoader().loadClass("usesapitrans.UsesDirectAPI").newInstance();
2074            m4.getClassLoader().loadClass("usesapitrans.UsesIndirectAPI").newInstance();
2075            m3.getClassLoader().loadClass("usesapitrans.UsesDirectAPI").newInstance();
2076            try {
2077                m3.getClassLoader().loadClass("usesapitrans.UsesIndirectAPI").newInstance();
2078                fail("Should not be able to use a transitive API class with no direct dependency");
2079            } catch (NoClassDefFoundError JavaDoc e) {}
2080            mgr.disable(new HashSet JavaDoc<Module>(Arrays.asList(m1, m2, m3, m4)));
2081            mgr.delete(m4);
2082            mgr.delete(m3);
2083            mgr.delete(m2);
2084            mgr.delete(m1);
2085        } finally {
2086            mgr.mutexPrivileged().exitWriteAccess();
2087        }
2088    }
2089
2090    public void testPublicPackagesCanBeExportedToSelectedFriendsOnlyIssue54123 () throws Exception JavaDoc {
2091        ModuleManager mgr = new ModuleManager(new FakeModuleInstaller(), new FakeEvents());
2092        mgr.mutexPrivileged().enterWriteAccess();
2093        try {
2094            Module m1 = mgr.create(new File JavaDoc(jars, "api-mod-export-friend.jar"), null, false, false, false);
2095            Module m2 = mgr.create(new File JavaDoc(jars, "uses-api-friend.jar"), null, false, false, false);
2096            Module m3 = mgr.create(new File JavaDoc(jars, "uses-and-exports-api.jar"), null, false, false, false);
2097            Module m4 = mgr.create(new File JavaDoc(jars, "uses-api-directly.jar"), null, false, false, false);
2098            Module m5 = mgr.create(new File JavaDoc(jars, "uses-api-impl-dep-for-friends.jar"), null, false, false, false);
2099            assertEquals("api-mod-export-api.jar had no problems", Collections.EMPTY_SET, m1.getProblems());
2100            assertEquals("uses-api-friend.jar had no problems", Collections.EMPTY_SET, m2.getProblems());
2101            assertEquals("uses-and-exports-api.jar had no problems", Collections.EMPTY_SET, m3.getProblems());
2102            assertEquals("uses-api-directly.jar had no problems", Collections.EMPTY_SET, m4.getProblems());
2103            assertEquals("uses-api-impl-dep-for-friends.jar had no problems", Collections.EMPTY_SET, m5.getProblems());
2104            mgr.enable(new HashSet JavaDoc<Module>(Arrays.asList(m1, m2, m3, m4, m5)));
2105            m2.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance();
2106            try {
2107                m2.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance();
2108                fail ("Even friends modules cannot access implementation classes");
2109            } catch (NoClassDefFoundError JavaDoc ex) {
2110                // ok
2111
}
2112
2113            try {
2114                m4.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance();
2115                fail ("m4 is not friend and should not be allowed to load the class");
2116            } catch (NoClassDefFoundError JavaDoc ex) {
2117                // ok
2118
}
2119            try {
2120                m4.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance();
2121                fail ("m4 is not friend and should not be allowed to load the implementation either");
2122            } catch (NoClassDefFoundError JavaDoc ex) {
2123                // ok
2124
}
2125            try {
2126                m5.getClassLoader().loadClass("usesapi.UsesPublicClass").newInstance();
2127            } catch (NoClassDefFoundError JavaDoc e) {
2128                fail("m5 has an implementation dependency and has not been allowed to load the public class");
2129            }
2130            try {
2131                m5.getClassLoader().loadClass("usesapi.UsesImplClass").newInstance();
2132            } catch (NoClassDefFoundError JavaDoc e) {
2133                fail("m5 has an implementation dependency and has not been allowed to load the imlpementation class");
2134            }
2135
2136            mgr.disable(new HashSet JavaDoc<Module>(Arrays.asList(m1, m2, m3, m4, m5)));
2137            mgr.delete(m5);
2138            mgr.delete(m4);
2139            mgr.delete(m3);
2140            mgr.delete(m2);
2141            mgr.delete(m1);
2142        } finally {
2143            mgr.mutexPrivileged().exitWriteAccess();
2144        }
2145    }
2146
2147    public void testModuleInterdependencies() throws Exception JavaDoc {
2148        FakeModuleInstaller installer = new FakeModuleInstaller();
2149        FakeEvents ev = new FakeEvents();
2150        ModuleManager mgr = new ModuleManager(installer, ev);
2151        mgr.mutexPrivileged().enterWriteAccess();
2152        try {
2153            Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, false, false);
2154            Module m2 = mgr.create(new File JavaDoc(jars, "depends-on-simple-module.jar"), null, false, false, false);
2155            Module m3 = mgr.create(new File JavaDoc(jars, "dep-on-dep-on-simple.jar"), null, false, false, false);
2156            Set JavaDoc<Module> m1m2 = new HashSet JavaDoc<Module>(Arrays.asList(m1, m2));
2157            Set JavaDoc<Module> m2m3 = new HashSet JavaDoc<Module>(Arrays.asList(m2, m3));
2158            assertEquals(Collections.EMPTY_SET, mgr.getModuleInterdependencies(m1, false, false));
2159            assertEquals(Collections.EMPTY_SET, mgr.getModuleInterdependencies(m1, false, true));
2160            assertEquals(Collections.singleton(m2), mgr.getModuleInterdependencies(m1, true, false));
2161            assertEquals(m2m3, mgr.getModuleInterdependencies(m1, true, true));
2162            assertEquals(Collections.singleton(m1), mgr.getModuleInterdependencies(m2, false, false));
2163            assertEquals(Collections.singleton(m1), mgr.getModuleInterdependencies(m2, false, true));
2164            assertEquals(Collections.singleton(m3), mgr.getModuleInterdependencies(m2, true, false));
2165            assertEquals(Collections.singleton(m3), mgr.getModuleInterdependencies(m2, true, true));
2166            assertEquals(Collections.singleton(m2), mgr.getModuleInterdependencies(m3, false, false));
2167            assertEquals(m1m2, mgr.getModuleInterdependencies(m3, false, true));
2168            assertEquals(Collections.EMPTY_SET, mgr.getModuleInterdependencies(m3, true, false));
2169            assertEquals(Collections.EMPTY_SET, mgr.getModuleInterdependencies(m3, true, true));
2170            m1 = mgr.create(new File JavaDoc(jars, "prov-foo.jar"), null, false, false, false);
2171            m2 = mgr.create(new File JavaDoc(jars, "prov-foo-bar.jar"), null, false, false, false);
2172            m3 = mgr.create(new File JavaDoc(jars, "req-foo.jar"), null, false, false, false);
2173            Module m4 = mgr.create(new File JavaDoc(jars, "prov-baz.jar"), null, false, false, false);
2174            Module m5 = mgr.create(new File JavaDoc(jars, "req-foo-baz.jar"), null, false, false, false);
2175            m1m2 = new HashSet JavaDoc<Module>(Arrays.asList(m1, m2));
2176            assertEquals(m1m2, mgr.getModuleInterdependencies(m3, false, true));
2177            Set JavaDoc<Module> m1m2m4 = new HashSet JavaDoc<Module>(Arrays.asList(m1, m2, m4));
2178            assertEquals(m1m2m4, mgr.getModuleInterdependencies(m5, false, true));
2179            Set JavaDoc<Module> m3m5 = new HashSet JavaDoc<Module>(Arrays.asList(m3, m5));
2180            assertEquals(m3m5, mgr.getModuleInterdependencies(m1, true, true));
2181            // XXX could do more...
2182
} finally {
2183            mgr.mutexPrivileged().exitWriteAccess();
2184        }
2185    }
2186
2187    public void testModuleClassLoaderWasNotReadyWhenTheChangeWasFiredIssue() throws Exception JavaDoc {
2188        doModuleClassLoaderWasNotReadyWhenTheChangeWasFiredIssue (1);
2189    }
2190    public void testGlobalClassLoaderWasNotReadyWhenTheChangeWasFiredIssue() throws Exception JavaDoc {
2191        doModuleClassLoaderWasNotReadyWhenTheChangeWasFiredIssue (2);
2192    }
2193    public void testModuleManagerClassLoaderWasNotReadyWhenTheChangeWasFiredIssue() throws Exception JavaDoc {
2194        doModuleClassLoaderWasNotReadyWhenTheChangeWasFiredIssue (3);
2195    }
2196
2197    private void doModuleClassLoaderWasNotReadyWhenTheChangeWasFiredIssue (final int typeOfClassLoader) throws Exception JavaDoc {
2198        FakeModuleInstaller installer = new FakeModuleInstaller();
2199        FakeEvents ev = new FakeEvents();
2200        final ModuleManager mgr = new ModuleManager(installer, ev);
2201        mgr.mutexPrivileged().enterWriteAccess();
2202        try {
2203            final Module m1 = mgr.create(new File JavaDoc(jars, "simple-module.jar"), null, false, false, false);
2204
2205            class L implements java.beans.PropertyChangeListener JavaDoc {
2206                ClassLoader JavaDoc l;
2207                IllegalStateException JavaDoc ex;
2208
2209                public void propertyChange (java.beans.PropertyChangeEvent JavaDoc event) {
2210                    if (m1.PROP_ENABLED.equals (event.getPropertyName ())) {
2211                        try {
2212                            this.l = get ();
2213                        } catch (IllegalStateException JavaDoc ex) {
2214                            this.ex = ex;
2215                        }
2216                    }
2217                }
2218
2219                public ClassLoader JavaDoc get () {
2220                    switch (typeOfClassLoader) {
2221                        case 1: return m1.getClassLoader ();
2222                        case 2: return Thread.currentThread ().getContextClassLoader ();
2223                        case 3: return mgr.getClassLoader ();
2224                    }
2225                    fail ("Wrong type: " + typeOfClassLoader);
2226                    return null;
2227                }
2228            }
2229            L JavaDoc l = new L JavaDoc ();
2230            m1.addPropertyChangeListener (l);
2231
2232            mgr.enable (m1);
2233
2234            assertTrue ("Successfully enabled", m1.isEnabled ());
2235            assertEquals ("Classloader at the time of PROP_ENABLED is the same as now", l.get (), l.l);
2236            assertNull ("No exception thrown", l.ex);
2237            //System.out.println("L: " + l.l);
2238
m1.removePropertyChangeListener (l);
2239
2240            mgr.disable (m1);
2241        } finally {
2242            mgr.mutexPrivileged().exitWriteAccess();
2243        }
2244    }
2245
2246    /** @see "#76917" */
2247    public void testProblemsStillCorrectWithHardAndSoftMixture() throws Exception JavaDoc {
2248        File JavaDoc m1j = new File JavaDoc(getWorkDir(), "m1.jar");
2249        createJar(m1j, Collections.<String JavaDoc,String JavaDoc>emptyMap(), Collections.singletonMap("OpenIDE-Module", "m1"));
2250        File JavaDoc m2j = new File JavaDoc(getWorkDir(), "m2.jar");
2251        Map JavaDoc<String JavaDoc,String JavaDoc> mani = new HashMap JavaDoc<String JavaDoc,String JavaDoc>();
2252        mani.put("OpenIDE-Module", "m2");
2253        mani.put("OpenIDE-Module-Module-Dependencies", "m1");
2254        mani.put("OpenIDE-Module-Java-Dependencies", "Java > 2046");
2255        createJar(m2j, Collections.<String JavaDoc,String JavaDoc>emptyMap(), mani);
2256        FakeModuleInstaller installer = new FakeModuleInstaller();
2257        FakeEvents ev = new FakeEvents();
2258        ModuleManager mgr = new ModuleManager(installer, ev);
2259        mgr.mutexPrivileged().enterWriteAccess();
2260        try {
2261            Module m2 = mgr.create(m2j, null, false, false, false);
2262            assertEquals("initially m2 has two problems: Java and m1", 2, m2.getProblems().size());
2263            Module m1 = mgr.create(m1j, null, false, false, false);
2264            assertEquals("m1 has no problems", Collections.emptySet(), m1.getProblems());
2265            assertEquals("now m2 should have just one problem: Java", 1, m2.getProblems().size());
2266            Dependency d = (Dependency) m2.getProblems().iterator().next();
2267            assertEquals(Dependency.TYPE_JAVA, d.getType());
2268        } finally {
2269            mgr.mutexPrivileged().exitWriteAccess();
2270        }
2271    }
2272
2273    private File JavaDoc copyJar(File JavaDoc file, String JavaDoc manifest) throws IOException JavaDoc {
2274        File JavaDoc ret = File.createTempFile(file.getName(), "2ndcopy", file.getParentFile());
2275        JarFile JavaDoc jar = new JarFile JavaDoc(file);
2276        JarOutputStream JavaDoc os = new JarOutputStream JavaDoc(new FileOutputStream JavaDoc(ret), new Manifest JavaDoc(
2277            new ByteArrayInputStream JavaDoc(manifest.getBytes())
2278        ));
2279        Enumeration JavaDoc<JarEntry JavaDoc> en = jar.entries();
2280        while (en.hasMoreElements()) {
2281            JarEntry JavaDoc elem = en.nextElement();
2282            if (elem.getName().equals("META-INF/MANIFEST.MF")) {
2283                continue;
2284            }
2285            os.putNextEntry(elem);
2286            InputStream JavaDoc is = jar.getInputStream(elem);
2287            FileUtil.copy(is, os);
2288            is.close();
2289        }
2290        os.close();
2291        return ret;
2292    }
2293
2294    private static Module createModule(ModuleManager mgr, String JavaDoc manifest) throws Exception JavaDoc {
2295        return mgr.createFixed(new Manifest JavaDoc(new ByteArrayInputStream JavaDoc(manifest.getBytes())), null, ModuleManagerTest.class.getClassLoader());
2296    }
2297
2298}
2299
Popular Tags