1 package org.apache.maven.shared.utils.xml;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.io.StringWriter;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30
31 import javax.annotation.Nonnull;
32
33
34
35
36
37
38 public class Xpp3Dom
39 implements Iterable<Xpp3Dom>
40 {
41 private static final long serialVersionUID = 2567894443061173996L;
42
43 private String name;
44
45 private String value;
46
47 private Map<String, String> attributes;
48
49 final List<Xpp3Dom> childList;
50
51 final Map<String, Xpp3Dom> childMap;
52
53 private Xpp3Dom parent;
54
55
56
57
58 public static final String CHILDREN_COMBINATION_MODE_ATTRIBUTE = "combine.children";
59
60 private static final String CHILDREN_COMBINATION_MERGE = "merge";
61
62
63
64
65 public static final String CHILDREN_COMBINATION_APPEND = "append";
66
67 @SuppressWarnings( "UnusedDeclaration" )
68 private static final String DEFAULT_CHILDREN_COMBINATION_MODE = CHILDREN_COMBINATION_MERGE;
69
70
71
72
73 public static final String SELF_COMBINATION_MODE_ATTRIBUTE = "combine.self";
74
75
76
77
78 public static final String SELF_COMBINATION_OVERRIDE = "override";
79
80
81
82
83 public static final String SELF_COMBINATION_MERGE = "merge";
84
85 @SuppressWarnings( "UnusedDeclaration" )
86 private static final String DEFAULT_SELF_COMBINATION_MODE = SELF_COMBINATION_MERGE;
87
88 private static final String[] EMPTY_STRING_ARRAY = new String[0];
89 private static final Xpp3Dom[] EMPTY_DOM_ARRAY = new Xpp3Dom[0];
90
91
92
93
94 public Xpp3Dom( String name )
95 {
96 this.name = name;
97 childList = new ArrayList<Xpp3Dom>();
98 childMap = new HashMap<String, Xpp3Dom>();
99 }
100
101
102
103
104
105 public Xpp3Dom( Xpp3Dom source )
106 {
107 this( source, source.getName() );
108 }
109
110
111
112
113
114
115 public Xpp3Dom( @Nonnull Xpp3Dom src, String name )
116 {
117 this.name = name;
118
119 int size = src.getChildCount();
120 childList = new ArrayList<Xpp3Dom>( size );
121 childMap = new HashMap<String, Xpp3Dom>();
122
123 setValue( src.getValue() );
124
125 for ( String attributeName : src.getAttributeNames() )
126 {
127 setAttribute( attributeName, src.getAttribute( attributeName ) );
128 }
129
130 for ( Xpp3Dom xpp3Dom : src.getChildren() )
131 {
132 addChild( new Xpp3Dom( xpp3Dom ) );
133 }
134 }
135
136
137
138
139 public String getName()
140 {
141 return name;
142 }
143
144
145
146
147 @Nonnull public String getValue()
148 {
149 return value;
150 }
151
152
153
154
155 public void setValue( @Nonnull String value )
156 {
157 this.value = value;
158 }
159
160
161
162
163
164 public String[] getAttributeNames()
165 {
166 boolean isNothing = attributes == null || attributes.isEmpty();
167 return isNothing ? EMPTY_STRING_ARRAY : attributes.keySet().toArray( new String[attributes.size()] );
168 }
169
170
171
172
173
174
175 public String getAttribute( String nameParameter )
176 {
177 return this.attributes != null ? this.attributes.get( nameParameter ) : null;
178 }
179
180
181
182
183
184 public void setAttribute( @Nonnull String nameParameter, @Nonnull String valueParameter )
185 {
186 if ( valueParameter == null )
187 {
188 throw new NullPointerException( "value can not be null" );
189 }
190 if ( nameParameter == null )
191 {
192 throw new NullPointerException( "name can not be null" );
193 }
194 if ( attributes == null )
195 {
196 attributes = new HashMap<String, String>();
197 }
198
199 attributes.put( nameParameter, valueParameter );
200 }
201
202
203
204
205
206 public Xpp3Dom getChild( int i )
207 {
208 return childList.get( i );
209 }
210
211
212
213
214
215 public Xpp3Dom getChild( String nameParameter )
216 {
217 return childMap.get( nameParameter );
218 }
219
220
221
222
223 public void addChild( Xpp3Dom child )
224 {
225 child.setParent( this );
226 childList.add( child );
227 childMap.put( child.getName(), child );
228 }
229
230
231
232
233 public Xpp3Dom[] getChildren()
234 {
235 boolean isNothing = childList == null || childList.isEmpty();
236 return isNothing ? EMPTY_DOM_ARRAY : childList.toArray( new Xpp3Dom[childList.size()] );
237 }
238
239 private List<Xpp3Dom> getChildrenList()
240 {
241 boolean isNothing = childList == null || childList.isEmpty();
242 return isNothing ? Collections.<Xpp3Dom>emptyList() : childList;
243 }
244
245
246
247
248
249 public Xpp3Dom[] getChildren( String nameParameter )
250 {
251 List<Xpp3Dom> children = getChildrenList( nameParameter );
252 return children.toArray( new Xpp3Dom[children.size()] );
253 }
254
255 List<Xpp3Dom> getChildrenList( String nameParameter )
256 {
257 if ( childList == null )
258 {
259 return Collections.emptyList();
260 }
261 else
262 {
263 ArrayList<Xpp3Dom> children = new ArrayList<Xpp3Dom>();
264 for ( Xpp3Dom aChildList : childList )
265 {
266 if ( nameParameter.equals( aChildList.getName() ) )
267 {
268 children.add( aChildList );
269 }
270 }
271 return children;
272 }
273 }
274
275
276
277
278 public int getChildCount()
279 {
280 if ( childList == null )
281 {
282 return 0;
283 }
284
285 return childList.size();
286 }
287
288
289
290
291 public void removeChild( int i )
292 {
293 Xpp3Dom child = childList.remove( i );
294 childMap.values().remove( child );
295 child.setParent( null );
296 }
297
298
299
300
301 public Xpp3Dom getParent()
302 {
303 return parent;
304 }
305
306
307
308
309 public void setParent( Xpp3Dom parent )
310 {
311 this.parent = parent;
312 }
313
314
315
316
317
318 private static Xpp3Dom merge( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
319 {
320 return Xpp3DomUtils.merge( dominant, recessive, childMergeOverride );
321 }
322
323
324
325
326
327
328
329 public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
330 {
331 return Xpp3DomUtils.mergeXpp3Dom( dominant, recessive, childMergeOverride );
332 }
333
334
335
336
337
338
339 public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive )
340 {
341 return Xpp3DomUtils.mergeXpp3Dom( dominant, recessive );
342 }
343
344
345 public boolean equals( Object obj )
346 {
347 if ( obj == this )
348 {
349 return true;
350 }
351
352 if ( !( obj instanceof Xpp3Dom ) )
353 {
354 return false;
355 }
356
357 Xpp3Dom dom = (Xpp3Dom) obj;
358
359 return !( name == null ? dom.name != null : !name.equals( dom.name ) )
360 && !( value == null ? dom.value != null : !value.equals( dom.value ) )
361 && !( attributes == null ? dom.attributes != null : !attributes.equals( dom.attributes ) )
362 && !( childList == null ? dom.childList != null : !childList.equals( dom.childList ) );
363 }
364
365
366 public int hashCode()
367 {
368 int result = 17;
369 result = 37 * result + ( name != null ? name.hashCode() : 0 );
370 result = 37 * result + ( value != null ? value.hashCode() : 0 );
371 result = 37 * result + ( attributes != null ? attributes.hashCode() : 0 );
372 result = 37 * result + ( childList != null ? childList.hashCode() : 0 );
373 return result;
374 }
375
376
377 public String toString()
378 {
379 try
380 {
381 StringWriter writer = new StringWriter();
382 Xpp3DomWriter.write( getPrettyPrintXMLWriter( writer ), this );
383 return writer.toString();
384 }
385 catch ( final IOException e )
386 {
387
388 throw (AssertionError) new AssertionError( "Unexpected IOException from StringWriter." ).initCause( e );
389 }
390 }
391
392
393
394
395 public String toUnescapedString()
396 {
397 try
398 {
399 StringWriter writer = new StringWriter();
400 Xpp3DomWriter.write( getPrettyPrintXMLWriter( writer ), this, false );
401 return writer.toString();
402 }
403 catch ( final IOException e )
404 {
405
406 throw (AssertionError) new AssertionError( "Unexpected IOException from StringWriter." ).initCause( e );
407 }
408 }
409
410 private PrettyPrintXMLWriter getPrettyPrintXMLWriter( StringWriter writer )
411 {
412 return new PrettyPrintXMLWriter( writer, "UTF-8", null );
413 }
414
415
416
417
418
419 public static boolean isNotEmpty( String str )
420 {
421 return str != null && str.length() > 0;
422 }
423
424
425
426
427
428 public static boolean isEmpty( String str )
429 {
430 return str == null || str.trim().length() == 0;
431 }
432
433
434 public Iterator<Xpp3Dom> iterator()
435 {
436 return getChildrenList().iterator();
437 }
438 }