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.ArrayList;
20 import java.util.Iterator;
21 import java.util.List;
22 import javax.xml.XMLConstants;
23 import javax.xml.namespace.QName;
24 import javax.xml.stream.Location;
25 import javax.xml.stream.XMLEventFactory;
26 import javax.xml.stream.XMLStreamException;
27 import javax.xml.stream.events.XMLEvent;
28 import javax.xml.stream.util.XMLEventConsumer;
29
30 import org.springframework.util.StringUtils;
31 import org.springframework.xml.namespace.QNameUtils;
32 import org.springframework.xml.namespace.SimpleNamespaceContext;
33 import org.xml.sax.Attributes;
34 import org.xml.sax.Locator;
35
36
37
38
39
40
41
42
43
44
45 public class StaxEventContentHandler extends AbstractStaxContentHandler {
46
47 private final XMLEventFactory eventFactory;
48
49 private final XMLEventConsumer eventConsumer;
50
51 private Locator locator;
52
53
54
55
56
57
58
59 public StaxEventContentHandler(XMLEventConsumer consumer) {
60 eventFactory = XMLEventFactory.newInstance();
61 eventConsumer = consumer;
62 }
63
64
65
66
67
68
69
70
71 public StaxEventContentHandler(XMLEventConsumer consumer, XMLEventFactory factory) {
72 eventFactory = factory;
73 eventConsumer = consumer;
74 }
75
76 public void setDocumentLocator(Locator locator) {
77 this.locator = locator;
78 }
79
80 protected void startDocumentInternal() throws XMLStreamException {
81 consumeEvent(eventFactory.createStartDocument());
82 }
83
84 protected void endDocumentInternal() throws XMLStreamException {
85 consumeEvent(eventFactory.createEndDocument());
86 }
87
88 protected void startElementInternal(QName name, Attributes atts, SimpleNamespaceContext namespaceContext)
89 throws XMLStreamException {
90 List attributes = getAttributes(atts);
91 List namespaces = createNamespaces(namespaceContext);
92 consumeEvent(eventFactory.createStartElement(name, attributes.iterator(), namespaces.iterator()));
93 }
94
95 protected void endElementInternal(QName name, SimpleNamespaceContext namespaceContext) throws XMLStreamException {
96 List namespaces = createNamespaces(namespaceContext);
97 consumeEvent(eventFactory.createEndElement(name, namespaces.iterator()));
98 }
99
100 protected void charactersInternal(char[] ch, int start, int length) throws XMLStreamException {
101 consumeEvent(eventFactory.createCharacters(new String(ch, start, length)));
102 }
103
104 protected void ignorableWhitespaceInternal(char[] ch, int start, int length) throws XMLStreamException {
105 consumeEvent(eventFactory.createIgnorableSpace(new String(ch, start, length)));
106 }
107
108 protected void processingInstructionInternal(String target, String data) throws XMLStreamException {
109 consumeEvent(eventFactory.createProcessingInstruction(target, data));
110 }
111
112 private void consumeEvent(XMLEvent event) throws XMLStreamException {
113 if (locator != null) {
114 eventFactory.setLocation(new SaxLocation(locator));
115 }
116 eventConsumer.add(event);
117 }
118
119
120 private List createNamespaces(SimpleNamespaceContext namespaceContext) {
121 List namespaces = new ArrayList();
122 String defaultNamespaceUri = namespaceContext.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX);
123 if (StringUtils.hasLength(defaultNamespaceUri)) {
124 namespaces.add(eventFactory.createNamespace(defaultNamespaceUri));
125 }
126 for (Iterator iterator = namespaceContext.getBoundPrefixes(); iterator.hasNext();) {
127 String prefix = (String) iterator.next();
128 String namespaceUri = namespaceContext.getNamespaceURI(prefix);
129 namespaces.add(eventFactory.createNamespace(prefix, namespaceUri));
130 }
131 return namespaces;
132 }
133
134 private List getAttributes(Attributes attributes) {
135 List list = new ArrayList();
136 for (int i = 0; i < attributes.getLength(); i++) {
137 QName name = QNameUtils.toQName(attributes.getURI(i), attributes.getQName(i));
138 if (!("xmlns".equals(name.getLocalPart()) || "xmlns".equals(QNameUtils.getPrefix(name)))) {
139 list.add(eventFactory.createAttribute(name, attributes.getValue(i)));
140 }
141 }
142 return list;
143 }
144
145
146
147
148
149 protected void skippedEntityInternal(String name) throws XMLStreamException {
150 }
151
152 private static class SaxLocation implements Location {
153
154 private Locator locator;
155
156 public SaxLocation(Locator locator) {
157 this.locator = locator;
158 }
159
160 public int getLineNumber() {
161 return locator.getLineNumber();
162 }
163
164 public int getColumnNumber() {
165 return locator.getColumnNumber();
166 }
167
168 public int getCharacterOffset() {
169 return -1;
170 }
171
172 public String getPublicId() {
173 return locator.getPublicId();
174 }
175
176 public String getSystemId() {
177 return locator.getSystemId();
178 }
179 }
180 }