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.soap.server.endpoint.adapter.method;
18  
19  import java.lang.reflect.ParameterizedType;
20  import java.lang.reflect.Type;
21  import java.util.ArrayList;
22  import java.util.Iterator;
23  import java.util.List;
24  import javax.xml.namespace.QName;
25  
26  import org.springframework.core.MethodParameter;
27  import org.springframework.util.Assert;
28  import org.springframework.ws.context.MessageContext;
29  import org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver;
30  import org.springframework.ws.soap.SoapHeaderElement;
31  import org.springframework.ws.soap.SoapMessage;
32  import org.springframework.ws.soap.server.endpoint.annotation.SoapHeader;
33  import org.springframework.xml.namespace.QNameUtils;
34  
35  /**
36   * Implementation of {@link MethodArgumentResolver} that supports resolving {@link SoapHeaderElement} parameters. Target
37   * method parameters must be annotated with {@link SoapHeader} to indicate the SOAP header to resolve. This resolver
38   * supports simple {@link SoapHeaderElement} parameters and {@link List} parameters for elements that appear multiple
39   * times in the same SOAP header. </p> The following snippet shows an example of supported declarations.
40   * <pre>
41   * {@code
42   * public void soapHeaderElement(@SoapHeader("{http://springframework.org/ws}header") SoapHeaderElement element)
43   * <p/>
44   * public void soapHeaderElementList(@SoapHeader("{http://springframework.org/ws}header") List<SoapHeaderElement>
45   * elements)
46   * </pre>
47   *
48   * @author Tareq Abedrabbo
49   * @author Arjen Poutsma
50   * @see SoapHeader
51   * @since 2.0
52   */
53  public class SoapHeaderElementMethodArgumentResolver implements MethodArgumentResolver {
54  
55      public boolean supportsParameter(MethodParameter parameter) {
56          SoapHeader soapHeader = parameter.getParameterAnnotation(SoapHeader.class);
57          if (soapHeader == null) {
58              return false;
59          }
60  
61          Class<?> parameterType = parameter.getParameterType();
62  
63          // Simple SoapHeaderElement parameter
64          if (SoapHeaderElement.class.equals(parameterType)) {
65              return true;
66          }
67  
68          // List<SoapHeaderElement> parameter
69          if (List.class.equals(parameterType)) {
70              Type genericType = parameter.getGenericParameterType();
71              if (genericType instanceof ParameterizedType) {
72                  ParameterizedType parameterizedType = (ParameterizedType) genericType;
73                  Type[] typeArguments = parameterizedType.getActualTypeArguments();
74                  if (typeArguments.length == 1 && SoapHeaderElement.class.equals(typeArguments[0])) {
75                      return true;
76                  }
77              }
78          }
79          return false;
80      }
81  
82      public Object resolveArgument(MessageContext messageContext, MethodParameter parameter) throws Exception {
83          Assert.isInstanceOf(SoapMessage.class, messageContext.getRequest());
84          SoapMessage request = (SoapMessage) messageContext.getRequest();
85          org.springframework.ws.soap.SoapHeader soapHeader = request.getSoapHeader();
86  
87          String paramValue = parameter.getParameterAnnotation(SoapHeader.class).value();
88  
89          Assert.isTrue(QNameUtils.validateQName(paramValue), "Invalid header qualified name [" + paramValue + "]. " +
90                  "QName must be of the form '{namespace}localPart'.");
91  
92          QName qname = QName.valueOf(paramValue);
93  
94          Class<?> parameterType = parameter.getParameterType();
95  
96          if (SoapHeaderElement.class.equals(parameterType)) {
97              return extractSoapHeader(qname, soapHeader);
98          }
99          else if (List.class.equals(parameterType)) {
100             return extractSoapHeaderList(qname, soapHeader);
101         }
102         // should not happen
103         throw new UnsupportedOperationException();
104     }
105 
106     private SoapHeaderElement extractSoapHeader(QName qname, org.springframework.ws.soap.SoapHeader soapHeader) {
107         Iterator<SoapHeaderElement> elements = soapHeader.examineAllHeaderElements();
108         while (elements.hasNext()) {
109             SoapHeaderElement e = elements.next();
110             if (e.getName().equals(qname)) {
111                 return e;
112             }
113         }
114         return null;
115     }
116 
117     private List<SoapHeaderElement> extractSoapHeaderList(QName qname,
118                                                           org.springframework.ws.soap.SoapHeader soapHeader) {
119         List<SoapHeaderElement> result = new ArrayList<SoapHeaderElement>();
120         Iterator<SoapHeaderElement> elements = soapHeader.examineAllHeaderElements();
121         while (elements.hasNext()) {
122             SoapHeaderElement e = elements.next();
123             if (e.getName().equals(qname)) {
124                 result.add(e);
125             }
126         }
127         return result;
128     }
129 }