1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.maven.shared.utils.xml;
20  
21  import java.util.HashMap;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Map;
25  
26  
27  
28  
29  public class Xpp3DomUtils {
30      
31  
32  
33  
34  
35  
36      public static Xpp3Dom mergeXpp3Dom(Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride) {
37          return dominant != null ? merge(dominant, recessive, childMergeOverride) : recessive;
38      }
39  
40      
41  
42  
43  
44  
45      public static Xpp3Dom mergeXpp3Dom(Xpp3Dom dominant, Xpp3Dom recessive) {
46          return dominant != null ? merge(dominant, recessive, null) : recessive;
47      }
48  
49      
50  
51  
52  
53  
54  
55      public static Xpp3Dom merge(Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride) {
56          if (recessive == null || isCombineSelfOverride(dominant)) {
57              return dominant;
58          }
59  
60          if (isEmpty(dominant.getValue())) {
61              dominant.setValue(recessive.getValue());
62          }
63  
64          for (String attr : recessive.getAttributeNames()) {
65              if (isEmpty(dominant.getAttribute(attr))) {
66                  dominant.setAttribute(attr, recessive.getAttribute(attr));
67              }
68          }
69  
70          if (recessive.getChildCount() > 0) {
71              boolean mergeChildren = isMergeChildren(dominant, childMergeOverride);
72  
73              if (mergeChildren) {
74                  Map<String, Iterator<Xpp3Dom>> commonChildren = getCommonChildren(dominant, recessive);
75                  for (Xpp3Dom recessiveChild : recessive) {
76                      Iterator<Xpp3Dom> it = commonChildren.get(recessiveChild.getName());
77                      if (it == null) {
78                          dominant.addChild(new Xpp3Dom(recessiveChild));
79                      } else if (it.hasNext()) {
80                          Xpp3Dom dominantChild = it.next();
81                          merge(dominantChild, recessiveChild, childMergeOverride);
82                      }
83                  }
84              } else {
85                  Xpp3Dom[] dominantChildren = dominant.getChildren();
86                  dominant.childList.clear();
87                  for (Xpp3Dom child : recessive) {
88                      dominant.addChild(new Xpp3Dom(child));
89                  }
90  
91                  for (Xpp3Dom aDominantChildren : dominantChildren) {
92                      dominant.addChild(aDominantChildren);
93                  }
94              }
95          }
96          return dominant;
97      }
98  
99      private static Map<String, Iterator<Xpp3Dom>> getCommonChildren(Xpp3Dom dominant, Xpp3Dom recessive) {
100         Map<String, Iterator<Xpp3Dom>> commonChildren = new HashMap<String, Iterator<Xpp3Dom>>();
101 
102         for (String childName : recessive.childMap.keySet()) {
103             List<Xpp3Dom> dominantChildren = dominant.getChildrenList(childName);
104             if (dominantChildren.size() > 0) {
105                 commonChildren.put(childName, dominantChildren.iterator());
106             }
107         }
108         return commonChildren;
109     }
110 
111     private static boolean isCombineSelfOverride(Xpp3Dom xpp3Dom) {
112         String selfMergeMode = xpp3Dom.getAttribute(Xpp3Dom.SELF_COMBINATION_MODE_ATTRIBUTE);
113         return Xpp3Dom.SELF_COMBINATION_OVERRIDE.equals(selfMergeMode);
114     }
115 
116     private static boolean isMergeChildren(Xpp3Dom dominant, Boolean override) {
117         return override != null ? override : !isMergeChildren(dominant);
118     }
119 
120     private static boolean isMergeChildren(Xpp3Dom dominant) {
121         return Xpp3Dom.CHILDREN_COMBINATION_APPEND.equals(
122                 dominant.getAttribute(Xpp3Dom.CHILDREN_COMBINATION_MODE_ATTRIBUTE));
123     }
124 
125     
126 
127 
128 
129 
130 
131     @Deprecated
132     public static boolean isEmpty(String str) {
133         return str == null || str.trim().length() == 0;
134     }
135 }