KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jelly > impl > DefaultTagLibraryResolver


1 /*
2  * Copyright 2002,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 package org.apache.commons.jelly.impl;
17
18 import org.apache.commons.discovery.ResourceClass;
19 import org.apache.commons.discovery.ResourceClassIterator;
20 import org.apache.commons.discovery.resource.ClassLoaders;
21 import org.apache.commons.discovery.resource.classes.DiscoverClasses;
22 import org.apache.commons.jelly.TagLibrary;
23 import org.apache.commons.jelly.util.ClassLoaderUtils;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27
28 /**
29  * <p><code>DefaultTagLibraryResolver</code> is a default implemenation
30  * which attempts to interpret the URI as a String called 'jelly:className'
31  * and class load the given Java class. Otherwise META-INF/services/jelly/uri
32  * is searched for on the thread context's class path and, if found, that
33  * class will be loaded.</p>
34  *
35  * @author <a HREF="mailto:jstrachan@apache.org">James Strachan</a>
36  * @version $Revision: 155420 $
37  */

38 public class DefaultTagLibraryResolver implements TagLibraryResolver {
39
40     /** The Log to which logging calls will be made. */
41     private static final Log log = LogFactory.getLog(DefaultTagLibraryResolver.class);
42
43     private DiscoverClasses discovery;
44
45     /**
46      * The class loader to use for instantiating application objects.
47      * If not specified, the context class loader, or the class loader
48      * used to load this class itself, is used, based on the value of the
49      * <code>useContextClassLoader</code> variable.
50      */

51     private ClassLoader JavaDoc classLoader;
52
53     /**
54      * Do we want to use the Context ClassLoader when loading classes
55      * for instantiating new objects? Default is <code>false</code>.
56      */

57     private boolean useContextClassLoader = false;
58
59
60     public DefaultTagLibraryResolver() {
61     }
62
63
64     // TagLibraryResolver interface
65
//-------------------------------------------------------------------------
66

67     /**
68      * Attempts to resolve the given URI to be associated with a TagLibrary
69      * otherwise null is returned to indicate no tag library could be found
70      * so that the namespace URI should be treated as just vanilla XML.
71      */

72     public TagLibrary resolveTagLibrary(String JavaDoc uri) {
73         DiscoverClasses discovery = getDiscoverClasses();
74         String JavaDoc name = uri;
75         if ( uri.startsWith( "jelly:" ) ) {
76             name = "jelly." + uri.substring(6);
77         }
78
79         log.info( "Looking up service name: " + name );
80
81 /*
82         ClassLoaders loaders = ClassLoaders.getAppLoaders(TagLibrary.class, getClass(), false);
83
84         DiscoverClass discover = new DiscoverClass(loaders);
85         Class implClass = discover.find(TestInterface2.class);
86
87
88
89         TagLibrary answer = null;
90         try {
91             answer = (TagLibrary) DiscoverSingleton.find(TagLibrary.class, name);
92         }
93         catch (Exception e) {
94             log.error( "Could not load service: " + name );
95         }
96         return answer;
97 */

98         ResourceClassIterator iter = discovery.findResourceClasses(name);
99         while (iter.hasNext()) {
100             ResourceClass resource = iter.nextResourceClass();
101             try {
102                 Class JavaDoc typeClass = resource.loadClass();
103                 if ( typeClass != null ) {
104                     return newInstance(uri, typeClass);
105                 }
106             }
107             catch (Exception JavaDoc e) {
108                 log.error( "Could not load service: " + resource );
109             }
110         }
111         log.info( "Could not find any services for name: " + name );
112         return null;
113     }
114
115     // Properties
116
//-------------------------------------------------------------------------
117

118     /**
119      * Return the class loader to be used for instantiating application objects
120      * when required. This is determined based upon the following rules:
121      * <ul>
122      * <li>The class loader set by <code>setClassLoader()</code>, if any</li>
123      * <li>The thread context class loader, if it exists and the
124      * <code>useContextClassLoader</code> property is set to true</li>
125      * <li>The class loader used to load the XMLParser class itself.
126      * </ul>
127      */

128     public ClassLoader JavaDoc getClassLoader() {
129         return ClassLoaderUtils.getClassLoader(classLoader, useContextClassLoader, getClass());
130     }
131
132     /**
133      * Set the class loader to be used for instantiating application objects
134      * when required.
135      *
136      * @param classLoader The new class loader to use, or <code>null</code>
137      * to revert to the standard rules
138      */

139     public void setClassLoader(ClassLoader JavaDoc classLoader) {
140         this.classLoader = classLoader;
141     }
142
143     /**
144      * Return the boolean as to whether the context classloader should be used.
145      */

146     public boolean getUseContextClassLoader() {
147         return useContextClassLoader;
148     }
149
150     /**
151      * Determine whether to use the Context ClassLoader (the one found by
152      * calling <code>Thread.currentThread().getContextClassLoader()</code>)
153      * to resolve/load classes. If not
154      * using Context ClassLoader, then the class-loading defaults to
155      * using the calling-class' ClassLoader.
156      *
157      * @param boolean determines whether to use JellyContext ClassLoader.
158      */

159     public void setUseContextClassLoader(boolean use) {
160         useContextClassLoader = use;
161     }
162
163     /**
164      * @return the DiscoverClasses instance to use to locate services.
165      * This object is lazily created if it has not been configured.
166      */

167     public DiscoverClasses getDiscoverClasses() {
168         if ( discovery == null ) {
169             ClassLoaders loaders = ClassLoaders.getAppLoaders(TagLibrary.class, getClass(), false);
170             discovery = new DiscoverClasses(loaders);
171         }
172         return discovery;
173     }
174
175     /**
176      * Sets the fully configured DiscoverClasses instance to be used to
177      * lookup services
178      */

179     public void setDiscoverClasses(DiscoverClasses discovery) {
180         this.discovery = discovery;
181     }
182
183     // Implementation methods
184
//-------------------------------------------------------------------------
185

186     /**
187      * Instantiates the given class name. Otherwise an exception is logged
188      * and null is returned
189      */

190     protected TagLibrary loadClass(String JavaDoc uri, String JavaDoc className) {
191         try {
192             Class JavaDoc theClass = getClassLoader().loadClass(className);
193             if ( theClass != null ) {
194                 return newInstance(uri, theClass);
195             }
196         }
197         catch (ClassNotFoundException JavaDoc e) {
198             log.error("Could not find the class: " + className + " when trying to resolve URI: " + uri, e);
199         }
200         return null;
201     }
202
203
204     /**
205      * Creates a new instance of the given TagLibrary class or
206      * return null if it could not be instantiated.
207      */

208     protected TagLibrary newInstance(String JavaDoc uri, Class JavaDoc theClass) {
209         try {
210             Object JavaDoc object = theClass.newInstance();
211             if (object instanceof TagLibrary) {
212                 return (TagLibrary) object;
213             }
214             else {
215                 log.error(
216                     "The tag library object mapped to: "
217                         + uri
218                         + " is not a TagLibrary. Object = "
219                         + object);
220             }
221         }
222         catch (Exception JavaDoc e) {
223             log.error(
224                 "Could not instantiate instance of class: " + theClass.getName() + ". Reason: " + e,
225                 e);
226         }
227         return null;
228     }
229
230 }
Popular Tags