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   * @version $Id$
47   */
48  public class ComponentsXmlMergerTest
49      extends PlexusTestCase
50  {
51      public void testBasic()
52          throws Exception
53      {
54          ComponentsXmlMerger merger = (ComponentsXmlMerger) lookup( Merger.class, "componentsXml" );
55          assertNotNull( merger );
56      }
57  
58      public void testComponentsXmlFileMerge()
59          throws Exception
60      {
61          File dominantXml = getTestFile( "src/test/resources/org/codehaus/plexus/metadata/merge/dominant.xml" );
62          File recessiveXml = getTestFile( "src/test/resources/org/codehaus/plexus/metadata/merge/recessive.xml" );
63          Document dDoc = new SAXBuilder().build( dominantXml );
64          Document rDoc = new SAXBuilder().build( recessiveXml );
65          // ComponentsXmlMerger merger = new ComponentsXmlMerger (dDoc);
66          Merger merger = lookup( Merger.class, "componentsXml" );
67          assertNotNull( merger );
68          merger.merge( dDoc, rDoc );
69  
70          File merged_xml = getTestFile( "target/merged.xml" );
71          if ( merged_xml.exists() )
72          {
73              FileUtils.forceDelete( merged_xml );
74          }
75          merger.writeMergedDocument( dDoc, merged_xml );
76          assertTrue( merged_xml.exists() );
77          // read merged xml and verify it was merged as expected 
78          Document mDoc = new SAXBuilder().build( merged_xml );
79          Element mRootElt = mDoc.getRootElement();
80          assertTrue( mRootElt.getName().equals( "component-set" ) );
81          assertEquals( 1, mRootElt.getChildren( "components" ).size() );
82          List componentEltList = mRootElt.getChild( "components" ).getChildren( "component" );
83          assertEquals( 2, componentEltList.size() );
84          Element cElt = (Element) componentEltList.get( 0 );
85  
86          assertEquals( "org.codehaus.plexus.metadata.component.IComponent", cElt.getChildTextTrim( "role" ) );
87          assertEquals( "org.codehaus.plexus.metadata.component.DominantComponent", cElt.getChildTextTrim( "implementation" ) );
88  
89          assertEquals( "Should only have 1 description element.", 1, cElt.getChildren( "description" ).size() );
90          assertEquals( "Description for Dominant component", cElt.getChildTextTrim( "description" ) );
91  
92          assertEquals( "Should only have 1 configuration element.", 1, cElt.getChildren( "configuration" ).size() );
93          // assert Merged configuration properties
94          Element configurationElt = cElt.getChild( "configuration" );
95          assertNotNull( configurationElt );
96          assertEquals( 1, configurationElt.getChildren( "prop1" ).size() );
97          assertEquals( "Dominant Property1 value", configurationElt.getChildTextTrim( "prop1" ) );
98          assertEquals( 1, configurationElt.getChildren( "prop2" ).size() );
99          assertEquals( 0, configurationElt.getChildren( "prop3" ).size() );
100 
101         // now for the second component
102         cElt = (Element) componentEltList.get( 1 );
103         assertEquals( "org.codehaus.plexus.metadata.component.INonConflictingComponent", cElt.getChildTextTrim( "role" ) );
104         assertEquals( "org.codehaus.plexus.metadata.component.RecessiveComponent", cElt.getChildTextTrim( "implementation" ) );
105 
106         assertEquals( 1, mRootElt.getChildren( "lifecycle-handler-manager" ).size() );
107         assertEquals( "org.codehaus.plexus.lifecycle.DefaultLifecycleHandlerManager", mRootElt
108             .getChild( "lifecycle-handler-manager" ).getAttributeValue( "implementation" ) );
109     }
110 
111     public void testInvalidMergeableElements()
112         throws Exception
113     {
114         // dominant Component Element
115         AbstractMergeableElement dCE = new ComponentElement( new Element( "component" ) );
116         Element roleElt = new Element( "role" );
117         roleElt.setText( "org.codehaus.plexus.ISampleRole" );
118         dCE.addContent( roleElt );
119 
120         AbstractMergeableElementList reqElt = new RequirementsElement( new Element( "requirement" ) );
121         // attempt and invalid merge
122         try
123         {
124             dCE.merge( reqElt );
125             fail( "Expected MergeException!" );
126         }
127         catch ( MergeException e )
128         {
129             // do nothing.
130         }
131     }
132 
133     /**
134      * Tests if &lt;component&gt; elements from two sets are being merged properly.
135      *
136      * @throws Exception if there was an unexpected error.
137      */
138     public void testComponentsMerge()
139         throws Exception
140     {
141         // dominant Components Element
142         AbstractMergeableElement dParent = new ComponentsElement( new Element( "components" ) );
143         Element dCE = new Element( "component" );
144         dParent.addContent( dCE );
145         Element roleElt = new Element( "role" );
146         roleElt.setText( "org.codehaus.plexus.ISampleRole" );
147         dCE.addContent( roleElt );
148         Element roleHintElt = new Element( "role-hint" );
149         roleHintElt.setText( "sample-role-hint" );
150         dCE.addContent( roleHintElt );
151         Element implElt = new Element( "implementation" );
152         implElt.setText( "org.codehaus.plexus.DominantImplementation" );
153         dCE.addContent( implElt );
154         Element requirementsElt = new Element( "requirements" );
155         Element reqElt = new Element( "requirement" );
156         Element reqRoleElt = new Element( "role" );
157         reqRoleElt.setText( "org.codehaus.plexus.IRequiredRole" );
158         reqElt.addContent( reqRoleElt );
159         requirementsElt.addContent( reqElt );
160         dCE.addContent( requirementsElt );
161 
162         // recessive Component Element
163         AbstractMergeableElement rParent = new ComponentsElement( new Element( "components" ) );
164         Element rCE = new Element( "component" );
165         rParent.addContent( rCE );
166         roleElt = new Element( "role" );
167         roleElt.setText( "org.codehaus.plexus.ISampleRole" );
168         rCE.addContent( roleElt );
169         roleHintElt = new Element( "role-hint" );
170         roleHintElt.setText( "sample-role-hint" );
171         rCE.addContent( roleHintElt );
172         implElt = new Element( "implementation" );
173         implElt.setText( "org.codehaus.plexus.RecessiveImplementation" );
174         rCE.addContent( implElt );
175         Element lifecycleHandlerElt = new Element( "lifecycle-handler" );
176         rCE.addContent( lifecycleHandlerElt );
177         lifecycleHandlerElt.setText( "plexus-configurable" );
178         requirementsElt = new Element( "requirements" );
179         reqElt = new Element( "requirement" );
180         reqRoleElt = new Element( "role" );
181         reqRoleElt.setText( "org.codehaus.plexus.IRequiredRole" );
182         reqElt.addContent( reqRoleElt );
183         requirementsElt.addContent( reqElt );
184         Element reqRoleHintElt = new Element( "role-hint" );
185         reqRoleHintElt.setText( "recessive-required-role-hint" );
186         reqElt.addContent( reqRoleHintElt );
187         rCE.addContent( requirementsElt );
188 
189         // attempt to merge
190         dParent.merge( rParent );
191         assertEquals( 1, dParent.getChildren( "component" ).size() );
192         assertEquals( "org.codehaus.plexus.DominantImplementation", dParent.getChild( "component" )
193             .getChildText( "implementation" ) );
194         assertEquals( 1, dParent.getChild( "component" ).getChild( "requirements" ).getChildren( "requirement" ).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
203      */
204     public void testDeepComponentsMerge()
205         throws Exception
206     {
207         // FIXME: Review this after MergeStrategies are in place.
208         if ( true )
209         {
210             return;
211         }
212 
213         // dominant Component Element
214         AbstractMergeableElement dCE = new ComponentElement( new Element( "component" ) );
215         Element roleElt = new Element( "role" );
216         roleElt.setText( "org.codehaus.plexus.ISampleRole" );
217         dCE.addContent( roleElt );
218         Element roleHintElt;
219         // roleHintElt = new Element ("role-hint");
220         // roleHintElt.setText ("sample-hint");
221         // dCE.addContent (roleHintElt);
222         Element implElt = new Element( "implementation" );
223         implElt.setText( "org.codehaus.plexus.DominantImplementation" );
224         dCE.addContent( implElt );
225         Element requirementsElt = new Element( "requirements" );
226         Element reqElt = new Element( "requirement" );
227         Element reqRoleElt = new Element( "role" );
228         reqRoleElt.setText( "org.codehaus.plexus.IRequiredRole" );
229         reqElt.addContent( reqRoleElt );
230         requirementsElt.addContent( reqElt );
231         dCE.addContent( requirementsElt );
232 
233         // recessive Component Element
234         AbstractMergeableElement rCE = new ComponentElement( new Element( "component" ) );
235         roleElt = new Element( "role" );
236         roleElt.setText( "org.codehaus.plexus.ISampleRole" );
237         rCE.addContent( roleElt );
238         roleHintElt = new Element( "role-hint" );
239         roleHintElt.setText( "recessive-hint" );
240         rCE.addContent( roleHintElt );
241         implElt = new Element( "implementation" );
242         implElt.setText( "org.codehaus.plexus.RecessiveImplementation" );
243         rCE.addContent( implElt );
244         Element lifecycleHandlerElt = new Element( "lifecycle-handler" );
245         rCE.addContent( lifecycleHandlerElt );
246         lifecycleHandlerElt.setText( "plexus-configurable" );
247         requirementsElt = new Element( "requirements" );
248         reqElt = new Element( "requirement" );
249         reqRoleElt = new Element( "role" );
250         reqRoleElt.setText( "org.codehaus.plexus.IRequiredRole" );
251         reqElt.addContent( reqRoleElt );
252         requirementsElt.addContent( reqElt );
253         Element reqRoleHintElt = new Element( "role-hint" );
254         reqRoleHintElt.setText( "recessive-required-role-hint" );
255         reqElt.addContent( reqRoleHintElt );
256         rCE.addContent( requirementsElt );
257 
258         // attempt to merge
259         dCE.merge( rCE );
260 
261         // verify the merge
262         assertTrue( null != dCE.getChild( "role" ) );
263         assertEquals( "org.codehaus.plexus.ISampleRole", dCE.getChildText( "role" ) );
264         assertTrue( null != dCE.getChild( "role-hint" ) );
265         assertEquals( "recessive-hint", dCE.getChildText( "role-hint" ) );
266         assertTrue( null != dCE.getChild( "lifecycle-handler" ) );
267         assertEquals( "plexus-configurable", dCE.getChildText( "lifecycle-handler" ) );
268         assertTrue( null != dCE.getChild( "requirements" ) );
269         assertEquals( 1, dCE.getChild( "requirements" ).getChildren( "requirement" ).size() );
270         assertEquals( "recessive-required-role-hint", ( (Element) dCE.getChild( "requirements" )
271             .getChildren( "requirement" ).get( 0 ) ).getChildText( "role-hint" ) );
272     }
273     
274     public void testMergeRoleComponents() throws Exception
275     {
276         SAXBuilder saxBuilder = new SAXBuilder();
277 
278         String source1 = "<component-set>\n" + 
279             "  <components>\n" + 
280             "    <component>\n" + 
281             "      <role>org.codehaus.plexus.metadata.component.DockerComposeConfigHandler</role>\n" + 
282             "      <implementation>org.codehaus.plexus.metadata.component.DominantComponent</implementation>\n" + 
283             "    </component>\n" + 
284             "    <component>\n" + 
285             "      <role>org.codehaus.plexus.metadata.component.PropertyConfigHandler</role>\n" + 
286             "      <implementation>org.codehaus.plexus.metadata.component.DominantComponent</implementation>\n" + 
287             "    </component>\n" + 
288             "  </components>\n" + 
289             "</component-set>";
290         Document doc1 = saxBuilder.build( new StringReader( source1 ) );
291         
292         String source2 = "<component-set>\n" + 
293             "  <components>\n" + 
294             "    <component>\n" + 
295             "      <role>org.codehaus.plexus.metadata.component.ExternalConfigHandler</role>\n" + 
296             "      <implementation>org.codehaus.plexus.metadata.component.DominantComponent</implementation>\n" + 
297             "    </component>\n" + 
298             "  </components>\n" + 
299             "</component-set>";
300         Document doc2 = saxBuilder.build( new StringReader( source2 ) );
301         
302         PlexusXmlMerger merger = new PlexusXmlMerger();
303         Document mergedDoc = merger.merge( doc1, doc2 );
304         
305         List<Element> components = mergedDoc.detachRootElement().getChild( "components" ).getChildren();
306         assertEquals( 3, components.size() );
307     }
308     
309 }