Merged core and core-tiger modules
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.adapter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.oxm.GenericMarshaller;
|
||||
import org.springframework.oxm.GenericUnmarshaller;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
|
||||
/**
|
||||
* Subclass of {@link MarshallingMethodEndpointAdapter} that supports {@link GenericMarshaller} and {@link
|
||||
* GenericUnmarshaller}. More specifically, this adapter is aware of the {@link Method#getGenericParameterTypes()} and
|
||||
* {@link Method#getGenericReturnType()}.
|
||||
* <p/>
|
||||
* Prefer to use this adapter rather than the plain {@link MarshallingMethodEndpointAdapter} in combination with Java 5
|
||||
* marshallers, such as the {@link Jaxb2Marshaller}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0.2
|
||||
*/
|
||||
public class GenericMarshallingMethodEndpointAdapter extends MarshallingMethodEndpointAdapter {
|
||||
|
||||
/**
|
||||
* Creates a new <code>GenericMarshallingMethodEndpointAdapter</code>. The {@link Marshaller} and {@link
|
||||
* Unmarshaller} must be injected using properties.
|
||||
*
|
||||
* @see #setMarshaller(org.springframework.oxm.Marshaller)
|
||||
* @see #setUnmarshaller(org.springframework.oxm.Unmarshaller)
|
||||
*/
|
||||
public GenericMarshallingMethodEndpointAdapter() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>GenericMarshallingMethodEndpointAdapter</code> with the given marshaller. If the given {@link
|
||||
* Marshaller} also implements the {@link Unmarshaller} interface, it is used for both marshalling and
|
||||
* unmarshalling. Otherwise, an exception is thrown.
|
||||
* <p/>
|
||||
* Note that all {@link Marshaller} implementations in Spring-WS also implement the {@link Unmarshaller} interface,
|
||||
* so that you can safely use this constructor.
|
||||
*
|
||||
* @param marshaller object used as marshaller and unmarshaller
|
||||
* @throws IllegalArgumentException when <code>marshaller</code> does not implement the {@link Unmarshaller}
|
||||
* interface
|
||||
*/
|
||||
public GenericMarshallingMethodEndpointAdapter(Marshaller marshaller) {
|
||||
super(marshaller);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>GenericMarshallingMethodEndpointAdapter</code> with the given marshaller and unmarshaller.
|
||||
*
|
||||
* @param marshaller the marshaller to use
|
||||
* @param unmarshaller the unmarshaller to use
|
||||
*/
|
||||
public GenericMarshallingMethodEndpointAdapter(Marshaller marshaller, Unmarshaller unmarshaller) {
|
||||
super(marshaller, unmarshaller);
|
||||
}
|
||||
|
||||
protected boolean supportsInternal(MethodEndpoint methodEndpoint) {
|
||||
Method method = methodEndpoint.getMethod();
|
||||
return supportsReturnType(method) && supportsParameters(method);
|
||||
}
|
||||
|
||||
private boolean supportsReturnType(Method method) {
|
||||
if (Void.TYPE.equals(method.getReturnType())) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (getMarshaller() instanceof GenericMarshaller) {
|
||||
return ((GenericMarshaller) getMarshaller()).supports(method.getGenericReturnType());
|
||||
}
|
||||
else {
|
||||
return getMarshaller().supports(method.getReturnType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean supportsParameters(Method method) {
|
||||
if (method.getParameterTypes().length != 1) {
|
||||
return false;
|
||||
}
|
||||
else if (getUnmarshaller() instanceof GenericUnmarshaller) {
|
||||
GenericUnmarshaller genericUnmarshaller = (GenericUnmarshaller) getUnmarshaller();
|
||||
return genericUnmarshaller.supports(method.getGenericParameterTypes()[0]);
|
||||
}
|
||||
else {
|
||||
return getUnmarshaller().supports(method.getParameterTypes()[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.adapter;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Properties;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.XPathParam;
|
||||
import org.springframework.xml.namespace.SimpleNamespaceContext;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* Adapter that supports endpoint methods that use marshalling. Supports methods with the following signature:
|
||||
* <pre>
|
||||
* void handleMyMessage(@XPathParam("/root/child/text")String param);
|
||||
* </pre>
|
||||
* or
|
||||
* <pre>
|
||||
* Source handleMyMessage(@XPathParam("/root/child/text")String param1, @XPathParam("/root/child/number")double
|
||||
* param2);
|
||||
* </pre>
|
||||
* I.e. methods that return either <code>void</code> or a {@link Source}, and have parameters annotated with {@link
|
||||
* XPathParam} that specify the XPath expression that should be bound to that parameter. The parameter can be of the
|
||||
* following types: <ul> <li><code>boolean</code>, or {@link Boolean}</li> <li><code>double</code>, or {@link
|
||||
* Double}</li> <li>{@link String}</li> <li>{@link Node}</li> <li>{@link NodeList}</li> </ul>
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class XPathParamAnnotationMethodEndpointAdapter extends AbstractMethodEndpointAdapter
|
||||
implements InitializingBean {
|
||||
|
||||
private XPathFactory xpathFactory;
|
||||
|
||||
private Properties namespaces;
|
||||
|
||||
/** Sets namespaces used in the XPath expression. Maps prefixes to namespaces. */
|
||||
public void setNamespaces(Properties namespaces) {
|
||||
this.namespaces = namespaces;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
xpathFactory = XPathFactory.newInstance();
|
||||
}
|
||||
|
||||
/** Supports methods with @XPathParam parameters, and return either <code>Source</code> or nothing. */
|
||||
protected boolean supportsInternal(MethodEndpoint methodEndpoint) {
|
||||
Method method = methodEndpoint.getMethod();
|
||||
if (!(Source.class.isAssignableFrom(method.getReturnType()) || Void.TYPE.equals(method.getReturnType()))) {
|
||||
return false;
|
||||
}
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
if (getXPathParamAnnotation(method, i) == null || !isSuportedType(parameterTypes[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private XPathParam getXPathParamAnnotation(Method method, int paramIdx) {
|
||||
Annotation[][] paramAnnotations = method.getParameterAnnotations();
|
||||
for (int annIdx = 0; annIdx < paramAnnotations[paramIdx].length; annIdx++) {
|
||||
if (paramAnnotations[paramIdx][annIdx].annotationType().equals(XPathParam.class)) {
|
||||
return (XPathParam) paramAnnotations[paramIdx][annIdx];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isSuportedType(Class<?> clazz) {
|
||||
return Boolean.class.isAssignableFrom(clazz) || Boolean.TYPE.isAssignableFrom(clazz) ||
|
||||
Double.class.isAssignableFrom(clazz) || Double.TYPE.isAssignableFrom(clazz) ||
|
||||
Node.class.isAssignableFrom(clazz) || NodeList.class.isAssignableFrom(clazz) ||
|
||||
String.class.isAssignableFrom(clazz);
|
||||
}
|
||||
|
||||
protected void invokeInternal(MessageContext messageContext, MethodEndpoint methodEndpoint) throws Exception {
|
||||
Element payloadElement = getRootElement(messageContext.getRequest().getPayloadSource());
|
||||
Object[] args = getMethodArguments(payloadElement, methodEndpoint.getMethod());
|
||||
Object result = methodEndpoint.invoke(args);
|
||||
if (result != null && result instanceof Source) {
|
||||
Source responseSource = (Source) result;
|
||||
WebServiceMessage response = messageContext.getResponse();
|
||||
transform(responseSource, response.getPayloadResult());
|
||||
}
|
||||
}
|
||||
|
||||
private Object[] getMethodArguments(Element payloadElement, Method method) throws XPathExpressionException {
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
XPath xpath = createXPath();
|
||||
Object[] args = new Object[parameterTypes.length];
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
String expression = getXPathParamAnnotation(method, i).value();
|
||||
QName conversionType;
|
||||
if (Boolean.class.isAssignableFrom(parameterTypes[i]) || Boolean.TYPE.isAssignableFrom(parameterTypes[i])) {
|
||||
conversionType = XPathConstants.BOOLEAN;
|
||||
}
|
||||
else
|
||||
if (Double.class.isAssignableFrom(parameterTypes[i]) || Double.TYPE.isAssignableFrom(parameterTypes[i])) {
|
||||
conversionType = XPathConstants.NUMBER;
|
||||
}
|
||||
else if (Node.class.isAssignableFrom(parameterTypes[i])) {
|
||||
conversionType = XPathConstants.NODE;
|
||||
}
|
||||
else if (NodeList.class.isAssignableFrom(parameterTypes[i])) {
|
||||
conversionType = XPathConstants.NODESET;
|
||||
}
|
||||
else if (String.class.isAssignableFrom(parameterTypes[i])) {
|
||||
conversionType = XPathConstants.STRING;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid parameter type [" + parameterTypes[i] + "]. " +
|
||||
"Supported are: Boolean, Double, Node, NodeList, and String.");
|
||||
}
|
||||
args[i] = xpath.evaluate(expression, payloadElement, conversionType);
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
private XPath createXPath() {
|
||||
XPath xpath = xpathFactory.newXPath();
|
||||
if (namespaces != null) {
|
||||
SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext();
|
||||
namespaceContext.setBindings(namespaces);
|
||||
xpath.setNamespaceContext(namespaceContext);
|
||||
}
|
||||
return xpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root element of the given source.
|
||||
*
|
||||
* @param source the source to get the root element from
|
||||
* @return the root element
|
||||
*/
|
||||
private Element getRootElement(Source source) throws TransformerException {
|
||||
DOMResult domResult = new DOMResult();
|
||||
transform(source, domResult);
|
||||
Document document = (Document) domResult.getNode();
|
||||
return document.getDocumentElement();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.ws.server.endpoint.mapping.AbstractAnnotationMethodEndpointMapping;
|
||||
import org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping;
|
||||
|
||||
/**
|
||||
* Indicates that an annotated class is an "Endpoint" (e.g. a web service endpoint).
|
||||
* <p/>
|
||||
* This annotation serves as a specialization of {@link Component @Component}, allowing for implementation classes to be
|
||||
* autodetected through classpath scanning. Instances of this class are typically picked up by an {@link
|
||||
* AbstractAnnotationMethodEndpointMapping} implementation, such as {@link SoapActionAnnotationMethodEndpointMapping}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Component
|
||||
public @interface Endpoint {
|
||||
|
||||
/**
|
||||
* The value may indicate a suggestion for a logical component name, to be turned into a Spring bean in case of an
|
||||
* autodetected component.
|
||||
*
|
||||
* @return the suggested component name, if any
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks an endpoint method as the handler for an incoming request. The annotation values signify the the request
|
||||
* payload root element that is handled by the method.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface PayloadRoot {
|
||||
|
||||
/**
|
||||
* Signifies the local part of the payload root element handled by the annotated method.
|
||||
*
|
||||
* @see #namespace()
|
||||
*/
|
||||
String localPart();
|
||||
|
||||
/**
|
||||
* Signifies the namespace of the payload root element handled by the annotated method.
|
||||
*
|
||||
* @see #localPart()
|
||||
*/
|
||||
String namespace() default "";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Indicates that a method parameter should be bound to an XPath expression. The annotation value signifies the XPath
|
||||
* expression to use. The parameter can be of the following types: <ul> <li><code>boolean</code>, or {@link
|
||||
* Boolean}</li> <li><code>double</code>, or {@link Double}</li> <li>{@link String}</li> <li>{@link
|
||||
* org.w3c.dom.Node}</li> <li>{@link org.w3c.dom.NodeList}</li> </ul>
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.ws.server.endpoint.adapter.XPathParamAnnotationMethodEndpointAdapter
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface XPathParam {
|
||||
|
||||
String value();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
JDK 1.5+ annotations for Spring-WS endpoints.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.mapping;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
|
||||
/**
|
||||
* Abstract base for {@link org.springframework.ws.server.EndpointMapping} implementations that map classes tagged with
|
||||
* an annotation. By default the annotation is {@link Endpoint}, but this can be overriden in subclasses.
|
||||
* <p/>
|
||||
* The methods of each bean carrying @Endpoint will be registered using {@link #registerMethods(String)}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public abstract class AbstractAnnotationMethodEndpointMapping extends AbstractMethodEndpointMapping {
|
||||
|
||||
private boolean detectEndpointsInAncestorContexts = false;
|
||||
|
||||
/**
|
||||
* Set whether to detect endpoint beans in ancestor ApplicationContexts.
|
||||
* <p/>
|
||||
* Default is "false": Only endpoint beans in the current ApplicationContext will be detected, i.e. only in the
|
||||
* context that this EndpointMapping itself is defined in (typically the current MessageDispatcherServlet's
|
||||
* context).
|
||||
* <p/>
|
||||
* Switch this flag on to detect endpoint beans in ancestor contexts (typically the Spring root
|
||||
* WebApplicationContext) as well.
|
||||
*/
|
||||
public void setDetectEndpointsInAncestorContexts(boolean detectEndpointsInAncestorContexts) {
|
||||
this.detectEndpointsInAncestorContexts = detectEndpointsInAncestorContexts;
|
||||
}
|
||||
|
||||
/** Returns the 'endpoint' annotation type. Default is {@link Endpoint}. */
|
||||
protected Class<? extends Annotation> getEndpointAnnotationType() {
|
||||
return Endpoint.class;
|
||||
}
|
||||
|
||||
protected final void initApplicationContext() throws BeansException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Looking for endpoints in application context: " + getApplicationContext());
|
||||
}
|
||||
String[] beanNames = (this.detectEndpointsInAncestorContexts ?
|
||||
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
|
||||
getApplicationContext().getBeanNamesForType(Object.class));
|
||||
|
||||
for (int i = 0; i < beanNames.length; i++) {
|
||||
String beanName = beanNames[i];
|
||||
Class endpointClass = getApplicationContext().getType(beanName);
|
||||
if (endpointClass != null &&
|
||||
AnnotationUtils.findAnnotation(endpointClass, getEndpointAnnotationType()) != null) {
|
||||
registerMethods(beanName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.mapping;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.EndpointMapping;
|
||||
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
|
||||
import org.springframework.ws.server.endpoint.support.PayloadRootUtils;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link EndpointMapping} interface that uses the {@link PayloadRoot} annotation to map methods
|
||||
* to request payload root elements.
|
||||
* <p/>
|
||||
* Endpoints typically have the following form:
|
||||
* <pre>
|
||||
* @Endpoint
|
||||
* public class MyEndpoint{
|
||||
* @PayloadRoot(localPart = "Request",
|
||||
* namespace = "http://springframework.org/spring-ws")
|
||||
* public Source doSomethingWithRequest() {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class PayloadRootAnnotationMethodEndpointMapping extends AbstractAnnotationMethodEndpointMapping {
|
||||
|
||||
private static TransformerFactory transformerFactory;
|
||||
|
||||
static {
|
||||
transformerFactory = TransformerFactory.newInstance();
|
||||
}
|
||||
|
||||
protected String getLookupKeyForMessage(MessageContext messageContext) throws Exception {
|
||||
QName qName =
|
||||
PayloadRootUtils.getPayloadRootQName(messageContext.getRequest().getPayloadSource(), transformerFactory)
|
||||
;
|
||||
return qName != null ? qName.toString() : null;
|
||||
}
|
||||
|
||||
protected String getLookupKeyForMethod(Method method) {
|
||||
PayloadRoot annotation = method.getAnnotation(PayloadRoot.class);
|
||||
if (annotation != null) {
|
||||
QName qname;
|
||||
if (StringUtils.hasLength(annotation.localPart()) && StringUtils.hasLength(annotation.namespace())) {
|
||||
qname = new QName(annotation.namespace(), annotation.localPart());
|
||||
}
|
||||
else {
|
||||
qname = new QName(annotation.localPart());
|
||||
}
|
||||
return qname.toString();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.addressing.server;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.soap.addressing.core.MessageAddressingProperties;
|
||||
import org.springframework.ws.soap.addressing.server.annotation.Action;
|
||||
import org.springframework.ws.soap.addressing.server.annotation.Address;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link org.springframework.ws.server.EndpointMapping} interface that uses the {@link Action}
|
||||
* annotation to map methods to a WS-Addressing <code>Action</code> header.
|
||||
* <p/>
|
||||
* Endpoints typically have the following form:
|
||||
* <pre>
|
||||
* @Endpoint
|
||||
* @Address("mailto:joe@fabrikam123.example")
|
||||
* public class MyEndpoint{
|
||||
* @Action("http://fabrikam123.example/mail/Delete")
|
||||
* public Source doSomethingWithRequest() {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* If set, the {@link Address} annotation on the endpoint class should be equal to the {@link
|
||||
* org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getTo() destination} property of the
|
||||
* incominging message.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see Action
|
||||
* @see Address
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class AnnotationActionEndpointMapping extends AbstractActionMethodEndpointMapping implements BeanPostProcessor {
|
||||
|
||||
/** Returns the 'endpoint' annotation type. Default is {@link Endpoint}. */
|
||||
protected Class<? extends Annotation> getEndpointAnnotationType() {
|
||||
return Endpoint.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the action value for the specified method. Default implementation looks for the {@link Action} annotation
|
||||
* value.
|
||||
*/
|
||||
protected URI getActionForMethod(Method method) {
|
||||
Action action = method.getAnnotation(Action.class);
|
||||
if (action != null && StringUtils.hasText(action.value())) {
|
||||
try {
|
||||
return new URI(action.value());
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Action annotation [" + action.value() + "] on [" + method + "]");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address property of the given {@link MethodEndpoint}, by looking for the {@link Address} annotation.
|
||||
* The value of this property should match the {@link org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getTo()
|
||||
* destination} of incoming messages. Returns <code>null</code> if the anotation is not present, thus ignoring the
|
||||
* destination property.
|
||||
*
|
||||
* @param endpoint the method endpoint to return the address for
|
||||
* @return the endpoint address; or <code>null</code> to ignore the destination property
|
||||
*/
|
||||
protected URI getEndpointAddress(Object endpoint) {
|
||||
MethodEndpoint methodEndpoint = (MethodEndpoint) endpoint;
|
||||
Class endpointClass = methodEndpoint.getMethod().getDeclaringClass();
|
||||
Address address = AnnotationUtils.findAnnotation(endpointClass, Address.class);
|
||||
if (address != null && StringUtils.hasText(address.value())) {
|
||||
return getActionUri(address.value(), methodEndpoint);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected URI getResponseAction(Object endpoint, MessageAddressingProperties map) {
|
||||
MethodEndpoint methodEndpoint = (MethodEndpoint) endpoint;
|
||||
Action action = methodEndpoint.getMethod().getAnnotation(Action.class);
|
||||
if (action != null && StringUtils.hasText(action.output())) {
|
||||
return getActionUri(action.output(), methodEndpoint);
|
||||
}
|
||||
else {
|
||||
return super.getResponseAction(endpoint, map);
|
||||
}
|
||||
}
|
||||
|
||||
protected URI getFaultAction(Object endpoint, MessageAddressingProperties map) {
|
||||
MethodEndpoint methodEndpoint = (MethodEndpoint) endpoint;
|
||||
Action action = methodEndpoint.getMethod().getAnnotation(Action.class);
|
||||
if (action != null && StringUtils.hasText(action.fault())) {
|
||||
return getActionUri(action.fault(), methodEndpoint);
|
||||
}
|
||||
else {
|
||||
return super.getResponseAction(endpoint, map);
|
||||
}
|
||||
}
|
||||
|
||||
private URI getActionUri(String action, MethodEndpoint methodEndpoint) {
|
||||
try {
|
||||
return new URI(action);
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid Action annotation [" + action + "] on [" + methodEndpoint + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public final Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public final Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (AopUtils.getTargetClass(bean).getAnnotation(getEndpointAnnotationType()) != null) {
|
||||
registerMethods(bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.addressing.server.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks an endpoint method as the handler for an incoming request. The annotation value signifies the value for the
|
||||
* request WS-Addressing <code>Action</code> header that is handled by the method.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.5.0
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Action {
|
||||
|
||||
/** Signifies the value for the request WS-Addressing <code>Action</code> header that is handled by the method. */
|
||||
String value();
|
||||
|
||||
/** Signifies the value for the response WS-Addressing <code>Action</code> header that is provided by the method. */
|
||||
String output() default "";
|
||||
|
||||
/**
|
||||
* Signifies the value for the fault response WS-Addressing <code>Action</code> header that is provided by the
|
||||
* method.
|
||||
*/
|
||||
String fault() default "";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.addressing.server.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks an endpoint with a WS-Addressing <code>Address</code>. If this annotation is applied, the {@link #value()} is
|
||||
* compared to the {@link org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getTo() destination}
|
||||
* property of the incominging message.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.5.0
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface Address {
|
||||
|
||||
/**
|
||||
* The value may indicate a suggestion for a logical component name, to be turned into a Spring bean in case of an
|
||||
* autodetected component.
|
||||
*
|
||||
* @return the suggested component name, if any
|
||||
*/
|
||||
String value();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.server.endpoint;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.FaultCode;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.SoapFault;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link org.springframework.ws.server.EndpointExceptionResolver} interface that uses the {@link
|
||||
* SoapFault} annotation to map exceptions to SOAP Faults.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class SoapFaultAnnotationExceptionResolver extends AbstractSoapFaultDefinitionExceptionResolver {
|
||||
|
||||
protected final SoapFaultDefinition getFaultDefinition(Object endpoint, Exception ex) {
|
||||
SoapFault faultAnnotation = ex.getClass().getAnnotation(SoapFault.class);
|
||||
if (faultAnnotation != null) {
|
||||
SoapFaultDefinition definition = new SoapFaultDefinition();
|
||||
if (faultAnnotation.faultCode() != FaultCode.CUSTOM) {
|
||||
definition.setFaultCode(faultAnnotation.faultCode().value());
|
||||
}
|
||||
else if (StringUtils.hasLength(faultAnnotation.customFaultCode())) {
|
||||
definition.setFaultCode(QName.valueOf(faultAnnotation.customFaultCode()));
|
||||
}
|
||||
definition.setFaultStringOrReason(faultAnnotation.faultStringOrReason());
|
||||
definition.setLocale(StringUtils.parseLocaleString(faultAnnotation.locale()));
|
||||
return definition;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.server.endpoint.annotation;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.springframework.ws.soap.SoapBody;
|
||||
import org.springframework.ws.soap.soap11.Soap11Body;
|
||||
|
||||
/**
|
||||
* Enumeration that represents the standard SOAP Fault codes for use with the JDK 1.5+ {@link SoapFault} annotation.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public enum FaultCode {
|
||||
|
||||
/**
|
||||
* Constant used to indicate that a fault must be created with a custom fault code. When this value is used, the
|
||||
* <code>customFaultCode</code> string property must be used on {@link SoapFault}.
|
||||
* <p/>
|
||||
* Note that custom Fault Codes are only supported on SOAP 1.1.
|
||||
*
|
||||
* @see SoapFault#customFaultCode()
|
||||
* @see Soap11Body#addFault(javax.xml.namespace.QName,String,java.util.Locale)
|
||||
*/
|
||||
CUSTOM(new QName("CUSTOM")),
|
||||
|
||||
/**
|
||||
* Constant used to indicate that a <code>Client</code> fault must be created.
|
||||
*
|
||||
* @see SoapBody#addClientOrSenderFault(String,java.util.Locale)
|
||||
*/
|
||||
CLIENT(new QName("CLIENT")),
|
||||
|
||||
/**
|
||||
* Constant <code>QName</code> used to indicate that a <code>Receiver</code> fault must be created.
|
||||
*
|
||||
* @see SoapBody#addServerOrReceiverFault(String,java.util.Locale)
|
||||
*/
|
||||
RECEIVER(new QName("RECEIVER")),
|
||||
|
||||
/**
|
||||
* Constant <code>QName</code> used to indicate that a <code>Sender</code> fault must be created.
|
||||
*
|
||||
* @see SoapBody#addServerOrReceiverFault(String,java.util.Locale)
|
||||
*/
|
||||
SENDER(new QName("SENDER")),
|
||||
|
||||
/**
|
||||
* Constant <code>QName</code> used to indicate that a <code>Server</code> fault must be created.
|
||||
*
|
||||
* @see SoapBody#addClientOrSenderFault(String,java.util.Locale)
|
||||
*/
|
||||
SERVER(new QName("SERVER"));
|
||||
|
||||
private final QName value;
|
||||
|
||||
private FaultCode(QName value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public QName value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.server.endpoint.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks an endpoint method as the handler for an incoming request. The annotation value signifies the value for the
|
||||
* request <code>SOAPAction</code> header that is handled by the method.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface SoapAction {
|
||||
|
||||
/** Signifies the value for the request <code>SOAPAction</code> header that is handled by the method. */
|
||||
String value();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.server.endpoint.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
/**
|
||||
* Marks an exception class with the fault elements that should be returned whenever this exception is thrown.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface SoapFault {
|
||||
|
||||
/** The fault code. */
|
||||
FaultCode faultCode();
|
||||
|
||||
/**
|
||||
* The custom fault code, to be used if {@link #faultCode()} is set to {@link FaultCode#CUSTOM}.
|
||||
* <p/>
|
||||
* The format used is that of {@link QName#toString()}, i.e. "{" + Namespace URI + "}" + local part, where the
|
||||
* namespace is optional.
|
||||
* <p/>
|
||||
* Note that custom Fault Codes are only supported on SOAP 1.1.
|
||||
*/
|
||||
String customFaultCode() default "";
|
||||
|
||||
/** The fault string or reason text. By default, it is set to the exception message. */
|
||||
String faultStringOrReason() default "";
|
||||
|
||||
/** The fault string locale. By default, it is English. */
|
||||
String locale() default "en";
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
JDK 1.5+ annotations for Spring-WS SOAP endpoints.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.server.endpoint.mapping;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.EndpointInterceptor;
|
||||
import org.springframework.ws.server.EndpointInvocationChain;
|
||||
import org.springframework.ws.server.endpoint.mapping.AbstractAnnotationMethodEndpointMapping;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.server.SoapEndpointInvocationChain;
|
||||
import org.springframework.ws.soap.server.SoapEndpointMapping;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.SoapAction;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link org.springframework.ws.server.EndpointMapping} interface that uses the {@link
|
||||
* SoapAction} annotation to map methods to the request SOAPAction header.
|
||||
* <p/>
|
||||
* Endpoints typically have the following form:
|
||||
* <pre>
|
||||
* @Endpoint
|
||||
* public class MyEndpoint{
|
||||
* @SoapAction("http://springframework.org/spring-ws/SoapAction")
|
||||
* public Source doSomethingWithRequest() {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class SoapActionAnnotationMethodEndpointMapping extends AbstractAnnotationMethodEndpointMapping
|
||||
implements SoapEndpointMapping {
|
||||
|
||||
private String[] actorsOrRoles;
|
||||
|
||||
private boolean isUltimateReceiver = true;
|
||||
|
||||
public final void setActorOrRole(String actorOrRole) {
|
||||
Assert.notNull(actorOrRole, "actorOrRole must not be null");
|
||||
actorsOrRoles = new String[]{actorOrRole};
|
||||
}
|
||||
|
||||
public final void setActorsOrRoles(String[] actorsOrRoles) {
|
||||
Assert.notEmpty(actorsOrRoles, "actorsOrRoles must not be empty");
|
||||
this.actorsOrRoles = actorsOrRoles;
|
||||
}
|
||||
|
||||
public final void setUltimateReceiver(boolean ultimateReceiver) {
|
||||
isUltimateReceiver = ultimateReceiver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>SoapEndpointInvocationChain</code> based on the given endpoint, and the set interceptors, and
|
||||
* actors/roles.
|
||||
*
|
||||
* @param endpoint the endpoint
|
||||
* @param interceptors the endpoint interceptors
|
||||
* @return the created invocation chain
|
||||
* @see #setInterceptors(org.springframework.ws.server.EndpointInterceptor[])
|
||||
* @see #setActorsOrRoles(String[])
|
||||
*/
|
||||
protected final EndpointInvocationChain createEndpointInvocationChain(MessageContext messageContext,
|
||||
Object endpoint,
|
||||
EndpointInterceptor[] interceptors) {
|
||||
return new SoapEndpointInvocationChain(endpoint, interceptors, actorsOrRoles, isUltimateReceiver);
|
||||
}
|
||||
|
||||
protected String getLookupKeyForMessage(MessageContext messageContext) throws Exception {
|
||||
if (messageContext.getRequest() instanceof SoapMessage) {
|
||||
SoapMessage request = (SoapMessage) messageContext.getRequest();
|
||||
String soapAction = request.getSoapAction();
|
||||
if (StringUtils.hasLength(soapAction) && soapAction.charAt(0) == '"' &&
|
||||
soapAction.charAt(soapAction.length() - 1) == '"') {
|
||||
return soapAction.substring(1, soapAction.length() - 1);
|
||||
}
|
||||
else {
|
||||
return soapAction;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getLookupKeyForMethod(Method method) {
|
||||
SoapAction soapAction = method.getAnnotation(SoapAction.class);
|
||||
return soapAction != null ? soapAction.value() : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright ${YEAR} 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter;
|
||||
import org.springframework.ws.server.endpoint.adapter.XPathParamAnnotationMethodEndpointAdapter;
|
||||
|
||||
public class WebServicesNamespaceHandlerTigerTest extends TestCase {
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
applicationContext =
|
||||
new ClassPathXmlApplicationContext("webServicesNamespaceHandlerTest-tiger.xml", getClass());
|
||||
}
|
||||
|
||||
public void testMarshallingEndpoints() throws Exception {
|
||||
Map result = applicationContext.getBeansOfType(GenericMarshallingMethodEndpointAdapter.class);
|
||||
assertFalse("no MarshallingMethodEndpointAdapter found", result.isEmpty());
|
||||
}
|
||||
|
||||
public void testXpathEndpoints() throws Exception {
|
||||
Map result = applicationContext.getBeansOfType(XPathParamAnnotationMethodEndpointAdapter.class);
|
||||
assertFalse("no XPathParamAnnotationMethodEndpointAdapter found", result.isEmpty());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package org.springframework.ws.server.endpoint.adapter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import static org.easymock.EasyMock.*;
|
||||
import org.springframework.oxm.GenericMarshaller;
|
||||
import org.springframework.oxm.GenericUnmarshaller;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.xml.transform.StringResult;
|
||||
import org.springframework.xml.transform.StringSource;
|
||||
|
||||
public class GenericMarshallingMethodEndpointAdapterTest extends TestCase {
|
||||
|
||||
private GenericMarshallingMethodEndpointAdapter adapter;
|
||||
|
||||
private boolean noResponseInvoked;
|
||||
|
||||
private GenericMarshaller marshallerMock;
|
||||
|
||||
private GenericUnmarshaller unmarshallerMock;
|
||||
|
||||
private boolean responseInvoked;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
adapter = new GenericMarshallingMethodEndpointAdapter();
|
||||
marshallerMock = createMock(GenericMarshaller.class);
|
||||
adapter.setMarshaller(marshallerMock);
|
||||
unmarshallerMock = createMock(GenericUnmarshaller.class);
|
||||
adapter.setUnmarshaller(unmarshallerMock);
|
||||
adapter.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public void testNoResponse() throws Exception {
|
||||
WebServiceMessage messageMock = createMock(WebServiceMessage.class);
|
||||
expect(messageMock.getPayloadSource()).andReturn(new StringSource("<request/>"));
|
||||
WebServiceMessageFactory factoryMock = createMock(WebServiceMessageFactory.class);
|
||||
MessageContext messageContext = new DefaultMessageContext(messageMock, factoryMock);
|
||||
|
||||
Method noResponse = getClass().getMethod("noResponse", MyGenericType.class);
|
||||
MethodEndpoint methodEndpoint = new MethodEndpoint(this, noResponse);
|
||||
expect(unmarshallerMock.unmarshal(isA(Source.class))).andReturn(new MyGenericType<MyType>());
|
||||
|
||||
replay(marshallerMock, unmarshallerMock, messageMock, factoryMock);
|
||||
|
||||
assertFalse("Method invoked", noResponseInvoked);
|
||||
adapter.invoke(messageContext, methodEndpoint);
|
||||
assertTrue("Method not invoked", noResponseInvoked);
|
||||
|
||||
verify(marshallerMock, unmarshallerMock, messageMock, factoryMock);
|
||||
}
|
||||
|
||||
public void testNoRequestPayload() throws Exception {
|
||||
WebServiceMessage messageMock = createMock(WebServiceMessage.class);
|
||||
expect(messageMock.getPayloadSource()).andReturn(null);
|
||||
WebServiceMessageFactory factoryMock = createMock(WebServiceMessageFactory.class);
|
||||
MessageContext messageContext = new DefaultMessageContext(messageMock, factoryMock);
|
||||
|
||||
Method noResponse = getClass().getMethod("noResponse", MyGenericType.class);
|
||||
MethodEndpoint methodEndpoint = new MethodEndpoint(this, noResponse);
|
||||
|
||||
replay(marshallerMock, unmarshallerMock, messageMock, factoryMock);
|
||||
|
||||
assertFalse("Method invoked", noResponseInvoked);
|
||||
adapter.invoke(messageContext, methodEndpoint);
|
||||
assertTrue("Method not invoked", noResponseInvoked);
|
||||
|
||||
verify(marshallerMock, unmarshallerMock, messageMock, factoryMock);
|
||||
}
|
||||
|
||||
public void testResponse() throws Exception {
|
||||
WebServiceMessage requestMock = createMock(WebServiceMessage.class);
|
||||
expect(requestMock.getPayloadSource()).andReturn(new StringSource("<request/>"));
|
||||
WebServiceMessage responseMock = createMock(WebServiceMessage.class);
|
||||
expect(responseMock.getPayloadResult()).andReturn(new StringResult());
|
||||
WebServiceMessageFactory factoryMock = createMock(WebServiceMessageFactory.class);
|
||||
expect(factoryMock.createWebServiceMessage()).andReturn(responseMock);
|
||||
MessageContext messageContext = new DefaultMessageContext(requestMock, factoryMock);
|
||||
|
||||
Method response = getClass().getMethod("response", MyGenericType.class);
|
||||
MethodEndpoint methodEndpoint = new MethodEndpoint(this, response);
|
||||
expect(unmarshallerMock.unmarshal(isA(Source.class))).andReturn(new MyGenericType<MyType>());
|
||||
marshallerMock.marshal(isA(MyGenericType.class), isA(Result.class));
|
||||
|
||||
replay(marshallerMock, unmarshallerMock, requestMock, responseMock, factoryMock);
|
||||
|
||||
assertFalse("Method invoked", responseInvoked);
|
||||
adapter.invoke(messageContext, methodEndpoint);
|
||||
assertTrue("Method not invoked", responseInvoked);
|
||||
|
||||
verify(marshallerMock, unmarshallerMock, requestMock, responseMock, factoryMock);
|
||||
}
|
||||
|
||||
public void testSupportedNoResponse() throws NoSuchMethodException {
|
||||
Method noResponse = getClass().getMethod("noResponse", MyGenericType.class);
|
||||
MethodEndpoint methodEndpoint = new MethodEndpoint(this, noResponse);
|
||||
expect(unmarshallerMock.supports(noResponse.getGenericParameterTypes()[0])).andReturn(true);
|
||||
|
||||
replay(marshallerMock, unmarshallerMock);
|
||||
|
||||
assertTrue("Method unsupported", adapter.supportsInternal(methodEndpoint));
|
||||
|
||||
verify(marshallerMock, unmarshallerMock);
|
||||
}
|
||||
|
||||
public void testSupportedResponse() throws NoSuchMethodException {
|
||||
Method response = getClass().getMethod("response", MyGenericType.class);
|
||||
MethodEndpoint methodEndpoint = new MethodEndpoint(this, response);
|
||||
|
||||
expect(unmarshallerMock.supports(response.getGenericParameterTypes()[0])).andReturn(true);
|
||||
expect(marshallerMock.supports(response.getGenericReturnType())).andReturn(true);
|
||||
|
||||
replay(marshallerMock, unmarshallerMock);
|
||||
|
||||
assertTrue("Method unsupported", adapter.supportsInternal(methodEndpoint));
|
||||
|
||||
verify(marshallerMock, unmarshallerMock);
|
||||
}
|
||||
|
||||
public void testUnsupportedMethodMultipleParams() throws NoSuchMethodException {
|
||||
Method unsupported = getClass().getMethod("unsupportedMultipleParams", String.class, String.class);
|
||||
|
||||
replay(marshallerMock, unmarshallerMock);
|
||||
|
||||
assertFalse("Method supported", adapter.supportsInternal(new MethodEndpoint(this, unsupported)));
|
||||
|
||||
verify(marshallerMock, unmarshallerMock);
|
||||
}
|
||||
|
||||
public void testUnsupportedMethodWrongParam() throws NoSuchMethodException {
|
||||
Method unsupported = getClass().getMethod("unsupportedWrongParam", String.class);
|
||||
expect(unmarshallerMock.supports(unsupported.getGenericParameterTypes()[0])).andReturn(false);
|
||||
expect(marshallerMock.supports(unsupported.getGenericReturnType())).andReturn(true);
|
||||
|
||||
replay(marshallerMock, unmarshallerMock);
|
||||
|
||||
assertFalse("Method supported", adapter.supportsInternal(new MethodEndpoint(this, unsupported)));
|
||||
|
||||
verify(marshallerMock, unmarshallerMock);
|
||||
}
|
||||
|
||||
public void testUnsupportedMethodWrongReturnType() throws NoSuchMethodException {
|
||||
Method unsupported = getClass().getMethod("unsupportedWrongParam", String.class);
|
||||
expect(marshallerMock.supports(unsupported.getGenericReturnType())).andReturn(false);
|
||||
|
||||
replay(marshallerMock, unmarshallerMock);
|
||||
|
||||
assertFalse("Method supported", adapter.supportsInternal(new MethodEndpoint(this, unsupported)));
|
||||
|
||||
verify(marshallerMock, unmarshallerMock);
|
||||
}
|
||||
|
||||
public void noResponse(MyGenericType<MyType> type) {
|
||||
noResponseInvoked = true;
|
||||
|
||||
}
|
||||
|
||||
public MyGenericType<MyType> response(MyGenericType<MyType> type) {
|
||||
responseInvoked = true;
|
||||
return type;
|
||||
}
|
||||
|
||||
public void unsupportedMultipleParams(String s1, String s2) {
|
||||
}
|
||||
|
||||
public String unsupportedWrongParam(String s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
private static class MyType {
|
||||
|
||||
}
|
||||
|
||||
private static class MyGenericType<T> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.adapter;
|
||||
|
||||
import java.util.Properties;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import static org.easymock.EasyMock.*;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.XPathParam;
|
||||
import org.springframework.xml.transform.StringResult;
|
||||
import org.springframework.xml.transform.StringSource;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.Text;
|
||||
|
||||
public class XPathParamAnnotationMethodEndpointAdapterTest extends TestCase {
|
||||
|
||||
private static final String CONTENTS = "<root><child><text>text</text><number>42.0</number></child></root>";
|
||||
|
||||
private XPathParamAnnotationMethodEndpointAdapter adapter;
|
||||
|
||||
private boolean supportedTypesInvoked = false;
|
||||
|
||||
private boolean supportedSourceInvoked;
|
||||
|
||||
private boolean namespacesInvoked;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
adapter = new XPathParamAnnotationMethodEndpointAdapter();
|
||||
adapter.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public void testUnsupportedInvalidParam() throws NoSuchMethodException {
|
||||
MethodEndpoint endpoint = new MethodEndpoint(this, "unsupportedInvalidParamType", new Class[]{Integer.TYPE});
|
||||
assertFalse("Method supported", adapter.supports(endpoint));
|
||||
}
|
||||
|
||||
public void testUnsupportedInvalidReturnType() throws NoSuchMethodException {
|
||||
MethodEndpoint endpoint = new MethodEndpoint(this, "unsupportedInvalidReturnType", new Class[]{String.class});
|
||||
assertFalse("Method supported", adapter.supports(endpoint));
|
||||
}
|
||||
|
||||
public void testUnsupportedInvalidParams() throws NoSuchMethodException {
|
||||
MethodEndpoint endpoint =
|
||||
new MethodEndpoint(this, "unsupportedInvalidParams", new Class[]{String.class, String.class});
|
||||
assertFalse("Method supported", adapter.supports(endpoint));
|
||||
}
|
||||
|
||||
public void testSupportedTypes() throws NoSuchMethodException {
|
||||
MethodEndpoint endpoint = new MethodEndpoint(this, "supportedTypes",
|
||||
new Class[]{Boolean.TYPE, Double.TYPE, Node.class, NodeList.class, String.class});
|
||||
assertTrue("Not all types supported", adapter.supports(endpoint));
|
||||
}
|
||||
|
||||
public void testSupportsStringSource() throws NoSuchMethodException {
|
||||
MethodEndpoint endpoint = new MethodEndpoint(this, "supportedStringSource", new Class[]{String.class});
|
||||
assertTrue("StringSource method not supported", adapter.supports(endpoint));
|
||||
}
|
||||
|
||||
public void testSupportsSource() throws NoSuchMethodException {
|
||||
MethodEndpoint endpoint = new MethodEndpoint(this, "supportedSource", new Class[]{String.class});
|
||||
assertTrue("Source method not supported", adapter.supports(endpoint));
|
||||
}
|
||||
|
||||
public void testSupportsVoid() throws NoSuchMethodException {
|
||||
MethodEndpoint endpoint = new MethodEndpoint(this, "supportedVoid", new Class[]{String.class});
|
||||
assertTrue("void method not supported", adapter.supports(endpoint));
|
||||
}
|
||||
|
||||
public void testInvokeTypes() throws Exception {
|
||||
WebServiceMessage messageMock = createMock(WebServiceMessage.class);
|
||||
expect(messageMock.getPayloadSource()).andReturn(new StringSource(CONTENTS));
|
||||
WebServiceMessageFactory factoryMock = createMock(WebServiceMessageFactory.class);
|
||||
replay(messageMock, factoryMock);
|
||||
|
||||
MessageContext messageContext = new DefaultMessageContext(messageMock, factoryMock);
|
||||
MethodEndpoint endpoint = new MethodEndpoint(this, "supportedTypes",
|
||||
new Class[]{Boolean.TYPE, Double.TYPE, Node.class, NodeList.class, String.class});
|
||||
adapter.invoke(messageContext, endpoint);
|
||||
assertTrue("Method not invoked", supportedTypesInvoked);
|
||||
|
||||
verify(messageMock, factoryMock);
|
||||
}
|
||||
|
||||
public void testInvokeSource() throws Exception {
|
||||
WebServiceMessage requestMock = createMock(WebServiceMessage.class);
|
||||
WebServiceMessage responseMock = createMock(WebServiceMessage.class);
|
||||
expect(requestMock.getPayloadSource()).andReturn(new StringSource(CONTENTS));
|
||||
expect(responseMock.getPayloadResult()).andReturn(new StringResult());
|
||||
WebServiceMessageFactory factoryMock = createMock(WebServiceMessageFactory.class);
|
||||
expect(factoryMock.createWebServiceMessage()).andReturn(responseMock);
|
||||
replay(requestMock, responseMock, factoryMock);
|
||||
|
||||
MessageContext messageContext = new DefaultMessageContext(requestMock, factoryMock);
|
||||
MethodEndpoint endpoint = new MethodEndpoint(this, "supportedSource", new Class[]{String.class});
|
||||
adapter.invoke(messageContext, endpoint);
|
||||
assertTrue("Method not invoked", supportedSourceInvoked);
|
||||
|
||||
verify(requestMock, responseMock, factoryMock);
|
||||
}
|
||||
|
||||
public void testInvokeVoidDom() throws Exception {
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
Document document = documentBuilder.newDocument();
|
||||
String rootNamespace = "http://rootnamespace";
|
||||
Element rootElement = document.createElementNS(rootNamespace, "root");
|
||||
document.appendChild(rootElement);
|
||||
String childNamespace = "http://childnamespace";
|
||||
Element first = document.createElementNS(childNamespace, "child");
|
||||
rootElement.appendChild(first);
|
||||
Text text = document.createTextNode("value");
|
||||
first.appendChild(text);
|
||||
Element second = document.createElementNS(rootNamespace, "other-child");
|
||||
rootElement.appendChild(second);
|
||||
text = document.createTextNode("other-value");
|
||||
second.appendChild(text);
|
||||
|
||||
WebServiceMessage requestMock = createMock(WebServiceMessage.class);
|
||||
expect(requestMock.getPayloadSource()).andReturn(new DOMSource(first));
|
||||
WebServiceMessageFactory factoryMock = createMock(WebServiceMessageFactory.class);
|
||||
|
||||
replay(requestMock, factoryMock);
|
||||
|
||||
Properties namespaces = new Properties();
|
||||
namespaces.setProperty("root", rootNamespace);
|
||||
namespaces.setProperty("child", childNamespace);
|
||||
adapter.setNamespaces(namespaces);
|
||||
|
||||
MessageContext messageContext = new DefaultMessageContext(requestMock, factoryMock);
|
||||
MethodEndpoint endpoint = new MethodEndpoint(this, "namespaces", new Class[]{Node.class});
|
||||
adapter.invoke(messageContext, endpoint);
|
||||
assertTrue("Method not invoked", namespacesInvoked);
|
||||
}
|
||||
|
||||
public void supportedVoid(@XPathParam("/")String param1) {
|
||||
}
|
||||
|
||||
public Source supportedSource(@XPathParam("/")String param1) {
|
||||
supportedSourceInvoked = true;
|
||||
return new StringSource("<response/>");
|
||||
}
|
||||
|
||||
public StringSource supportedStringSource(@XPathParam("/")String param1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void supportedTypes(@XPathParam("/root/child")boolean param1,
|
||||
@XPathParam("/root/child/number")double param2,
|
||||
@XPathParam("/root/child")Node param3,
|
||||
@XPathParam("/root/*")NodeList param4,
|
||||
@XPathParam("/root/child/text")String param5) {
|
||||
supportedTypesInvoked = true;
|
||||
assertTrue("Invalid boolean value", param1);
|
||||
assertEquals("Invalid double value", 42D, param2, 0.00001D);
|
||||
assertEquals("Invalid Node value", "child", param3.getLocalName());
|
||||
assertEquals("Invalid NodeList value", 1, param4.getLength());
|
||||
assertEquals("Invalid Node value", "child", param4.item(0).getLocalName());
|
||||
assertEquals("Invalid Node value", "text", param5);
|
||||
}
|
||||
|
||||
public void unsupportedInvalidParams(@XPathParam("/")String param1, String param2) {
|
||||
|
||||
}
|
||||
|
||||
public String unsupportedInvalidReturnType(@XPathParam("/")String param1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void unsupportedInvalidParamType(@XPathParam("/")int param1) {
|
||||
}
|
||||
|
||||
public void namespaces(@XPathParam(".")Node param) {
|
||||
namespacesInvoked = true;
|
||||
assertEquals("Invalid parameter", "child", param.getLocalName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.mapping;
|
||||
|
||||
public @interface Log {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.mapping;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
|
||||
@Aspect
|
||||
public class LogAspect {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(LogAspect.class);
|
||||
|
||||
private boolean logInvoked = false;
|
||||
|
||||
public boolean isLogInvoked() {
|
||||
return logInvoked;
|
||||
}
|
||||
|
||||
@Pointcut("@annotation(org.springframework.ws.server.endpoint.mapping.Log)")
|
||||
private void loggedMethod() {
|
||||
|
||||
}
|
||||
|
||||
@Around("loggedMethod()")
|
||||
public void log(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
logInvoked = true;
|
||||
logger.info("Before: " + joinPoint.getSignature());
|
||||
try {
|
||||
joinPoint.proceed();
|
||||
}
|
||||
finally {
|
||||
logger.info("After: " + joinPoint.getSignature());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.mapping;
|
||||
|
||||
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
|
||||
|
||||
class OtherBean {
|
||||
|
||||
@PayloadRoot(localPart = "Request2", namespace = "http://springframework.org/spring-ws")
|
||||
public void doIt() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.mapping;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.EndpointAdapter;
|
||||
import org.springframework.ws.server.MessageDispatcher;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.adapter.PayloadMethodEndpointAdapter;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessage;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
|
||||
import org.springframework.ws.soap.server.SoapMessageDispatcher;
|
||||
|
||||
public class PayloadRootAnnotationMethodEndpointMappingTest extends AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
private PayloadRootAnnotationMethodEndpointMapping mapping;
|
||||
|
||||
protected String getConfigPath() {
|
||||
return "applicationContext.xml";
|
||||
}
|
||||
|
||||
public void setMapping(PayloadRootAnnotationMethodEndpointMapping mapping) {
|
||||
this.mapping = mapping;
|
||||
}
|
||||
|
||||
public void testRegistration() throws NoSuchMethodException {
|
||||
MethodEndpoint endpoint = mapping.lookupEndpoint("{http://springframework.org/spring-ws}Request");
|
||||
assertNotNull("MethodEndpoint not registered", endpoint);
|
||||
Method doIt = PayloadRootEndpoint.class.getMethod("doIt", Source.class);
|
||||
MethodEndpoint expected = new MethodEndpoint("endpoint", applicationContext, doIt);
|
||||
assertEquals("Invalid endpoint registered", expected, endpoint);
|
||||
|
||||
assertNull("Invalid endpoint registered",
|
||||
mapping.lookupEndpoint("{http://springframework.org/spring-ws}Request2"));
|
||||
}
|
||||
|
||||
public void testInvoke() throws Exception {
|
||||
|
||||
MessageFactory messageFactory = MessageFactory.newInstance();
|
||||
SOAPMessage request = messageFactory.createMessage();
|
||||
request.getSOAPBody().addBodyElement(QName.valueOf("{http://springframework.org/spring-ws}Request"));
|
||||
MessageContext messageContext =
|
||||
new DefaultMessageContext(new SaajSoapMessage(request), new SaajSoapMessageFactory(messageFactory));
|
||||
EndpointAdapter adapter = new PayloadMethodEndpointAdapter();
|
||||
|
||||
MessageDispatcher messageDispatcher = new SoapMessageDispatcher();
|
||||
messageDispatcher.setApplicationContext(applicationContext);
|
||||
messageDispatcher.setEndpointMappings(Collections.singletonList(mapping));
|
||||
messageDispatcher.setEndpointAdapters(Collections.singletonList(adapter));
|
||||
|
||||
messageDispatcher.receive(messageContext);
|
||||
|
||||
PayloadRootEndpoint endpoint = (PayloadRootEndpoint) applicationContext.getBean("endpoint");
|
||||
assertTrue("doIt() not invoked on endpoint", endpoint.isDoItInvoked());
|
||||
|
||||
LogAspect aspect = (LogAspect) applicationContext.getBean("logAspect");
|
||||
assertTrue("log() not invoked on aspect", aspect.isLogInvoked());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.server.endpoint.mapping;
|
||||
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
|
||||
|
||||
@Endpoint
|
||||
public class PayloadRootEndpoint {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(PayloadRootEndpoint.class);
|
||||
|
||||
private boolean doItInvoked = false;
|
||||
|
||||
public boolean isDoItInvoked() {
|
||||
return doItInvoked;
|
||||
}
|
||||
|
||||
@PayloadRoot(localPart = "Request", namespace = "http://springframework.org/spring-ws")
|
||||
@org.springframework.ws.server.endpoint.mapping.Log
|
||||
public void doIt(Source payload) {
|
||||
doItInvoked = true;
|
||||
logger.info("In doIt()");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright ${YEAR} 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.addressing.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import javax.xml.soap.MimeHeaders;
|
||||
import javax.xml.soap.SOAPConstants;
|
||||
import javax.xml.soap.SOAPException;
|
||||
|
||||
import org.custommonkey.xmlunit.XMLTestCase;
|
||||
import org.custommonkey.xmlunit.XMLUnit;
|
||||
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.EndpointInvocationChain;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.soap.addressing.server.annotation.Action;
|
||||
import org.springframework.ws.soap.addressing.server.annotation.Address;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessage;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
|
||||
|
||||
public class AnnotationActionMethodEndpointMappingTest extends XMLTestCase {
|
||||
|
||||
private StaticApplicationContext applicationContext;
|
||||
|
||||
private AnnotationActionEndpointMapping mapping;
|
||||
|
||||
private MessageFactory messageFactory;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
|
||||
XMLUnit.setIgnoreWhitespace(true);
|
||||
applicationContext = new StaticApplicationContext();
|
||||
applicationContext.registerSingleton("mapping", AnnotationActionEndpointMapping.class);
|
||||
mapping = (AnnotationActionEndpointMapping) applicationContext.getBean("mapping");
|
||||
}
|
||||
|
||||
public void testNoAddress() throws Exception {
|
||||
applicationContext.registerSingleton("endpoint", Endpoint1.class);
|
||||
applicationContext.refresh();
|
||||
MessageContext messageContext = createMessageContext();
|
||||
|
||||
EndpointInvocationChain chain = mapping.getEndpoint(messageContext);
|
||||
assertNotNull("MethodEndpoint not registered", chain);
|
||||
MethodEndpoint expected = new MethodEndpoint(applicationContext.getBean("endpoint"), "doIt", new Class[0]);
|
||||
assertEquals("Invalid endpoint registered", expected, chain.getEndpoint());
|
||||
}
|
||||
|
||||
public void testAddress() throws Exception {
|
||||
applicationContext.registerSingleton("endpoint", Endpoint2.class);
|
||||
applicationContext.refresh();
|
||||
MessageContext messageContext = createMessageContext();
|
||||
|
||||
EndpointInvocationChain chain = mapping.getEndpoint(messageContext);
|
||||
assertNotNull("MethodEndpoint not registered", chain);
|
||||
MethodEndpoint expected = new MethodEndpoint(applicationContext.getBean("endpoint"), "doIt", new Class[0]);
|
||||
assertEquals("Invalid endpoint registered", expected, chain.getEndpoint());
|
||||
}
|
||||
|
||||
private MessageContext createMessageContext() throws SOAPException, IOException {
|
||||
MimeHeaders mimeHeaders = new MimeHeaders();
|
||||
mimeHeaders.addHeader("Content-Type", " application/soap+xml");
|
||||
InputStream is = getClass().getResourceAsStream("valid.xml");
|
||||
assertNotNull("Could not load valid.xml", is);
|
||||
try {
|
||||
SaajSoapMessage message = new SaajSoapMessage(messageFactory.createMessage(mimeHeaders, is));
|
||||
return new DefaultMessageContext(message, new SaajSoapMessageFactory(messageFactory));
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Endpoint
|
||||
private static class Endpoint1 {
|
||||
|
||||
@Action("http://fabrikam123.example/mail/Delete")
|
||||
public void doIt() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Endpoint
|
||||
@Address("mailto:joe@fabrikam123.example")
|
||||
private static class Endpoint2 {
|
||||
|
||||
@Action("http://fabrikam123.example/mail/Delete")
|
||||
public void doIt() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.server.endpoint;
|
||||
|
||||
import java.util.Locale;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import javax.xml.soap.SOAPConstants;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.SoapMessageFactory;
|
||||
import org.springframework.ws.soap.SoapVersion;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessage;
|
||||
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.FaultCode;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.SoapFault;
|
||||
import org.springframework.ws.soap.soap11.Soap11Fault;
|
||||
import org.springframework.ws.soap.soap12.Soap12Fault;
|
||||
|
||||
public class SoapFaultAnnotationExceptionResolverTest extends TestCase {
|
||||
|
||||
private SoapFaultAnnotationExceptionResolver resolver;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
resolver = new SoapFaultAnnotationExceptionResolver();
|
||||
}
|
||||
|
||||
public void testResolveExceptionClientSoap11() throws Exception {
|
||||
MessageFactory saajFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
|
||||
SoapMessageFactory factory = new SaajSoapMessageFactory(saajFactory);
|
||||
MessageContext context = new DefaultMessageContext(factory);
|
||||
|
||||
boolean result = resolver.resolveException(context, null, new MyClientException());
|
||||
assertTrue("resolveException returns false", result);
|
||||
assertTrue("Context has no response", context.hasResponse());
|
||||
SoapMessage response = (SoapMessage) context.getResponse();
|
||||
assertTrue("Resonse has no fault", response.getSoapBody().hasFault());
|
||||
Soap11Fault fault = (Soap11Fault) response.getSoapBody().getFault();
|
||||
assertEquals("Invalid fault code on fault", SoapVersion.SOAP_11.getClientOrSenderFaultName(),
|
||||
fault.getFaultCode());
|
||||
assertEquals("Invalid fault string on fault", "Client error", fault.getFaultStringOrReason());
|
||||
assertNull("Detail on fault", fault.getFaultDetail());
|
||||
}
|
||||
|
||||
public void testResolveExceptionSenderSoap12() throws Exception {
|
||||
MessageFactory saajFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
|
||||
SoapMessageFactory factory = new SaajSoapMessageFactory(saajFactory);
|
||||
MessageContext context = new DefaultMessageContext(factory);
|
||||
|
||||
boolean result = resolver.resolveException(context, null, new MySenderException());
|
||||
assertTrue("resolveException returns false", result);
|
||||
assertTrue("Context has no response", context.hasResponse());
|
||||
SoapMessage response = (SoapMessage) context.getResponse();
|
||||
assertTrue("Resonse has no fault", response.getSoapBody().hasFault());
|
||||
Soap12Fault fault = (Soap12Fault) response.getSoapBody().getFault();
|
||||
assertEquals("Invalid fault code on fault", SoapVersion.SOAP_12.getClientOrSenderFaultName(),
|
||||
fault.getFaultCode());
|
||||
assertEquals("Invalid fault string on fault", "Sender error", fault.getFaultReasonText(Locale.ENGLISH));
|
||||
assertNull("Detail on fault", fault.getFaultDetail());
|
||||
}
|
||||
|
||||
public void testResolveExceptionServerSoap11() throws Exception {
|
||||
MessageFactory saajFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
|
||||
SoapMessageFactory factory = new SaajSoapMessageFactory(saajFactory);
|
||||
MessageContext context = new DefaultMessageContext(factory);
|
||||
|
||||
boolean result = resolver.resolveException(context, null, new MyServerException());
|
||||
assertTrue("resolveException returns false", result);
|
||||
assertTrue("Context has no response", context.hasResponse());
|
||||
SoapMessage response = (SoapMessage) context.getResponse();
|
||||
assertTrue("Resonse has no fault", response.getSoapBody().hasFault());
|
||||
Soap11Fault fault = (Soap11Fault) response.getSoapBody().getFault();
|
||||
assertEquals("Invalid fault code on fault", SoapVersion.SOAP_11.getServerOrReceiverFaultName(),
|
||||
fault.getFaultCode());
|
||||
assertEquals("Invalid fault string on fault", "Server error", fault.getFaultStringOrReason());
|
||||
assertNull("Detail on fault", fault.getFaultDetail());
|
||||
}
|
||||
|
||||
public void testResolveExceptionReceiverSoap12() throws Exception {
|
||||
MessageFactory saajFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
|
||||
SOAPMessage message = saajFactory.createMessage();
|
||||
SoapMessageFactory factory = new SaajSoapMessageFactory(saajFactory);
|
||||
MessageContext context = new DefaultMessageContext(new SaajSoapMessage(message), factory);
|
||||
|
||||
boolean result = resolver.resolveException(context, null, new MyReceiverException());
|
||||
assertTrue("resolveException returns false", result);
|
||||
assertTrue("Context has no response", context.hasResponse());
|
||||
SoapMessage response = (SoapMessage) context.getResponse();
|
||||
assertTrue("Resonse has no fault", response.getSoapBody().hasFault());
|
||||
Soap12Fault fault = (Soap12Fault) response.getSoapBody().getFault();
|
||||
assertEquals("Invalid fault code on fault", SoapVersion.SOAP_12.getServerOrReceiverFaultName(),
|
||||
fault.getFaultCode());
|
||||
assertEquals("Invalid fault string on fault", "Receiver error", fault.getFaultReasonText(Locale.ENGLISH));
|
||||
assertNull("Detail on fault", fault.getFaultDetail());
|
||||
}
|
||||
|
||||
public void testResolveExceptionDefault() throws Exception {
|
||||
SoapFaultDefinition defaultFault = new SoapFaultDefinition();
|
||||
defaultFault.setFaultCode(SoapFaultDefinition.CLIENT);
|
||||
defaultFault.setFaultStringOrReason("faultstring");
|
||||
resolver.setDefaultFault(defaultFault);
|
||||
MessageFactory saajFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
|
||||
SoapMessageFactory factory = new SaajSoapMessageFactory(saajFactory);
|
||||
MessageContext context = new DefaultMessageContext(factory);
|
||||
|
||||
boolean result = resolver.resolveException(context, null, new NonAnnotatedException());
|
||||
assertTrue("resolveException returns false", result);
|
||||
assertTrue("Context has no response", context.hasResponse());
|
||||
SoapMessage response = (SoapMessage) context.getResponse();
|
||||
assertTrue("Resonse has no fault", response.getSoapBody().hasFault());
|
||||
Soap11Fault fault = (Soap11Fault) response.getSoapBody().getFault();
|
||||
assertEquals("Invalid fault code on fault", SoapVersion.SOAP_11.getClientOrSenderFaultName(),
|
||||
fault.getFaultCode());
|
||||
assertEquals("Invalid fault string on fault", "faultstring", fault.getFaultStringOrReason());
|
||||
assertNull("Detail on fault", fault.getFaultDetail());
|
||||
}
|
||||
|
||||
public void testResolveExceptionCustom() throws Exception {
|
||||
MessageFactory saajFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
|
||||
SoapMessageFactory factory = new SaajSoapMessageFactory(saajFactory);
|
||||
MessageContext context = new DefaultMessageContext(factory);
|
||||
|
||||
boolean result = resolver.resolveException(context, null, new MyCustomException());
|
||||
assertTrue("resolveException returns false", result);
|
||||
assertTrue("Context has no response", context.hasResponse());
|
||||
SoapMessage response = (SoapMessage) context.getResponse();
|
||||
assertTrue("Resonse has no fault", response.getSoapBody().hasFault());
|
||||
Soap11Fault fault = (Soap11Fault) response.getSoapBody().getFault();
|
||||
assertEquals("Invalid fault code on fault", new QName("http://springframework.org/spring-ws", "Fault"),
|
||||
fault.getFaultCode());
|
||||
assertEquals("Invalid fault string on fault", "MyCustomException thrown", fault.getFaultStringOrReason());
|
||||
assertEquals("Invalid fault locale on fault", new Locale("nl"), fault.getFaultStringLocale());
|
||||
}
|
||||
|
||||
public void testResolveExceptionInheritance() throws Exception {
|
||||
MessageFactory saajFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
|
||||
SoapMessageFactory factory = new SaajSoapMessageFactory(saajFactory);
|
||||
MessageContext context = new DefaultMessageContext(factory);
|
||||
|
||||
boolean result = resolver.resolveException(context, null, new MySubClientException());
|
||||
assertTrue("resolveException returns false", result);
|
||||
assertTrue("Context has no response", context.hasResponse());
|
||||
SoapMessage response = (SoapMessage) context.getResponse();
|
||||
assertTrue("Resonse has no fault", response.getSoapBody().hasFault());
|
||||
Soap11Fault fault = (Soap11Fault) response.getSoapBody().getFault();
|
||||
assertEquals("Invalid fault code on fault", SoapVersion.SOAP_11.getClientOrSenderFaultName(),
|
||||
fault.getFaultCode());
|
||||
assertEquals("Invalid fault string on fault", "Client error", fault.getFaultStringOrReason());
|
||||
assertNull("Detail on fault", fault.getFaultDetail());
|
||||
}
|
||||
|
||||
public void testResolveExceptionExceptionMessage() throws Exception {
|
||||
MessageFactory saajFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
|
||||
SoapMessageFactory factory = new SaajSoapMessageFactory(saajFactory);
|
||||
MessageContext context = new DefaultMessageContext(factory);
|
||||
|
||||
boolean result = resolver.resolveException(context, null, new NoStringOrReasonException("Exception message"));
|
||||
assertTrue("resolveException returns false", result);
|
||||
assertTrue("Context has no response", context.hasResponse());
|
||||
SoapMessage response = (SoapMessage) context.getResponse();
|
||||
assertTrue("Resonse has no fault", response.getSoapBody().hasFault());
|
||||
Soap11Fault fault = (Soap11Fault) response.getSoapBody().getFault();
|
||||
assertEquals("Invalid fault code on fault", SoapVersion.SOAP_11.getClientOrSenderFaultName(),
|
||||
fault.getFaultCode());
|
||||
assertEquals("Invalid fault string on fault", "Exception message", fault.getFaultStringOrReason());
|
||||
assertNull("Detail on fault", fault.getFaultDetail());
|
||||
}
|
||||
|
||||
@SoapFault(faultCode = FaultCode.CLIENT, faultStringOrReason = "Client error")
|
||||
public class MyClientException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
public class MySubClientException extends MyClientException {
|
||||
|
||||
}
|
||||
|
||||
@SoapFault(faultCode = FaultCode.CLIENT)
|
||||
public class NoStringOrReasonException extends Exception {
|
||||
|
||||
public NoStringOrReasonException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
@SoapFault(faultCode = FaultCode.SENDER, faultStringOrReason = "Sender error")
|
||||
public class MySenderException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
@SoapFault(faultCode = FaultCode.SERVER, faultStringOrReason = "Server error")
|
||||
public class MyServerException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
@SoapFault(faultCode = FaultCode.RECEIVER, faultStringOrReason = "Receiver error")
|
||||
public class MyReceiverException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
@SoapFault(faultCode = FaultCode.CUSTOM, customFaultCode = "{http://springframework.org/spring-ws}Fault",
|
||||
faultStringOrReason = "MyCustomException thrown", locale = "nl")
|
||||
public class MyCustomException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
public class NonAnnotatedException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.soap.server.endpoint.mapping;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import static org.easymock.EasyMock.*;
|
||||
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.EndpointInvocationChain;
|
||||
import org.springframework.ws.server.endpoint.MethodEndpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.SoapAction;
|
||||
|
||||
public class SoapActionAnnotationMethodEndpointMappingTest extends TestCase {
|
||||
|
||||
private SoapActionAnnotationMethodEndpointMapping mapping;
|
||||
|
||||
private StaticApplicationContext applicationContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
applicationContext = new StaticApplicationContext();
|
||||
applicationContext.registerSingleton("mapping", SoapActionAnnotationMethodEndpointMapping.class);
|
||||
applicationContext.registerSingleton("endpoint", MyEndpoint.class);
|
||||
applicationContext.refresh();
|
||||
mapping = (SoapActionAnnotationMethodEndpointMapping) applicationContext.getBean("mapping");
|
||||
}
|
||||
|
||||
public void testRegistration() throws Exception {
|
||||
SoapMessage requestMock = createMock(SoapMessage.class);
|
||||
expect(requestMock.getSoapAction()).andReturn("http://springframework.org/spring-ws/SoapAction");
|
||||
WebServiceMessageFactory factoryMock = createMock(WebServiceMessageFactory.class);
|
||||
replay(requestMock, factoryMock);
|
||||
|
||||
MessageContext context = new DefaultMessageContext(requestMock, factoryMock);
|
||||
EndpointInvocationChain chain = mapping.getEndpoint(context);
|
||||
assertNotNull("MethodEndpoint not registered", chain);
|
||||
Method doIt = MyEndpoint.class.getMethod("doIt", new Class[0]);
|
||||
MethodEndpoint expected = new MethodEndpoint("endpoint", applicationContext, doIt);
|
||||
assertEquals("Invalid endpoint registered", expected, chain.getEndpoint());
|
||||
|
||||
verify(requestMock, factoryMock);
|
||||
}
|
||||
|
||||
@Endpoint
|
||||
private static class MyEndpoint {
|
||||
|
||||
@SoapAction("http://springframework.org/spring-ws/SoapAction")
|
||||
public void doIt() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:sws="http://www.springframework.org/schema/web-services" xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-1.5.xsd">
|
||||
|
||||
<sws:marshalling-endpoints/>
|
||||
|
||||
<bean id="marshaller" class="org.springframework.ws.config.DummyMarshaller"/>
|
||||
|
||||
<sws:xpath-endpoints>
|
||||
<sws:namespace prefix="sws" uri="http://www.springframework.org/spring-ws"/>
|
||||
</sws:xpath-endpoints>
|
||||
|
||||
</beans>
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
|
||||
<bean id="mapping"
|
||||
class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"/>
|
||||
|
||||
<bean id="endpoint" class="org.springframework.ws.server.endpoint.mapping.PayloadRootEndpoint"/>
|
||||
|
||||
<bean id="other" class="org.springframework.ws.server.endpoint.mapping.OtherBean"/>
|
||||
|
||||
<bean id="logAspect" class="org.springframework.ws.server.endpoint.mapping.LogAspect"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,17 @@
|
||||
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||
xmlns:f123="http://www.fabrikam123.example/svc53">
|
||||
<S:Header>
|
||||
<wsa:MessageID>uuid:aaaabbbb-cccc-dddd-eeee-ffffffffffff</wsa:MessageID>
|
||||
<wsa:ReplyTo>
|
||||
<wsa:Address>http://example.com/business/client1</wsa:Address>
|
||||
</wsa:ReplyTo>
|
||||
<wsa:To S:mustUnderstand="true">mailto:joe@fabrikam123.example</wsa:To>
|
||||
<wsa:Action>http://fabrikam123.example/mail/Delete</wsa:Action>
|
||||
</S:Header>
|
||||
<S:Body>
|
||||
<f123:Delete>
|
||||
<maxCount>42</maxCount>
|
||||
</f123:Delete>
|
||||
</S:Body>
|
||||
</S:Envelope>
|
||||
Reference in New Issue
Block a user