1 package org.codehaus.plexus.util.xml;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import org.codehaus.plexus.util.xml.pull.XmlSerializer;
20
21 import java.io.IOException;
22 import java.util.HashMap;
23 import java.util.Map;
24
25
26 public class Xpp3DomUtils
27 {
28 public static final String CHILDREN_COMBINATION_MODE_ATTRIBUTE = "combine.children";
29
30 public static final String CHILDREN_COMBINATION_MERGE = "merge";
31
32 public static final String CHILDREN_COMBINATION_APPEND = "append";
33
34
35
36
37
38
39 public static final String DEFAULT_CHILDREN_COMBINATION_MODE = CHILDREN_COMBINATION_MERGE;
40
41 public static final String SELF_COMBINATION_MODE_ATTRIBUTE = "combine.self";
42
43 public static final String SELF_COMBINATION_OVERRIDE = "override";
44
45 public static final String SELF_COMBINATION_MERGE = "merge";
46
47
48
49
50
51
52 public static final String ID_COMBINATION_MODE_ATTRIBUTE = "combine.id";
53
54
55
56
57
58
59
60 public static final String KEYS_COMBINATION_MODE_ATTRIBUTE = "combine.keys";
61
62
63
64
65
66
67
68 public static final String DEFAULT_SELF_COMBINATION_MODE = SELF_COMBINATION_MERGE;
69
70 public void writeToSerializer( String namespace, XmlSerializer serializer, Xpp3Dom dom )
71 throws IOException
72 {
73
74
75 SerializerXMLWriter xmlWriter = new SerializerXMLWriter( namespace, serializer );
76 Xpp3DomWriter.write( xmlWriter, dom );
77 if ( xmlWriter.getExceptions().size() > 0 )
78 {
79 throw (IOException) xmlWriter.getExceptions().get( 0 );
80 }
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
125 {
126
127 if ( recessive == null )
128 {
129 return;
130 }
131
132 boolean mergeSelf = true;
133
134 String selfMergeMode = dominant.getAttribute( SELF_COMBINATION_MODE_ATTRIBUTE );
135
136 if ( isNotEmpty( selfMergeMode ) && SELF_COMBINATION_OVERRIDE.equals( selfMergeMode ) )
137 {
138 mergeSelf = false;
139 }
140
141 if ( mergeSelf )
142 {
143 if ( isEmpty( dominant.getValue() ) && !isEmpty( recessive.getValue() ) )
144 {
145 dominant.setValue( recessive.getValue() );
146 dominant.setInputLocation( recessive.getInputLocation() );
147 }
148
149 String[] recessiveAttrs = recessive.getAttributeNames();
150 for ( String attr : recessiveAttrs )
151 {
152 if ( isEmpty( dominant.getAttribute( attr ) ) )
153 {
154 dominant.setAttribute( attr, recessive.getAttribute( attr ) );
155 }
156 }
157
158 boolean mergeChildren = true;
159
160 if ( childMergeOverride != null )
161 {
162 mergeChildren = childMergeOverride;
163 }
164 else
165 {
166 String childMergeMode = dominant.getAttribute( CHILDREN_COMBINATION_MODE_ATTRIBUTE );
167
168 if ( isNotEmpty( childMergeMode ) && CHILDREN_COMBINATION_APPEND.equals( childMergeMode ) )
169 {
170 mergeChildren = false;
171 }
172 }
173
174 final String keysValue = recessive.getAttribute( KEYS_COMBINATION_MODE_ATTRIBUTE );
175
176 Xpp3Dom[] children = recessive.getChildren();
177 for ( Xpp3Dom recessiveChild : children )
178 {
179 String idValue = recessiveChild.getAttribute( ID_COMBINATION_MODE_ATTRIBUTE );
180
181 Xpp3Dom childDom = null;
182 if ( isNotEmpty( idValue ) )
183 {
184 for ( Xpp3Dom dominantChild : dominant.getChildren() )
185 {
186 if ( idValue.equals( dominantChild.getAttribute( ID_COMBINATION_MODE_ATTRIBUTE ) ) )
187 {
188 childDom = dominantChild;
189
190 mergeChildren = true;
191 }
192 }
193 }
194 else if ( isNotEmpty( keysValue ) )
195 {
196 String[] keys = keysValue.split( "," );
197 Map<String, String> recessiveKeyValues = new HashMap<>( keys.length );
198 for ( String key : keys )
199 {
200 recessiveKeyValues.put( key, recessiveChild.getAttribute( key ) );
201 }
202
203 for ( Xpp3Dom dominantChild : dominant.getChildren() )
204 {
205 Map<String, String> dominantKeyValues = new HashMap<>( keys.length );
206 for ( String key : keys )
207 {
208 dominantKeyValues.put( key, dominantChild.getAttribute( key ) );
209 }
210
211 if ( recessiveKeyValues.equals( dominantKeyValues ) )
212 {
213 childDom = dominantChild;
214
215 mergeChildren = true;
216 }
217 }
218
219 }
220 else
221 {
222 childDom = dominant.getChild( recessiveChild.getName() );
223 }
224
225 if ( mergeChildren && childDom != null )
226 {
227 mergeIntoXpp3Dom( childDom, recessiveChild, childMergeOverride );
228 }
229 else
230 {
231 dominant.addChild( new Xpp3Dom( recessiveChild ) );
232 }
233 }
234 }
235 }
236
237
238
239
240
241
242
243
244
245
246
247
248 public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
249 {
250 if ( dominant != null )
251 {
252 mergeIntoXpp3Dom( dominant, recessive, childMergeOverride );
253 return dominant;
254 }
255 return recessive;
256 }
257
258
259
260
261
262
263
264
265
266
267
268 public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive )
269 {
270 if ( dominant != null )
271 {
272 mergeIntoXpp3Dom( dominant, recessive, null );
273 return dominant;
274 }
275 return recessive;
276 }
277
278 public static boolean isNotEmpty( String str )
279 {
280 return ( str != null && str.length() > 0 );
281 }
282
283 public static boolean isEmpty( String str )
284 {
285 return ( str == null || str.trim().length() == 0 );
286 }
287 }