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.StringWriter;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29
30 import javax.annotation.Nonnull;
31
32
33
34
35
36
37 public class Xpp3Dom
38 implements Iterable<Xpp3Dom>
39 {
40 @SuppressWarnings( "UnusedDeclaration" )
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 public static final String CHILDREN_COMBINATION_MODE_ATTRIBUTE = "combine.children";
56
57 private static final String CHILDREN_COMBINATION_MERGE = "merge";
58
59 public static final String CHILDREN_COMBINATION_APPEND = "append";
60
61 @SuppressWarnings( "UnusedDeclaration" )
62 private static final String DEFAULT_CHILDREN_COMBINATION_MODE = CHILDREN_COMBINATION_MERGE;
63
64 public static final String SELF_COMBINATION_MODE_ATTRIBUTE = "combine.self";
65
66 public static final String SELF_COMBINATION_OVERRIDE = "override";
67
68 public static final String SELF_COMBINATION_MERGE = "merge";
69
70 @SuppressWarnings( "UnusedDeclaration" )
71 private static final String DEFAULT_SELF_COMBINATION_MODE = SELF_COMBINATION_MERGE;
72
73 private static final String[] EMPTY_STRING_ARRAY = new String[0];
74 private static final Xpp3Dom[] EMPTY_DOM_ARRAY = new Xpp3Dom[0];
75
76 public Xpp3Dom( String name )
77 {
78 this.name = name;
79 childList = new ArrayList<Xpp3Dom>();
80 childMap = new HashMap<String, Xpp3Dom>();
81 }
82
83 public Xpp3Dom( Xpp3Dom source )
84 {
85 this( source, source.getName() );
86 }
87
88 public Xpp3Dom( @Nonnull Xpp3Dom src, String name )
89 {
90 this.name = name;
91
92 int size = src.getChildCount();
93 childList = new ArrayList<Xpp3Dom>( size );
94 childMap = new HashMap<String, Xpp3Dom>();
95
96 setValue( src.getValue() );
97
98 for ( String attributeName : src.getAttributeNames() )
99 {
100 setAttribute( attributeName, src.getAttribute( attributeName ) );
101 }
102
103 for ( Xpp3Dom xpp3Dom : src.getChildren() )
104 {
105 addChild( new Xpp3Dom( xpp3Dom ) );
106 }
107 }
108
109 public String getName()
110 {
111 return name;
112 }
113
114 @Nonnull public String getValue()
115 {
116 return value;
117 }
118
119 public void setValue( @Nonnull String value )
120 {
121 this.value = value;
122 }
123
124
125 public String[] getAttributeNames()
126 {
127 boolean isNothing = attributes == null || attributes.isEmpty();
128 return isNothing ? EMPTY_STRING_ARRAY : attributes.keySet().toArray( new String[attributes.size()] );
129 }
130
131
132 public String getAttribute( String name )
133 {
134 return attributes != null ? attributes.get( name ) : null;
135 }
136
137 @SuppressWarnings( "ConstantConditions" )
138 public void setAttribute( @Nonnull String name, @Nonnull String value )
139 {
140 if ( value == null )
141 {
142 throw new NullPointerException( "value can not be null" );
143 }
144 if ( name == null )
145 {
146 throw new NullPointerException( "name can not be null" );
147 }
148 if ( attributes == null )
149 {
150 attributes = new HashMap<String, String>();
151 }
152
153 attributes.put( name, value );
154 }
155
156 public Xpp3Dom getChild( int i )
157 {
158 return childList.get( i );
159 }
160
161 public Xpp3Dom getChild( String name )
162 {
163 return childMap.get( name );
164 }
165
166 public void addChild( Xpp3Dom child )
167 {
168 child.setParent( this );
169 childList.add( child );
170 childMap.put( child.getName(), child );
171 }
172
173 public Xpp3Dom[] getChildren()
174 {
175 boolean isNothing = childList == null || childList.isEmpty();
176 return isNothing ? EMPTY_DOM_ARRAY : childList.toArray( new Xpp3Dom[childList.size()] );
177 }
178
179 private List<Xpp3Dom> getChildrenList()
180 {
181 boolean isNothing = childList == null || childList.isEmpty();
182 return isNothing ? Collections.<Xpp3Dom>emptyList() : childList;
183 }
184
185 public Xpp3Dom[] getChildren( String name )
186 {
187 List<Xpp3Dom> children = getChildrenList( name );
188 return children.toArray( new Xpp3Dom[children.size()] );
189 }
190
191 List<Xpp3Dom> getChildrenList( String name )
192 {
193 if ( childList == null )
194 {
195 return Collections.emptyList();
196 }
197 else
198 {
199 ArrayList<Xpp3Dom> children = new ArrayList<Xpp3Dom>();
200 for ( Xpp3Dom aChildList : childList )
201 {
202 if ( name.equals( aChildList.getName() ) )
203 {
204 children.add( aChildList );
205 }
206 }
207 return children;
208 }
209 }
210
211 public int getChildCount()
212 {
213 if ( childList == null )
214 {
215 return 0;
216 }
217
218 return childList.size();
219 }
220
221 public void removeChild( int i )
222 {
223 Xpp3Dom child = childList.remove( i );
224 childMap.values().remove( child );
225 child.setParent( null );
226 }
227
228 public Xpp3Dom getParent()
229 {
230 return parent;
231 }
232
233 public void setParent( Xpp3Dom parent )
234 {
235 this.parent = parent;
236 }
237
238
239
240
241
242 private static Xpp3Dom merge( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
243 {
244 return Xpp3DomUtils.merge( dominant, recessive, childMergeOverride );
245 }
246
247 public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
248 {
249 return Xpp3DomUtils.mergeXpp3Dom( dominant, recessive, childMergeOverride );
250 }
251
252 public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive )
253 {
254 return Xpp3DomUtils.mergeXpp3Dom( dominant, recessive );
255 }
256
257 public boolean equals( Object obj )
258 {
259 if ( obj == this )
260 {
261 return true;
262 }
263
264 if ( !( obj instanceof Xpp3Dom ) )
265 {
266 return false;
267 }
268
269 Xpp3Dom dom = (Xpp3Dom) obj;
270
271 return !( name == null ? dom.name != null : !name.equals( dom.name ) )
272 && !( value == null ? dom.value != null : !value.equals( dom.value ) )
273 && !( attributes == null ? dom.attributes != null : !attributes.equals( dom.attributes ) )
274 && !( childList == null ? dom.childList != null : !childList.equals( dom.childList ) );
275 }
276
277 public int hashCode()
278 {
279 int result = 17;
280 result = 37 * result + ( name != null ? name.hashCode() : 0 );
281 result = 37 * result + ( value != null ? value.hashCode() : 0 );
282 result = 37 * result + ( attributes != null ? attributes.hashCode() : 0 );
283 result = 37 * result + ( childList != null ? childList.hashCode() : 0 );
284 return result;
285 }
286
287 public String toString()
288 {
289 StringWriter writer = new StringWriter();
290 Xpp3DomWriter.write( getPrettyPrintXMLWriter( writer ), this );
291 return writer.toString();
292
293 }
294
295 public String toUnescapedString()
296 {
297 StringWriter writer = new StringWriter();
298 Xpp3DomWriter.write( getPrettyPrintXMLWriter( writer ), this, false );
299 return writer.toString();
300 }
301
302 private PrettyPrintXMLWriter getPrettyPrintXMLWriter( StringWriter writer )
303 {
304 return new PrettyPrintXMLWriter( writer, "UTF-8", null );
305 }
306
307 public static boolean isNotEmpty( String str )
308 {
309 return str != null && str.length() > 0;
310 }
311
312 public static boolean isEmpty( String str )
313 {
314 return str == null || str.trim().length() == 0;
315 }
316
317 public Iterator<Xpp3Dom> iterator()
318 {
319 return getChildrenList().iterator();
320 }
321 }