1 package org.codehaus.plexus.util.xml;
2
3 import java.io.IOException;
4 import java.util.HashMap;
5 import java.util.Map;
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import org.codehaus.plexus.util.xml.pull.XmlSerializer;
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 private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
123 {
124
125 if ( recessive == null )
126 {
127 return;
128 }
129
130 boolean mergeSelf = true;
131
132 String selfMergeMode = dominant.getAttribute( SELF_COMBINATION_MODE_ATTRIBUTE );
133
134 if ( isNotEmpty( selfMergeMode ) && SELF_COMBINATION_OVERRIDE.equals( selfMergeMode ) )
135 {
136 mergeSelf = false;
137 }
138
139 if ( mergeSelf )
140 {
141 String[] recessiveAttrs = recessive.getAttributeNames();
142 for ( String attr : recessiveAttrs )
143 {
144 if ( isEmpty( dominant.getAttribute( attr ) ) )
145 {
146 dominant.setAttribute( attr, recessive.getAttribute( attr ) );
147 }
148 }
149
150 boolean mergeChildren = true;
151
152 if ( childMergeOverride != null )
153 {
154 mergeChildren = childMergeOverride;
155 }
156 else
157 {
158 String childMergeMode = dominant.getAttribute( CHILDREN_COMBINATION_MODE_ATTRIBUTE );
159
160 if ( isNotEmpty( childMergeMode ) && CHILDREN_COMBINATION_APPEND.equals( childMergeMode ) )
161 {
162 mergeChildren = false;
163 }
164 }
165
166 final String keysValue = recessive.getAttribute( KEYS_COMBINATION_MODE_ATTRIBUTE );
167
168 Xpp3Dom[] children = recessive.getChildren();
169 for ( Xpp3Dom recessiveChild : children )
170 {
171 String idValue = recessiveChild.getAttribute( ID_COMBINATION_MODE_ATTRIBUTE );
172
173 Xpp3Dom childDom = null;
174 if ( isNotEmpty( idValue ) )
175 {
176 for ( Xpp3Dom dominantChild : dominant.getChildren() )
177 {
178 if ( idValue.equals( dominantChild.getAttribute( ID_COMBINATION_MODE_ATTRIBUTE ) ) )
179 {
180 childDom = dominantChild;
181
182 mergeChildren = true;
183 }
184 }
185 }
186 else if ( isNotEmpty( keysValue ) )
187 {
188 String[] keys = keysValue.split( "," );
189 Map<String, String> recessiveKeyValues = new HashMap<>( keys.length );
190 for ( String key : keys )
191 {
192 recessiveKeyValues.put( key, recessiveChild.getAttribute( key ) );
193 }
194
195 for ( Xpp3Dom dominantChild : dominant.getChildren() )
196 {
197 Map<String, String> dominantKeyValues = new HashMap<>( keys.length );
198 for ( String key : keys )
199 {
200 dominantKeyValues.put( key, dominantChild.getAttribute( key ) );
201 }
202
203 if ( recessiveKeyValues.equals( dominantKeyValues ) )
204 {
205 childDom = dominantChild;
206
207 mergeChildren = true;
208 }
209 }
210
211 }
212 else
213 {
214 childDom = dominant.getChild( recessiveChild.getName() );
215 }
216
217 if ( mergeChildren && childDom != null )
218 {
219 mergeIntoXpp3Dom( childDom, recessiveChild, childMergeOverride );
220 }
221 else
222 {
223 dominant.addChild( new Xpp3Dom( recessiveChild ) );
224 }
225 }
226 }
227 }
228
229
230
231
232
233
234
235
236
237
238
239
240 public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
241 {
242 if ( dominant != null )
243 {
244 mergeIntoXpp3Dom( dominant, recessive, childMergeOverride );
245 return dominant;
246 }
247 return recessive;
248 }
249
250
251
252
253
254
255
256
257
258
259
260 public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive )
261 {
262 if ( dominant != null )
263 {
264 mergeIntoXpp3Dom( dominant, recessive, null );
265 return dominant;
266 }
267 return recessive;
268 }
269
270
271
272
273 @Deprecated
274 public static boolean isNotEmpty( String str )
275 {
276 return ( str != null && str.length() > 0 );
277 }
278
279
280
281
282 @Deprecated
283 public static boolean isEmpty( String str )
284 {
285 return ( str == null || str.length() == 0 );
286 }
287 }