1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.internal.xml;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.Reader;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28
29 import org.apache.maven.api.xml.XmlNode;
30 import org.codehaus.plexus.util.IOUtil;
31 import org.codehaus.plexus.util.xml.pull.MXParser;
32 import org.codehaus.plexus.util.xml.pull.XmlPullParser;
33 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
34
35
36
37
38 public class XmlNodeBuilder {
39 private static final boolean DEFAULT_TRIM = true;
40
41 public static XmlNodeImpl build(Reader reader) throws XmlPullParserException, IOException {
42 return build(reader, null);
43 }
44
45
46
47
48
49
50
51
52
53 public static XmlNodeImpl build(Reader reader, InputLocationBuilder locationBuilder)
54 throws XmlPullParserException, IOException {
55 return build(reader, DEFAULT_TRIM, locationBuilder);
56 }
57
58 public static XmlNodeImpl build(InputStream is, String encoding) throws XmlPullParserException, IOException {
59 return build(is, encoding, DEFAULT_TRIM);
60 }
61
62 public static XmlNodeImpl build(InputStream is, String encoding, boolean trim)
63 throws XmlPullParserException, IOException {
64 try {
65 final XmlPullParser parser = new MXParser();
66 parser.setInput(is, encoding);
67
68 final XmlNodeImpl node = build(parser, trim);
69 is.close();
70 is = null;
71
72 return node;
73 } finally {
74 IOUtil.close(is);
75 }
76 }
77
78 public static XmlNodeImpl build(Reader reader, boolean trim) throws XmlPullParserException, IOException {
79 return build(reader, trim, null);
80 }
81
82
83
84
85
86
87
88
89
90
91 public static XmlNodeImpl build(Reader reader, boolean trim, InputLocationBuilder locationBuilder)
92 throws XmlPullParserException, IOException {
93 try {
94 final XmlPullParser parser = new MXParser();
95 parser.setInput(reader);
96
97 final XmlNodeImpl node = build(parser, trim, locationBuilder);
98 reader.close();
99 reader = null;
100
101 return node;
102 } finally {
103 IOUtil.close(reader);
104 }
105 }
106
107 public static XmlNodeImpl build(XmlPullParser parser) throws XmlPullParserException, IOException {
108 return build(parser, DEFAULT_TRIM);
109 }
110
111 public static XmlNodeImpl build(XmlPullParser parser, boolean trim) throws XmlPullParserException, IOException {
112 return build(parser, trim, null);
113 }
114
115
116
117
118
119
120
121
122
123
124 public static XmlNodeImpl build(XmlPullParser parser, boolean trim, InputLocationBuilder locationBuilder)
125 throws XmlPullParserException, IOException {
126 boolean spacePreserve = false;
127 String name = null;
128 String value = null;
129 Object location = null;
130 Map<String, String> attrs = null;
131 List<XmlNode> children = null;
132 int eventType = parser.getEventType();
133 boolean emptyTag = false;
134 while (eventType != XmlPullParser.END_DOCUMENT) {
135 if (eventType == XmlPullParser.START_TAG) {
136 emptyTag = parser.isEmptyElementTag();
137 if (name == null) {
138 name = parser.getName();
139 location = locationBuilder != null ? locationBuilder.toInputLocation(parser) : null;
140 int attributesSize = parser.getAttributeCount();
141 if (attributesSize > 0) {
142 attrs = new HashMap<>();
143 for (int i = 0; i < attributesSize; i++) {
144 String aname = parser.getAttributeName(i);
145 String avalue = parser.getAttributeValue(i);
146 attrs.put(aname, avalue);
147 spacePreserve = spacePreserve || ("xml:space".equals(aname) && "preserve".equals(avalue));
148 }
149 }
150 } else {
151 if (children == null) {
152 children = new ArrayList<>();
153 }
154 XmlNode child = build(parser, trim, locationBuilder);
155 children.add(child);
156 }
157 } else if (eventType == XmlPullParser.TEXT) {
158 String text = parser.getText();
159 if (trim && !spacePreserve) {
160 text = text.trim();
161 }
162 value = value != null ? value + text : text;
163 } else if (eventType == XmlPullParser.END_TAG) {
164 return new XmlNodeImpl(
165 name,
166 children == null ? (value != null ? value : emptyTag ? null : "") : null,
167 attrs,
168 children,
169 location);
170 }
171 eventType = parser.next();
172 }
173 throw new IllegalStateException("End of document found before returning to 0 depth");
174 }
175
176
177
178
179
180
181 public interface InputLocationBuilder {
182 Object toInputLocation(XmlPullParser parser);
183 }
184 }