View Javadoc
1   package org.codehaus.plexus.metadata.merge;
2   
3   /*
4    * The MIT License
5    *
6    * Copyright (c) 2006, The Codehaus
7    *
8    * Permission is hereby granted, free of charge, to any person obtaining a copy of
9    * this software and associated documentation files (the "Software"), to deal in
10   * the Software without restriction, including without limitation the rights to
11   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12   * of the Software, and to permit persons to whom the Software is furnished to do
13   * so, subject to the following conditions:
14   *
15   * The above copyright notice and this permission notice shall be included in all
16   * copies or substantial portions of the Software.
17   *
18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24   * SOFTWARE.
25   */
26  
27  import java.io.File;
28  import java.io.StringReader;
29  import java.util.List;
30  
31  import org.codehaus.plexus.PlexusTestCase;
32  import org.codehaus.plexus.metadata.merge.support.AbstractMergeableElement;
33  import org.codehaus.plexus.metadata.merge.support.AbstractMergeableElementList;
34  import org.codehaus.plexus.metadata.merge.support.ComponentElement;
35  import org.codehaus.plexus.metadata.merge.support.ComponentsElement;
36  import org.codehaus.plexus.metadata.merge.support.RequirementsElement;
37  import org.codehaus.plexus.util.FileUtils;
38  import org.jdom2.Document;
39  import org.jdom2.Element;
40  import org.jdom2.input.SAXBuilder;
41  
42  /**
43   * Tests for {@link ComponentsXmlMerger}.
44   *
45   * @author <a href='mailto:rahul.thakur.xdev@gmail.com'>Rahul Thakur</a>
46   */
47  public class ComponentsXmlMergerTest extends PlexusTestCase {
48      public void testBasic() throws Exception {
49          ComponentsXmlMerger merger = (ComponentsXmlMerger) lookup(Merger.class, "componentsXml");
50          assertNotNull(merger);
51      }
52  
53      public void testComponentsXmlFileMerge() throws Exception {
54          File dominantXml = getTestFile("src/test/resources/org/codehaus/plexus/metadata/merge/dominant.xml");
55          File recessiveXml = getTestFile("src/test/resources/org/codehaus/plexus/metadata/merge/recessive.xml");
56          Document dDoc = new SAXBuilder().build(dominantXml);
57          Document rDoc = new SAXBuilder().build(recessiveXml);
58          // ComponentsXmlMerger merger = new ComponentsXmlMerger (dDoc);
59          Merger merger = lookup(Merger.class, "componentsXml");
60          assertNotNull(merger);
61          merger.merge(dDoc, rDoc);
62  
63          File merged_xml = getTestFile("target/merged.xml");
64          if (merged_xml.exists()) {
65              FileUtils.forceDelete(merged_xml);
66          }
67          merger.writeMergedDocument(dDoc, merged_xml);
68          assertTrue(merged_xml.exists());
69          // read merged xml and verify it was merged as expected
70          Document mDoc = new SAXBuilder().build(merged_xml);
71          Element mRootElt = mDoc.getRootElement();
72          assertTrue(mRootElt.getName().equals("component-set"));
73          assertEquals(1, mRootElt.getChildren("components").size());
74          List componentEltList = mRootElt.getChild("components").getChildren("component");
75          assertEquals(2, componentEltList.size());
76          Element cElt = (Element) componentEltList.get(0);
77  
78          assertEquals("org.codehaus.plexus.metadata.component.IComponent", cElt.getChildTextTrim("role"));
79          assertEquals(
80                  "org.codehaus.plexus.metadata.component.DominantComponent", cElt.getChildTextTrim("implementation"));
81  
82          assertEquals(
83                  "Should only have 1 description element.",
84                  1,
85                  cElt.getChildren("description").size());
86          assertEquals("Description for Dominant component", cElt.getChildTextTrim("description"));
87  
88          assertEquals(
89                  "Should only have 1 configuration element.",
90                  1,
91                  cElt.getChildren("configuration").size());
92          // assert Merged configuration properties
93          Element configurationElt = cElt.getChild("configuration");
94          assertNotNull(configurationElt);
95          assertEquals(1, configurationElt.getChildren("prop1").size());
96          assertEquals("Dominant Property1 value", configurationElt.getChildTextTrim("prop1"));
97          assertEquals(1, configurationElt.getChildren("prop2").size());
98          assertEquals(0, configurationElt.getChildren("prop3").size());
99  
100         // now for the second component
101         cElt = (Element) componentEltList.get(1);
102         assertEquals("org.codehaus.plexus.metadata.component.INonConflictingComponent", cElt.getChildTextTrim("role"));
103         assertEquals(
104                 "org.codehaus.plexus.metadata.component.RecessiveComponent", cElt.getChildTextTrim("implementation"));
105 
106         assertEquals(1, mRootElt.getChildren("lifecycle-handler-manager").size());
107         assertEquals(
108                 "org.codehaus.plexus.lifecycle.DefaultLifecycleHandlerManager",
109                 mRootElt.getChild("lifecycle-handler-manager").getAttributeValue("implementation"));
110     }
111 
112     public void testInvalidMergeableElements() throws Exception {
113         // dominant Component Element
114         AbstractMergeableElement dCE = new ComponentElement(new Element("component"));
115         Element roleElt = new Element("role");
116         roleElt.setText("org.codehaus.plexus.ISampleRole");
117         dCE.addContent(roleElt);
118 
119         AbstractMergeableElementList reqElt = new RequirementsElement(new Element("requirement"));
120         // attempt and invalid merge
121         try {
122             dCE.merge(reqElt);
123             fail("Expected MergeException!");
124         } catch (MergeException e) {
125             // do nothing.
126         }
127     }
128 
129     /**
130      * Tests if &lt;component&gt; elements from two sets are being merged properly.
131      *
132      * @throws Exception if there was an unexpected error.
133      */
134     public void testComponentsMerge() throws Exception {
135         // dominant Components Element
136         AbstractMergeableElement dParent = new ComponentsElement(new Element("components"));
137         Element dCE = new Element("component");
138         dParent.addContent(dCE);
139         Element roleElt = new Element("role");
140         roleElt.setText("org.codehaus.plexus.ISampleRole");
141         dCE.addContent(roleElt);
142         Element roleHintElt = new Element("role-hint");
143         roleHintElt.setText("sample-role-hint");
144         dCE.addContent(roleHintElt);
145         Element implElt = new Element("implementation");
146         implElt.setText("org.codehaus.plexus.DominantImplementation");
147         dCE.addContent(implElt);
148         Element requirementsElt = new Element("requirements");
149         Element reqElt = new Element("requirement");
150         Element reqRoleElt = new Element("role");
151         reqRoleElt.setText("org.codehaus.plexus.IRequiredRole");
152         reqElt.addContent(reqRoleElt);
153         requirementsElt.addContent(reqElt);
154         dCE.addContent(requirementsElt);
155 
156         // recessive Component Element
157         AbstractMergeableElement rParent = new ComponentsElement(new Element("components"));
158         Element rCE = new Element("component");
159         rParent.addContent(rCE);
160         roleElt = new Element("role");
161         roleElt.setText("org.codehaus.plexus.ISampleRole");
162         rCE.addContent(roleElt);
163         roleHintElt = new Element("role-hint");
164         roleHintElt.setText("sample-role-hint");
165         rCE.addContent(roleHintElt);
166         implElt = new Element("implementation");
167         implElt.setText("org.codehaus.plexus.RecessiveImplementation");
168         rCE.addContent(implElt);
169         Element lifecycleHandlerElt = new Element("lifecycle-handler");
170         rCE.addContent(lifecycleHandlerElt);
171         lifecycleHandlerElt.setText("plexus-configurable");
172         requirementsElt = new Element("requirements");
173         reqElt = new Element("requirement");
174         reqRoleElt = new Element("role");
175         reqRoleElt.setText("org.codehaus.plexus.IRequiredRole");
176         reqElt.addContent(reqRoleElt);
177         requirementsElt.addContent(reqElt);
178         Element reqRoleHintElt = new Element("role-hint");
179         reqRoleHintElt.setText("recessive-required-role-hint");
180         reqElt.addContent(reqRoleHintElt);
181         rCE.addContent(requirementsElt);
182 
183         // attempt to merge
184         dParent.merge(rParent);
185         assertEquals(1, dParent.getChildren("component").size());
186         assertEquals(
187                 "org.codehaus.plexus.DominantImplementation",
188                 dParent.getChild("component").getChildText("implementation"));
189         assertEquals(
190                 1,
191                 dParent.getChild("component")
192                         .getChild("requirements")
193                         .getChildren("requirement")
194                         .size());
195     }
196 
197     /**
198      * <em>This is deprecated as we dont' want to drill to merging
199      * nested elements within a component.</em><p>
200      * <em>Keeping this around for testing MergeStrategy implmentation.</em>
201      *
202      * @throws Exception in case of an error.
203      */
204     public void testDeepComponentsMerge() throws Exception {
205         // FIXME: Review this after MergeStrategies are in place.
206         if (true) {
207             return;
208         }
209 
210         // dominant Component Element
211         AbstractMergeableElement dCE = new ComponentElement(new Element("component"));
212         Element roleElt = new Element("role");
213         roleElt.setText("org.codehaus.plexus.ISampleRole");
214         dCE.addContent(roleElt);
215         Element roleHintElt;
216         // roleHintElt = new Element ("role-hint");
217         // roleHintElt.setText ("sample-hint");
218         // dCE.addContent (roleHintElt);
219         Element implElt = new Element("implementation");
220         implElt.setText("org.codehaus.plexus.DominantImplementation");
221         dCE.addContent(implElt);
222         Element requirementsElt = new Element("requirements");
223         Element reqElt = new Element("requirement");
224         Element reqRoleElt = new Element("role");
225         reqRoleElt.setText("org.codehaus.plexus.IRequiredRole");
226         reqElt.addContent(reqRoleElt);
227         requirementsElt.addContent(reqElt);
228         dCE.addContent(requirementsElt);
229 
230         // recessive Component Element
231         AbstractMergeableElement rCE = new ComponentElement(new Element("component"));
232         roleElt = new Element("role");
233         roleElt.setText("org.codehaus.plexus.ISampleRole");
234         rCE.addContent(roleElt);
235         roleHintElt = new Element("role-hint");
236         roleHintElt.setText("recessive-hint");
237         rCE.addContent(roleHintElt);
238         implElt = new Element("implementation");
239         implElt.setText("org.codehaus.plexus.RecessiveImplementation");
240         rCE.addContent(implElt);
241         Element lifecycleHandlerElt = new Element("lifecycle-handler");
242         rCE.addContent(lifecycleHandlerElt);
243         lifecycleHandlerElt.setText("plexus-configurable");
244         requirementsElt = new Element("requirements");
245         reqElt = new Element("requirement");
246         reqRoleElt = new Element("role");
247         reqRoleElt.setText("org.codehaus.plexus.IRequiredRole");
248         reqElt.addContent(reqRoleElt);
249         requirementsElt.addContent(reqElt);
250         Element reqRoleHintElt = new Element("role-hint");
251         reqRoleHintElt.setText("recessive-required-role-hint");
252         reqElt.addContent(reqRoleHintElt);
253         rCE.addContent(requirementsElt);
254 
255         // attempt to merge
256         dCE.merge(rCE);
257 
258         // verify the merge
259         assertTrue(null != dCE.getChild("role"));
260         assertEquals("org.codehaus.plexus.ISampleRole", dCE.getChildText("role"));
261         assertTrue(null != dCE.getChild("role-hint"));
262         assertEquals("recessive-hint", dCE.getChildText("role-hint"));
263         assertTrue(null != dCE.getChild("lifecycle-handler"));
264         assertEquals("plexus-configurable", dCE.getChildText("lifecycle-handler"));
265         assertTrue(null != dCE.getChild("requirements"));
266         assertEquals(1, dCE.getChild("requirements").getChildren("requirement").size());
267         assertEquals(
268                 "recessive-required-role-hint",
269                 ((Element) dCE.getChild("requirements")
270                                 .getChildren("requirement")
271                                 .get(0))
272                         .getChildText("role-hint"));
273     }
274 
275     public void testMergeRoleComponents() throws Exception {
276         SAXBuilder saxBuilder = new SAXBuilder();
277 
278         String source1 = "<component-set>\n" + "  <components>\n"
279                 + "    <component>\n"
280                 + "      <role>org.codehaus.plexus.metadata.component.DockerComposeConfigHandler</role>\n"
281                 + "      <implementation>org.codehaus.plexus.metadata.component.DominantComponent</implementation>\n"
282                 + "    </component>\n"
283                 + "    <component>\n"
284                 + "      <role>org.codehaus.plexus.metadata.component.PropertyConfigHandler</role>\n"
285                 + "      <implementation>org.codehaus.plexus.metadata.component.DominantComponent</implementation>\n"
286                 + "    </component>\n"
287                 + "  </components>\n"
288                 + "</component-set>";
289         Document doc1 = saxBuilder.build(new StringReader(source1));
290 
291         String source2 = "<component-set>\n" + "  <components>\n"
292                 + "    <component>\n"
293                 + "      <role>org.codehaus.plexus.metadata.component.ExternalConfigHandler</role>\n"
294                 + "      <implementation>org.codehaus.plexus.metadata.component.DominantComponent</implementation>\n"
295                 + "    </component>\n"
296                 + "  </components>\n"
297                 + "</component-set>";
298         Document doc2 = saxBuilder.build(new StringReader(source2));
299 
300         PlexusXmlMerger merger = new PlexusXmlMerger();
301         Document mergedDoc = merger.merge(doc1, doc2);
302 
303         List<Element> components =
304                 mergedDoc.detachRootElement().getChild("components").getChildren();
305         assertEquals(3, components.size());
306     }
307 }