1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.ws.server.endpoint.adapter.method;
18
19 import java.io.ByteArrayInputStream;
20 import javax.xml.stream.Location;
21 import javax.xml.stream.XMLInputFactory;
22 import javax.xml.stream.XMLStreamException;
23 import javax.xml.stream.XMLStreamReader;
24 import javax.xml.stream.util.StreamReaderDelegate;
25 import javax.xml.transform.Source;
26 import javax.xml.transform.dom.DOMResult;
27 import javax.xml.transform.dom.DOMSource;
28 import javax.xml.transform.sax.SAXSource;
29 import javax.xml.transform.stax.StAXSource;
30 import javax.xml.transform.stream.StreamSource;
31
32 import org.springframework.core.MethodParameter;
33 import org.springframework.xml.JaxpVersion;
34
35 import org.w3c.dom.Document;
36 import org.w3c.dom.Node;
37 import org.xml.sax.InputSource;
38
39
40
41
42
43
44
45
46 public class SourcePayloadMethodProcessor extends AbstractPayloadSourceMethodProcessor {
47
48 private XMLInputFactory inputFactory = createXmlInputFactory();
49
50
51
52 @Override
53 protected boolean supportsRequestPayloadParameter(MethodParameter parameter) {
54 return supports(parameter);
55 }
56
57 @Override
58 protected Source resolveRequestPayloadArgument(MethodParameter parameter, Source requestPayload) throws Exception {
59 Class<?> parameterType = parameter.getParameterType();
60 if (parameterType.isAssignableFrom(requestPayload.getClass())) {
61 return requestPayload;
62 }
63 if (DOMSource.class.isAssignableFrom(parameterType)) {
64 DOMResult domResult = new DOMResult();
65 transform(requestPayload, domResult);
66 Node node = domResult.getNode();
67 if (node.getNodeType() == Node.DOCUMENT_NODE) {
68 return new DOMSource(((Document) node).getDocumentElement());
69 }
70 else {
71 return new DOMSource(domResult.getNode());
72 }
73 }
74 else if (SAXSource.class.isAssignableFrom(parameterType)) {
75 ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload);
76 InputSource inputSource = new InputSource(bis);
77 return new SAXSource(inputSource);
78 }
79 else if (StreamSource.class.isAssignableFrom(parameterType)) {
80 ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload);
81 return new StreamSource(bis);
82 }
83 else if (JaxpVersion.isAtLeastJaxp14() && Jaxp14StaxHandler.isStaxSource(parameterType)) {
84 XMLStreamReader streamReader;
85 try {
86 streamReader = inputFactory.createXMLStreamReader(requestPayload);
87 } catch (UnsupportedOperationException ignored) {
88 streamReader = null;
89 }
90 catch (XMLStreamException ignored) {
91 streamReader = null;
92 }
93 if (streamReader == null) {
94 ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload);
95 streamReader = inputFactory.createXMLStreamReader(bis);
96 }
97 return Jaxp14StaxHandler.createStaxSource(streamReader, requestPayload.getSystemId());
98 }
99 throw new IllegalArgumentException("Unknown Source type: " + parameterType);
100 }
101
102
103
104 @Override
105 protected boolean supportsResponsePayloadReturnType(MethodParameter returnType) {
106 return supports(returnType);
107 }
108
109 @Override
110 protected Source createResponsePayload(MethodParameter returnType, Object returnValue) {
111 return (Source) returnValue;
112 }
113
114 private boolean supports(MethodParameter parameter) {
115 return Source.class.isAssignableFrom(parameter.getParameterType());
116 }
117
118
119
120
121
122
123
124
125
126
127 protected XMLInputFactory createXmlInputFactory() {
128 return XMLInputFactory.newInstance();
129 }
130
131
132 private static class Jaxp14StaxHandler {
133
134 private static boolean isStaxSource(Class<?> clazz) {
135 return StAXSource.class.isAssignableFrom(clazz);
136 }
137
138 private static Source createStaxSource(XMLStreamReader streamReader, String systemId) {
139 return new StAXSource(new SystemIdStreamReaderDelegate(streamReader, systemId));
140 }
141
142 }
143
144 private static class SystemIdStreamReaderDelegate extends StreamReaderDelegate {
145
146 private final String systemId;
147
148 private SystemIdStreamReaderDelegate(XMLStreamReader reader, String systemId) {
149 super(reader);
150 this.systemId = systemId;
151 }
152
153 @Override
154 public Location getLocation() {
155 final Location parentLocation = getParent().getLocation();
156 return new Location() {
157 public int getLineNumber() {
158 return parentLocation != null ? parentLocation.getLineNumber() : -1;
159 }
160
161 public int getColumnNumber() {
162 return parentLocation != null ? parentLocation.getColumnNumber() : -1;
163 }
164
165 public int getCharacterOffset() {
166 return parentLocation != null ? parentLocation.getLineNumber() : -1;
167 }
168
169 public String getPublicId() {
170 return parentLocation != null ? parentLocation.getPublicId() : null;
171 }
172
173 public String getSystemId() {
174 return systemId;
175 }
176 };
177 }
178 }
179
180 }