001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.axis2; 019 020 import java.io.IOException; 021 import java.io.InputStream; 022 import java.net.MalformedURLException; 023 import java.net.URL; 024 import java.util.HashMap; 025 import java.util.Iterator; 026 import java.util.List; 027 028 import javax.wsdl.Binding; 029 import javax.wsdl.Definition; 030 import javax.wsdl.Port; 031 import javax.wsdl.Service; 032 import javax.wsdl.WSDLException; 033 import javax.wsdl.extensions.http.HTTPBinding; 034 import javax.wsdl.extensions.soap.SOAPBinding; 035 import javax.wsdl.extensions.soap12.SOAP12Binding; 036 import javax.wsdl.factory.WSDLFactory; 037 import javax.wsdl.xml.WSDLReader; 038 import javax.xml.namespace.QName; 039 import javax.xml.ws.WebServiceException; 040 041 import org.apache.axis2.Constants; 042 import org.apache.axis2.description.AxisOperation; 043 import org.apache.axis2.description.AxisService; 044 import org.apache.axis2.description.Parameter; 045 import org.apache.axis2.description.java2wsdl.Java2WSDLConstants; 046 import org.apache.axis2.engine.MessageReceiver; 047 import org.apache.axis2.jaxws.description.DescriptionFactory; 048 import org.apache.axis2.jaxws.description.EndpointDescription; 049 import org.apache.axis2.jaxws.description.ServiceDescription; 050 import org.apache.axis2.jaxws.description.builder.BindingTypeAnnot; 051 import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite; 052 import org.apache.axis2.jaxws.description.builder.MethodDescriptionComposite; 053 import org.apache.axis2.jaxws.description.builder.WebServiceAnnot; 054 import org.apache.axis2.jaxws.description.builder.WebServiceProviderAnnot; 055 import org.apache.axis2.jaxws.description.builder.WsdlComposite; 056 import org.apache.axis2.jaxws.description.builder.WsdlGenerator; 057 import org.apache.axis2.jaxws.description.builder.converter.JavaClassToDBCConverter; 058 import org.apache.axis2.jaxws.server.JAXWSMessageReceiver; 059 import org.apache.axis2.wsdl.WSDLUtil; 060 import org.apache.commons.logging.Log; 061 import org.apache.commons.logging.LogFactory; 062 import org.apache.geronimo.axis2.util.SimpleWSDLLocator; 063 import org.apache.geronimo.jaxws.JAXWSUtils; 064 import org.apache.geronimo.jaxws.PortInfo; 065 import org.apache.ws.commons.schema.utils.NamespaceMap; 066 067 /** 068 * @version $Rev$ $Date$ 069 */ 070 public class AxisServiceGenerator { 071 private static final Log log = LogFactory.getLog(AxisServiceGenerator.class); 072 073 private MessageReceiver messageReceiver; 074 075 public AxisServiceGenerator(){ 076 this.messageReceiver = new JAXWSMessageReceiver(); 077 } 078 079 public void setMessageReceiver(MessageReceiver messageReceiver) { 080 this.messageReceiver = messageReceiver; 081 } 082 083 public AxisService getServiceFromClass(Class endpointClass) throws Exception { 084 ServiceDescription serviceDescription = 085 DescriptionFactory.createServiceDescription(endpointClass); 086 EndpointDescription[] edArray = serviceDescription.getEndpointDescriptions(); 087 AxisService service = edArray[0].getAxisService(); 088 089 if (service.getNameSpacesMap() == null) { 090 NamespaceMap map = new NamespaceMap(); 091 map.put(Java2WSDLConstants.AXIS2_NAMESPACE_PREFIX, 092 Java2WSDLConstants.AXIS2_XSD); 093 map.put(Java2WSDLConstants.DEFAULT_SCHEMA_NAMESPACE_PREFIX, 094 Java2WSDLConstants.URI_2001_SCHEMA_XSD); 095 service.setNameSpacesMap(map); 096 } 097 098 String endpointClassName = endpointClass.getName(); 099 ClassLoader classLoader = endpointClass.getClassLoader(); 100 101 service.addParameter(new Parameter(Constants.SERVICE_CLASS, endpointClassName)); 102 service.setClassLoader(classLoader); 103 104 for(Iterator<AxisOperation> opIterator = service.getOperations() ; opIterator.hasNext() ;){ 105 AxisOperation operation = opIterator.next(); 106 operation.setMessageReceiver(this.messageReceiver); 107 } 108 109 Parameter serviceDescriptionParam = 110 new Parameter(EndpointDescription.AXIS_SERVICE_PARAMETER, edArray[0]); 111 service.addParameter(serviceDescriptionParam); 112 113 return service; 114 } 115 116 public AxisService getServiceFromWSDL(PortInfo portInfo, Class endpointClass, URL configurationBaseUrl) throws Exception { 117 String wsdlFile = portInfo.getWsdlFile(); 118 if (wsdlFile == null || wsdlFile.equals("")) { 119 throw new Exception("WSDL file is required."); 120 } 121 122 String endpointClassName = endpointClass.getName(); 123 ClassLoader classLoader = endpointClass.getClassLoader(); 124 125 QName serviceQName = portInfo.getWsdlService(); 126 if (serviceQName == null) { 127 serviceQName = JAXWSUtils.getServiceQName(endpointClass); 128 } 129 130 QName portQName = portInfo.getWsdlPort(); 131 if (portQName == null) { 132 portQName = JAXWSUtils.getPortQName(endpointClass); 133 } 134 135 Definition wsdlDefinition = readWSDL(wsdlFile, configurationBaseUrl, classLoader); 136 137 Service wsdlService = wsdlDefinition.getService(serviceQName); 138 if (wsdlService == null) { 139 throw new Exception("Service '" + serviceQName + "' not found in WSDL"); 140 } 141 142 Port port = wsdlService.getPort(portQName.getLocalPart()); 143 if (port == null) { 144 throw new Exception("Port '" + portQName.getLocalPart() + "' not found in WSDL"); 145 } 146 147 Binding binding = port.getBinding(); 148 List extElements = binding.getExtensibilityElements(); 149 Iterator extElementsIterator =extElements.iterator(); 150 String bindingS = javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING; //this is the default. 151 while (extElementsIterator.hasNext()) { 152 Object o = extElementsIterator.next(); 153 if (o instanceof SOAPBinding) { 154 SOAPBinding sp = (SOAPBinding)o; 155 if (sp.getElementType().getNamespaceURI().equals("http://schemas.xmlsoap.org/wsdl/soap/")) { 156 //todo: how to we tell if it is MTOM or not. 157 bindingS = javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING; 158 } 159 } else if (o instanceof SOAP12Binding) { 160 SOAP12Binding sp = (SOAP12Binding)o; 161 if (sp.getElementType().getNamespaceURI().equals("http://schemas.xmlsoap.org/wsdl/soap12/")) { 162 //todo: how to we tell if it is MTOM or not. 163 bindingS = javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING; 164 } 165 } else if (o instanceof HTTPBinding) { 166 HTTPBinding sp = (HTTPBinding)o; 167 if (sp.getElementType().getNamespaceURI().equals("http://www.w3.org/2004/08/wsdl/http")) { 168 bindingS = javax.xml.ws.http.HTTPBinding.HTTP_BINDING; 169 } 170 } 171 } 172 173 Class endPointClass = classLoader.loadClass(endpointClassName); 174 JavaClassToDBCConverter converter = new JavaClassToDBCConverter(endPointClass); 175 HashMap<String, DescriptionBuilderComposite> dbcMap = converter.produceDBC(); 176 177 DescriptionBuilderComposite dbc = dbcMap.get(endpointClassName); 178 dbc.setClassLoader(classLoader); 179 dbc.setWsdlDefinition(wsdlDefinition); 180 dbc.setClassName(endpointClassName); 181 dbc.setCustomWsdlGenerator(new WSDLGeneratorImpl(wsdlDefinition)); 182 183 if (dbc.getWebServiceAnnot() != null) { //information specified in .wsdl should overwrite annotation. 184 WebServiceAnnot serviceAnnot = dbc.getWebServiceAnnot(); 185 serviceAnnot.setPortName(portQName.getLocalPart()); 186 serviceAnnot.setServiceName(serviceQName.getLocalPart()); 187 serviceAnnot.setTargetNamespace(serviceQName.getNamespaceURI()); 188 if (dbc.getBindingTypeAnnot() !=null && bindingS != null && !bindingS.equals("")) { 189 BindingTypeAnnot bindingAnnot = dbc.getBindingTypeAnnot(); 190 bindingAnnot.setValue(bindingS); 191 } 192 } else if (dbc.getWebServiceProviderAnnot() != null) { 193 WebServiceProviderAnnot serviceProviderAnnot = dbc.getWebServiceProviderAnnot(); 194 serviceProviderAnnot.setPortName(portQName.getLocalPart()); 195 serviceProviderAnnot.setServiceName(serviceQName.getLocalPart()); 196 serviceProviderAnnot.setTargetNamespace(serviceQName.getNamespaceURI()); 197 if (dbc.getBindingTypeAnnot() !=null && bindingS != null && !bindingS.equals("")) { 198 BindingTypeAnnot bindingAnnot = dbc.getBindingTypeAnnot(); 199 bindingAnnot.setValue(bindingS); 200 } 201 } 202 203 AxisService service = getService(dbcMap); 204 205 service.setName(serviceQName.getLocalPart()); 206 service.setEndpointName(portQName.getLocalPart()); 207 208 for(Iterator<AxisOperation> opIterator = service.getOperations() ; opIterator.hasNext() ;){ 209 AxisOperation operation = opIterator.next(); 210 operation.setMessageReceiver(this.messageReceiver); 211 String MEP = operation.getMessageExchangePattern(); 212 if (!WSDLUtil.isOutputPresentForMEP(MEP)) { 213 List<MethodDescriptionComposite> mdcList = dbc.getMethodDescriptionComposite(operation.getName().toString()); 214 for(Iterator<MethodDescriptionComposite> mIterator = mdcList.iterator(); mIterator.hasNext();){ 215 MethodDescriptionComposite mdc = mIterator.next(); 216 //TODO: JAXWS spec says need to check Holder param exist before taking a method as OneWay 217 mdc.setOneWayAnnot(true); 218 } 219 } 220 } 221 222 return service; 223 } 224 225 private AxisService getService(HashMap<String, DescriptionBuilderComposite> dbcMap) { 226 return getEndpointDescription(dbcMap).getAxisService(); 227 } 228 229 private EndpointDescription getEndpointDescription(HashMap<String, DescriptionBuilderComposite> dbcMap) { 230 List<ServiceDescription> serviceDescList = DescriptionFactory.createServiceDescriptionFromDBCMap(dbcMap); 231 if (serviceDescList == null || serviceDescList.isEmpty()) { 232 throw new RuntimeException("No service"); 233 } 234 ServiceDescription serviceDescription = serviceDescList.get(0); 235 EndpointDescription[] edArray = serviceDescription.getEndpointDescriptions(); 236 if (edArray == null || edArray.length == 0) { 237 throw new RuntimeException("No endpoint"); 238 } 239 return edArray[0]; 240 } 241 242 private class WSDLGeneratorImpl implements WsdlGenerator { 243 private Definition def; 244 245 public WSDLGeneratorImpl(Definition def) { 246 this.def = def; 247 } 248 249 public WsdlComposite generateWsdl(String implClass, String bindingType) throws WebServiceException { 250 // Need WSDL generation code 251 WsdlComposite composite = new WsdlComposite(); 252 composite.setWsdlFileName(implClass); 253 HashMap<String, Definition> testMap = new HashMap<String, Definition>(); 254 testMap.put(composite.getWsdlFileName(), def); 255 composite.setWsdlDefinition(testMap); 256 return composite; 257 } 258 } 259 260 protected Definition readWSDL(String wsdlLocation, 261 URL configurationBaseUrl, 262 ClassLoader classLoader) 263 throws IOException, WSDLException { 264 Definition wsdlDefinition = null; 265 URL wsdlURL = getWsdlURL(wsdlLocation, configurationBaseUrl, classLoader); 266 InputStream wsdlStream = null; 267 try { 268 wsdlStream = wsdlURL.openStream(); 269 WSDLFactory factory = WSDLFactory.newInstance(); 270 WSDLReader reader = factory.newWSDLReader(); 271 reader.setFeature("javax.wsdl.importDocuments", true); 272 reader.setFeature("javax.wsdl.verbose", false); 273 SimpleWSDLLocator wsdlLocator = new SimpleWSDLLocator(wsdlURL.toString()); 274 wsdlDefinition = reader.readWSDL(wsdlLocator); 275 } finally { 276 if (wsdlStream != null) { 277 wsdlStream.close(); 278 } 279 } 280 return wsdlDefinition; 281 } 282 283 public static URL getWsdlURL(String wsdlFile, URL configurationBaseUrl, ClassLoader classLoader) { 284 URL wsdlURL = null; 285 if (wsdlFile != null) { 286 try { 287 wsdlURL = new URL(wsdlFile); 288 } catch (MalformedURLException e) { 289 // Not a URL, try as a resource 290 wsdlURL = classLoader.getResource(wsdlFile); 291 292 if (wsdlURL == null && configurationBaseUrl != null) { 293 // Cannot get it as a resource, try with 294 // configurationBaseUrl 295 try { 296 wsdlURL = new URL(configurationBaseUrl, wsdlFile); 297 } catch (MalformedURLException ee) { 298 // ignore 299 } 300 } 301 } 302 } 303 return wsdlURL; 304 } 305 306 public static EndpointDescription getEndpointDescription(AxisService service) { 307 Parameter param = service.getParameter(EndpointDescription.AXIS_SERVICE_PARAMETER); 308 return (param == null) ? null : (EndpointDescription) param.getValue(); 309 } 310 311 }