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