View Javadoc

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