1 /*
2 Copyright (c) 2006, University of Tromsø
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice, this list
9 of conditions and the following disclaimer.
10
11 * Redistributions in binary form must reproduce the above copyright notice, this
12 list of conditions and the following disclaimer in the documentation and/or other
13 materials provided with the distribution.
14
15 * Neither the name of the University of Tromsø nor the names of its contributors may
16 be used to endorse or promote products derived from this software without specific
17 prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
22 SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
28 DAMAGE.
29 */
30
31 package axis.dynamic;
32
33 import java.util.Arrays;
34 import java.util.Map.Entry;
35
36 import org.apache.axis.AxisFault;
37 import org.apache.axis.constants.Style;
38 import org.apache.axis.constants.Use;
39 import org.apache.axis.deployment.wsdd.WSDDService;
40 import org.apache.axis.description.JavaServiceDesc;
41 import org.apache.axis.description.ServiceDesc;
42 import org.apache.axis.handlers.soap.SOAPService;
43 import org.apache.axis.providers.BasicProvider;
44
45
46 /**
47 * Publishes a bean as a web service.
48 */
49 public class SoapReceiver
50 extends SoapInterface {
51 /** the bean that actually implements the service. */
52 private Object _target;
53
54 /** the service description (name, style, etc.) */
55 private final ServiceDesc _service = new JavaServiceDesc();
56
57 /** the axis engine configuration. */
58 private SoapServerConfiguration _configuration;
59
60 /**
61 * @param target bean that actually implements the web service.
62 */
63 public void setTarget( Object target )
64 {
65 _target = target;
66 }
67
68 /**
69 * used as default service name. may be overridden by setting the serviceName property.
70 * @param name
71 * @see BeanNameAware#setBeanName(String)
72 */
73 public void setBeanName( String name )
74 {
75 if (_service.getName() == null) _service.setName(name);
76 }
77
78 /**
79 * service name. if not set, bean name is used. if that is also not set, {@link #deploy()}
80 * will throw an {@link IllegalArgumentException}.
81 * @param name
82 * @see BeanNameAware#setBeanName(String)
83 */
84 public void setServiceName( String name )
85 {
86 _service.setName(name);
87 }
88
89 /**
90 * Java methods to be published as web service operations. If not set, all methods will be used.
91 * I'm not sure if that includes {@link #toString()} etc. See Axis documentation.
92 * @param methods Java methods to be published as web service operations.
93 */
94 public void setAllowedMethods( String[] methods )
95 {
96 _service.setAllowedMethods(Arrays.asList(methods));
97 }
98
99 /**
100 * if not set, defaults to {@link Style#RPC}.
101 * @param style
102 * @see SoapInterface#setStyle(Style)
103 * @see JavaServiceDesc#setStyle(Style)
104 */
105 @Override
106 public void setStyle( Style style )
107 {
108 _service.setStyle(style);
109 }
110
111 /**
112 * if not set, defaults to {@link Use#ENCODED}.
113 * @param use
114 * @see SoapInterface#setUse(Use)
115 * @see JavaServiceDesc#setUse(Use)
116 */
117 @Override
118 public void setUse( Use use )
119 {
120 _service.setUse(use);
121 }
122
123 /**
124 * @param configuration
125 */
126 public void setServerConfiguration( SoapServerConfiguration configuration )
127 {
128 _configuration = configuration;
129 }
130
131 /**
132 * calls {@link #deploy()}
133 * should only be called once for each configured SoapReceiver.
134 * @throws AxisFault if service cannot be created
135 * @see InitializingBean#afterPropertiesSet()
136 */
137 public void afterPropertiesSet() throws AxisFault
138 {
139 deploy();
140 }
141
142 /**
143 * should only be called once for each configured SoapReceiver.
144 * @throws AxisFault if service cannot be created
145 */
146 public void deploy() throws AxisFault
147 {
148 if (_service.getName() == null) throw new IllegalStateException("name not set");
149 if (_configuration == null) throw new IllegalStateException("configuration not set");
150 _configuration.deployService(_service.getName(), createService());
151 }
152
153 /**
154 * calls {@link #undeploy()}
155 * @see DisposableBean#destroy()
156 */
157 public void destroy()
158 {
159 undeploy();
160 }
161
162 /**
163 *
164 */
165 public void undeploy()
166 {
167 if (_service.getName() == null) throw new IllegalStateException("name not set");
168 if (_configuration == null) throw new IllegalStateException("registry not set");
169 _configuration.undeployService(_service.getName());
170 }
171
172 /**
173 * @return a new soap service.
174 * @throws AxisFault if service description cannot be initialized
175 * @see WSDDService#makeNewInstance
176 */
177 public SOAPService createService() throws AxisFault
178 {
179 if (_service.getName() == null) throw new IllegalStateException("name not set");
180 if (_target == null) throw new IllegalStateException("target not set");
181
182 // note: request and/or response chain may be null
183 SOAPService service = new SOAPService(getRequestChain(), new ObjectRPCProvider(_target), getResponseChain());
184 service.setName(_service.getName());
185
186 // set the wsdl port type to the service name. otherwise, generated wsdl uses the class name for the port type,
187 // which is ugly for Cglib classes. I'm not sure though that this is the correct solution...
188 // see org.apache.axis.providers.BasicProvider.generateWSDL() and org.apache.axis.wsdl.fromJava.Emitter.init()
189 service.setOption(BasicProvider.OPTION_WSDL_PORTTYPE, _service.getName());
190
191 service.setServiceDescription(_service);
192 setProperties(service);
193
194 // If we don't do this now, something weird will happen: if the service's ?wsdl is generated *before*
195 // one of it's operations is invoked, the service won't have *any* operation at all. As long as it lives.
196 // But doing this now also may help to catch errors early and speed up the first invocation.
197 // Note: the MessageContext parameter can be null - this calls our ObjectRPCProvider in the end,
198 // which ignores the parameter. The usual JavaProvider could handle null as well.
199 service.getInitializedServiceDesc(null);
200
201 return service;
202 }
203
204 /**
205 * sets our properties into the given service.
206 * @param service
207 */
208 private void setProperties( SOAPService service )
209 {
210 for (Entry<String, Object> entry : _properties.entrySet())
211 {
212 service.setOption(entry.getKey(), entry.getValue());
213 }
214 }
215
216 }
217