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;
18  
19  import java.util.HashMap;
20  import java.util.Map;
21  import javax.xml.parsers.DocumentBuilder;
22  import javax.xml.parsers.DocumentBuilderFactory;
23  import javax.xml.transform.Source;
24  import javax.xml.transform.dom.DOMSource;
25  
26  import org.springframework.ws.WebServiceMessage;
27  import org.springframework.ws.WebServiceMessageFactory;
28  import org.springframework.ws.context.DefaultMessageContext;
29  import org.springframework.ws.context.MessageContext;
30  import org.springframework.ws.server.endpoint.MethodEndpoint;
31  import org.springframework.ws.server.endpoint.annotation.XPathParam;
32  import org.springframework.xml.transform.StringResult;
33  import org.springframework.xml.transform.StringSource;
34  
35  import org.junit.Assert;
36  import org.junit.Before;
37  import org.junit.Test;
38  import org.w3c.dom.Document;
39  import org.w3c.dom.Element;
40  import org.w3c.dom.Node;
41  import org.w3c.dom.NodeList;
42  import org.w3c.dom.Text;
43  
44  import static org.easymock.EasyMock.*;
45  
46  public class XPathParamAnnotationMethodEndpointAdapterTest {
47  
48      private static final String CONTENTS = "<root><child><text>text</text><number>42.0</number></child></root>";
49  
50      private XPathParamAnnotationMethodEndpointAdapter adapter;
51  
52      private boolean supportedTypesInvoked = false;
53  
54      private boolean supportedSourceInvoked;
55  
56      private boolean namespacesInvoked;
57  
58      @Before
59      public void setUp() throws Exception {
60          adapter = new XPathParamAnnotationMethodEndpointAdapter();
61          adapter.afterPropertiesSet();
62      }
63  
64      @Test
65      public void testUnsupportedInvalidParam() throws NoSuchMethodException {
66          MethodEndpoint endpoint = new MethodEndpoint(this, "unsupportedInvalidParamType", new Class[]{Integer.TYPE});
67          Assert.assertFalse("Method supported", adapter.supports(endpoint));
68      }
69  
70      @Test
71      public void testUnsupportedInvalidReturnType() throws NoSuchMethodException {
72          MethodEndpoint endpoint = new MethodEndpoint(this, "unsupportedInvalidReturnType", new Class[]{String.class});
73          Assert.assertFalse("Method supported", adapter.supports(endpoint));
74      }
75  
76      @Test
77      public void testUnsupportedInvalidParams() throws NoSuchMethodException {
78          MethodEndpoint endpoint =
79                  new MethodEndpoint(this, "unsupportedInvalidParams", new Class[]{String.class, String.class});
80          Assert.assertFalse("Method supported", adapter.supports(endpoint));
81      }
82  
83      @Test
84      public void testSupportedTypes() throws NoSuchMethodException {
85          MethodEndpoint endpoint = new MethodEndpoint(this, "supportedTypes",
86                  new Class[]{Boolean.TYPE, Double.TYPE, Node.class, NodeList.class, String.class});
87          Assert.assertTrue("Not all types supported", adapter.supports(endpoint));
88      }
89  
90      @Test
91      public void testSupportsStringSource() throws NoSuchMethodException {
92          MethodEndpoint endpoint = new MethodEndpoint(this, "supportedStringSource", new Class[]{String.class});
93          Assert.assertTrue("StringSource method not supported", adapter.supports(endpoint));
94      }
95  
96      @Test
97      public void testSupportsSource() throws NoSuchMethodException {
98          MethodEndpoint endpoint = new MethodEndpoint(this, "supportedSource", new Class[]{String.class});
99          Assert.assertTrue("Source method not supported", adapter.supports(endpoint));
100     }
101 
102     @Test
103     public void testSupportsVoid() throws NoSuchMethodException {
104         MethodEndpoint endpoint = new MethodEndpoint(this, "supportedVoid", new Class[]{String.class});
105         Assert.assertTrue("void method not supported", adapter.supports(endpoint));
106     }
107 
108     @Test
109     public void testInvokeTypes() throws Exception {
110         WebServiceMessage messageMock = createMock(WebServiceMessage.class);
111         expect(messageMock.getPayloadSource()).andReturn(new StringSource(CONTENTS));
112         WebServiceMessageFactory factoryMock = createMock(WebServiceMessageFactory.class);
113         replay(messageMock, factoryMock);
114 
115         MessageContext messageContext = new DefaultMessageContext(messageMock, factoryMock);
116         MethodEndpoint endpoint = new MethodEndpoint(this, "supportedTypes",
117                 new Class[]{Boolean.TYPE, Double.TYPE, Node.class, NodeList.class, String.class});
118         adapter.invoke(messageContext, endpoint);
119         Assert.assertTrue("Method not invoked", supportedTypesInvoked);
120 
121         verify(messageMock, factoryMock);
122     }
123 
124     @Test
125     public void testInvokeSource() throws Exception {
126         WebServiceMessage requestMock = createMock(WebServiceMessage.class);
127         WebServiceMessage responseMock = createMock(WebServiceMessage.class);
128         expect(requestMock.getPayloadSource()).andReturn(new StringSource(CONTENTS));
129         expect(responseMock.getPayloadResult()).andReturn(new StringResult());
130         WebServiceMessageFactory factoryMock = createMock(WebServiceMessageFactory.class);
131         expect(factoryMock.createWebServiceMessage()).andReturn(responseMock);
132         replay(requestMock, responseMock, factoryMock);
133 
134         MessageContext messageContext = new DefaultMessageContext(requestMock, factoryMock);
135         MethodEndpoint endpoint = new MethodEndpoint(this, "supportedSource", new Class[]{String.class});
136         adapter.invoke(messageContext, endpoint);
137         Assert.assertTrue("Method not invoked", supportedSourceInvoked);
138 
139         verify(requestMock, responseMock, factoryMock);
140     }
141 
142     @Test
143     public void testInvokeVoidDom() throws Exception {
144         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
145         DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
146         Document document = documentBuilder.newDocument();
147         String rootNamespace = "http://rootnamespace";
148         Element rootElement = document.createElementNS(rootNamespace, "root");
149         document.appendChild(rootElement);
150         String childNamespace = "http://childnamespace";
151         Element first = document.createElementNS(childNamespace, "child");
152         rootElement.appendChild(first);
153         Text text = document.createTextNode("value");
154         first.appendChild(text);
155         Element second = document.createElementNS(rootNamespace, "other-child");
156         rootElement.appendChild(second);
157         text = document.createTextNode("other-value");
158         second.appendChild(text);
159 
160         WebServiceMessage requestMock = createMock(WebServiceMessage.class);
161         expect(requestMock.getPayloadSource()).andReturn(new DOMSource(first));
162         WebServiceMessageFactory factoryMock = createMock(WebServiceMessageFactory.class);
163 
164         replay(requestMock, factoryMock);
165 
166         Map<String, String> namespaces = new HashMap<String, String>();
167         namespaces.put("root", rootNamespace);
168         namespaces.put("child", childNamespace);
169         adapter.setNamespaces(namespaces);
170 
171         MessageContext messageContext = new DefaultMessageContext(requestMock, factoryMock);
172         MethodEndpoint endpoint = new MethodEndpoint(this, "namespaces", new Class[]{Node.class});
173         adapter.invoke(messageContext, endpoint);
174         Assert.assertTrue("Method not invoked", namespacesInvoked);
175     }
176 
177     public void supportedVoid(@XPathParam("/")String param1) {
178     }
179 
180     public Source supportedSource(@XPathParam("/")String param1) {
181         supportedSourceInvoked = true;
182         return new StringSource("<response/>");
183     }
184 
185     public StringSource supportedStringSource(@XPathParam("/")String param1) {
186         return null;
187     }
188 
189     public void supportedTypes(@XPathParam("/root/child")boolean param1,
190                                @XPathParam("/root/child/number")double param2,
191                                @XPathParam("/root/child")Node param3,
192                                @XPathParam("/root/*")NodeList param4,
193                                @XPathParam("/root/child/text")String param5) {
194         supportedTypesInvoked = true;
195         Assert.assertTrue("Invalid boolean value", param1);
196         Assert.assertEquals("Invalid double value", 42D, param2, 0.00001D);
197         Assert.assertEquals("Invalid Node value", "child", param3.getLocalName());
198         Assert.assertEquals("Invalid NodeList value", 1, param4.getLength());
199         Assert.assertEquals("Invalid Node value", "child", param4.item(0).getLocalName());
200         Assert.assertEquals("Invalid Node value", "text", param5);
201     }
202 
203     public void unsupportedInvalidParams(@XPathParam("/")String param1, String param2) {
204 
205     }
206 
207     public String unsupportedInvalidReturnType(@XPathParam("/")String param1) {
208         return null;
209     }
210 
211     public void unsupportedInvalidParamType(@XPathParam("/")int param1) {
212     }
213 
214     public void namespaces(@XPathParam(".")Node param) {
215         namespacesInvoked = true;
216         Assert.assertEquals("Invalid parameter", "child", param.getLocalName());
217     }
218 }