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