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
319
320 public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
321 {
322 return Xpp3DomUtils.mergeXpp3Dom( dominant, recessive, childMergeOverride );
323 }
324
325
326
327
328
329
330 public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive )
331 {
332 return Xpp3DomUtils.mergeXpp3Dom( dominant, recessive );
333 }
334
335
336 public boolean equals( Object obj )
337 {
338 if ( obj == this )
339 {
340 return true;
341 }
342
343 if ( !( obj instanceof Xpp3Dom ) )
344 {
345 return false;
346 }
347
348 Xpp3Dom dom = (Xpp3Dom) obj;
349
350 return !( name == null ? dom.name != null : !name.equals( dom.name ) )
351 && !( value == null ? dom.value != null : !value.equals( dom.value ) )
352 && !( attributes == null ? dom.attributes != null : !attributes.equals( dom.attributes ) )
353 && !( childList == null ? dom.childList != null : !childList.equals( dom.childList ) );
354 }
355
356
357 public int hashCode()
358 {
359 int result = 17;
360 result = 37 * result + ( name != null ? name.hashCode() : 0 );
361 result = 37 * result + ( value != null ? value.hashCode() : 0 );
362 result = 37 * result + ( attributes != null ? attributes.hashCode() : 0 );
363 result = 37 * result + ( childList != null ? childList.hashCode() : 0 );
364 return result;
365 }
366
367
368 public String toString()
369 {
370 try
371 {
372 StringWriter writer = new StringWriter();
373 Xpp3DomWriter.write( getPrettyPrintXMLWriter( writer ), this );
374 return writer.toString();
375 }
376 catch ( final IOException e )
377 {
378
379 throw (AssertionError) new AssertionError( "Unexpected IOException from StringWriter." ).initCause( e );
380 }
381 }
382
383
384
385
386 public String toUnescapedString()
387 {
388 try
389 {
390 StringWriter writer = new StringWriter();
391 Xpp3DomWriter.write( getPrettyPrintXMLWriter( writer ), this, false );
392 return writer.toString();
393 }
394 catch ( final IOException e )
395 {
396
397 throw (AssertionError) new AssertionError( "Unexpected IOException from StringWriter." ).initCause( e );
398 }
399 }
400
401 private PrettyPrintXMLWriter getPrettyPrintXMLWriter( StringWriter writer )
402 {
403 return new PrettyPrintXMLWriter( writer, "UTF-8", null );
404 }
405
406
407
408
409
410 public static boolean isNotEmpty( String str )
411 {
412 return str != null && str.length() > 0;
413 }
414
415
416
417
418
419 public static boolean isEmpty( String str )
420 {
421 return str == null || str.trim().length() == 0;
422 }
423
424
425 public Iterator<Xpp3Dom> iterator()
426 {
427 return getChildrenList().iterator();
428 }
429 }