All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jibx.ws.server.ServiceDefinition Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2007-2009, Sosnoski Software Associates Limited. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 * following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
 * disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 * following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of
 * JiBX nor the names of its contributors may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.jibx.ws.server;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.jibx.runtime.IBindingFactory;
import org.jibx.runtime.IUnmarshallingContext;
import org.jibx.runtime.JiBXException;
import org.jibx.ws.WsBindingException;
import org.jibx.ws.WsConfigurationException;
import org.jibx.ws.io.XmlOptions;
import org.jibx.ws.transport.OutputCompletionListener;
import org.jibx.ws.util.Utility;

/**
 * Defines a service to be invoked by JiBX/WS.
 * 

* After setting the required properties on this class, the {@link #init()} method must be called to initialize this * class. *

* When using JiBX to configure the service, this class is populated from the XML service definition document by JiBX * unmarshalling and the init() method is automatically called after the properties have been set. * * @author Dennis M. Sosnoski */ public final class ServiceDefinition { /** The name of the protocol to use for the service. */ private String m_protocolName; /** Schema file name, with name also used as default for base name. */ // private String m_schemaName; /** Base name, used for service, binding, port type, and port. */ // private String m_baseName; /** Service name, generated if not supplied. */ private String m_serviceName; /** Binding name (in SOAP terms), generated if not supplied. */ // private String m_soapBindingName; /** Port type name, generated if not supplied. */ // private String m_portTypeName; /** Port name, generated if not supplied. */ // private String m_portName; /** Namespace for WSDL definitions. */ // private String m_wsdlNamespace; /** Actual service object. */ private Object m_serviceObject; /** Actual service class. */ private String m_serviceClassName; private Class m_serviceClass; /** Exception handler object. */ private ServiceExceptionHandler m_serviceExceptionHandlerObject; /** Exception handler class. */ private Class m_serviceExceptionHandlerClass; /** Binding factory for inbound request body, only needed if multiple bindings to message classes. */ private IBindingFactory m_inBodyBindingFactory; /** Binding factory for outbound response body, only needed if multiple bindings to message classes. */ private IBindingFactory m_outBodyBindingFactory; /** Handlers used for reading and writing headers. */ private List m_hdefs; /** Operations included in service interface. */ private List m_opdefs; /** Whether to include stack trace in default fault handling. */ private boolean m_includeStackTraceOnFault; /** Output Completion Listener object. */ private OutputCompletionListener m_outputCompletionListenerObject; /** Output Completion Listener class. */ private Class m_outputCompletionListenerClass; /** Options for formatting outbound XML. */ private XmlOptions m_xmlOptions; /** List of {@link TransportOptionsDefinition}. */ private List m_transportOptDefs; /** Path to WSDL file. */ private String m_wsdlFilepath; /** Whether to transform WSDL location using WSDL request. */ private boolean m_wsdlLocationTransform; /** * Method called after unmarshalling is complete. * * @param ctx unmarshalling context * @throws JiBXException if error in configuration */ protected void postset(IUnmarshallingContext ctx) throws JiBXException { try { init(); } catch (WsConfigurationException e) { throw new JiBXException("Error initializing ServiceDefinition", e); } } /** * This method must be called after all properties have been set. This fills in any names not supplied by the * binding and initializes the contained definition objects (eg. handler definitions). * * @throws WsConfigurationException on configuration error */ public void init() throws WsConfigurationException { // initialize all of the handler definitions for (int i = 0; i < getHandlerDefinitions().size(); i++) { HandlerDefinition hdef = (HandlerDefinition) getHandlerDefinitions().get(i); hdef.init(); } checkForDuplicateTransportOptionDefinitions(); for (Iterator iterator = getTransportOptionsDefinitions().iterator(); iterator.hasNext();) { TransportOptionsDefinition todef = (TransportOptionsDefinition) iterator.next(); todef.init(); } // handle any names not defined by configuration // if (m_baseName == null) { // if (m_schemaName != null) { // String name = m_schemaName; // int split = name.lastIndexOf('.'); // if (split > 0) { // name = name.substring(0, split); // } // m_baseName = name; // } // } // if (m_serviceName == null) { // m_serviceName = m_baseName + "Service"; // } // if (m_soapBindingName == null) { // m_soapBindingName = m_baseName + "Binding"; // } // if (m_portTypeName == null) { // m_portTypeName = m_baseName + "Interface"; // } // if (m_portName == null) { // m_portName = m_baseName; // } if (m_serviceName == null) { m_serviceName = "Service"; } if (getProtocolName() == null) { setProtocolName("SOAP1.1"); } } /** * Checks that only one {@link TransportOptionsDefinition} instance exists for each * {@link TransportOptionsDefinition} class. */ private void checkForDuplicateTransportOptionDefinitions() { if (m_transportOptDefs != null) { Set definedOptions = new HashSet(); for (Iterator iterator = m_transportOptDefs.iterator(); iterator.hasNext();) { TransportOptionsDefinition def = (TransportOptionsDefinition) iterator.next(); String type = def.getClass().getName(); if (definedOptions.contains(type)) { throw new IllegalArgumentException("Duplicate transport options definition of type " + type); } definedOptions.add(type); } } } // /** // * Sets the base name used to derive other names for this service. If supplied, this replaces the schema file name // * as the base for generating other names used in the WSDL for the service. // * // * @param baseName base name // */ // public void setBaseName(String baseName) { // m_baseName = baseName; // } /** * Set name of protocol to use for service. * * @param name protocol name */ public void setProtocolName(String name) { m_protocolName = name; } /** * Get the name of protocol to use for this service. * * @return protocol name */ public String getProtocolName() { return m_protocolName; } // /** // * Sets the name of the XML schema to be used for WSDL generation. // * // * @param schemaName schema name // */ // public void setSchemaName(String schemaName) { // m_schemaName = schemaName; // } // // /** // * Get name of XML schema to be used for WSDL generation. // * // * @return schema name // */ // public String getSchemaName() { // return m_schemaName; // } // // /** // * Sets the namespace URI for WSDL definitions. This is required if WSDL generation is to be supported, but is // * optional and unused otherwise. // * // * @param wsdlNamespace the namespace // */ // public void setWsdlNamespace(String wsdlNamespace) { // m_wsdlNamespace = wsdlNamespace; // } // // /** // * Get namespace for generated WSDL. // * // * @return schema name // */ // public String getWsdlNamespace() { // return m_wsdlNamespace; // } /** * Sets the number of spaces to indent output XML. The default is to suppress all indentation and generate XML with * no added spaces or line breaks. Alternatively, for more control over output format, use * {@link #setXmlOptions(XmlOptions)}. * * @param indentCount number of spaces to use */ public void setIndentCount(int indentCount) { getXmlOptions().setIndentCount(indentCount); } /** * Sets the options for formatting of the outbound XML message for the service. * * @param options message options */ public void setXmlOptions(XmlOptions options) { m_xmlOptions = options; } /** * Returns the formatting options for outbound XML. If no options have been set, this will create default options. * * @return XML formatting options */ public XmlOptions getXmlOptions() { if (m_xmlOptions == null) { m_xmlOptions = new XmlOptions(); } return m_xmlOptions; } /** * Sets the optional name to be used for this service. If not supplied, a name is generated * by appending "Service" to the base name. * * @param serviceName the service name */ public void setServiceName(String serviceName) { m_serviceName = serviceName; } /** * Get service name. * * @return service name */ public String getServiceName() { return m_serviceName; } // /** // * Sets the optional name to be used for the service binding in generated WSDL. If not supplied, a name is // * generated by appending "Binding" to the base name. // * // * @param soapBindingName the binding name // */ // public void setSoapBindingName(String soapBindingName) { // m_soapBindingName = soapBindingName; // } // // /** // * Get SOAP binding name. // * // * @return SOAP binding name // */ // public String getSoapBindingName() { // return m_soapBindingName; // } // // /** // * Sets the optional name to be used for the service port type in generated WSDL. If not supplied, a name is // * generated by appending "Interface" to the base name. // * // * @param portTypeName the port type name // */ // public void setPortTypeName(String portTypeName) { // m_portTypeName = portTypeName; // } // // /** // * Get port type name. // * // * @return port type name // */ // public String getPortTypeName() { // return m_portTypeName; // } // // /** // * Sets the optional name to be used for the service port in generated WSDL. If not supplied, the base name is // * used as the port name. // * // * @param portName port name // */ // public void setPortName(String portName) { // m_portName = portName; // } // // /** // * Get port name. // * // * @return port name // */ // public String getPortName() { // return m_portName; // } /** * Get service object. * * @return service object */ public Object getServiceObject() { return m_serviceObject; } /** * Sets the object to be used for processing requests for this service. The object will potentially be used by * multiple service instances, so the methods that implement the service operations must be thread safe. * Alternatively, if using the Spring Framework, the object can use a scoped proxy to create new object instances * for the desired object scope. *

* Either this method or {@link #setServiceClassName(String)} must be called. * * @param serviceObject the service service object */ public void setServiceObject(Object serviceObject) { m_serviceObject = serviceObject; } /** * Sets the fully qualified name of class used to process requests for this service. All operations defined for the * service must be implemented by methods of this class. A separate instance of the specified class will be * constructed for each service instance, unless all of the operations use static methods, in which case only a * single instance of the specified class will be constructed. *

* Either this method or {@link #setServiceObject(Object)} must be called. * * @param serviceClassName the full name of the service class */ public void setServiceClassName(String serviceClassName) { m_serviceClassName = serviceClassName; } /** * Get service class information. * * @return service class information * @throws WsConfigurationException if service class unavailable */ public Class getServiceClass() throws WsConfigurationException { if (m_serviceClass == null) { if (m_serviceObject != null) { m_serviceClass = m_serviceObject.getClass(); } else { m_serviceClass = Utility.loadClass(m_serviceClassName); if (m_serviceClass == null) { throw new WsConfigurationException("Service class " + m_serviceClassName + " not found in classpath"); } } } return m_serviceClass; } /** * Get fault handler object. * * @return fault handler object */ public ServiceExceptionHandler getServiceExceptionHandlerObject() { return m_serviceExceptionHandlerObject; } /** * Sets the object to be used for handling exceptions in processing the message or executing the service method. * The object will potentially be used by multiple service instances, so the methods must be thread safe. * Alternatively, if using the Spring Framework, the object can use a scoped proxy to create new object instances * for the desired object scope. *

* Either this method or {@link #setServiceExceptionHandlerClassName(String)} must be called. * * @param serviceExceptionHandler the service exception handler object */ public void setServiceExceptionHandlerObject(ServiceExceptionHandler serviceExceptionHandler) { m_serviceExceptionHandlerObject = serviceExceptionHandler; } /** * Sets the fully qualified name of class used for handling faults. A separate instance of the specified class will * be constructed for each service instance. *

* Either this method or {@link #setServiceExceptionHandlerObject(ServiceExceptionHandler)} must be called. * * @param serviceExceptionHandlerClassName the full name of the fault handler class * @throws WsConfigurationException if fault handler class unavailable */ public void setServiceExceptionHandlerClassName(String serviceExceptionHandlerClassName) throws WsConfigurationException { if (serviceExceptionHandlerClassName != null) { m_serviceExceptionHandlerClass = Utility.loadClass(serviceExceptionHandlerClassName); if (m_serviceExceptionHandlerClass == null) { throw new WsConfigurationException("Fault handler class " + serviceExceptionHandlerClassName + " not found in classpath"); } } } /** * Get fault handler class information. * * @return fault handler class information */ public Class getServiceExceptionHandlerClass() { return m_serviceExceptionHandlerClass; } /** * Calls {@link #setBindingFactory(IBindingFactory)} with the factory retrieved from the specified locator. * * @param locator the locator for the binding factory to use for all request and response message bodies * @throws WsBindingException if unable to find binding in the directory * @throws WsConfigurationException if either package or binding name are not set */ private void setBindingLocator(BindingLocator locator) throws WsBindingException, WsConfigurationException { if (locator != null) { setBindingFactory(locator.getBindingFactory()); } } /** * Calls {@link #setInBodyBindingFactory(IBindingFactory)} with the factory retrieved from the specified locator. * * @param locator the locator for the binding factory to use for all request message bodies * @throws WsBindingException if unable to find binding in the directory * @throws WsConfigurationException if either package or binding name are not set */ private void setInBodyBindingLocator(BindingLocator locator) throws WsBindingException, WsConfigurationException { if (locator != null) { setInBodyBindingFactory(locator.getBindingFactory()); } } /** * Calls {@link #setOutBindingFactory(IBindingFactory)} with the factory retrieved from the specified locator. * * @param locator the locator for the binding factory to use for all response message bodies * @throws WsBindingException if unable to find binding in the directory * @throws WsConfigurationException if either package or binding name are not set */ private void setOutBodyBindingLocator(BindingLocator locator) throws WsBindingException, WsConfigurationException { if (locator != null) { setOutBodyBindingFactory(locator.getBindingFactory()); } } /** * Sets the optional JiBX binding factory used for the body of the request and response messages exchanged by * operations. For finer-grain control, call either or both of {@link #setInBodyBindingFactory(IBindingFactory)} and * {@link #setOutBodyBindingFactory(IBindingFactory)}. *

* If no binding factory is specified, JiBX/WS assumes that there is a single binding factory that includes bindings * for all of the possible request and response message bodies, and will look up this factory based on the class of * one of the request or response message bodies. * * @param factory the binding factory to use for all request and response message bodies */ public void setBindingFactory(IBindingFactory factory) { setInBodyBindingFactory(factory); setOutBodyBindingFactory(factory); } /** * Sets the optional JiBX binding factory used for the request message bodies received by operations. * * @param factory the binding factory to use for all request message bodies */ public void setInBodyBindingFactory(IBindingFactory factory) { m_inBodyBindingFactory = factory; } /** * Returns the optional JiBX binding factory used for the request message bodies received by operations. * * @return the binding factory to use for all request message bodies */ public IBindingFactory getInBodyBindingFactory() { return m_inBodyBindingFactory; } /** * Sets the optional JiBX binding factory used for the response message bodies sent by operations. * * @param factory the binding factory to use for all response message bodies */ public void setOutBodyBindingFactory(IBindingFactory factory) { m_outBodyBindingFactory = factory; } /** * Returns the optional JiBX binding factory used for the response message bodies sent by operations. * * @return the binding factory to use for all response message bodies */ public IBindingFactory getOutBodyBindingFactory() { return m_outBodyBindingFactory; } /** * Sets the definitions of the handlers for the service. * * @param hdefs a list of {@link HandlerDefinition} */ public void setHandlerDefinitions(List hdefs) { m_hdefs = hdefs; } /** * Get handler definitions. * * @return list of {@link HandlerDefinition}s */ public List getHandlerDefinitions() { if (m_hdefs == null) { return Collections.EMPTY_LIST; } return m_hdefs; } /** * Sets the operations to be made available for the service. Each operation uses an associated method within the * service class specified by the {@link #setServiceClassName(String)} or {@link #setServiceObject(Object)} methods. *

* With the doc/lit style of web services supported by JiBX/WS the input message element name always determines the * particular operation to be performed. JiBX/WS actually finds the input message element name corresponding to each * operation by doing a reverse lookup of the methods in the service class. Since only one type of object can be * associated with an element, there's a fixed linkage between the element name and the object type. This means that * the type of the input parameter used for each operation method within a service must be unique. * * @param opdefs a list of {@link OperationDefinition} */ public void setOperationDefinitions(List opdefs) { m_opdefs = opdefs; } /** * Get operation definitions. * * @return list of {@link OperationDefinition}s */ public List getOperationDefinitions() { return m_opdefs; } /** * Sets whether a stack trace should be included when a SOAP fault is created as the result of an unhandled error. * * @param includeStackTraceOnFault set to true if a stack trace should be created, false * otherwise. */ public void setIncludeStackTraceOnFault(boolean includeStackTraceOnFault) { m_includeStackTraceOnFault = includeStackTraceOnFault; } /** * Returns whether a stack trace should be included when a SOAP fault is created as the result of an unhandled * error. * * @return true if a stack trace should be created, false otherwise. */ public boolean getIncludeStackTraceOnFault() { return m_includeStackTraceOnFault; } /** * Sets the fully qualified name of class to be notified of the completion of output. A separate instance of the * specified class will be constructed for each service instance. * * @param outputCompletionListenerClassName the full name of the listener class * @throws WsConfigurationException if listener class unavailable * @see #setOutputCompletionListener(OutputCompletionListener) */ public void setOutputCompletionListenerClassName(String outputCompletionListenerClassName) throws WsConfigurationException { if (outputCompletionListenerClassName != null) { m_outputCompletionListenerClass = Utility.loadClass(outputCompletionListenerClassName); if (m_outputCompletionListenerClass == null) { throw new WsConfigurationException("Output Listener class " + outputCompletionListenerClassName + " not found in classpath"); } } } /** * Sets the object to be notified of the completion of output. * * @param listener the listener object to be notified * @see #setOutputCompletionListenerClassName(String) */ public void setOutputCompletionListener(OutputCompletionListener listener) { this.m_outputCompletionListenerObject = listener; } /** * Get outputCompletionListenerObject. * * @return outputCompletionListenerObject */ public OutputCompletionListener getOutputCompletionListenerObject() { return m_outputCompletionListenerObject; } /** * Get outputCompletionListenerClass. * * @return outputCompletionListenerClass */ public Class getOutputCompletionListenerClass() { return m_outputCompletionListenerClass; } /** * Sets the definition of options that are specific to a particular transport. At most one definition may be * supplied for each transport. * * @param definitions list of {@link TransportOptionsDefinition}. The list must contain no more than one * TransportOptionsDefinition object for each TransportOptionsDefinition class. * @throws IllegalArgumentException if a duplicate transport options definition is found */ public void setTransportOptionsDefinitions(List definitions) { m_transportOptDefs = definitions; } /** * Gets a list of all defined {@link TransportOptionsDefinition}s. * * @return the transport options definitions that have been defined, or an empty list if none have been defined. */ protected Collection getTransportOptionsDefinitions() { if (m_transportOptDefs == null) { return Collections.EMPTY_LIST; } return m_transportOptDefs; } /** * Sets the path to an existing WSDL file. * * @param wsdlFilepath path to WSDL file */ public void setWsdlFilepath(String wsdlFilepath) { m_wsdlFilepath = wsdlFilepath; } /** * Gets the path to existing WSDL file. * * @return path to WSDL file */ protected String getWsdlFilepath() { return m_wsdlFilepath; } /** * Sets whether WSDL locations should be transformed using the location of the WSDL request. * * @param transform set to true if a location should be transformed, false * otherwise. */ public void setWsdlLocationTransform(boolean transform) { m_wsdlLocationTransform = transform; } /** * Get wsdlLocationTransform. * * @return wsdlLocationTransform */ protected boolean getWsdlLocationTransform() { return m_wsdlLocationTransform; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy