1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.server.endpoint;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.OutputStream;
24 import java.io.Reader;
25 import java.util.Locale;
26 import javax.xml.stream.XMLEventReader;
27 import javax.xml.stream.XMLStreamConstants;
28 import javax.xml.stream.XMLStreamException;
29 import javax.xml.stream.XMLStreamReader;
30 import javax.xml.transform.Source;
31 import javax.xml.transform.stream.StreamSource;
32
33 import org.springframework.core.NestedRuntimeException;
34 import org.springframework.xml.namespace.QNameUtils;
35 import org.springframework.xml.transform.TransformerObjectSupport;
36 import org.springframework.xml.transform.TraxUtils;
37
38 import nu.xom.Attribute;
39 import nu.xom.Builder;
40 import nu.xom.Document;
41 import nu.xom.Element;
42 import nu.xom.NodeFactory;
43 import nu.xom.ParentNode;
44 import nu.xom.ParsingException;
45 import nu.xom.Serializer;
46 import nu.xom.ValidityException;
47 import nu.xom.converters.DOMConverter;
48 import org.w3c.dom.Node;
49 import org.xml.sax.InputSource;
50 import org.xml.sax.SAXException;
51 import org.xml.sax.XMLReader;
52
53
54
55
56
57
58
59
60
61
62
63
64
65 @Deprecated
66 @SuppressWarnings("Since15")
67 public abstract class AbstractXomPayloadEndpoint extends TransformerObjectSupport implements PayloadEndpoint {
68
69 public final Source invoke(Source request) throws Exception {
70 Element requestElement = null;
71 if (request != null) {
72 XomSourceCallback sourceCallback = new XomSourceCallback();
73 try {
74 TraxUtils.doWithSource(request, sourceCallback);
75 }
76 catch (XomParsingException ex) {
77 throw (ParsingException) ex.getCause();
78 }
79 requestElement = sourceCallback.element;
80 }
81 Element responseElement = invokeInternal(requestElement);
82 return responseElement != null ? convertResponse(responseElement) : null;
83 }
84
85 private Source convertResponse(Element responseElement) throws IOException {
86 ByteArrayOutputStream os = new ByteArrayOutputStream();
87 Serializer serializer = createSerializer(os);
88 Document document = responseElement.getDocument();
89 if (document == null) {
90 document = new Document(responseElement);
91 }
92 serializer.write(document);
93 byte[] bytes = os.toByteArray();
94 return new StreamSource(new ByteArrayInputStream(bytes));
95 }
96
97
98
99
100
101
102
103
104
105
106 protected Serializer createSerializer(OutputStream outputStream) {
107 return new Serializer(outputStream);
108 }
109
110
111
112
113
114
115
116
117 protected abstract Element invokeInternal(Element requestElement) throws Exception;
118
119 private static class XomSourceCallback implements TraxUtils.SourceCallback {
120
121 private Element element;
122
123 public void domSource(Node node) {
124 if (node.getNodeType() == Node.ELEMENT_NODE) {
125 element = DOMConverter.convert((org.w3c.dom.Element) node);
126 }
127 else if (node.getNodeType() == Node.DOCUMENT_NODE) {
128 Document document = DOMConverter.convert((org.w3c.dom.Document) node);
129 element = document.getRootElement();
130 }
131 else {
132 throw new IllegalArgumentException("DOMSource contains neither Document nor Element");
133 }
134 }
135
136 public void saxSource(XMLReader reader, InputSource inputSource) throws IOException, SAXException {
137 try {
138 Builder builder = new Builder(reader);
139 Document document;
140 if (inputSource.getByteStream() != null) {
141 document = builder.build(inputSource.getByteStream());
142 }
143 else if (inputSource.getCharacterStream() != null) {
144 document = builder.build(inputSource.getCharacterStream());
145 }
146 else {
147 throw new IllegalArgumentException(
148 "InputSource in SAXSource contains neither byte stream nor character stream");
149 }
150 element = document.getRootElement();
151 }
152 catch (ValidityException ex) {
153 throw new XomParsingException(ex);
154 }
155 catch (ParsingException ex) {
156 throw new XomParsingException(ex);
157 }
158 }
159
160 public void staxSource(XMLEventReader eventReader) throws XMLStreamException {
161 throw new IllegalArgumentException("XMLEventReader not supported");
162 }
163
164 public void staxSource(XMLStreamReader streamReader) throws XMLStreamException {
165 Document document = StaxStreamConverter.convert(streamReader);
166 element = document.getRootElement();
167 }
168
169 public void streamSource(InputStream inputStream) throws IOException {
170 try {
171 Builder builder = new Builder();
172 Document document = builder.build(inputStream);
173 element = document.getRootElement();
174 }
175 catch (ParsingException ex) {
176 throw new XomParsingException(ex);
177 }
178 }
179
180 public void streamSource(Reader reader) throws IOException {
181 try {
182 Builder builder = new Builder();
183 Document document = builder.build(reader);
184 element = document.getRootElement();
185 }
186 catch (ParsingException ex) {
187 throw new XomParsingException(ex);
188 }
189 }
190
191 public void source(String systemId) throws Exception {
192 try {
193 Builder builder = new Builder();
194 Document document = builder.build(systemId);
195 element = document.getRootElement();
196 }
197 catch (ParsingException ex) {
198 throw new XomParsingException(ex);
199 }
200 }
201 }
202
203 private static class XomParsingException extends NestedRuntimeException {
204
205 private XomParsingException(ParsingException ex) {
206 super(ex.getMessage(), ex);
207 }
208 }
209
210 private static class StaxStreamConverter {
211
212 private static Document convert(XMLStreamReader streamReader) throws XMLStreamException {
213 NodeFactory nodeFactory = new NodeFactory();
214 Document document = null;
215 Element element = null;
216 ParentNode parent = null;
217 boolean documentFinished = false;
218 while (streamReader.hasNext()) {
219 int event = streamReader.next();
220 switch (event) {
221 case XMLStreamConstants.START_DOCUMENT:
222 document = nodeFactory.startMakingDocument();
223 parent = document;
224 break;
225 case XMLStreamConstants.END_DOCUMENT:
226 nodeFactory.finishMakingDocument(document);
227 documentFinished = true;
228 break;
229 case XMLStreamConstants.START_ELEMENT:
230 if (document == null) {
231 document = nodeFactory.startMakingDocument();
232 parent = document;
233 }
234 String name = QNameUtils.toQualifiedName(streamReader.getName());
235 if (element == null) {
236 element = nodeFactory.makeRootElement(name, streamReader.getNamespaceURI());
237 document.setRootElement(element);
238 }
239 else {
240 element = nodeFactory.startMakingElement(name, streamReader.getNamespaceURI());
241 parent.appendChild(element);
242 }
243 convertNamespaces(streamReader, element);
244 convertAttributes(streamReader, nodeFactory);
245 parent = element;
246 break;
247 case XMLStreamConstants.END_ELEMENT:
248 nodeFactory.finishMakingElement(element);
249 parent = parent.getParent();
250 break;
251 case XMLStreamConstants.ATTRIBUTE:
252 convertAttributes(streamReader, nodeFactory);
253 break;
254 case XMLStreamConstants.CHARACTERS:
255 nodeFactory.makeText(streamReader.getText());
256 break;
257 case XMLStreamConstants.COMMENT:
258 nodeFactory.makeComment(streamReader.getText());
259 break;
260 default:
261 break;
262 }
263 }
264 if (!documentFinished) {
265 nodeFactory.finishMakingDocument(document);
266 }
267 return document;
268 }
269
270 private static void convertNamespaces(XMLStreamReader streamReader, Element element) {
271 for (int i = 0; i < streamReader.getNamespaceCount(); i++) {
272 String uri = streamReader.getNamespaceURI(i);
273 String prefix = streamReader.getNamespacePrefix(i);
274
275 element.addNamespaceDeclaration(prefix, uri);
276 }
277
278 }
279
280 private static void convertAttributes(XMLStreamReader streamReader, NodeFactory nodeFactory) {
281 for (int i = 0; i < streamReader.getAttributeCount(); i++) {
282 String name = QNameUtils.toQualifiedName(streamReader.getAttributeName(i));
283 String uri = streamReader.getAttributeNamespace(i);
284 String value = streamReader.getAttributeValue(i);
285 Attribute.Type type = convertAttributeType(streamReader.getAttributeType(i));
286
287 nodeFactory.makeAttribute(name, uri, value, type);
288 }
289 }
290
291 private static Attribute.Type convertAttributeType(String type) {
292 type = type.toUpperCase(Locale.ENGLISH);
293 if ("CDATA".equals(type)) {
294 return Attribute.Type.CDATA;
295 }
296 else if ("ENTITIES".equals(type)) {
297 return Attribute.Type.ENTITIES;
298 }
299 else if ("ENTITY".equals(type)) {
300 return Attribute.Type.ENTITY;
301 }
302 else if ("ENUMERATION".equals(type)) {
303 return Attribute.Type.ENUMERATION;
304 }
305 else if ("ID".equals(type)) {
306 return Attribute.Type.ID;
307 }
308 else if ("IDREF".equals(type)) {
309 return Attribute.Type.IDREF;
310 }
311 else if ("IDREFS".equals(type)) {
312 return Attribute.Type.IDREFS;
313 }
314 else if ("NMTOKEN".equals(type)) {
315 return Attribute.Type.NMTOKEN;
316 }
317 else if ("NMTOKENS".equals(type)) {
318 return Attribute.Type.NMTOKENS;
319 }
320 else if ("NOTATION".equals(type)) {
321 return Attribute.Type.NOTATION;
322 }
323 else {
324 return Attribute.Type.UNDECLARED;
325 }
326 }
327
328 }
329 }