/* * Copyright 2001-2005 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.deployment.wsdd; import org.apache.axis.AxisEngine; import org.apache.axis.AxisFault; import org.apache.axis.ConfigurationException; import org.apache.axis.Constants; import org.apache.axis.EngineConfiguration; import org.apache.axis.FaultableHandler; import org.apache.axis.Handler; import org.apache.axis.MessageContext; import org.apache.axis.attachments.Attachments; import org.apache.axis.attachments.AttachmentsImpl; import org.apache.axis.constants.Style; import org.apache.axis.constants.Use; import org.apache.axis.description.JavaServiceDesc; import org.apache.axis.description.ServiceDesc; import org.apache.axis.encoding.DeserializerFactory; import org.apache.axis.encoding.SerializationContext; import org.apache.axis.encoding.SerializerFactory; import org.apache.axis.encoding.TypeMapping; import org.apache.axis.encoding.TypeMappingRegistry; import org.apache.axis.encoding.TypeMappingRegistryImpl; import org.apache.axis.encoding.ser.ArraySerializerFactory; import org.apache.axis.encoding.ser.BaseDeserializerFactory; import org.apache.axis.encoding.ser.BaseSerializerFactory; import org.apache.axis.handlers.HandlerInfoChainFactory; import org.apache.axis.handlers.soap.SOAPService; import org.apache.axis.providers.java.JavaProvider; import org.apache.axis.utils.Messages; import org.apache.axis.utils.XMLUtils; import org.w3c.dom.Element; import org.xml.sax.helpers.AttributesImpl; import javax.xml.namespace.QName; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import java.util.Vector; /** * A service represented in WSDD. * * @author Glen Daniels (gdaniels@apache.org) */ public class WSDDService extends WSDDTargetedChain implements WSDDTypeMappingContainer { private TypeMappingRegistry tmr = null; private Vector faultFlows = new Vector(); private Vector typeMappings = new Vector(); private Vector operations = new Vector(); /** Which namespaces should auto-dispatch to this service? */ private Vector namespaces = new Vector(); /** Which roles does this service support? */ private List roles = new ArrayList(); private String descriptionURL; /** Style - document, wrapped, message, or RPC (the default) */ private Style style = Style.DEFAULT; /** Use - encoded (the default) or literal */ private Use use = Use.DEFAULT; private transient SOAPService cachedService = null; /** * Our provider - used to figure out which Handler we use as a service * pivot (see getInstance() below) */ private QName providerQName; // private HandlerInfoChainFactory _hiChainFactory; private WSDDJAXRPCHandlerInfoChain _wsddHIchain; JavaServiceDesc desc = new JavaServiceDesc(); /** * Is streaming (i.e. NO high-fidelity recording, deserialize on the fly) * on for this service? */ private boolean streaming = false; /** * What attachment format should be used? */ private int sendType = Attachments.SEND_TYPE_NOTSET; /** * Default constructor */ public WSDDService() { } /** * * @param e (Element) XXX * @throws WSDDException XXX */ public WSDDService(Element e) throws WSDDException { super(e); desc.setName(getQName().getLocalPart()); String styleStr = e.getAttribute(ATTR_STYLE); if (styleStr != null && !styleStr.equals("")) { style = Style.getStyle(styleStr, Style.DEFAULT); desc.setStyle(style); providerQName = style.getProvider(); } String useStr = e.getAttribute(ATTR_USE); if (useStr != null && !useStr.equals("")) { use = Use.getUse(useStr, Use.DEFAULT); desc.setUse(use); } else { if (style != Style.RPC) { // Default to use=literal if not style=RPC use = Use.LITERAL; desc.setUse(use); } } String streamStr = e.getAttribute(ATTR_STREAMING); if (streamStr != null && streamStr.equals("on")) { streaming = true; } String attachmentStr = e.getAttribute(ATTR_ATTACHMENT_FORMAT); if (attachmentStr != null && !attachmentStr.equals("")) { sendType = AttachmentsImpl.getSendType(attachmentStr); } Element [] operationElements = getChildElements(e, ELEM_WSDD_OPERATION); for (int i = 0; i < operationElements.length; i++) { WSDDOperation operation = new WSDDOperation(operationElements[i], desc); addOperation(operation); } Element [] typeMappingElements = getChildElements(e, ELEM_WSDD_TYPEMAPPING); for (int i = 0; i < typeMappingElements.length; i++) { WSDDTypeMapping mapping = new WSDDTypeMapping(typeMappingElements[i]); typeMappings.add(mapping); } Element [] beanMappingElements = getChildElements(e, ELEM_WSDD_BEANMAPPING); for (int i = 0; i < beanMappingElements.length; i++) { WSDDBeanMapping mapping = new WSDDBeanMapping(beanMappingElements[i]); typeMappings.add(mapping); } Element [] arrayMappingElements = getChildElements(e, ELEM_WSDD_ARRAYMAPPING); for (int i = 0; i < arrayMappingElements.length; i++) { WSDDArrayMapping mapping = new WSDDArrayMapping(arrayMappingElements[i]); typeMappings.add(mapping); } Element [] namespaceElements = getChildElements(e, ELEM_WSDD_NAMESPACE); for (int i = 0; i < namespaceElements.length; i++) { // Register a namespace for this service String ns = XMLUtils.getChildCharacterData(namespaceElements[i]); namespaces.add(ns); } if (!namespaces.isEmpty()) desc.setNamespaceMappings(namespaces); Element [] roleElements = getChildElements(e, ELEM_WSDD_ROLE); for (int i = 0; i < roleElements.length; i++) { String role = XMLUtils.getChildCharacterData(roleElements[i]); roles.add(role); } Element wsdlElem = getChildElement(e, ELEM_WSDD_WSDLFILE); if (wsdlElem != null) { String fileName = XMLUtils.getChildCharacterData(wsdlElem); desc.setWSDLFile(fileName.trim()); } Element docElem = getChildElement(e, ELEM_WSDD_DOC); if (docElem != null) { WSDDDocumentation documentation = new WSDDDocumentation(docElem); desc.setDocumentation(documentation.getValue()); } Element urlElem = getChildElement(e, ELEM_WSDD_ENDPOINTURL); if (urlElem != null) { String endpointURL = XMLUtils.getChildCharacterData(urlElem); desc.setEndpointURL(endpointURL); } String providerStr = e.getAttribute(ATTR_PROVIDER); if (providerStr != null && !providerStr.equals("")) { providerQName = XMLUtils.getQNameFromString(providerStr, e); if (WSDDConstants.QNAME_JAVAMSG_PROVIDER.equals(providerQName)) { // Message style if message provider... desc.setStyle(Style.MESSAGE); } } // Add in JAX-RPC support for HandlerInfo chains Element hcEl = getChildElement(e, ELEM_WSDD_JAXRPC_CHAIN); if (hcEl != null) { _wsddHIchain = new WSDDJAXRPCHandlerInfoChain(hcEl); } // Initialize TypeMappingRegistry initTMR(); // call to validate standard descriptors for this service validateDescriptors(); } /** * Initialize a TypeMappingRegistry with the * WSDDTypeMappings. * Note: Extensions of WSDDService may override * initTMR to popluate the tmr with different * type mappings. */ protected void initTMR() throws WSDDException { // If not created, construct a tmr // and populate it with the type mappings. if (tmr == null) { createTMR(); for (int i=0; i 0) { FaultableHandler wrapper = new FaultableHandler(service); for (int i = 0; i < faultFlows.length; i++) { WSDDFaultFlow flow = faultFlows[i]; Handler faultHandler = flow.getInstance(registry); wrapper.setOption("fault-" + flow.getQName().getLocalPart(), faultHandler); } } try { service.getInitializedServiceDesc(MessageContext.getCurrentContext()); } catch (AxisFault axisFault) { throw new ConfigurationException(axisFault); } cachedService = service; return service; } public void deployTypeMapping(WSDDTypeMapping mapping) throws WSDDException { if (!typeMappings.contains(mapping)) { typeMappings.add(mapping); } if (tmr == null) { createTMR(); } try { // Get the encoding style from the mapping, if it isn't set // use the use of the service to map doc/lit or rpc/enc String encodingStyle = mapping.getEncodingStyle(); if (encodingStyle == null) { encodingStyle = use.getEncoding(); } TypeMapping tm = tmr.getOrMakeTypeMapping(encodingStyle); desc.setTypeMappingRegistry(tmr); desc.setTypeMapping(tm); SerializerFactory ser = null; DeserializerFactory deser = null; // Try to construct a serializerFactory by introspecting for the // following: // public static create(Class javaType, QName xmlType) // public (Class javaType, QName xmlType) // public () // // The BaseSerializerFactory createFactory() method is a utility // that does this for us. if (mapping.getSerializerName() != null && !mapping.getSerializerName().equals("")) { ser = BaseSerializerFactory.createFactory(mapping.getSerializer(), mapping.getLanguageSpecificType(), mapping.getQName()); } if (mapping instanceof WSDDArrayMapping && ser instanceof ArraySerializerFactory) { WSDDArrayMapping am = (WSDDArrayMapping) mapping; ArraySerializerFactory factory = (ArraySerializerFactory) ser; factory.setComponentType(am.getInnerType()); } if (mapping.getDeserializerName() != null && !mapping.getDeserializerName().equals("")) { deser = BaseDeserializerFactory.createFactory(mapping.getDeserializer(), mapping.getLanguageSpecificType(), mapping.getQName()); } tm.register( mapping.getLanguageSpecificType(), mapping.getQName(), ser, deser); } catch (ClassNotFoundException e) { log.error(Messages.getMessage("unabletoDeployTypemapping00", mapping.getQName().toString()), e); throw new WSDDNonFatalException(e); } catch (Exception e) { throw new WSDDException(e); } } /** * Write this element out to a SerializationContext */ public void writeToContext(SerializationContext context) throws IOException { AttributesImpl attrs = new AttributesImpl(); QName name = getQName(); if (name != null) { attrs.addAttribute("", ATTR_NAME, ATTR_NAME, "CDATA", context.qName2String(name)); } if (providerQName != null) { attrs.addAttribute("", ATTR_PROVIDER, ATTR_PROVIDER, "CDATA", context.qName2String(providerQName)); } if (style != Style.DEFAULT) { attrs.addAttribute("", ATTR_STYLE, ATTR_STYLE, "CDATA", style.getName()); } if (use != Use.DEFAULT) { attrs.addAttribute("", ATTR_USE, ATTR_USE, "CDATA", use.getName()); } if (streaming) { attrs.addAttribute("", ATTR_STREAMING, ATTR_STREAMING, "CDATA", "on"); } if (sendType != Attachments.SEND_TYPE_NOTSET) { attrs.addAttribute("", ATTR_ATTACHMENT_FORMAT, ATTR_ATTACHMENT_FORMAT, "CDATA", AttachmentsImpl.getSendTypeString(sendType)); } context.startElement(WSDDConstants.QNAME_SERVICE, attrs); if (desc.getWSDLFile() != null) { context.startElement(QNAME_WSDLFILE, null); context.writeSafeString(desc.getWSDLFile()); context.endElement(); } if (desc.getDocumentation() != null) { WSDDDocumentation documentation = new WSDDDocumentation(desc.getDocumentation()); documentation.writeToContext(context); } for (int i = 0; i < operations.size(); i++) { WSDDOperation operation = (WSDDOperation) operations.elementAt(i); operation.writeToContext(context); } writeFlowsToContext(context); writeParamsToContext(context); for (int i=0; i < typeMappings.size(); i++) { ((WSDDTypeMapping) typeMappings.elementAt(i)).writeToContext(context); } for (int i=0; i < namespaces.size(); i++ ) { context.startElement(QNAME_NAMESPACE, null); context.writeString((String)namespaces.get(i)); context.endElement(); } String endpointURL = desc.getEndpointURL(); if (endpointURL != null) { context.startElement(QNAME_ENDPOINTURL, null); context.writeSafeString(endpointURL); context.endElement(); } if (_wsddHIchain != null) { _wsddHIchain.writeToContext(context); } context.endElement(); } public void setCachedService(SOAPService service) { cachedService = service; } public Vector getTypeMappings() { return typeMappings; } public void setTypeMappings(Vector typeMappings) { this.typeMappings = typeMappings; } public void deployToRegistry(WSDDDeployment registry) { registry.addService(this); // Register the name of the service as a valid namespace, just for // backwards compatibility registry.registerNamespaceForService(getQName().getLocalPart(), this); for (int i = 0; i < namespaces.size(); i++) { String namespace = (String) namespaces.elementAt(i); registry.registerNamespaceForService(namespace, this); } super.deployToRegistry(registry); } public void removeNamespaceMappings(WSDDDeployment registry) { for (int i = 0; i < namespaces.size(); i++) { String namespace = (String) namespaces.elementAt(i); registry.removeNamespaceMapping(namespace); } registry.removeNamespaceMapping(getQName().getLocalPart()); } public TypeMapping getTypeMapping(String encodingStyle) { // If type mapping registry not initialized yet, return null. if (tmr == null) { return null; } return (TypeMapping) tmr.getOrMakeTypeMapping(encodingStyle); } public WSDDJAXRPCHandlerInfoChain getHandlerInfoChain() { return _wsddHIchain; } public void setHandlerInfoChain(WSDDJAXRPCHandlerInfoChain hichain) { _wsddHIchain = hichain; } }