| /* |
| * Copyright 2001-2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.axis.providers; |
| |
| import java.util.Hashtable; |
| |
| import javax.xml.namespace.QName; |
| |
| import org.apache.axis.AxisFault; |
| import org.apache.axis.Constants; |
| import org.apache.axis.MessageContext; |
| import org.apache.axis.AxisEngine; |
| import org.apache.axis.components.logger.LogFactory; |
| import org.apache.axis.description.ServiceDesc; |
| import org.apache.axis.description.JavaServiceDesc; |
| import org.apache.axis.handlers.BasicHandler; |
| import org.apache.axis.handlers.soap.SOAPService; |
| import org.apache.axis.utils.Messages; |
| import org.apache.axis.wsdl.fromJava.Emitter; |
| import org.apache.commons.logging.Log; |
| import org.w3c.dom.Document; |
| |
| /** |
| * This class has one way of keeping track of the |
| * operations declared for a particular service |
| * provider. I'm not exactly married to this though. |
| */ |
| public abstract class BasicProvider extends BasicHandler { |
| |
| public static final String OPTION_WSDL_PORTTYPE = "wsdlPortType"; |
| public static final String OPTION_WSDL_SERVICEELEMENT = "wsdlServiceElement"; |
| public static final String OPTION_WSDL_SERVICEPORT = "wsdlServicePort"; |
| public static final String OPTION_WSDL_TARGETNAMESPACE = "wsdlTargetNamespace"; |
| public static final String OPTION_WSDL_INPUTSCHEMA = "wsdlInputSchema"; |
| public static final String OPTION_WSDL_SOAPACTION_MODE = "wsdlSoapActionMode"; |
| public static final String OPTION_EXTRACLASSES = "extraClasses"; |
| |
| protected static Log log = |
| LogFactory.getLog(BasicProvider.class.getName()); |
| |
| // The enterprise category is for stuff that an enterprise product might |
| // want to track, but in a simple environment (like the AXIS build) would |
| // be nothing more than a nuisance. |
| protected static Log entLog = |
| LogFactory.getLog(Constants.ENTERPRISE_LOG_CATEGORY); |
| |
| /** |
| * This method returns a ServiceDesc that contains the correct |
| * implimentation class. |
| */ |
| public abstract void initServiceDesc(SOAPService service, |
| MessageContext msgContext) |
| throws AxisFault; |
| |
| public void addOperation(String name, QName qname) { |
| Hashtable operations = (Hashtable)getOption("Operations"); |
| if (operations == null) { |
| operations = new Hashtable(); |
| setOption("Operations", operations); |
| } |
| operations.put(qname, name); |
| } |
| |
| public String getOperationName(QName qname) { |
| Hashtable operations = (Hashtable)getOption("Operations"); |
| if (operations == null) return null; |
| return (String)operations.get(qname); |
| } |
| |
| public QName[] getOperationQNames() { |
| Hashtable operations = (Hashtable)getOption("Operations"); |
| if (operations == null) return null; |
| Object[] keys = operations.keySet().toArray(); |
| QName[] qnames = new QName[keys.length]; |
| System.arraycopy(keys,0,qnames,0,keys.length); |
| return qnames; |
| } |
| |
| public String[] getOperationNames() { |
| Hashtable operations = (Hashtable)getOption("Operations"); |
| if (operations == null) return null; |
| Object[] values = operations.values().toArray(); |
| String[] names = new String[values.length]; |
| System.arraycopy(values,0,names,0,values.length); |
| return names; |
| } |
| |
| /** |
| * Generate the WSDL for this service. |
| * |
| * Put in the "WSDL" property of the message context |
| * as a org.w3c.dom.Document |
| */ |
| public void generateWSDL(MessageContext msgContext) throws AxisFault { |
| if (log.isDebugEnabled()) |
| log.debug("Enter: BasicProvider::generateWSDL (" + this +")"); |
| |
| /* Find the service we're invoking so we can grab it's options */ |
| /***************************************************************/ |
| SOAPService service = msgContext.getService(); |
| |
| ServiceDesc serviceDesc = service.getInitializedServiceDesc(msgContext); |
| |
| // Calculate the appropriate namespaces for the WSDL we're going |
| // to put out. |
| // |
| // If we've been explicitly told which namespaces to use, respect |
| // that. If not: |
| // |
| // The "interface namespace" should be either: |
| // 1) The namespace of the ServiceDesc |
| // 2) The transport URL (if there's no ServiceDesc ns) |
| |
| try { |
| // Location URL is whatever is explicitly set in the MC |
| String locationUrl = msgContext.getStrProp(MessageContext.WSDLGEN_SERV_LOC_URL); |
| |
| if (locationUrl == null) { |
| // If nothing, try what's explicitly set in the ServiceDesc |
| locationUrl = serviceDesc.getEndpointURL(); |
| } |
| |
| if (locationUrl == null) { |
| // If nothing, use the actual transport URL |
| locationUrl = msgContext.getStrProp(MessageContext.TRANS_URL); |
| } |
| |
| // Interface namespace is whatever is explicitly set |
| String interfaceNamespace = msgContext.getStrProp(MessageContext.WSDLGEN_INTFNAMESPACE); |
| |
| if (interfaceNamespace == null) { |
| // If nothing, use the default namespace of the ServiceDesc |
| interfaceNamespace = serviceDesc.getDefaultNamespace(); |
| } |
| |
| if (interfaceNamespace == null) { |
| // If nothing still, use the location URL determined above |
| interfaceNamespace = locationUrl; |
| } |
| |
| //Do we want to do this? |
| // |
| // if (locationUrl == null) { |
| // locationUrl = url; |
| // } else { |
| // try { |
| // URL urlURL = new URL(url); |
| // URL locationURL = new URL(locationUrl); |
| // URL urlTemp = new URL(urlURL.getProtocol(), |
| // locationURL.getHost(), |
| // locationURL.getPort(), |
| // urlURL.getFile()); |
| // interfaceNamespace += urlURL.getFile(); |
| // locationUrl = urlTemp.toString(); |
| // } catch (Exception e) { |
| // locationUrl = url; |
| // interfaceNamespace = url; |
| // } |
| // } |
| |
| Emitter emitter = new Emitter(); |
| |
| // This seems like a good idea, but in fact isn't because the |
| // emitter will figure out a reasonable name (<classname>Service) |
| // for the WSDL service element name. We provide the 'alias' |
| // setting to explicitly set this name. See bug 13262 for more info. |
| //emitter.setServiceElementName(serviceDesc.getName()); |
| |
| // service alias may be provided if exact naming is required, |
| // otherwise Axis will name it according to the implementing class name |
| String alias = (String) service.getOption("alias"); |
| if (alias != null) |
| emitter.setServiceElementName(alias); |
| |
| // Set style/use |
| emitter.setStyle(serviceDesc.getStyle()); |
| emitter.setUse(serviceDesc.getUse()); |
| |
| if (serviceDesc instanceof JavaServiceDesc) { |
| emitter.setClsSmart(((JavaServiceDesc)serviceDesc).getImplClass(), |
| locationUrl); |
| } |
| |
| // If a wsdl target namespace was provided, use the targetNamespace. |
| // Otherwise use the interfaceNamespace constructed above. |
| String targetNamespace = (String) service.getOption(OPTION_WSDL_TARGETNAMESPACE); |
| if (targetNamespace == null || targetNamespace.length() == 0) { |
| targetNamespace = interfaceNamespace; |
| } |
| emitter.setIntfNamespace(targetNamespace); |
| |
| emitter.setLocationUrl(locationUrl); |
| emitter.setServiceDesc(serviceDesc); |
| emitter.setTypeMappingRegistry(msgContext.getTypeMappingRegistry()); |
| |
| String wsdlPortType = (String) service.getOption(OPTION_WSDL_PORTTYPE); |
| String wsdlServiceElement = (String) service.getOption(OPTION_WSDL_SERVICEELEMENT); |
| String wsdlServicePort = (String) service.getOption(OPTION_WSDL_SERVICEPORT); |
| String wsdlInputSchema = (String) service.getOption(OPTION_WSDL_INPUTSCHEMA); |
| String wsdlSoapActinMode = (String) service.getOption(OPTION_WSDL_SOAPACTION_MODE); |
| String extraClasses = (String) service.getOption(OPTION_EXTRACLASSES); |
| |
| if (wsdlPortType != null && wsdlPortType.length() > 0) { |
| emitter.setPortTypeName(wsdlPortType); |
| } |
| if (wsdlServiceElement != null && wsdlServiceElement.length() > 0) { |
| emitter.setServiceElementName(wsdlServiceElement); |
| } |
| if (wsdlServicePort != null && wsdlServicePort.length() > 0) { |
| emitter.setServicePortName(wsdlServicePort); |
| } |
| if (wsdlInputSchema != null && wsdlInputSchema.length() > 0) { |
| emitter.setInputSchema(wsdlInputSchema); |
| } |
| if (wsdlSoapActinMode != null && wsdlSoapActinMode.length() > 0) { |
| emitter.setSoapAction(wsdlSoapActinMode); |
| } |
| |
| if (extraClasses != null && extraClasses.length() > 0) { |
| emitter.setExtraClasses(extraClasses, msgContext.getClassLoader()); |
| } |
| |
| if (msgContext.isPropertyTrue(AxisEngine.PROP_EMIT_ALL_TYPES)) { |
| emitter.setEmitAllTypes(true); |
| } |
| |
| Document doc = emitter.emit(Emitter.MODE_ALL); |
| |
| msgContext.setProperty("WSDL", doc); |
| } catch (NoClassDefFoundError e) { |
| entLog.info(Messages.getMessage("toAxisFault00"), e); |
| throw new AxisFault(e.toString(), e); |
| } catch (Exception e) { |
| entLog.info(Messages.getMessage("toAxisFault00"), e); |
| throw AxisFault.makeFault(e); |
| } |
| |
| if (log.isDebugEnabled()) |
| log.debug("Exit: BasicProvider::generateWSDL (" + this +")"); |
| } |
| } |