View Javadoc

1   /*
2    * Copyright 2005-2010 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.ws.server.endpoint.mapping.jaxb;
18  
19  import java.lang.reflect.Method;
20  import javax.xml.bind.JAXBContext;
21  import javax.xml.bind.JAXBException;
22  import javax.xml.bind.JAXBIntrospector;
23  import javax.xml.bind.annotation.XmlRootElement;
24  import javax.xml.namespace.QName;
25  
26  import org.springframework.core.MethodParameter;
27  import org.springframework.ws.context.MessageContext;
28  import org.springframework.ws.server.endpoint.mapping.AbstractAnnotationMethodEndpointMapping;
29  import org.springframework.ws.server.endpoint.support.PayloadRootUtils;
30  import org.springframework.xml.transform.TransformerHelper;
31  
32  /**
33   * Implementation of the {@link org.springframework.ws.server.EndpointMapping EndpointMapping} interface that uses the
34   * JAXB2 {@link XmlRootElement} annotation to map methods to request payload root elements.
35   * <p/>
36   * Endpoints typically have the following form:
37   * <pre>
38   * &#64;Endpoint
39   * public class MyEndpoint{
40   *    public void doSomethingWithRequest(&#64;RequestBody MyRootElement rootElement) {
41   *       ...
42   *    }
43   * }
44   * </pre>
45   * where MyRootElement is annotated with {@code @XmlRootElement}:
46   * <pre>
47   * &#64;XmlRootElement(name = "myRoot", namespace = "http://springframework.org/spring-ws")
48   * public class MyRootElement {
49   *   ...
50   * }
51   * </pre>
52   *
53   * @author Arjen Poutsma
54   * @since 2.0
55   */
56  public class XmlRootElementEndpointMapping extends AbstractAnnotationMethodEndpointMapping<QName> {
57  
58      private TransformerHelper transformerHelper = new TransformerHelper();
59  
60      public void setTransformerHelper(TransformerHelper transformerHelper) {
61          this.transformerHelper = transformerHelper;
62      }
63  
64      @Override
65      protected QName getLookupKeyForMethod(Method method) {
66          Class<?>[] parameterTypes = method.getParameterTypes();
67          for (int i = 0; i < parameterTypes.length; i++) {
68              MethodParameter methodParameter = new MethodParameter(method, i);
69              Class<?> parameterType = methodParameter.getParameterType();
70              if (parameterType.isAnnotationPresent(XmlRootElement.class)) {
71                  QName result = handleRootElement(parameterType);
72                  if (result != null) {
73                      return result;
74                  }
75              }
76  
77          }
78          return null;
79      }
80  
81      private QName handleRootElement(Class<?> parameterType) {
82          try {
83              Object param = parameterType.newInstance();
84              QName result = getElementName(parameterType, param);
85              if (result != null) {
86                  return result;
87              }
88          }
89          catch (InstantiationException e) {
90              // ignore
91          }
92          catch (IllegalAccessException ex) {
93              // ignore
94          }
95          return null;
96      }
97  
98      private QName getElementName(Class<?> parameterType, Object param) {
99          try {
100             JAXBContext context = JAXBContext.newInstance(parameterType);
101             JAXBIntrospector introspector = context.createJAXBIntrospector();
102             return introspector.getElementName(param);
103         }
104         catch (JAXBException ex) {
105             return null;
106         }
107     }
108 
109     @Override
110     protected QName getLookupKeyForMessage(MessageContext messageContext) throws Exception {
111         return PayloadRootUtils.getPayloadRootQName(messageContext.getRequest().getPayloadSource(), transformerHelper);
112     }
113 }