SWS-351 - Arbitrary parameter injection for @Endpoints

This commit is contained in:
Arjen Poutsma
2010-05-07 09:58:31 +00:00
parent f738427b74
commit 3556ee7f01
3 changed files with 77 additions and 19 deletions

View File

@@ -17,13 +17,18 @@
package org.springframework.ws.server.endpoint.adapter.method;
import java.io.ByteArrayInputStream;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamSource;
import org.springframework.core.MethodParameter;
import org.springframework.xml.JaxpVersion;
import org.springframework.xml.transform.StaxSource;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@@ -36,8 +41,11 @@ import org.xml.sax.InputSource;
* @author Arjen Poutsma
* @since 2.0
*/
@SuppressWarnings("Since15")
public class SourcePayloadMethodProcessor extends AbstractPayloadSourceMethodProcessor {
private XMLInputFactory inputFactory = createXmlInputFactory();
// MethodArgumentResolver
@Override
@@ -55,14 +63,18 @@ public class SourcePayloadMethodProcessor extends AbstractPayloadSourceMethodPro
DOMResult domResult = new DOMResult();
transform(requestPayload, domResult);
Node node = domResult.getNode();
if (node instanceof Document) {
Document document = (Document) node;
return new DOMSource(document.getDocumentElement());
if (node.getNodeType() == Node.DOCUMENT_NODE) {
return new DOMSource(((Document) node).getDocumentElement());
}
else {
return new DOMSource(domResult.getNode());
}
}
else if (StaxSource.class.isAssignableFrom(parameterType)) {
ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload);
XMLStreamReader streamReader = inputFactory.createXMLStreamReader(bis);
return new StaxSource(streamReader);
}
else if (SAXSource.class.isAssignableFrom(parameterType)) {
ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload);
InputSource inputSource = new InputSource(bis);
@@ -72,8 +84,12 @@ public class SourcePayloadMethodProcessor extends AbstractPayloadSourceMethodPro
ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload);
return new StreamSource(bis);
}
// should not happen
throw new UnsupportedOperationException();
else if (JaxpVersion.isAtLeastJaxp14() && Jaxp14StaxHandler.isStaxSource(parameterType)) {
ByteArrayInputStream bis = convertToByteArrayInputStream(requestPayload);
XMLStreamReader streamReader = inputFactory.createXMLStreamReader(bis);
return Jaxp14StaxHandler.createStaxSource(streamReader);
}
throw new IllegalArgumentException("Unknown Source type: " + parameterType);
}
// MethodReturnValueHandler
@@ -92,4 +108,30 @@ public class SourcePayloadMethodProcessor extends AbstractPayloadSourceMethodPro
return Source.class.isAssignableFrom(parameter.getParameterType());
}
/**
* Create a {@code XMLInputFactory} that this resolver will use to create {@link javax.xml.stream.XMLStreamReader}
* and {@link javax.xml.stream.XMLEventReader} objects.
* <p/>
* Can be overridden in subclasses, adding further initialization of the factory. The resulting factory is cached,
* so this method will only be called once.
*
* @return the created factory
*/
protected XMLInputFactory createXmlInputFactory() {
return XMLInputFactory.newInstance();
}
/** Inner class to avoid a static JAXP 1.4 dependency. */
private static class Jaxp14StaxHandler {
private static boolean isStaxSource(Class<?> clazz) {
return StAXSource.class.isAssignableFrom(clazz);
}
private static Source createStaxSource(XMLStreamReader streamReader) {
return new StAXSource(streamReader);
}
}
}

View File

@@ -19,14 +19,17 @@ package org.springframework.ws.server.endpoint.adapter.method;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamSource;
import org.springframework.core.MethodParameter;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import org.springframework.xml.transform.StaxSource;
import org.springframework.xml.transform.StringSource;
/** @author Arjen Poutsma */
@SuppressWarnings("Since15")
public class SourcePayloadMethodProcessorTest extends AbstractPayloadMethodProcessorTestCase {
@Override
@@ -36,20 +39,22 @@ public class SourcePayloadMethodProcessorTest extends AbstractPayloadMethodProce
@Override
protected MethodParameter[] createSupportedParameters() throws NoSuchMethodException {
return new MethodParameter[] {
new MethodParameter(getClass().getMethod("source", Source.class), 0),
new MethodParameter(getClass().getMethod("dom", DOMSource.class), 0),
new MethodParameter(getClass().getMethod("sax", SAXSource.class), 0),
new MethodParameter(getClass().getMethod("stream", StreamSource.class), 0)};
return new MethodParameter[]{new MethodParameter(getClass().getMethod("source", Source.class), 0),
new MethodParameter(getClass().getMethod("dom", DOMSource.class), 0),
new MethodParameter(getClass().getMethod("stax1", StaxSource.class), 0),
new MethodParameter(getClass().getMethod("sax", SAXSource.class), 0),
new MethodParameter(getClass().getMethod("stream", StreamSource.class), 0),
new MethodParameter(getClass().getMethod("stax2", StAXSource.class), 0)};
}
@Override
protected MethodParameter[] createSupportedReturnTypes() throws NoSuchMethodException {
return new MethodParameter[] {
new MethodParameter(getClass().getMethod("source", Source.class), -1),
new MethodParameter(getClass().getMethod("dom", DOMSource.class), -1),
new MethodParameter(getClass().getMethod("sax", SAXSource.class), -1),
new MethodParameter(getClass().getMethod("stream", StreamSource.class), -1)};
return new MethodParameter[]{new MethodParameter(getClass().getMethod("source", Source.class), -1),
new MethodParameter(getClass().getMethod("dom", DOMSource.class), -1),
new MethodParameter(getClass().getMethod("stax1", StaxSource.class), -1),
new MethodParameter(getClass().getMethod("sax", SAXSource.class), -1),
new MethodParameter(getClass().getMethod("stream", StreamSource.class), -1),
new MethodParameter(getClass().getMethod("stax2", StAXSource.class), -1)};
}
@Override
@@ -67,6 +72,11 @@ public class SourcePayloadMethodProcessorTest extends AbstractPayloadMethodProce
return source;
}
@ResponsePayload
public StaxSource stax1(@RequestPayload StaxSource source) {
return source;
}
@ResponsePayload
public SAXSource sax(@RequestPayload SAXSource source) {
return source;
@@ -76,4 +86,9 @@ public class SourcePayloadMethodProcessorTest extends AbstractPayloadMethodProce
public StreamSource stream(@RequestPayload StreamSource source) {
return source;
}
@ResponsePayload
public StAXSource stax2(@RequestPayload StAXSource source) {
return source;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006 the original author or authors.
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,18 +47,19 @@ public abstract class JaxpVersion {
private static int jaxpVersion = JAXP_10;
static {
ClassLoader classLoader = JaxpVersion.class.getClassLoader();
try {
ClassUtils.forName(JAXP_14_CLASS_NAME);
ClassUtils.forName(JAXP_14_CLASS_NAME, classLoader);
jaxpVersion = JAXP_14;
}
catch (ClassNotFoundException ex1) {
try {
ClassUtils.forName(JAXP_13_CLASS_NAME);
ClassUtils.forName(JAXP_13_CLASS_NAME, classLoader);
jaxpVersion = JAXP_13;
}
catch (ClassNotFoundException ex2) {
try {
ClassUtils.forName(JAXP_11_CLASS_NAME);
ClassUtils.forName(JAXP_11_CLASS_NAME, classLoader);
jaxpVersion = JAXP_11;
}
catch (ClassNotFoundException ex3) {