1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.soap.axiom;
18
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import javax.xml.namespace.QName;
24 import javax.xml.stream.XMLStreamConstants;
25
26 import org.springframework.util.Assert;
27 import org.springframework.xml.namespace.QNameUtils;
28
29 import org.apache.axiom.om.OMAttribute;
30 import org.apache.axiom.om.OMContainer;
31 import org.apache.axiom.om.OMElement;
32 import org.apache.axiom.om.OMFactory;
33 import org.apache.axiom.om.OMNamespace;
34 import org.xml.sax.Attributes;
35 import org.xml.sax.ContentHandler;
36 import org.xml.sax.Locator;
37 import org.xml.sax.SAXException;
38 import org.xml.sax.ext.LexicalHandler;
39
40
41
42
43
44
45
46
47
48 class AxiomHandler implements ContentHandler, LexicalHandler {
49
50 private final OMFactory factory;
51
52 private final List<OMContainer> elements = new ArrayList<OMContainer>();
53
54 private Map<String, String> namespaces = new HashMap<String, String>();
55
56 private final OMContainer container;
57
58 private int charactersType = XMLStreamConstants.CHARACTERS;
59
60 AxiomHandler(OMContainer container, OMFactory factory) {
61 Assert.notNull(container, "'container' must not be null");
62 Assert.notNull(factory, "'factory' must not be null");
63 this.factory = factory;
64 this.container = container;
65 }
66
67 private OMContainer getParent() {
68 if (!elements.isEmpty()) {
69 return elements.get(elements.size() - 1);
70 }
71 else {
72 return container;
73 }
74 }
75
76 public void startPrefixMapping(String prefix, String uri) throws SAXException {
77 namespaces.put(prefix, uri);
78 }
79
80 public void endPrefixMapping(String prefix) throws SAXException {
81 namespaces.remove(prefix);
82 }
83
84 public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
85 OMContainer parent = getParent();
86 OMNamespace ns = factory.createOMNamespace(uri, QNameUtils.toQName(uri, qName).getPrefix());
87 OMElement element = factory.createOMElement(localName, ns, parent);
88 for (Map.Entry<String, String> entry : namespaces.entrySet()) {
89 String prefix = entry.getKey();
90 if (prefix.length() == 0) {
91 element.declareDefaultNamespace((String) entry.getValue());
92 }
93 else {
94 element.declareNamespace((String) entry.getValue(), prefix);
95 }
96 }
97 for (int i = 0; i < atts.getLength(); i++) {
98 QName attrName = QNameUtils.toQName(atts.getURI(i), atts.getQName(i));
99 String value = atts.getValue(i);
100 if (!atts.getQName(i).startsWith("xmlns")) {
101 OMNamespace namespace = factory.createOMNamespace(attrName.getNamespaceURI(), attrName.getPrefix());
102 OMAttribute attribute = factory.createOMAttribute(attrName.getLocalPart(), namespace, value);
103 element.addAttribute(attribute);
104 }
105 }
106
107 elements.add(element);
108 }
109
110 public void endElement(String uri, String localName, String qName) throws SAXException {
111 elements.remove(elements.size() - 1);
112 }
113
114 public void characters(char ch[], int start, int length) throws SAXException {
115 String data = new String(ch, start, length);
116 OMContainer parent = getParent();
117 factory.createOMText(parent, data, charactersType);
118 }
119
120 public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
121 charactersType = XMLStreamConstants.SPACE;
122 characters(ch, start, length);
123 charactersType = XMLStreamConstants.CHARACTERS;
124 }
125
126 public void processingInstruction(String target, String data) throws SAXException {
127 OMContainer parent = getParent();
128 factory.createOMProcessingInstruction(parent, target, data);
129 }
130
131 public void comment(char ch[], int start, int length) throws SAXException {
132 String content = new String(ch, start, length);
133 OMContainer parent = getParent();
134 factory.createOMComment(parent, content);
135 }
136
137 public void startCDATA() throws SAXException {
138 charactersType = XMLStreamConstants.CDATA;
139 }
140
141 public void endCDATA() throws SAXException {
142 charactersType = XMLStreamConstants.CHARACTERS;
143 }
144
145 public void startEntity(String name) throws SAXException {
146 if (!isPredefinedEntityReference(name)) {
147 charactersType = XMLStreamConstants.ENTITY_REFERENCE;
148 }
149 }
150
151 public void endEntity(String name) throws SAXException {
152 charactersType = XMLStreamConstants.CHARACTERS;
153 }
154
155 private boolean isPredefinedEntityReference(String name) {
156 return "lt".equals(name) || "gt".equals(name) || "amp".equals(name) || "quot".equals(name) ||
157 "apos".equals(name);
158 }
159
160
161
162
163
164 public void setDocumentLocator(Locator locator) {
165 }
166
167 public void startDocument() throws SAXException {
168 }
169
170 public void endDocument() throws SAXException {
171 }
172
173 public void skippedEntity(String name) throws SAXException {
174 }
175
176 public void startDTD(String name, String publicId, String systemId) throws SAXException {
177 }
178
179 public void endDTD() throws SAXException {
180 }
181 }