KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > configuration > EngineConfigurationFactoryFinder


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Axis" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  */

55
56 package org.jboss.axis.configuration;
57
58 import org.apache.commons.discovery.ResourceClassIterator;
59 import org.apache.commons.discovery.tools.ClassUtils;
60 import org.jboss.axis.AxisProperties;
61 import org.jboss.axis.EngineConfigurationFactory;
62 import org.jboss.axis.utils.Messages;
63 import org.jboss.logging.Logger;
64
65 import java.lang.reflect.InvocationTargetException JavaDoc;
66 import java.lang.reflect.Method JavaDoc;
67 import java.security.AccessController JavaDoc;
68 import java.security.PrivilegedAction JavaDoc;
69
70
71 /**
72  * This is a default implementation of EngineConfigurationFactory.
73  * It is user-overrideable by a system property without affecting
74  * the caller. If you decide to override it, use delegation if
75  * you want to inherit the behaviour of this class as using
76  * class extension will result in tight loops. That is, your
77  * class should implement EngineConfigurationFactory and keep
78  * an instance of this class in a member field and delegate
79  * methods to that instance when the default behaviour is
80  * required.
81  *
82  * @author Richard A. Sitze
83  */

84 public class EngineConfigurationFactoryFinder
85 {
86    private static Logger log = Logger.getLogger(EngineConfigurationFactoryFinder.class.getName());
87
88    private static final Class JavaDoc mySpi = EngineConfigurationFactory.class;
89
90    private static final Class JavaDoc[] newFactoryParamTypes =
91            new Class JavaDoc[]{Object JavaDoc.class};
92
93    private static final String JavaDoc requiredMethod =
94            "public static EngineConfigurationFactory newFactory(Object)";
95
96    static
97    {
98       AxisProperties.setClassOverrideProperty(EngineConfigurationFactory.class,
99               EngineConfigurationFactory.SYSTEM_PROPERTY_NAME);
100
101       AxisProperties.setClassDefaults(EngineConfigurationFactory.class,
102               new String JavaDoc[]{
103                  "org.jboss.axis.configuration.EngineConfigurationFactoryServlet",
104                  "org.jboss.axis.configuration.EngineConfigurationFactoryDefault",
105               });
106    }
107
108    private EngineConfigurationFactoryFinder()
109    {
110    }
111
112
113    /**
114     * Create the default engine configuration and detect whether the user
115     * has overridden this with their own.
116     * <p/>
117     * The discovery mechanism will use the following logic:
118     * <p/>
119     * - discover all available EngineConfigurationFactories
120     * - find all META-INF/services/org.jboss.axis.EngineConfigurationFactory
121     * files available through class loaders.
122     * - read files (see Discovery) to obtain implementation(s) of that
123     * interface
124     * - For each impl, call 'newFactory(Object param)'
125     * - Each impl should examine the 'param' and return a new factory ONLY
126     * - if it knows what to do with it
127     * (i.e. it knows what to do with the 'real' type)
128     * - it can find it's configuration information
129     * - Return first non-null factory found.
130     * - Try EngineConfigurationFactoryServlet.newFactory(obj)
131     * - Try EngineConfigurationFactoryDefault.newFactory(obj)
132     * - If zero found (all return null), throw exception
133     * <p/>
134     * ***
135     * This needs more work: System.properties, etc.
136     * Discovery will have more tools to help with that
137     * (in the manner of use below) in the near future.
138     * ***
139     */

140    public static EngineConfigurationFactory newFactory(final Object JavaDoc obj)
141    {
142       /**
143        * recreate on each call is critical to gaining
144        * the right class loaders. Do not cache.
145        */

146       final Object JavaDoc[] params = new Object JavaDoc[]{obj};
147
148       /**
149        * Find and examine each service
150        */

151       return (EngineConfigurationFactory)AccessController.doPrivileged(new PrivilegedAction JavaDoc()
152       {
153          public Object JavaDoc run()
154          {
155             ResourceClassIterator services = AxisProperties.getResourceClassIterator(mySpi);
156
157             EngineConfigurationFactory factory = null;
158
159             while (factory == null && services.hasNext())
160             {
161                try
162                {
163                   Class JavaDoc service = services.nextResourceClass().loadClass();
164
165                   /* service == null
166                    * if class resource wasn't loadable
167                    */

168                   if (service != null)
169                   {
170                      factory = newFactory(service, newFactoryParamTypes, params);
171                   }
172                }
173                catch (Exception JavaDoc e)
174                {
175                   // there was an exception creating the factory
176
// the most likely cause was the JDK 1.4 problem
177
// in the discovery code that requires servlet.jar
178
// to be in the client classpath. For now, fall
179
// through to the next factory
180
}
181             }
182
183             if (factory != null)
184             {
185                if (log.isDebugEnabled())
186                {
187                   log.debug(Messages.getMessage("engineFactory", factory.getClass().getName()));
188                }
189             }
190             else
191             {
192                log.error(Messages.getMessage("engineConfigFactoryMissing"));
193                // we should be throwing an exception here,
194
//
195
// but again, requires more refactoring than we want to swallow
196
// at this point in time. Ifthis DOES occur, it's a coding error:
197
// factory should NEVER be null.
198
// Testing will find this, as NullPointerExceptions will be generated
199
// elsewhere.
200
}
201
202             return factory;
203          }
204       });
205    }
206
207    public static EngineConfigurationFactory newFactory()
208    {
209       return newFactory(null);
210    }
211
212    private static EngineConfigurationFactory newFactory(Class JavaDoc service,
213                                                         Class JavaDoc[] paramTypes,
214                                                         Object JavaDoc[] param)
215    {
216       /**
217        * Some JDK's may link on method resolution (findPublicStaticMethod)
218        * and others on method call (method.invoke).
219        *
220        * Either way, catch class load/resolve problems and return null.
221        */

222
223       try
224       {
225          /**
226           * Verify that service implements:
227           * public static EngineConfigurationFactory newFactory(Object);
228           */

229          Method JavaDoc method = ClassUtils.findPublicStaticMethod(service,
230                  EngineConfigurationFactory.class,
231                  "newFactory",
232                  paramTypes);
233
234          if (method == null)
235          {
236             log.warn(Messages.getMessage("engineConfigMissingNewFactory",
237                     service.getName(),
238                     requiredMethod));
239          }
240          else
241          {
242             try
243             {
244                return (EngineConfigurationFactory)method.invoke(null, param);
245             }
246             catch (InvocationTargetException JavaDoc e)
247             {
248                if (e.getTargetException() instanceof NoClassDefFoundError JavaDoc)
249                {
250                   log.debug(Messages.getMessage("engineConfigLoadFactory",
251                           service.getName()));
252                }
253                else
254                {
255                   log.warn(Messages.getMessage("engineConfigInvokeNewFactory",
256                           service.getName(),
257                           requiredMethod), e);
258                }
259             }
260             catch (Exception JavaDoc e)
261             {
262                log.warn(Messages.getMessage("engineConfigInvokeNewFactory",
263                        service.getName(),
264                        requiredMethod), e);
265             }
266          }
267       }
268       catch (NoClassDefFoundError JavaDoc e)
269       {
270          log.debug(Messages.getMessage("engineConfigLoadFactory",
271                  service.getName()));
272       }
273
274       return null;
275    }
276 }
277
Popular Tags