KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > net > axis > Deployment


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7  
8 // $Id: Deployment.java,v 1.16.2.3 2005/03/02 14:19:53 tdiesler Exp $
9
package org.jboss.net.axis;
10
11 // axis config and utils
12

13 import org.jboss.axis.ConfigurationException;
14 import org.jboss.axis.MessageContext;
15 import org.jboss.axis.deployment.wsdd.WSDDConstants;
16 import org.jboss.axis.deployment.wsdd.WSDDDeployment;
17 import org.jboss.axis.deployment.wsdd.WSDDException;
18 import org.jboss.axis.deployment.wsdd.WSDDProvider;
19 import org.jboss.axis.deployment.wsdd.WSDDService;
20 import org.jboss.axis.deployment.wsdd.WSDDTypeMapping;
21 import org.jboss.axis.encoding.TypeMappingRegistry;
22 import org.jboss.axis.handlers.soap.SOAPService;
23 import org.jboss.logging.Logger;
24 import org.w3c.dom.Element JavaDoc;
25
26 import javax.xml.namespace.QName JavaDoc;
27 import javax.xml.rpc.encoding.DeserializerFactory JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30
31 /**
32  * <p/>
33  * This subclass represents a wsdd deployment
34  * with scoped typemappings and service-specific
35  * classloading features. It may also serve as a place to
36  * statically register some other jboss-specific
37  * implementation classes in the axis package.
38  * </p>
39  * <p/>
40  * WSDDDeployment is used by Axis in two respects: Two parse a
41  * deployment descriptor and to host the accumulated
42  * configuration data. We use that circumstance to build up
43  * an additional deployment scope in jboss.net - services are
44  * registered in the central registry/engine but still pertain
45  * their relation (especially wrt typemapping delegation) to their
46  * original deployment. We do that by annotating the scope deployments
47  * in the service options.
48  * </p>
49  * <p/>
50  * This design is IMHO more clever and needs less
51  * overhead than the original approach of mapping services to
52  * classloaders. Furthermore, it allows us to introduce some JSR109
53  * related deployment concepts without global effect.
54  * </p>
55  *
56  * @author <a HREF="mailto:Christoph.Jung@infor.de">Christoph G. Jung</a>
57  * @version $Revision: 1.16.2.3 $
58  * @since 09.03.2002
59  */

60
61 public class Deployment extends WSDDDeployment
62 {
63
64    private static Logger log = Logger.getLogger(Deployment.class);
65
66    //
67
// Attributes
68
//
69

70    /**
71     * holds the classloader related to this deployment
72     * which is the thread context classloader at creation time
73     */

74    protected ClassLoader JavaDoc deploymentLoader;
75
76    /**
77     * these are our local typemappings
78     */

79    protected List JavaDoc typeMappings = new java.util.ArrayList JavaDoc();
80
81    /**
82     * whether our registry has already been built
83     */

84    protected boolean tmrCreated;
85    
86    /**
87     * this handler provider will be injected into Axis to load
88     * implementations from the right classloaders
89     */

90    static
91    {
92       WSDDProvider.registerProvider(WSDDConstants.QNAME_HANDLER_PROVIDER,
93               new ServiceClassLoaderAwareWSDDHandlerProvider());
94    }
95
96    //
97
// Constructors
98
//
99

100    /**
101     * Constructor for Deployment. Is used with server-config.wsdd
102     * in order to build the engine configuration. Is used with
103     * actual deployment documents to build scoped deployments.
104     * After calling the super constructor, we rebuild the typemappings
105     * with our typemapping implementation that may contain additional
106     * typemapping options. Unfortunately, you will have to do an
107     * enclosing Thread.currentThread().setContextClassLoader(loader)
108     * because of the f**cked constructor functionality of the super class.
109     * Its a 1st grade Java rule, guys! So rather use the static factory method.
110     */

111
112    protected Deployment(Element JavaDoc e, ClassLoader JavaDoc loader) throws WSDDException
113    {
114       super(e);
115       this.deploymentLoader = loader;
116       // if axis did use more factories, we did not have to do this
117
Element JavaDoc[] elements = getChildElements(e, "typeMapping");
118       for (int i = 0; i < elements.length; i++)
119       {
120          TypeMapping mapping = new TypeMapping(elements[i]);
121          deployTypeMapping(mapping);
122       }
123    }
124
125    /**
126     * the safe "constructor"
127     */

128    public static Deployment makeSafeDeployment(Element JavaDoc e, ClassLoader JavaDoc loader) throws WSDDException
129    {
130       ClassLoader JavaDoc old = Thread.currentThread().getContextClassLoader();
131       Thread.currentThread().setContextClassLoader(loader);
132       try
133       {
134          return new Deployment(e, loader);
135       }
136       finally
137       {
138          Thread.currentThread().setContextClassLoader(old);
139       }
140    }
141    
142    //
143
// protected helpers
144
//
145

146    /**
147     * return the deployment loader of this deployment
148     */

149    protected ClassLoader JavaDoc getDeploymentLoader()
150    {
151       return deploymentLoader;
152    }
153
154    /**
155     * return the scoped deployment for this service
156     */

157    protected static Deployment getDeployment(WSDDService service)
158    {
159       return (
160               (Deployment)service.getParametersTable().get(Constants.SERVICE_DEPLOYMENT_PARAMETER));
161    }
162
163    //
164
// Public API
165
//
166

167    /* (non-Javadoc)
168     * this is called whenever a service is parsed. This means that
169     * we will mark it to belong to us (and our classloader). Furthermore,
170     * upon existance of a dedicated paramter flag, we will shift the
171     * jaxrpc handler chain of the service into a separate property such
172     * that the provider class instead of the SoapService can control
173     * when it will be called.
174     * @see org.jboss.axis.deployment.wsdd.WSDDDeployment#deployService(org.jboss.axis.deployment.wsdd.WSDDService)
175     */

176
177    public void deployService(WSDDService service)
178    {
179       // registers deployment instance in service
180
// note that besides this entry, there will be only strings
181
// in the hashtable so maybe axis will hickup at some places
182
// when it does not expect a real instance value
183
service.getParametersTable().put(Constants.SERVICE_DEPLOYMENT_PARAMETER,
184               this);
185        
186       // do the handler chain shifting only once for parsing
187
if (service.getHandlerInfoChain() != null && "true".equals(service.getParameter(Constants.USE_PROVIDER_HANDLER_CHAIN)))
188       {
189          service.getParametersTable().put(Constants.PROVIDER_HANDLER_CHAIN, service.getHandlerInfoChain());
190          service.setParameter(Constants.USE_PROVIDER_HANDLER_CHAIN, "false");
191          service.setHandlerInfoChain(null);
192       }
193       super.deployService(service);
194    }
195
196    /**
197     * overwrite to equip with options
198     */

199    public void deployTypeMapping(WSDDTypeMapping typeMapping)
200            throws WSDDException
201    {
202       // we only register our own stuff ;-)
203
if (typeMapping instanceof TypeMapping)
204       {
205          if (tmrCreated)
206          {
207             try
208             {
209                installTypeMappingWithOptions((TypeMapping)typeMapping);
210             }
211             catch (ConfigurationException e)
212             {
213                throw new WSDDException("Could not install type mapping with options." + e);
214             }
215          }
216          else
217          {
218             typeMappings.add(typeMapping);
219          }
220       }
221    }
222
223    /*
224     * overrides the getdeployedservices method in order
225     * to prebuild the service instances (and hence
226     * address classloading issues when browsing
227     * the services list during a "get")
228     * implicitely requires a current message context
229     * for which the serviceservlet must cater.
230     * @see org.jboss.axis.EngineConfiguration#getDeployedServices()
231     */

232
233    public Iterator JavaDoc getDeployedServices() throws ConfigurationException
234    {
235       List JavaDoc serviceDescs = new java.util.ArrayList JavaDoc();
236       WSDDService[] services = getServices();
237       for (int count = 0; count < services.length; count++)
238       {
239          try
240          {
241             serviceDescs.add(getService(services[count].getQName()).
242                     getServiceDescription());
243          }
244          catch (ConfigurationException ex)
245          {
246             // If it's non-fatal, just keep on going
247
log.debug("Ingoring non-fatal exception: ", ex);
248          }
249       }
250       return serviceDescs.iterator();
251    }
252
253    /**
254     * hides the "old" uncoped way of constructing services and their
255     * tmrs and wraps it into a classloader aware shell
256     *
257     * @param serviceName
258     * @return
259     * @throws ConfigurationException
260     */

261
262    private SOAPService getServiceInternal(QName JavaDoc serviceName)
263            throws ConfigurationException
264    {
265       // This hack sets the deployment loader as the TCL
266
// If this is not done the org.jboss.test.jbossnet.admindevel.ExampleTestCase fails on redeployment
267
// The reason is that the HelloObj[] class gets loaded from a stale classloader
268
ClassLoader JavaDoc deploymentLoader = getDeploymentLoader();
269       Thread.currentThread().setContextClassLoader(deploymentLoader);
270
271       MessageContext currentContext = MessageContext.getCurrentContext();
272       if (currentContext != null)
273          currentContext.setClassLoader(deploymentLoader);
274
275       return super.getService(serviceName);
276    }
277
278    /* overrides the getService method in order
279     * to address scoping issues when setting service
280     * affinity. requires a current message context
281     * for which the serviceservlet must cater.
282     * @see org.jboss.axis.EngineConfiguration#getService(javax.xml.namespace.QName)
283     */

284
285    public SOAPService getService(QName JavaDoc serviceName) throws ConfigurationException
286    {
287       // we lookup the service meta-data
288
WSDDService wsddService = getWSDDService(serviceName);
289       if (wsddService != null)
290       {
291          // if its is there, we delegate to the scope deployment
292
// to do the real work
293
return getDeployment(wsddService).getServiceInternal(serviceName);
294       }
295       return null;
296    }
297
298    /* (non-Javadoc)
299     * the only place were ive seen accesses to that ugly function was in
300     * the client code when parsing replies to a non-configured service in order
301     * to get operationdescs. Seems like this will not break anything ...
302     * @see org.jboss.axis.EngineConfiguration#getServiceByNamespaceURI(java.lang.String)
303     */

304
305    public SOAPService getServiceByNamespaceURI(String JavaDoc arg0)
306            throws ConfigurationException
307    {
308       return null;
309    }
310
311    /* (non-Javadoc)
312     * when we deploy to a registry, we only want our services to be seen,
313     * but do not want our typemappings there
314     * @see org.jboss.axis.deployment.wsdd.WSDDDeployment#deployToRegistry(org.jboss.axis.deployment.wsdd.WSDDDeployment)
315     */

316    public void deployToRegistry(WSDDDeployment arg0)
317            throws ConfigurationException
318    {
319       // do the usual deployment stuff (remember that super.typeMappings
320
// will still be empty at this point).
321
super.deployToRegistry(arg0);
322       // pretend the same engine
323
configureEngine(arg0.getEngine());
324       // we delegate to the registries type mapping registry (and get
325
// our local typemappings installed here before)
326
getTypeMappingRegistry().delegate(arg0.getTypeMappingRegistry());
327    }
328
329
330    /* (non-Javadoc)
331     * @see org.jboss.axis.EngineConfiguration#getTypeMappingRegistry()
332     */

333    public TypeMappingRegistry getTypeMappingRegistry()
334            throws ConfigurationException
335    {
336       // if we need to create the tmr for the first time
337
if (!tmrCreated)
338       {
339          tmrCreated = true;
340          // we need to get all our typemappings known by our superclass
341
// because we want to hide them from the global registry
342
for (Iterator JavaDoc allTms = typeMappings.iterator(); allTms.hasNext();)
343          {
344             TypeMapping nextMapping = (TypeMapping)allTms.next();
345             installTypeMappingWithOptions(nextMapping);
346          }
347          tmrCreated = true;
348       }
349       // do the super call in each case
350
return super.getTypeMappingRegistry();
351    }
352
353    /**
354     * this helper serves to install typemappings with additional options
355     */

356    protected void installTypeMappingWithOptions(TypeMapping nextMapping) throws ConfigurationException
357    {
358       ClassLoader JavaDoc oldLoader = Thread.currentThread().getContextClassLoader();
359       Thread.currentThread().setContextClassLoader(getDeploymentLoader());
360       try
361       {
362          // first make sure that the mapping is installed correctly
363
super.deployTypeMapping(nextMapping);
364          // then access the factories in order to put the info there
365
org.jboss.axis.encoding.TypeMapping axisMapping =
366                  (org.jboss.axis.encoding.TypeMapping)getTypeMappingRegistry()
367                  .getTypeMapping(nextMapping.getEncodingStyle());
368          DeserializerFactory JavaDoc dser =
369                  axisMapping.getDeserializer(nextMapping.getQName());
370          if (dser instanceof ParameterizableDeserializerFactory)
371          {
372             // Load up our params
373
((ParameterizableDeserializerFactory)dser).setOptions(((TypeMapping)nextMapping).getParametersTable());
374          }
375       }
376       finally
377       {
378          Thread.currentThread().setContextClassLoader(oldLoader);
379       }
380    }
381
382 }
Popular Tags