1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.xml.stream;
18
19 import java.util.Iterator;
20 import javax.xml.stream.XMLEventReader;
21 import javax.xml.stream.XMLStreamConstants;
22 import javax.xml.stream.XMLStreamException;
23 import javax.xml.stream.events.Attribute;
24 import javax.xml.stream.events.Characters;
25 import javax.xml.stream.events.EndElement;
26 import javax.xml.stream.events.EntityDeclaration;
27 import javax.xml.stream.events.Namespace;
28 import javax.xml.stream.events.NotationDeclaration;
29 import javax.xml.stream.events.ProcessingInstruction;
30 import javax.xml.stream.events.StartElement;
31 import javax.xml.stream.events.XMLEvent;
32
33 import org.springframework.xml.namespace.QNameUtils;
34 import org.xml.sax.Attributes;
35 import org.xml.sax.SAXException;
36 import org.xml.sax.helpers.AttributesImpl;
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public class StaxEventXmlReader extends AbstractStaxXmlReader {
51
52 private final XMLEventReader reader;
53
54
55
56
57
58
59
60
61
62 public StaxEventXmlReader(XMLEventReader reader) {
63 try {
64 XMLEvent event = reader.peek();
65 if (event == null || !(event.isStartDocument() || event.isStartElement())) {
66 throw new IllegalStateException("XMLEventReader not at start of document or element");
67 }
68 }
69 catch (XMLStreamException ex) {
70 throw new IllegalStateException("Could not read first element: " + ex.getMessage());
71 }
72
73 this.reader = reader;
74 }
75
76 protected void parseInternal() throws SAXException, XMLStreamException {
77 boolean documentStarted = false;
78 boolean documentEnded = false;
79 int elementDepth = 0;
80 XMLEvent event = null;
81 while (reader.hasNext() && elementDepth >= 0) {
82 event = reader.nextEvent();
83 if (!event.isStartDocument() && !event.isEndDocument() && !documentStarted) {
84 handleStartDocument();
85 documentStarted = true;
86 }
87 switch (event.getEventType()) {
88 case XMLStreamConstants.START_ELEMENT:
89 elementDepth++;
90 handleStartElement(event.asStartElement());
91 break;
92 case XMLStreamConstants.END_ELEMENT:
93 elementDepth--;
94 if (elementDepth >= 0) {
95 handleEndElement(event.asEndElement());
96 }
97 break;
98 case XMLStreamConstants.PROCESSING_INSTRUCTION:
99 handleProcessingInstruction((ProcessingInstruction) event);
100 break;
101 case XMLStreamConstants.CHARACTERS:
102 case XMLStreamConstants.SPACE:
103 case XMLStreamConstants.CDATA:
104 handleCharacters(event.asCharacters());
105 break;
106 case XMLStreamConstants.START_DOCUMENT:
107 setLocator(event.getLocation());
108 handleStartDocument();
109 documentStarted = true;
110 break;
111 case XMLStreamConstants.END_DOCUMENT:
112 handleEndDocument();
113 documentEnded = true;
114 break;
115 case XMLStreamConstants.NOTATION_DECLARATION:
116 handleNotationDeclaration((NotationDeclaration) event);
117 break;
118 case XMLStreamConstants.ENTITY_DECLARATION:
119 handleEntityDeclaration((EntityDeclaration) event);
120 break;
121 }
122 }
123 if (!documentEnded) {
124 handleEndDocument();
125 }
126
127 }
128
129 private void handleCharacters(Characters characters) throws SAXException {
130 if (getContentHandler() != null) {
131 if (characters.isIgnorableWhiteSpace()) {
132 getContentHandler()
133 .ignorableWhitespace(characters.getData().toCharArray(), 0, characters.getData().length());
134 }
135 else {
136 getContentHandler().characters(characters.getData().toCharArray(), 0, characters.getData().length());
137 }
138 }
139 }
140
141 private void handleEndDocument() throws SAXException {
142 if (getContentHandler() != null) {
143 getContentHandler().endDocument();
144 }
145 }
146
147 private void handleEndElement(EndElement endElement) throws SAXException {
148 if (getContentHandler() != null) {
149 getContentHandler().endElement(endElement.getName().getNamespaceURI(), endElement.getName().getLocalPart(),
150 QNameUtils.toQualifiedName(endElement.getName()));
151
152 for (Iterator i = endElement.getNamespaces(); i.hasNext();) {
153 Namespace namespace = (Namespace) i.next();
154 getContentHandler().endPrefixMapping(namespace.getPrefix());
155 }
156 }
157 }
158
159 private void handleNotationDeclaration(NotationDeclaration declaration) throws SAXException {
160 if (getDTDHandler() != null) {
161 getDTDHandler().notationDecl(declaration.getName(), declaration.getPublicId(), declaration.getSystemId());
162 }
163 }
164
165 private void handleEntityDeclaration(EntityDeclaration entityDeclaration) throws SAXException {
166 if (getDTDHandler() != null) {
167 getDTDHandler().unparsedEntityDecl(entityDeclaration.getName(), entityDeclaration.getPublicId(),
168 entityDeclaration.getSystemId(), entityDeclaration.getNotationName());
169 }
170 }
171
172 private void handleProcessingInstruction(ProcessingInstruction pi) throws SAXException {
173 if (getContentHandler() != null) {
174 getContentHandler().processingInstruction(pi.getTarget(), pi.getData());
175 }
176 }
177
178 private void handleStartDocument() throws SAXException {
179 if (getContentHandler() != null) {
180 getContentHandler().startDocument();
181 }
182 }
183
184 private void handleStartElement(StartElement startElement) throws SAXException {
185 if (getContentHandler() != null) {
186 for (Iterator i = startElement.getNamespaces(); i.hasNext();) {
187 Namespace namespace = (Namespace) i.next();
188 getContentHandler().startPrefixMapping(namespace.getPrefix(), namespace.getNamespaceURI());
189 }
190
191 getContentHandler().startElement(startElement.getName().getNamespaceURI(),
192 startElement.getName().getLocalPart(), QNameUtils.toQualifiedName(startElement.getName()),
193 getAttributes(startElement));
194 }
195 }
196
197 private Attributes getAttributes(StartElement event) {
198 AttributesImpl attributes = new AttributesImpl();
199
200 for (Iterator i = event.getAttributes(); i.hasNext();) {
201 Attribute attribute = (Attribute) i.next();
202 attributes.addAttribute(attribute.getName().getNamespaceURI(), attribute.getName().getLocalPart(),
203 QNameUtils.toQualifiedName(attribute.getName()), attribute.getDTDType(), attribute.getValue());
204 }
205
206 return attributes;
207 }
208
209 }