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