View Javadoc
1   package org.codehaus.plexus.component.composition;
2   
3   import java.io.File;
4   import java.net.URL;
5   import java.util.List;
6   import java.util.Map;
7   import java.util.TreeMap;
8   
9   import org.codehaus.plexus.PlexusTestCase;
10  import org.codehaus.plexus.classworlds.realm.ClassRealm;
11  
12  import static org.codehaus.plexus.PlexusConstants.PLEXUS_DEFAULT_HINT;
13  
14  /** @author Jason van Zyl */
15  public class ComponentRealmCompositionTest extends PlexusTestCase {
16      //
17      // Component archives
18      //
19      private static final String PLUGIN_0_JAR = "src/test/test-components/plugin0-1.0-SNAPSHOT.jar";
20      private static final String PLUGIN_1_JAR = "src/test/test-components/plugin1-1.0-SNAPSHOT.jar";
21      private static final String COMPONENT_A_JAR = "src/test/test-components/component-a-1.0-SNAPSHOT.jar";
22      private static final String COMPONENT_B_JAR = "src/test/test-components/component-b-1.0-SNAPSHOT.jar";
23      private static final String COMPONENT_C_JAR = "src/test/test-components/component-c-1.0-SNAPSHOT.jar";
24      private static final String ARCHIVER_JAR = "src/test/test-components/plexus-archiver-1.0-alpha-8.jar";
25  
26      //
27      // Component roles
28      //
29      private static final String PLUGIN_0_ROLE = "org.codehaus.plexus.plugins.Plugin0";
30      private static final String PLUGIN_1_ROLE = "org.codehaus.plexus.plugins.Plugin1";
31  
32      //
33      // Component realms
34      //
35      private static final String PLUGIN_0_REALM = "plugin0Realm";
36      private static final String PLUGIN_1_REALM = "plugin1Realm";
37  
38      protected void setUp() throws Exception {
39          super.setUp();
40  
41          // Create ClassRealm plugin0 with plugin0 -> A, plugin0 -> B
42          createClassRealm(PLUGIN_0_REALM, PLUGIN_0_JAR, COMPONENT_A_JAR, COMPONENT_B_JAR, ARCHIVER_JAR);
43  
44          // Create ClassRealm plugin1 with plugin1 -> A, plugin1 -> C
45          createClassRealm(PLUGIN_1_REALM, PLUGIN_1_JAR, COMPONENT_A_JAR, COMPONENT_C_JAR, ARCHIVER_JAR);
46      }
47  
48      /*
49       * We are testing that when the same component implementation exists in more then one
50       * realm and components depend on those implementations, that the right realm is used
51       * to wire up the components.
52       *
53       * An example of this in practice are Maven plugins where each plugin is loaded into
54       * a separate realm and the plugin may have dependencies on other components. We want
55       * to make sure that a requirement, say a JarArchiver, for a given component, say the
56       * maven-jar-plugin, is wired up with a JarArchiver taken from the same realm as the
57       * maven-jar-plugin and not a different realm.
58       */
59  
60      public void testCompositionWhereTheSameImplementationExistsInDifferentRealms() throws Exception {
61          // Plugin0
62          getContainer().lookup(PLUGIN_0_ROLE);
63  
64          // Plugin1
65          getContainer().lookup(PLUGIN_1_ROLE);
66  
67          // Plugin0(alt)
68          getContainer().lookup(PLUGIN_0_ROLE, "alt");
69  
70          // Plugin1(alt)
71          getContainer().lookup(PLUGIN_1_ROLE, "alt");
72      }
73  
74      public void testThatASingletonComponentIntheCoreRealmWhenLookedUpInComponentRealmsYieldsTheSameInstance()
75              throws Exception {}
76  
77      public void testMultiRealmLookupMap() throws Exception {
78          Map<String, Object> plugin0Map = getContainer().lookupMap(PLUGIN_0_ROLE);
79          assertNotNull("plugin0Map is null", plugin0Map);
80          assertNotNull("plugin0Map does not contain a DefaultPlugin0", plugin0Map.get(PLEXUS_DEFAULT_HINT));
81          assertNotNull("plugin0Map does not contain a AltPlugin0", plugin0Map.get("alt"));
82          assertEquals("Expected only 2 components in plugin0Map", 2, plugin0Map.size());
83  
84          Map<String, Object> plugin1Map = getContainer().lookupMap(PLUGIN_1_ROLE);
85          assertNotNull("plugin1Map is null", plugin1Map);
86          assertNotNull("plugin1Map does not contain a DefaultPlugin1", plugin1Map.get(PLEXUS_DEFAULT_HINT));
87          assertNotNull("plugin1Map does not contain a AltPlugin1", plugin1Map.get("alt"));
88          assertEquals("Expected only 2 components in plugin1Map", 2, plugin1Map.size());
89      }
90  
91      public void testMultiRealmLookupList() throws Exception {
92          List<Object> plugin0List = getContainer().lookupList(PLUGIN_0_ROLE);
93          assertNotNull("plugin0List is null", plugin0List);
94          Map<String, Object> plugin0Map = mapByClassSimpleName(plugin0List);
95          assertNotNull("plugin0List does not contain a DefaultPlugin0", plugin0Map.get("DefaultPlugin0"));
96          assertNotNull("plugin0List does not contain a AltPlugin0", plugin0Map.get("AltPlugin0"));
97          assertEquals("Expected only 2 components in plugin0Map", 2, plugin0Map.size());
98  
99          List<Object> plugin1List = getContainer().lookupList(PLUGIN_1_ROLE);
100         assertNotNull("plugin1List is null", plugin1List);
101         Map<String, Object> plugin1Map = mapByClassSimpleName(plugin1List);
102         assertNotNull("plugin1List does not contain a DefaultPlugin1", plugin1Map.get("DefaultPlugin1"));
103         assertNotNull("plugin1List does not contain a AltPlugin1", plugin1Map.get("AltPlugin1"));
104         assertEquals("Expected only 2 components in plugin0Map", 2, plugin1Map.size());
105     }
106 
107     private ClassRealm createClassRealm(String id, String... jars) throws Exception {
108         // create the realm
109         ClassRealm classRealm = getContainer().createChildRealm(id);
110 
111         // populate the realm
112         for (String jar : jars) {
113             File file = new File(jar);
114             assertTrue(jar + " is not a file", file.isFile());
115 
116             URL url = file.toURI().toURL();
117             classRealm.addURL(url);
118         }
119 
120         // descover all component definitions in the realm and register them with the repository
121         getContainer().discoverComponents(classRealm);
122 
123         return classRealm;
124     }
125 
126     private Map<String, Object> mapByClassSimpleName(List<Object> objects) {
127         Map<String, Object> map = new TreeMap<String, Object>();
128         for (Object object : objects) {
129             map.put(object.getClass().getSimpleName(), object);
130         }
131         return map;
132     }
133 }