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.DescriptionBuilderComposite;
051 import org.apache.axis2.jaxws.description.builder.MethodDescriptionComposite;
052 import org.apache.axis2.jaxws.description.builder.WebServiceAnnot;
053 import org.apache.axis2.jaxws.description.builder.WebServiceProviderAnnot;
054 import org.apache.axis2.jaxws.description.builder.WsdlComposite;
055 import org.apache.axis2.jaxws.description.builder.WsdlGenerator;
056 import org.apache.axis2.jaxws.description.builder.converter.JavaClassToDBCConverter;
057 import org.apache.axis2.jaxws.server.JAXWSMessageReceiver;
058 import org.apache.axis2.wsdl.WSDLUtil;
059 import org.apache.commons.logging.Log;
060 import org.apache.commons.logging.LogFactory;
061 import org.apache.geronimo.axis2.util.SimpleWSDLLocator;
062 import org.apache.geronimo.jaxws.JAXWSUtils;
063 import org.apache.geronimo.jaxws.PortInfo;
064 import org.apache.ws.commons.schema.utils.NamespaceMap;
065
066 /**
067 * @version $Rev$ $Date$
068 */
069 public class AxisServiceGenerator {
070 private static final Log log = LogFactory.getLog(AxisServiceGenerator.class);
071
072 private MessageReceiver messageReceiver;
073
074 public AxisServiceGenerator(){
075 this.messageReceiver = new JAXWSMessageReceiver();
076 }
077
078 public void setMessageReceiver(MessageReceiver messageReceiver) {
079 this.messageReceiver = messageReceiver;
080 }
081
082 public AxisService getServiceFromClass(Class endpointClass) throws Exception {
083 ServiceDescription serviceDescription =
084 DescriptionFactory.createServiceDescription(endpointClass);
085 EndpointDescription[] edArray = serviceDescription.getEndpointDescriptions();
086 AxisService service = edArray[0].getAxisService();
087
088 if (service.getNameSpacesMap() == null) {
089 NamespaceMap map = new NamespaceMap();
090 map.put(Java2WSDLConstants.AXIS2_NAMESPACE_PREFIX,
091 Java2WSDLConstants.AXIS2_XSD);
092 map.put(Java2WSDLConstants.DEFAULT_SCHEMA_NAMESPACE_PREFIX,
093 Java2WSDLConstants.URI_2001_SCHEMA_XSD);
094 service.setNameSpacesMap(map);
095 }
096
097 String endpointClassName = endpointClass.getName();
098 ClassLoader classLoader = endpointClass.getClassLoader();
099
100 service.addParameter(new Parameter(Constants.SERVICE_CLASS, endpointClassName));
101 service.setClassLoader(classLoader);
102
103 for(Iterator<AxisOperation> opIterator = service.getOperations() ; opIterator.hasNext() ;){
104 AxisOperation operation = opIterator.next();
105 operation.setMessageReceiver(this.messageReceiver);
106 }
107
108 Parameter serviceDescriptionParam =
109 new Parameter(EndpointDescription.AXIS_SERVICE_PARAMETER, edArray[0]);
110 service.addParameter(serviceDescriptionParam);
111
112 return service;
113 }
114
115 public AxisService getServiceFromWSDL(PortInfo portInfo, Class endpointClass, URL configurationBaseUrl) throws Exception {
116 String wsdlFile = portInfo.getWsdlFile();
117 if (wsdlFile == null || wsdlFile.equals("")) {
118 throw new Exception("WSDL file is required.");
119 }
120
121 String endpointClassName = endpointClass.getName();
122 ClassLoader classLoader = endpointClass.getClassLoader();
123
124 QName serviceQName = portInfo.getWsdlService();
125 if (serviceQName == null) {
126 serviceQName = JAXWSUtils.getServiceQName(endpointClass);
127 }
128
129 QName portQName = portInfo.getWsdlPort();
130 if (portQName == null) {
131 portQName = JAXWSUtils.getPortQName(endpointClass);
132 }
133
134 Definition wsdlDefinition = readWSDL(wsdlFile, configurationBaseUrl, classLoader);
135
136 Service wsdlService = wsdlDefinition.getService(serviceQName);
137 if (wsdlService == null) {
138 throw new Exception("Service '" + serviceQName + "' not found in WSDL");
139 }
140
141 Port port = wsdlService.getPort(portQName.getLocalPart());
142 if (port == null) {
143 throw new Exception("Port '" + portQName.getLocalPart() + "' not found in WSDL");
144 }
145
146 String protocolBinding = null;
147 if (portInfo.getProtocolBinding() != null) {
148 protocolBinding = JAXWSUtils.getBindingURI(portInfo.getProtocolBinding());
149 } else {
150 protocolBinding = getBindingFromWSDL(port);
151 }
152
153 Class endPointClass = classLoader.loadClass(endpointClassName);
154 JavaClassToDBCConverter converter = new JavaClassToDBCConverter(endPointClass);
155 HashMap<String, DescriptionBuilderComposite> dbcMap = converter.produceDBC();
156
157 DescriptionBuilderComposite dbc = dbcMap.get(endpointClassName);
158 dbc.setClassLoader(classLoader);
159 dbc.setWsdlDefinition(wsdlDefinition);
160 dbc.setClassName(endpointClassName);
161 dbc.setCustomWsdlGenerator(new WSDLGeneratorImpl(wsdlDefinition));
162
163 if (dbc.getWebServiceAnnot() != null) { //information specified in .wsdl should overwrite annotation.
164 WebServiceAnnot serviceAnnot = dbc.getWebServiceAnnot();
165 serviceAnnot.setPortName(portQName.getLocalPart());
166 serviceAnnot.setServiceName(serviceQName.getLocalPart());
167 serviceAnnot.setTargetNamespace(serviceQName.getNamespaceURI());
168 processServiceBinding(dbc, protocolBinding);
169 } else if (dbc.getWebServiceProviderAnnot() != null) {
170 WebServiceProviderAnnot serviceProviderAnnot = dbc.getWebServiceProviderAnnot();
171 serviceProviderAnnot.setPortName(portQName.getLocalPart());
172 serviceProviderAnnot.setServiceName(serviceQName.getLocalPart());
173 serviceProviderAnnot.setTargetNamespace(serviceQName.getNamespaceURI());
174 processServiceBinding(dbc, protocolBinding);
175 }
176
177 /*
178 if (portInfo.isMTOMEnabled() != null) {
179 dbc.setIsMTOMEnabled(portInfo.isMTOMEnabled().booleanValue());
180 }
181 */
182
183 AxisService service = getService(dbcMap);
184
185 service.setName(serviceQName.getLocalPart());
186 service.setEndpointName(portQName.getLocalPart());
187
188 for(Iterator<AxisOperation> opIterator = service.getOperations() ; opIterator.hasNext() ;){
189 AxisOperation operation = opIterator.next();
190 operation.setMessageReceiver(this.messageReceiver);
191 String MEP = operation.getMessageExchangePattern();
192 if (!WSDLUtil.isOutputPresentForMEP(MEP)) {
193 List<MethodDescriptionComposite> mdcList = dbc.getMethodDescriptionComposite(operation.getName().toString());
194 for(Iterator<MethodDescriptionComposite> mIterator = mdcList.iterator(); mIterator.hasNext();){
195 MethodDescriptionComposite mdc = mIterator.next();
196 //TODO: JAXWS spec says need to check Holder param exist before taking a method as OneWay
197 mdc.setOneWayAnnot(true);
198 }
199 }
200 }
201
202 return service;
203 }
204
205 private String getBindingFromWSDL(Port port) {
206 Binding binding = port.getBinding();
207 List extElements = binding.getExtensibilityElements();
208 Iterator extElementsIterator = extElements.iterator();
209 String bindingS = javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING; //this is the default.
210 while (extElementsIterator.hasNext()) {
211 Object o = extElementsIterator.next();
212 if (o instanceof SOAPBinding) {
213 SOAPBinding sp = (SOAPBinding)o;
214 if (sp.getElementType().getNamespaceURI().equals("http://schemas.xmlsoap.org/wsdl/soap/")) {
215 bindingS = javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING;
216 }
217 } else if (o instanceof SOAP12Binding) {
218 SOAP12Binding sp = (SOAP12Binding)o;
219 if (sp.getElementType().getNamespaceURI().equals("http://schemas.xmlsoap.org/wsdl/soap12/")) {
220 bindingS = javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING;
221 }
222 } else if (o instanceof HTTPBinding) {
223 HTTPBinding sp = (HTTPBinding)o;
224 if (sp.getElementType().getNamespaceURI().equals("http://schemas.xmlsoap.org/wsdl/http/")) {
225 bindingS = javax.xml.ws.http.HTTPBinding.HTTP_BINDING;
226 }
227 }
228 }
229 return bindingS;
230 }
231
232 private void processServiceBinding(DescriptionBuilderComposite dbc, String bindingFromWSDL) {
233 if (dbc.getBindingTypeAnnot() == null || bindingFromWSDL == null || bindingFromWSDL.length() == 0) {
234 return;
235 }
236 String bindingFromAnnotation = dbc.getBindingTypeAnnot().value();
237 if (bindingFromAnnotation.equals(bindingFromWSDL)) {
238 return;
239 }
240 if (bindingFromWSDL.equals(javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING)) {
241 if (!bindingFromAnnotation.equals(javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING)) {
242 dbc.getBindingTypeAnnot().setValue(bindingFromWSDL);
243 }
244 } else if (bindingFromWSDL.equals(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)) {
245 if (!bindingFromAnnotation.equals(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
246 dbc.getBindingTypeAnnot().setValue(bindingFromWSDL);
247 }
248 } else {
249 dbc.getBindingTypeAnnot().setValue(bindingFromWSDL);
250 }
251 }
252
253 private AxisService getService(HashMap<String, DescriptionBuilderComposite> dbcMap) {
254 return getEndpointDescription(dbcMap).getAxisService();
255 }
256
257 private EndpointDescription getEndpointDescription(HashMap<String, DescriptionBuilderComposite> dbcMap) {
258 List<ServiceDescription> serviceDescList = DescriptionFactory.createServiceDescriptionFromDBCMap(dbcMap);
259 if (serviceDescList == null || serviceDescList.isEmpty()) {
260 throw new RuntimeException("No service");
261 }
262 ServiceDescription serviceDescription = serviceDescList.get(0);
263 EndpointDescription[] edArray = serviceDescription.getEndpointDescriptions();
264 if (edArray == null || edArray.length == 0) {
265 throw new RuntimeException("No endpoint");
266 }
267 return edArray[0];
268 }
269
270 private static class WSDLGeneratorImpl implements WsdlGenerator {
271 private Definition def;
272
273 public WSDLGeneratorImpl(Definition def) {
274 this.def = def;
275 }
276
277 public WsdlComposite generateWsdl(String implClass, String bindingType) throws WebServiceException {
278 // Need WSDL generation code
279 WsdlComposite composite = new WsdlComposite();
280 composite.setWsdlFileName(implClass);
281 HashMap<String, Definition> testMap = new HashMap<String, Definition>();
282 testMap.put(composite.getWsdlFileName(), def);
283 composite.setWsdlDefinition(testMap);
284 return composite;
285 }
286 }
287
288 protected Definition readWSDL(String wsdlLocation,
289 URL configurationBaseUrl,
290 ClassLoader classLoader)
291 throws IOException, WSDLException {
292 Definition wsdlDefinition = null;
293 URL wsdlURL = getWsdlURL(wsdlLocation, configurationBaseUrl, classLoader);
294 InputStream wsdlStream = null;
295 try {
296 wsdlStream = wsdlURL.openStream();
297 WSDLFactory factory = WSDLFactory.newInstance();
298 WSDLReader reader = factory.newWSDLReader();
299 reader.setFeature("javax.wsdl.importDocuments", true);
300 reader.setFeature("javax.wsdl.verbose", false);
301 SimpleWSDLLocator wsdlLocator = new SimpleWSDLLocator(wsdlURL.toString());
302 wsdlDefinition = reader.readWSDL(wsdlLocator);
303 } finally {
304 if (wsdlStream != null) {
305 wsdlStream.close();
306 }
307 }
308 return wsdlDefinition;
309 }
310
311 public static URL getWsdlURL(String wsdlFile, URL configurationBaseUrl, ClassLoader classLoader) {
312 URL wsdlURL = null;
313 if (wsdlFile != null) {
314 try {
315 wsdlURL = new URL(wsdlFile);
316 } catch (MalformedURLException e) {
317 // Not a URL, try as a resource
318 wsdlURL = classLoader.getResource(wsdlFile);
319
320 if (wsdlURL == null && configurationBaseUrl != null) {
321 // Cannot get it as a resource, try with
322 // configurationBaseUrl
323 try {
324 wsdlURL = new URL(configurationBaseUrl, wsdlFile);
325 } catch (MalformedURLException ee) {
326 // ignore
327 }
328 }
329 }
330 }
331 return wsdlURL;
332 }
333
334 public static EndpointDescription getEndpointDescription(AxisService service) {
335 Parameter param = service.getParameter(EndpointDescription.AXIS_SERVICE_PARAMETER);
336 return (param == null) ? null : (EndpointDescription) param.getValue();
337 }
338
339 public static boolean isSOAP11(AxisService service) {
340 EndpointDescription desc = AxisServiceGenerator.getEndpointDescription(service);
341 return javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING.equals(desc.getBindingType()) ||
342 javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING.equals(desc.getBindingType());
343 }
344
345 public static boolean isHTTP(AxisService service) {
346 EndpointDescription desc = AxisServiceGenerator.getEndpointDescription(service);
347 return javax.xml.ws.http.HTTPBinding.HTTP_BINDING.equals(desc.getBindingType());
348 }
349
350 }