View Javadoc
1   package org.codehaus.plexus.configuration;
2   
3   import java.io.IOException;
4   import java.io.StringReader;
5   import java.util.ArrayList;
6   import java.util.List;
7   
8   import org.codehaus.plexus.component.repository.ComponentDescriptor;
9   import org.codehaus.plexus.component.repository.ComponentRequirement;
10  import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
11  import org.codehaus.plexus.util.xml.Xpp3Dom;
12  import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
13  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
14  
15  /**
16   *
17   * @author <a href="mailto:kenney@apache.org">Kenney Westerhof</a>
18   *
19   */
20  public class PlexusComponentDescriptorMerger
21  {
22      /**
23       * Merges override and target, where target is updated with override.
24       */
25      public static void merge( ComponentDescriptor<?> override, ComponentDescriptor<?> target )
26      {
27          if ( override.getImplementation() != null )
28          {
29              target.setImplementation( override.getImplementation() );
30          }
31  
32          mergeRequirements( override, target );
33  
34          mergeConfiguration( override, target );
35  
36          // TODO: other getters/setters.
37      }
38  
39      private static void mergeConfiguration( ComponentDescriptor<?> override, ComponentDescriptor<?> target )
40      {
41          // try to parse the override dom. If this fails, do not update anything and keep
42          // the original target configuration.
43          Xpp3Dom overrideDom;
44  
45          try
46          {
47  
48              overrideDom = Xpp3DomBuilder.build( new StringReader( override.getConfiguration().toString() ) );
49          }
50          catch ( XmlPullParserException e1 )
51          {
52              return;
53          }
54          catch ( IOException e1 )
55          {
56              return;
57          }
58  
59          // try to parse the target dom. if this fails, replace it with the override configuration,
60          // dom, otherwise merge it.
61  
62          Xpp3Dom targetDom = null;
63  
64          if ( target.getConfiguration() != null )
65          {
66              try
67              {
68                  targetDom = Xpp3DomBuilder.build( new StringReader( target.getConfiguration().toString() ) );
69              }
70              catch ( XmlPullParserException e1 )
71              {
72              }
73              catch ( IOException e1 )
74              {
75              }
76          }
77  
78          if ( targetDom != null )
79          {
80              Xpp3Dom.mergeXpp3Dom( overrideDom, targetDom );
81          }
82          else
83          {
84              targetDom = overrideDom;
85          }
86  
87          target.setConfiguration( new XmlPlexusConfiguration( targetDom ) );
88      }
89  
90      private static void mergeRequirements( ComponentDescriptor<?> override, ComponentDescriptor<?> target )
91      {
92          List<ComponentRequirement> toAdd = new ArrayList<ComponentRequirement>();
93          List<ComponentRequirement> toRemove = new ArrayList<ComponentRequirement>();
94  
95          for ( ComponentRequirement sourceReq : override.getRequirements() )
96          {
97              for ( ComponentRequirement targetReq : target.getRequirements() )
98              {
99                  // if a fieldName is specified, only override target requirements
100                 // that also have a fieldname.
101                 if ( sourceReq.getFieldName() != null )
102                 {
103                     if ( sourceReq.getFieldName().equals( targetReq.getFieldName() ) )
104                     {
105                         toRemove.add( targetReq );
106                         toAdd.add( sourceReq );
107                         break;
108                     }
109                 }
110                 else if ( targetReq.getFieldName() == null )
111                 {
112                     // no fieldnames specified - just check for the role; hints may be
113                     // overriden too.
114 
115                     if ( sourceReq.getRole().equals( targetReq.getRole() ) )
116                     {
117                         toRemove.add( targetReq );
118                         toAdd.add( sourceReq );
119                     }
120                 }
121             }
122         }
123 
124         target.removeRequirements( toRemove );
125         target.addRequirements( toAdd );
126     }
127 
128 }