1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.xolite.dom;
17
18
19 import java.util.ArrayList;
20 import java.util.Iterator;
21 import java.util.List;
22
23 import javax.xml.namespace.NamespaceContext;
24
25 import net.sf.xolite.XMLParseException;
26 import net.sf.xolite.XMLSerializable;
27 import net.sf.xolite.impl.BaseXMLEventParser;
28 import net.sf.xolite.impl.MapPrefixResolver;
29 import net.sf.xolite.utils.RootHolder;
30
31 import org.w3c.dom.Attr;
32 import org.w3c.dom.Document;
33 import org.w3c.dom.DocumentType;
34 import org.w3c.dom.Element;
35 import org.w3c.dom.NamedNodeMap;
36 import org.w3c.dom.Node;
37 import org.w3c.dom.NodeList;
38 import org.w3c.dom.Text;
39
40
41
42
43
44 public class DomXMLEventParser extends BaseXMLEventParser {
45
46
47 private Element currentElement;
48
49
50
51
52
53 public DomXMLEventParser() {
54 }
55
56
57
58
59
60
61
62
63
64
65
66 public XMLSerializable parse(Document src) throws XMLParseException {
67 RootHolder holder = new RootHolder();
68 parse(src, holder);
69 return holder.getRoot();
70 }
71
72
73
74
75
76
77
78
79
80
81
82
83 public void parse(Document src, XMLSerializable rootHandler) throws XMLParseException {
84 if (src == null) throw new IllegalArgumentException("InputSource cannot be null");
85 if (rootHandler == null) throw new IllegalArgumentException("Root SaxHandler cannot be null");
86 try {
87 setup(rootHandler);
88 parseImpl(src.getDocumentElement());
89 tearDown();
90 } catch (Exception e) {
91 transformAndThrowException(e);
92 }
93 }
94
95
96
97
98
99 @Override
100 protected void tearDown() {
101 currentElement = null;
102 super.tearDown();
103 }
104
105
106 private void parseImpl(Element elem) throws Exception {
107 currentElement = elem;
108 startElementImpl(elem.getNamespaceURI(), elem.getLocalName());
109 NodeList childNodes = elem.getChildNodes();
110 int len = childNodes.getLength();
111 Node child;
112 for (int i = 0; i < len; i++) {
113 child = childNodes.item(i);
114 if (child.getNodeType() == Node.ELEMENT_NODE) {
115 parseImpl((Element) child);
116 }
117 }
118 currentElement = elem;
119 endElementImpl(elem.getNamespaceURI(), elem.getLocalName());
120 }
121
122
123
124
125
126 @Override
127 public String getNamespaceURI(String prefix) {
128 return DomUtils.getDefinedUri(currentElement, prefix);
129 }
130
131
132
133
134
135
136
137 @Override
138 public String getPrefix(String namespaceURI) {
139 return DomUtils.getDefinedPerfix(currentElement, namespaceURI);
140 }
141
142
143
144
145
146
147
148 @Override
149 public Iterator<String> getPrefixes(String namespaceURI) {
150 return DomUtils.getDefinedPerfixes(currentElement, namespaceURI).iterator();
151 }
152
153
154
155
156 @Override
157 public NamespaceContext getCurrentDefinedNamespaces() {
158 MapPrefixResolver prefixMapping = new MapPrefixResolver();
159 String prefix;
160 Element elem = currentElement;
161 NamedNodeMap attrs;
162 int len;
163 Attr a;
164 String attrName;
165 int attrNameLen;
166 Node parent;
167 while (elem != null) {
168
169 attrs = elem.getAttributes();
170 len = (attrs == null) ? 0 : attrs.getLength();
171 for (int i = 0; i < len; i++) {
172 a = (Attr) attrs.item(i);
173 attrName = a.getName();
174 if (attrName.startsWith("xmlns")) {
175 attrNameLen = attrName.length();
176 if (attrNameLen == 5) prefix = "";
177 else if ((attrNameLen > 6) && (attrName.charAt(5) == ':')) prefix = attrName.substring(6);
178 else prefix = null;
179 if (prefix != null) prefixMapping.addPrefixMapping(prefix, a.getValue());
180 }
181 }
182 parent = elem.getParentNode();
183 if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE)) elem = (Element) parent;
184 else elem = null;
185 }
186 return prefixMapping;
187 }
188
189
190 @Override
191 public XMLSerializable parseElement(String uri, String localName) throws XMLParseException {
192 XMLSerializable child = getFactory().createObject(uri, localName, this);
193 delegateParsingTo(child);
194 return child;
195 }
196
197
198 public String getElementText() {
199 if (currentElement == null) throw new IllegalStateException("No characters available");
200 String text = null;
201 NodeList childNodes = currentElement.getChildNodes();
202 int len = childNodes.getLength();
203 Node child;
204 String nodeText;
205 for (int i = 0; i < len; i++) {
206 child = childNodes.item(i);
207 if (child.getNodeType() == Node.TEXT_NODE) {
208 nodeText = ((Text) child).getData();
209 if (text == null) text = nodeText;
210 else text += nodeText;
211 }
212 }
213 return text;
214 }
215
216
217
218
219 @Override
220 protected void addLocationInfo(XMLParseException xpe) {
221 if (currentElement != null) {
222 xpe.setSource(getSourceDescription());
223 }
224 }
225
226
227 public String getSourceDescription() {
228 StringBuffer sb = new StringBuffer("DOM Document");
229 Document doc = (currentElement == null) ? null : currentElement.getOwnerDocument();
230 DocumentType docType = (doc == null) ? null : doc.getDoctype();
231 if (docType != null) sb.append(docType.getPublicId());
232 return sb.toString();
233 }
234
235
236
237
238 public String getAttributeValue(String attrName) throws XMLParseException {
239 return getAttributeValueNS(null, attrName);
240 }
241
242
243 public String getAttributeValueNS(String attrNamespaceURI, String attrName) throws XMLParseException {
244 if (currentElement == null) throw new XMLParseException(
245 "getAttributeValue(..) can only be called from startElement(..) method");
246 Attr attrib = (attrNamespaceURI == null) ? currentElement.getAttributeNode(attrName) : currentElement.getAttributeNodeNS(
247 attrNamespaceURI, attrName);
248 return (attrib == null) ? null : attrib.getValue();
249 }
250
251
252 public Iterator<String> getAttributeNamespaceIterator() throws XMLParseException {
253 if (currentElement == null) throw new XMLParseException(
254 "getAttributeNameIterator(..) can only be called from startElement(..) method");
255 List<String> uris = new ArrayList<String>();
256 NamedNodeMap attrMap = currentElement.getAttributes();
257 int len = attrMap.getLength();
258 for (int i = 0; i < len; i++) {
259 Node n = attrMap.item(i);
260 String uri = n.getNamespaceURI();
261 if (!uris.contains(uri)) uris.add(uri);
262 }
263 return uris.iterator();
264 }
265
266
267 public Iterator<String> getAttributeNameIterator(String attrNamespaceURI) throws XMLParseException {
268 if (currentElement == null) throw new XMLParseException(
269 "getAttributeNameIterator(..) can only be called from startElement(..) method");
270 NamedNodeMap attrMap = currentElement.getAttributes();
271 return new AttributeNameIterator(attrNamespaceURI, attrMap);
272 }
273
274
275
276
277
278
279 static class AttributeNameIterator implements Iterator<String> {
280
281 private String namespaceURI;
282 private NamedNodeMap attrMap;
283 private int nbrAttr;
284 private int index;
285
286
287 AttributeNameIterator(String uri, NamedNodeMap attrs) {
288 namespaceURI = uri;
289 attrMap = attrs;
290 index = 0;
291 nbrAttr = (attrMap == null) ? 0 : attrMap.getLength();
292 checkNextAttibuteNamespace();
293 }
294
295
296 private void checkNextAttibuteNamespace() {
297 boolean namespaceOK;
298 while (index < nbrAttr) {
299 Attr attribute = (Attr) attrMap.item(index);
300 if (namespaceURI == null) namespaceOK = (attribute.getNamespaceURI() == null);
301 else namespaceOK = namespaceURI.equals(attribute.getNamespaceURI());
302 if (namespaceOK) break;
303 else index++;
304 }
305 }
306
307
308 public boolean hasNext() {
309 return index < nbrAttr;
310 }
311
312
313 public String next() {
314 Attr attribute = (Attr) attrMap.item(index);
315 String name = attribute.getLocalName();
316 index++;
317 checkNextAttibuteNamespace();
318 return name;
319 }
320
321
322 public void remove() {
323 throw new UnsupportedOperationException("Cannot remove attribute");
324 }
325
326 }
327
328 }