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