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       * Merges override and target, where target is updated with override.
23       * @param override {@link ComponentDescriptor}
24       * @param target {@link ComponentDescriptor}.
25       */
26      public static void merge(ComponentDescriptor<?> override, ComponentDescriptor<?> target) {
27          if (override.getImplementation() != null) {
28              target.setImplementation(override.getImplementation());
29          }
30  
31          mergeRequirements(override, target);
32  
33          mergeConfiguration(override, target);
34  
35          // TODO: other getters/setters.
36      }
37  
38      private static void mergeConfiguration(ComponentDescriptor<?> override, ComponentDescriptor<?> target) {
39          // try to parse the override dom. If this fails, do not update anything and keep
40          // the original target configuration.
41          Xpp3Dom overrideDom;
42  
43          try {
44  
45              overrideDom = Xpp3DomBuilder.build(
46                      new StringReader(override.getConfiguration().toString()));
47          } catch (XmlPullParserException e1) {
48              return;
49          } catch (IOException e1) {
50              return;
51          }
52  
53          // try to parse the target dom. if this fails, replace it with the override configuration,
54          // dom, otherwise merge it.
55  
56          Xpp3Dom targetDom = null;
57  
58          if (target.getConfiguration() != null) {
59              try {
60                  targetDom = Xpp3DomBuilder.build(
61                          new StringReader(target.getConfiguration().toString()));
62              } catch (XmlPullParserException e1) {
63              } catch (IOException e1) {
64              }
65          }
66  
67          if (targetDom != null) {
68              Xpp3Dom.mergeXpp3Dom(overrideDom, targetDom);
69          } else {
70              targetDom = overrideDom;
71          }
72  
73          target.setConfiguration(new XmlPlexusConfiguration(targetDom));
74      }
75  
76      private static void mergeRequirements(ComponentDescriptor<?> override, ComponentDescriptor<?> target) {
77          List<ComponentRequirement> toAdd = new ArrayList<ComponentRequirement>();
78          List<ComponentRequirement> toRemove = new ArrayList<ComponentRequirement>();
79  
80          for (ComponentRequirement sourceReq : override.getRequirements()) {
81              for (ComponentRequirement targetReq : target.getRequirements()) {
82                  // if a fieldName is specified, only override target requirements
83                  // that also have a fieldname.
84                  if (sourceReq.getFieldName() != null) {
85                      if (sourceReq.getFieldName().equals(targetReq.getFieldName())) {
86                          toRemove.add(targetReq);
87                          toAdd.add(sourceReq);
88                          break;
89                      }
90                  } else if (targetReq.getFieldName() == null) {
91                      // no fieldnames specified - just check for the role; hints may be
92                      // overriden too.
93  
94                      if (sourceReq.getRole().equals(targetReq.getRole())) {
95                          toRemove.add(targetReq);
96                          toAdd.add(sourceReq);
97                      }
98                  }
99              }
100         }
101 
102         target.removeRequirements(toRemove);
103         target.addRequirements(toAdd);
104     }
105 }