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.adapter.method.jaxb;
18  
19  import java.io.ByteArrayOutputStream;
20  import java.io.IOException;
21  import javax.xml.bind.JAXBElement;
22  import javax.xml.bind.JAXBException;
23  import javax.xml.bind.annotation.XmlElement;
24  import javax.xml.bind.annotation.XmlType;
25  import javax.xml.namespace.QName;
26  import javax.xml.transform.Transformer;
27  import javax.xml.transform.TransformerFactory;
28  
29  import org.springframework.core.MethodParameter;
30  import org.springframework.ws.MockWebServiceMessage;
31  import org.springframework.ws.MockWebServiceMessageFactory;
32  import org.springframework.ws.WebServiceMessage;
33  import org.springframework.ws.context.DefaultMessageContext;
34  import org.springframework.ws.context.MessageContext;
35  import org.springframework.ws.server.endpoint.annotation.RequestPayload;
36  import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
37  import org.springframework.ws.soap.axiom.AxiomSoapMessage;
38  import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
39  import org.springframework.xml.transform.StringResult;
40  
41  import org.junit.Before;
42  import org.junit.Test;
43  import org.xml.sax.SAXException;
44  
45  import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
46  import static org.junit.Assert.assertEquals;
47  import static org.junit.Assert.assertTrue;
48  
49  public class JaxbElementPayloadMethodProcessorTest {
50  
51      private JaxbElementPayloadMethodProcessor processor;
52  
53      private MethodParameter supportedParameter;
54  
55      private MethodParameter supportedReturnType;
56  
57      private MethodParameter stringReturnType;
58  
59      @Before
60      public void setUp() throws Exception {
61          processor = new JaxbElementPayloadMethodProcessor();
62          supportedParameter = new MethodParameter(getClass().getMethod("supported", JAXBElement.class), 0);
63          supportedReturnType = new MethodParameter(getClass().getMethod("supported", JAXBElement.class), -1);
64          stringReturnType = new MethodParameter(getClass().getMethod("string"), -1);
65      }
66  
67      @Test
68      public void supportsParameter() {
69          assertTrue("processor does not support @JAXBElement parameter",
70                  processor.supportsParameter(supportedParameter));
71      }
72  
73      @Test
74      public void supportsReturnType() {
75          assertTrue("processor does not support @JAXBElement return type",
76                  processor.supportsReturnType(supportedReturnType));
77      }
78  
79      @Test
80      public void resolveArgument() throws JAXBException {
81          WebServiceMessage request = new MockWebServiceMessage("<myType xmlns='http://springframework.org'><string>Foo</string></myType>");
82          MessageContext messageContext = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
83  
84          JAXBElement<?> result = processor.resolveArgument(messageContext, supportedParameter);
85          assertTrue("result not a MyType", result.getValue() instanceof MyType);
86          MyType type = (MyType) result.getValue();
87          assertEquals("invalid result", "Foo", type.getString());
88      }
89  
90      @Test
91      public void handleReturnValue() throws JAXBException, IOException, SAXException {
92          MessageContext messageContext = new DefaultMessageContext(new MockWebServiceMessageFactory());
93  
94          MyType type = new MyType();
95          type.setString("Foo");
96          JAXBElement<MyType> element = new JAXBElement<MyType>(new QName("http://springframework.org", "type"), MyType.class, type);
97          processor.handleReturnValue(messageContext, supportedReturnType, element);
98          assertTrue("context has no response", messageContext.hasResponse());
99          MockWebServiceMessage response = (MockWebServiceMessage) messageContext.getResponse();
100         assertXMLEqual("<type xmlns='http://springframework.org'><string>Foo</string></type>", response.getPayloadAsString());
101     }
102 
103     @Test
104     public void handleReturnValueString() throws JAXBException, IOException, SAXException {
105         MessageContext messageContext = new DefaultMessageContext(new MockWebServiceMessageFactory());
106 
107         String s = "Foo";
108         JAXBElement<String> element = new JAXBElement<String>(new QName("http://springframework.org", "string"), String.class, s);
109         processor.handleReturnValue(messageContext, stringReturnType, element);
110         assertTrue("context has no response", messageContext.hasResponse());
111         MockWebServiceMessage response = (MockWebServiceMessage) messageContext.getResponse();
112         assertXMLEqual("<string xmlns='http://springframework.org'>Foo</string>", response.getPayloadAsString());
113     }
114 
115     @Test
116     public void handleReturnValueAxiom() throws Exception {
117         AxiomSoapMessageFactory messageFactory = new AxiomSoapMessageFactory();
118         MessageContext messageContext = new DefaultMessageContext(messageFactory);
119 
120         MyType type = new MyType();
121         type.setString("Foo");
122         JAXBElement<MyType> element = new JAXBElement<MyType>(new QName("http://springframework.org", "type"), MyType.class, type);
123 
124         processor.handleReturnValue(messageContext, supportedReturnType, element);
125         assertTrue("context has no response", messageContext.hasResponse());
126         AxiomSoapMessage response = (AxiomSoapMessage) messageContext.getResponse();
127 
128         Transformer transformer = TransformerFactory.newInstance().newTransformer();
129         StringResult payloadResult = new StringResult();
130         transformer.transform(response.getPayloadSource(), payloadResult);
131 
132         assertXMLEqual("<type xmlns='http://springframework.org'><string>Foo</string></type>",
133                 payloadResult.toString());
134 
135         ByteArrayOutputStream bos = new ByteArrayOutputStream();
136         response.writeTo(bos);
137         String messageResult = bos.toString("UTF-8");
138 
139         assertXMLEqual("<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'><soapenv:Body>" +
140                 "<type xmlns='http://springframework.org'><string>Foo</string></type>" +
141                 "</soapenv:Body></soapenv:Envelope>", messageResult);
142 
143     }
144 
145 
146     @ResponsePayload
147     public JAXBElement<MyType> supported(@RequestPayload JAXBElement<MyType> element) {
148         return element;
149     }
150 
151     @ResponsePayload
152     public JAXBElement<String> string() {
153         return new JAXBElement<String>(new QName("string"), String.class, "Foo");
154     }
155 
156     @XmlType(name="myType", namespace = "http://springframework.org")
157     public static class MyType {
158 
159         private String string;
160 
161         @XmlElement(name = "string", namespace = "http://springframework.org")
162         public String getString() {
163             return string;
164         }
165 
166         public void setString(String string) {
167             this.string = string;
168         }
169     }
170 
171 }