Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/axis/client/ServiceFactory.java


1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.axis.client;
18  
19  import org.apache.axis.EngineConfiguration;
20  import org.apache.axis.configuration.EngineConfigurationFactoryFinder;
21  import org.apache.axis.utils.ClassUtils;
22  import org.apache.axis.utils.Messages;
23  
24  import javax.naming.Context;
25  import javax.naming.InitialContext;
26  import javax.naming.Name;
27  import javax.naming.NamingException;
28  import javax.naming.RefAddr;
29  import javax.naming.Reference;
30  import javax.naming.spi.ObjectFactory;
31  import javax.xml.namespace.QName;
32  import javax.xml.rpc.ServiceException;
33  import java.lang.reflect.Constructor;
34  import java.net.URL;
35  import java.util.Hashtable;
36  import java.util.Map;
37  import java.util.Properties;
38  
39  /**
40   * Helper class for obtaining Services from JNDI.
41   *
42   * !!! WORK IN PROGRESS
43   * 
44   * @author Glen Daniels (gdaniels@apache.org)
45   */ 
46  
47  public class ServiceFactory extends javax.xml.rpc.ServiceFactory
48          implements ObjectFactory
49  {
50      // Constants for RefAddrs in the Reference.
51      public static final String SERVICE_CLASSNAME  = "service classname";
52      public static final String WSDL_LOCATION      = "WSDL location";
53      public static final String MAINTAIN_SESSION   = "maintain session";
54      public static final String SERVICE_NAMESPACE  = "service namespace";
55      public static final String SERVICE_LOCAL_PART = "service local part";
56      public static final String SERVICE_IMPLEMENTATION_NAME_PROPERTY = "serviceImplementationName";
57  
58      private static final String SERVICE_IMPLEMENTATION_SUFFIX = "Locator";
59  
60      private static EngineConfiguration _defaultEngineConfig = null;
61  
62      private static ThreadLocal threadDefaultConfig = new ThreadLocal();
63  
64      public static void setThreadDefaultConfig(EngineConfiguration config)
65      {
66          threadDefaultConfig.set(config);
67      }
68      
69      private static EngineConfiguration getDefaultEngineConfig() {
70          if (_defaultEngineConfig == null) {
71              _defaultEngineConfig =
72                  EngineConfigurationFactoryFinder.newFactory().getClientEngineConfig();
73          }
74          return _defaultEngineConfig;
75      }
76  
77      /**
78       * Obtain an AxisClient reference, using JNDI if possible, otherwise
79       * creating one using the standard Axis configuration pattern.  If we
80       * end up creating one and do have JNDI access, bind it to the passed
81       * name so we find it next time.
82       *
83       * @param environment
84       * @return a service
85       */
86      public static Service getService(Map environment)
87      {
88          Service service = null;
89          InitialContext context = null;
90  
91          EngineConfiguration configProvider =
92              (EngineConfiguration)environment.get(EngineConfiguration.PROPERTY_NAME);
93  
94          if (configProvider == null)
95              configProvider = (EngineConfiguration)threadDefaultConfig.get();
96  
97          if (configProvider == null)
98              configProvider = getDefaultEngineConfig();
99  
100         // First check to see if JNDI works
101         // !!! Might we need to set up context parameters here?
102         try {
103             context = new InitialContext();
104         } catch (NamingException e) {
105         }
106         
107         if (context != null) {
108             String name = (String)environment.get("jndiName");
109             if (name == null) {
110                 name = "axisServiceName";
111             }
112 
113             // We've got JNDI, so try to find an AxisClient at the
114             // specified name.
115             try {
116                 service = (Service)context.lookup(name);
117             } catch (NamingException e) {
118                 service = new Service(configProvider);
119                 try {
120                     context.bind(name, service);
121                 } catch (NamingException e1) {
122                     // !!! Couldn't do it, what should we do here?
123                 }
124             }
125         } else {
126             service = new Service(configProvider);
127         }
128 
129         return service;
130     }
131 
132     public Object getObjectInstance(Object refObject, Name name,
133             Context nameCtx, Hashtable environment) throws Exception
134     {
135         Object instance = null;
136         if (refObject instanceof Reference) {
137             Reference ref = (Reference) refObject;
138 
139             RefAddr addr = ref.get(SERVICE_CLASSNAME);
140             Object obj = null;
141             // If an explicit service classname is provided, then this is a
142             // generated Service class.  Just use its default constructor.
143             if (addr != null && (obj = addr.getContent()) instanceof String) {
144                 instance = ClassUtils.forName((String) obj).newInstance();
145             }
146             // else this is an instance of the Service class, so grab the
147             // reference data...
148             else {
149                 // Get the WSDL location...
150                 addr = ref.get(WSDL_LOCATION);
151                 if (addr != null && (obj = addr.getContent()) instanceof String) {
152                     URL wsdlLocation = new URL((String) obj);
153 
154                     // Build the service qname...
155                     addr = ref.get(SERVICE_NAMESPACE);
156                     if (addr != null
157                         && (obj = addr.getContent()) instanceof String) {
158                         String namespace = (String) obj;
159                         addr = ref.get(SERVICE_LOCAL_PART);
160                         if (addr != null
161                             && (obj = addr.getContent()) instanceof String) {
162                             String localPart = (String) obj;
163                             QName serviceName = new QName(namespace, localPart);
164 
165                             // Construct an instance of the service
166                             Class[] formalArgs = new Class[]
167                                     {URL.class, QName.class};
168                             Object[] actualArgs = new Object[]
169                                     {wsdlLocation, serviceName};
170                             Constructor ctor =
171                                     Service.class.getDeclaredConstructor(
172                                     formalArgs);
173                             instance = ctor.newInstance(actualArgs);
174                         }
175                     }
176                 }
177             }
178             // If maintainSession should be set to true, there will be an
179             // addr for it.
180             addr = ref.get(MAINTAIN_SESSION);
181             if (addr != null && instance instanceof Service) {
182                 ((Service) instance).setMaintainSession(true);
183             }
184         }
185         return instance;
186     } // getObjectInstance
187 
188     /**
189      *  Create a Service instance.
190      *  @param   wsdlDocumentLocation URL for the WSDL document location
191                               for the service
192      *  @param   serviceName  QName for the service.
193      *  @return  Service.
194      *  @throws  ServiceException If any error in creation of the specified service
195      */
196     public javax.xml.rpc.Service createService(URL wsdlDocumentLocation,
197             QName serviceName) throws ServiceException {
198         return new Service(wsdlDocumentLocation, serviceName);
199     } // createService
200 
201     /**
202      * Create a Service instance.  Since the WSDL file is not provided
203      * here, the Service object returned is quite simpleminded.
204      * Likewise, the Call object that service.createCall will return
205      * will also be simpleminded.  The caller must explicitly fill in
206      * all the info on the Call object (ie., endpoint address, etc.).
207      *
208      *  @param   serviceName QName for the service
209      *  @return  Service.
210      *  @throws  ServiceException If any error in creation of the specified service
211      */
212     public javax.xml.rpc.Service createService(QName serviceName)
213             throws ServiceException {
214         return new Service(serviceName);
215     } // createService
216 
217     /**
218      * Create an instance of the generated service implementation class 
219      * for a given service interface, if available. 
220      *
221      *  @param   serviceInterface Service interface 
222      *  @return  Service.
223      *  @throws  ServiceException If there is any error while creating the specified service, 
224      *      including the case where a generated service implementation class cannot be located
225      */
226     public javax.xml.rpc.Service loadService(Class serviceInterface) throws ServiceException {
227         if (serviceInterface == null) {
228             throw new IllegalArgumentException(
229                     Messages.getMessage("serviceFactoryIllegalServiceInterface"));
230         }
231         if (!(javax.xml.rpc.Service.class).isAssignableFrom(serviceInterface))
232         {
233             throw new ServiceException(
234                     Messages.getMessage("serviceFactoryServiceInterfaceRequirement", serviceInterface.getName()));
235         } else {
236             String serviceImplementationName = serviceInterface.getName() + SERVICE_IMPLEMENTATION_SUFFIX;
237             Service service = createService(serviceImplementationName);
238             return service;
239         }
240     }
241 
242     /**
243      * Create an instance of the generated service implementation class 
244      * for a given service interface, if available. 
245      * An implementation may use the provided wsdlDocumentLocation and properties 
246      * to help locate the generated implementation class. 
247      * If no such class is present, a ServiceException will be thrown.
248      *
249      *  @param   wsdlDocumentLocation URL for the WSDL document location for the service or null 
250      *  @param   serviceInterface Service interface 
251      *  @param   properties A set of implementation-specific properties 
252      *      to help locate the generated service implementation class 
253      *  @return  Service.
254      *  @throws  ServiceException If there is any error while creating the specified service, 
255      *      including the case where a generated service implementation class cannot be located
256      */
257     public javax.xml.rpc.Service loadService(URL wsdlDocumentLocation, 
258             Class serviceInterface, Properties properties) throws ServiceException {
259         if (serviceInterface == null) {
260             throw new IllegalArgumentException(
261                     Messages.getMessage("serviceFactoryIllegalServiceInterface"));
262         }
263         if (!(javax.xml.rpc.Service.class).isAssignableFrom(serviceInterface))
264         {
265             throw new ServiceException(
266                     Messages.getMessage("serviceFactoryServiceInterfaceRequirement", serviceInterface.getName()));
267         } else {
268             String serviceImplementationName = serviceInterface.getName() + SERVICE_IMPLEMENTATION_SUFFIX;
269             Service service = createService(serviceImplementationName);
270             return service;
271         }
272     }
273 
274     /**
275      * Create an instance of the generated service implementation class 
276      * for a given service, if available. 
277      * The service is uniquely identified by the wsdlDocumentLocation and serviceName arguments. 
278      * An implementation may use the provided properties to help locate the generated implementation class. 
279      * If no such class is present, a ServiceException will be thrown. 
280      *
281      *  @param   wsdlDocumentLocation URL for the WSDL document location for the service or null 
282      *  @param   serviceName Qualified name for the service 
283      *  @param   properties A set of implementation-specific properties 
284      *      to help locate the generated service implementation class 
285      *  @return  Service.
286      *  @throws  ServiceException If there is any error while creating the specified service, 
287      *      including the case where a generated service implementation class cannot be located
288      */
289     public javax.xml.rpc.Service loadService(URL wsdlDocumentLocation, 
290             QName serviceName, Properties properties) throws ServiceException {
291         String serviceImplementationName = properties.getProperty(SERVICE_IMPLEMENTATION_NAME_PROPERTY);
292         javax.xml.rpc.Service service = createService(serviceImplementationName);
293         if (service.getServiceName().equals(serviceName)) {
294             return service;
295         } else {
296             throw new ServiceException(
297                     Messages.getMessage("serviceFactoryServiceImplementationNotFound", serviceImplementationName));
298         }
299     }
300 
301     private Service createService(String serviceImplementationName) throws ServiceException {
302         if(serviceImplementationName == null) {
303             throw new IllegalArgumentException(Messages.getMessage("serviceFactoryInvalidServiceName"));
304         }
305         try {
306             Class serviceImplementationClass;
307             serviceImplementationClass = Thread.currentThread().getContextClassLoader().loadClass(serviceImplementationName);
308             if (!(org.apache.axis.client.Service.class).isAssignableFrom(serviceImplementationClass)) {
309                 throw new ServiceException(
310                         Messages.getMessage("serviceFactoryServiceImplementationRequirement", serviceImplementationName));
311             }
312             Service service = (Service) serviceImplementationClass.newInstance();
313             if (service.getServiceName() != null) {
314                 return service;
315             } else {
316                 throw new ServiceException(Messages.getMessage("serviceFactoryInvalidServiceName"));
317             }
318         } catch (ServiceException e) {
319             throw e;
320         } catch (Exception e){
321             throw new ServiceException(e);
322         }
323         
324     }
325 }