| /* |
| * 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.client; |
| |
| import org.apache.axis.EngineConfiguration; |
| import org.apache.axis.configuration.EngineConfigurationFactoryFinder; |
| import org.apache.axis.utils.ClassUtils; |
| import org.apache.axis.utils.Messages; |
| |
| import javax.naming.Context; |
| import javax.naming.InitialContext; |
| import javax.naming.Name; |
| import javax.naming.NamingException; |
| import javax.naming.RefAddr; |
| import javax.naming.Reference; |
| import javax.naming.spi.ObjectFactory; |
| import javax.xml.namespace.QName; |
| import javax.xml.rpc.ServiceException; |
| import java.lang.reflect.Constructor; |
| import java.net.URL; |
| import java.util.Hashtable; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| /** |
| * Helper class for obtaining Services from JNDI. |
| * |
| * !!! WORK IN PROGRESS |
| * |
| * @author Glen Daniels (gdaniels@apache.org) |
| */ |
| |
| public class ServiceFactory extends javax.xml.rpc.ServiceFactory |
| implements ObjectFactory |
| { |
| // Constants for RefAddrs in the Reference. |
| public static final String SERVICE_CLASSNAME = "service classname"; |
| public static final String WSDL_LOCATION = "WSDL location"; |
| public static final String MAINTAIN_SESSION = "maintain session"; |
| public static final String SERVICE_NAMESPACE = "service namespace"; |
| public static final String SERVICE_LOCAL_PART = "service local part"; |
| public static final String SERVICE_IMPLEMENTATION_NAME_PROPERTY = "serviceImplementationName"; |
| |
| private static final String SERVICE_IMPLEMENTATION_SUFFIX = "Locator"; |
| |
| private static EngineConfiguration _defaultEngineConfig = null; |
| |
| private static ThreadLocal threadDefaultConfig = new ThreadLocal(); |
| |
| public static void setThreadDefaultConfig(EngineConfiguration config) |
| { |
| threadDefaultConfig.set(config); |
| } |
| |
| private static EngineConfiguration getDefaultEngineConfig() { |
| if (_defaultEngineConfig == null) { |
| _defaultEngineConfig = |
| EngineConfigurationFactoryFinder.newFactory().getClientEngineConfig(); |
| } |
| return _defaultEngineConfig; |
| } |
| |
| /** |
| * Obtain an AxisClient reference, using JNDI if possible, otherwise |
| * creating one using the standard Axis configuration pattern. If we |
| * end up creating one and do have JNDI access, bind it to the passed |
| * name so we find it next time. |
| * |
| * @param environment |
| * @return a service |
| */ |
| public static Service getService(Map environment) |
| { |
| Service service = null; |
| InitialContext context = null; |
| |
| EngineConfiguration configProvider = |
| (EngineConfiguration)environment.get(EngineConfiguration.PROPERTY_NAME); |
| |
| if (configProvider == null) |
| configProvider = (EngineConfiguration)threadDefaultConfig.get(); |
| |
| if (configProvider == null) |
| configProvider = getDefaultEngineConfig(); |
| |
| // First check to see if JNDI works |
| // !!! Might we need to set up context parameters here? |
| try { |
| context = new InitialContext(); |
| } catch (NamingException e) { |
| } |
| |
| if (context != null) { |
| String name = (String)environment.get("jndiName"); |
| if (name == null) { |
| name = "axisServiceName"; |
| } |
| |
| // We've got JNDI, so try to find an AxisClient at the |
| // specified name. |
| try { |
| service = (Service)context.lookup(name); |
| } catch (NamingException e) { |
| service = new Service(configProvider); |
| try { |
| context.bind(name, service); |
| } catch (NamingException e1) { |
| // !!! Couldn't do it, what should we do here? |
| } |
| } |
| } else { |
| service = new Service(configProvider); |
| } |
| |
| return service; |
| } |
| |
| public Object getObjectInstance(Object refObject, Name name, |
| Context nameCtx, Hashtable environment) throws Exception |
| { |
| Object instance = null; |
| if (refObject instanceof Reference) { |
| Reference ref = (Reference) refObject; |
| |
| RefAddr addr = ref.get(SERVICE_CLASSNAME); |
| Object obj = null; |
| // If an explicit service classname is provided, then this is a |
| // generated Service class. Just use its default constructor. |
| if (addr != null && (obj = addr.getContent()) instanceof String) { |
| instance = ClassUtils.forName((String) obj).newInstance(); |
| } |
| // else this is an instance of the Service class, so grab the |
| // reference data... |
| else { |
| // Get the WSDL location... |
| addr = ref.get(WSDL_LOCATION); |
| if (addr != null && (obj = addr.getContent()) instanceof String) { |
| URL wsdlLocation = new URL((String) obj); |
| |
| // Build the service qname... |
| addr = ref.get(SERVICE_NAMESPACE); |
| if (addr != null |
| && (obj = addr.getContent()) instanceof String) { |
| String namespace = (String) obj; |
| addr = ref.get(SERVICE_LOCAL_PART); |
| if (addr != null |
| && (obj = addr.getContent()) instanceof String) { |
| String localPart = (String) obj; |
| QName serviceName = new QName(namespace, localPart); |
| |
| // Construct an instance of the service |
| Class[] formalArgs = new Class[] |
| {URL.class, QName.class}; |
| Object[] actualArgs = new Object[] |
| {wsdlLocation, serviceName}; |
| Constructor ctor = |
| Service.class.getDeclaredConstructor( |
| formalArgs); |
| instance = ctor.newInstance(actualArgs); |
| } |
| } |
| } |
| } |
| // If maintainSession should be set to true, there will be an |
| // addr for it. |
| addr = ref.get(MAINTAIN_SESSION); |
| if (addr != null && instance instanceof Service) { |
| ((Service) instance).setMaintainSession(true); |
| } |
| } |
| return instance; |
| } // getObjectInstance |
| |
| /** |
| * Create a Service instance. |
| * @param wsdlDocumentLocation URL for the WSDL document location |
| for the service |
| * @param serviceName QName for the service. |
| * @return Service. |
| * @throws ServiceException If any error in creation of the specified service |
| */ |
| public javax.xml.rpc.Service createService(URL wsdlDocumentLocation, |
| QName serviceName) throws ServiceException { |
| return new Service(wsdlDocumentLocation, serviceName); |
| } // createService |
| |
| /** |
| * Create a Service instance. Since the WSDL file is not provided |
| * here, the Service object returned is quite simpleminded. |
| * Likewise, the Call object that service.createCall will return |
| * will also be simpleminded. The caller must explicitly fill in |
| * all the info on the Call object (ie., endpoint address, etc.). |
| * |
| * @param serviceName QName for the service |
| * @return Service. |
| * @throws ServiceException If any error in creation of the specified service |
| */ |
| public javax.xml.rpc.Service createService(QName serviceName) |
| throws ServiceException { |
| return new Service(serviceName); |
| } // createService |
| |
| /** |
| * Create an instance of the generated service implementation class |
| * for a given service interface, if available. |
| * |
| * @param serviceInterface Service interface |
| * @return Service. |
| * @throws ServiceException If there is any error while creating the specified service, |
| * including the case where a generated service implementation class cannot be located |
| */ |
| public javax.xml.rpc.Service loadService(Class serviceInterface) throws ServiceException { |
| if (serviceInterface == null) { |
| throw new IllegalArgumentException( |
| Messages.getMessage("serviceFactoryIllegalServiceInterface")); |
| } |
| if (!(javax.xml.rpc.Service.class).isAssignableFrom(serviceInterface)) |
| { |
| throw new ServiceException( |
| Messages.getMessage("serviceFactoryServiceInterfaceRequirement", serviceInterface.getName())); |
| } else { |
| String serviceImplementationName = serviceInterface.getName() + SERVICE_IMPLEMENTATION_SUFFIX; |
| Service service = createService(serviceImplementationName); |
| return service; |
| } |
| } |
| |
| /** |
| * Create an instance of the generated service implementation class |
| * for a given service interface, if available. |
| * An implementation may use the provided wsdlDocumentLocation and properties |
| * to help locate the generated implementation class. |
| * If no such class is present, a ServiceException will be thrown. |
| * |
| * @param wsdlDocumentLocation URL for the WSDL document location for the service or null |
| * @param serviceInterface Service interface |
| * @param properties A set of implementation-specific properties |
| * to help locate the generated service implementation class |
| * @return Service. |
| * @throws ServiceException If there is any error while creating the specified service, |
| * including the case where a generated service implementation class cannot be located |
| */ |
| public javax.xml.rpc.Service loadService(URL wsdlDocumentLocation, |
| Class serviceInterface, Properties properties) throws ServiceException { |
| if (serviceInterface == null) { |
| throw new IllegalArgumentException( |
| Messages.getMessage("serviceFactoryIllegalServiceInterface")); |
| } |
| if (!(javax.xml.rpc.Service.class).isAssignableFrom(serviceInterface)) |
| { |
| throw new ServiceException( |
| Messages.getMessage("serviceFactoryServiceInterfaceRequirement", serviceInterface.getName())); |
| } else { |
| String serviceImplementationName = serviceInterface.getName() + SERVICE_IMPLEMENTATION_SUFFIX; |
| Service service = createService(serviceImplementationName); |
| return service; |
| } |
| } |
| |
| /** |
| * Create an instance of the generated service implementation class |
| * for a given service, if available. |
| * The service is uniquely identified by the wsdlDocumentLocation and serviceName arguments. |
| * An implementation may use the provided properties to help locate the generated implementation class. |
| * If no such class is present, a ServiceException will be thrown. |
| * |
| * @param wsdlDocumentLocation URL for the WSDL document location for the service or null |
| * @param serviceName Qualified name for the service |
| * @param properties A set of implementation-specific properties |
| * to help locate the generated service implementation class |
| * @return Service. |
| * @throws ServiceException If there is any error while creating the specified service, |
| * including the case where a generated service implementation class cannot be located |
| */ |
| public javax.xml.rpc.Service loadService(URL wsdlDocumentLocation, |
| QName serviceName, Properties properties) throws ServiceException { |
| String serviceImplementationName = properties.getProperty(SERVICE_IMPLEMENTATION_NAME_PROPERTY); |
| javax.xml.rpc.Service service = createService(serviceImplementationName); |
| if (service.getServiceName().equals(serviceName)) { |
| return service; |
| } else { |
| throw new ServiceException( |
| Messages.getMessage("serviceFactoryServiceImplementationNotFound", serviceImplementationName)); |
| } |
| } |
| |
| private Service createService(String serviceImplementationName) throws ServiceException { |
| if(serviceImplementationName == null) { |
| throw new IllegalArgumentException(Messages.getMessage("serviceFactoryInvalidServiceName")); |
| } |
| try { |
| Class serviceImplementationClass; |
| serviceImplementationClass = Thread.currentThread().getContextClassLoader().loadClass(serviceImplementationName); |
| if (!(org.apache.axis.client.Service.class).isAssignableFrom(serviceImplementationClass)) { |
| throw new ServiceException( |
| Messages.getMessage("serviceFactoryServiceImplementationRequirement", serviceImplementationName)); |
| } |
| Service service = (Service) serviceImplementationClass.newInstance(); |
| if (service.getServiceName() != null) { |
| return service; |
| } else { |
| throw new ServiceException(Messages.getMessage("serviceFactoryInvalidServiceName")); |
| } |
| } catch (ServiceException e) { |
| throw e; |
| } catch (Exception e){ |
| throw new ServiceException(e); |
| } |
| |
| } |
| } |