1 /* 2 * JBoss, Home of Professional Open Source. 3 * Copyright 2006, Red Hat Middleware LLC, and individual contributors 4 * as indicated by the @author tags. See the copyright.txt file in the 5 * distribution for a full listing of individual contributors. 6 * 7 * This is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU Lesser General Public License as 9 * published by the Free Software Foundation; either version 2.1 of 10 * the License, or (at your option) any later version. 11 * 12 * This software is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this software; if not, write to the Free 19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 21 */ 22 package javax.xml.rpc; 23 24 import java.net.URL; 25 import java.security.AccessController; 26 import java.security.PrivilegedAction; 27 import java.util.Properties; 28 import java.util.logging.Logger; 29 30 import javax.xml.namespace.QName; 31 32 /** The javax.xml.rpc.ServiceFactory is an abstract class that provides a 33 * factory for the creation of instances of the type javax.xml.rpc.Service. 34 * This abstract class follows the abstract static factory design pattern. 35 * This enables a J2SE based client to create a Service instance in a portable 36 * manner without using the constructor of the Service implementation class. 37 * 38 * The ServiceFactory implementation class is set using the 39 * javax.xml.rpc.ServiceFactory System property. 40 * 41 * @author Scott.Stark@jboss.org 42 * @author Thomas.Diesler@jboss.org 43 * @version 1.1 44 */ 45 public abstract class ServiceFactory 46 { 47 // provide logging 48 private static Logger log = Logger.getLogger(ServiceFactory.class.getName()); 49 50 // The singlton 51 private static ServiceFactory factory; 52 53 /** A constant representing the property used to lookup the name of a ServiceFactory implementation class. */ 54 public static final String SERVICEFACTORY_PROPERTY = "javax.xml.rpc.ServiceFactory"; 55 56 private static final String DEFAULT_SERVICE_FACTORY = "org.jboss.ws.core.jaxrpc.client.ServiceFactoryImpl"; 57 private static final String[] alternativeFactories = new String[] {}; 58 59 protected ServiceFactory() 60 { 61 } 62 63 /** Gets an instance of the ServiceFactory 64 * Only one copy of a factory exists and is returned to the application each time this method is called. 65 * 66 * The implementation class to be used can be overridden by setting the javax.xml.rpc.ServiceFactory system property. 67 * 68 * @return The ServiceFactory singleton 69 * @throws ServiceException on failure to instantiate the ServiceFactory impl 70 */ 71 public static ServiceFactory newInstance() throws ServiceException 72 { 73 // Create the factory singleton if needed 74 if (factory == null) 75 { 76 PrivilegedAction action = new PropertyAccessAction(SERVICEFACTORY_PROPERTY, DEFAULT_SERVICE_FACTORY); 77 String factoryName = (String)AccessController.doPrivileged(action); 78 79 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 80 try 81 { 82 try 83 { 84 Class factoryClass = loader.loadClass(factoryName); 85 factory = (ServiceFactory)factoryClass.newInstance(); 86 } 87 catch (ClassNotFoundException e) 88 { 89 // Throw the exception if the user asked for a specific factory 90 if (factoryName.equals(DEFAULT_SERVICE_FACTORY) == false) 91 throw e; 92 93 for (int i = 0; i < alternativeFactories.length; i++) 94 { 95 factoryName = alternativeFactories[i]; 96 try 97 { 98 Class factoryClass = loader.loadClass(factoryName); 99 return (ServiceFactory)factoryClass.newInstance(); 100 } 101 catch (ClassNotFoundException e1) 102 { 103 log.severe("Cannot load factory: " + factoryName); 104 } 105 } 106 } 107 } 108 catch (Throwable e) 109 { 110 throw new ServiceException("Failed to create factory: " + factoryName, e); 111 } 112 } 113 114 if (factory == null) 115 throw new ServiceException("Cannot find ServiceFactory implementation"); 116 117 return factory; 118 } 119 120 /** 121 * Create a <code>Service</code> instance. 122 * 123 * @param wsdlDocumentLocation URL for the WSDL document location 124 * @param serviceName QName for the service. 125 * @return Service. 126 * @throws ServiceException If any error in creation of the 127 * specified service 128 */ 129 public abstract Service createService(URL wsdlDocumentLocation, QName serviceName) throws ServiceException; 130 131 /** 132 * Create a <code>Service</code> instance. 133 * 134 * @param serviceName QName for the service 135 * @return Service. 136 * @throws ServiceException If any error in creation of the specified service 137 */ 138 public abstract Service createService(QName serviceName) throws ServiceException; 139 140 /** Create an instance of the generated service implementation class for a given service interface, if available. 141 * @param serviceInterface Service interface 142 * @return A Service 143 * @throws ServiceException If there is any error while creating the specified service, including the case where a 144 * generated service implementation class cannot be located 145 */ 146 public abstract Service loadService(Class serviceInterface) throws ServiceException; 147 148 /** 149 * Create an instance of the generated service implementation class for a given service interface, if available. 150 * An implementation may use the provided wsdlDocumentLocation and properties to help locate the generated implementation class. 151 * If no such class is present, a ServiceException will be thrown. 152 * 153 * @param wsdlDocumentLocation URL for the WSDL document location for the service or null 154 * @param serviceInterface Service interface 155 * @param props A set of implementation-specific properties to help locate the generated service implementation class 156 * @return A Service 157 * @throws ServiceException If there is any error while creating the specified service, including the case where a 158 * generated service implementation class cannot be located 159 */ 160 public abstract Service loadService(URL wsdlDocumentLocation, Class serviceInterface, Properties props) throws ServiceException; 161 162 /** 163 * Create an instance of the generated service implementation class for a given service, if available. 164 * The service is uniquely identified by the wsdlDocumentLocation and serviceName arguments. 165 * An implementation may use the provided properties to help locate the generated implementation class. 166 * If no such class is present, a ServiceException will be thrown. 167 * 168 * @param wsdlDocumentLocation URL for the WSDL document location for the service or null 169 * @param serviceName Qualified name for the service 170 * @param props A set of implementation-specific properties to help locate the generated service implementation class 171 * @return A Service 172 * @throws ServiceException If there is any error while creating the specified service, including the case where a generated service implementation class cannot be located 173 */ 174 public abstract Service loadService(URL wsdlDocumentLocation, QName serviceName, Properties props) throws ServiceException; 175 176 private static class PropertyAccessAction implements PrivilegedAction 177 { 178 private String name; 179 private String defaultValue; 180 181 PropertyAccessAction(String name, String defaultValue) 182 { 183 this.name = name; 184 this.defaultValue = defaultValue; 185 } 186 187 public Object run() 188 { 189 return System.getProperty(name, defaultValue); 190 } 191 } 192 }