View Javadoc
1 /* 2 * ==================================================================== 3 * 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 1999-2002 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, if 22 * any, must include the following acknowlegement: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowlegement may appear in the software itself, 26 * if and wherever such third-party acknowlegements normally appear. 27 * 28 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 29 * Foundation" must not be used to endorse or promote products derived 30 * from this software without prior written permission. For written 31 * permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache" 34 * nor may "Apache" appear in their names without prior written 35 * permission of the Apache Group. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 * 56 */ 57 package org.apache.commons.jelly.impl; 58 59 import org.apache.commons.discovery.ServiceDiscovery; 60 import org.apache.commons.discovery.ServiceInfo; 61 62 import org.apache.commons.jelly.TagLibrary; 63 64 import org.apache.commons.logging.Log; 65 import org.apache.commons.logging.LogFactory; 66 67 68 /*** 69 * <p><code>DefaultTagLibraryResolver</code> is a default implemenation 70 * which attempts to interpret the URI as a String called 'jelly:className' 71 * and class load the given Java class. Otherwise META-INF/services/jelly/uri 72 * is searched for on the thread context's class path and, if found, that 73 * class will be loaded.</p> 74 * 75 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> 76 * @version $Revision: 1.12 $ 77 */ 78 public class DefaultTagLibraryResolver implements TagLibraryResolver { 79 80 /*** The Log to which logging calls will be made. */ 81 private static final Log log = LogFactory.getLog(DefaultTagLibraryResolver.class); 82 83 private ServiceDiscovery discovery; 84 85 /*** 86 * The class loader to use for instantiating application objects. 87 * If not specified, the context class loader, or the class loader 88 * used to load this class itself, is used, based on the value of the 89 * <code>useContextClassLoader</code> variable. 90 */ 91 private ClassLoader classLoader; 92 93 /*** 94 * Do we want to use the Context ClassLoader when loading classes 95 * for instantiating new objects? Default is <code>false</code>. 96 */ 97 private boolean useContextClassLoader = false; 98 99 100 public DefaultTagLibraryResolver() { 101 } 102 103 104 // TagLibraryResolver interface 105 //------------------------------------------------------------------------- 106 107 /*** 108 * Attempts to resolve the given URI to be associated with a TagLibrary 109 * otherwise null is returned to indicate no tag library could be found 110 * so that the namespace URI should be treated as just vanilla XML. 111 */ 112 public TagLibrary resolveTagLibrary(String uri) { 113 ServiceDiscovery discovery = getServiceDiscovery(); 114 String name = uri; 115 if ( uri.startsWith( "jelly:" ) ) { 116 name = "jelly." + uri.substring(6); 117 } 118 119 log.info( "Looking up service name: " + name ); 120 121 ServiceInfo[] infoArray = discovery.findServices(name); 122 123 if ( infoArray != null && infoArray.length > 0 ) { 124 for (int i = 0; i < infoArray.length; i++ ) { 125 ServiceInfo info = infoArray[i]; 126 try { 127 Class typeClass = info.getLoader().loadClass( info.getImplName() ); 128 if ( typeClass != null ) { 129 return newInstance(uri, typeClass); 130 } 131 } 132 catch (Exception e) { 133 log.error( "Could not load service: " + info.getImplName() 134 + " with loader: " + info.getLoader() 135 ); 136 } 137 } 138 } 139 else { 140 log.info( "Could not find any services for name: " + name ); 141 } 142 return null; 143 } 144 145 // Properties 146 //------------------------------------------------------------------------- 147 148 /*** 149 * Return the class loader to be used for instantiating application objects 150 * when required. This is determined based upon the following rules: 151 * <ul> 152 * <li>The class loader set by <code>setClassLoader()</code>, if any</li> 153 * <li>The thread context class loader, if it exists and the 154 * <code>useContextClassLoader</code> property is set to true</li> 155 * <li>The class loader used to load the XMLParser class itself. 156 * </ul> 157 */ 158 public ClassLoader getClassLoader() { 159 if (this.classLoader != null) { 160 return (this.classLoader); 161 } 162 if (this.useContextClassLoader) { 163 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 164 if (classLoader != null) { 165 return (classLoader); 166 } 167 } 168 return (this.getClass().getClassLoader()); 169 } 170 171 /*** 172 * Set the class loader to be used for instantiating application objects 173 * when required. 174 * 175 * @param classLoader The new class loader to use, or <code>null</code> 176 * to revert to the standard rules 177 */ 178 public void setClassLoader(ClassLoader classLoader) { 179 this.classLoader = classLoader; 180 } 181 182 /*** 183 * Return the boolean as to whether the context classloader should be used. 184 */ 185 public boolean getUseContextClassLoader() { 186 return useContextClassLoader; 187 } 188 189 /*** 190 * Determine whether to use the Context ClassLoader (the one found by 191 * calling <code>Thread.currentThread().getContextClassLoader()</code>) 192 * to resolve/load classes. If not 193 * using Context ClassLoader, then the class-loading defaults to 194 * using the calling-class' ClassLoader. 195 * 196 * @param boolean determines whether to use JellyContext ClassLoader. 197 */ 198 public void setUseContextClassLoader(boolean use) { 199 useContextClassLoader = use; 200 } 201 202 /*** 203 * @return the ServiceDiscovery instance to use to locate services. 204 * This object is lazily created if it has not been configured. 205 */ 206 public ServiceDiscovery getServiceDiscovery() { 207 if ( discovery == null ) { 208 discovery = ServiceDiscovery.getServiceDiscovery(); 209 discovery.addClassLoader( getClassLoader() ); 210 } 211 return discovery; 212 } 213 214 /*** 215 * Sets the fully configured ServiceDiscovery instance to be used to 216 * lookup services 217 */ 218 public void setServiceDiscovery(ServiceDiscovery discovery) { 219 this.discovery = discovery; 220 } 221 222 // Implementation methods 223 //------------------------------------------------------------------------- 224 225 /*** 226 * Instantiates the given class name. Otherwise an exception is logged 227 * and null is returned 228 */ 229 protected TagLibrary loadClass(String uri, String className) { 230 try { 231 Class theClass = getClassLoader().loadClass(className); 232 if ( theClass != null ) { 233 return newInstance(uri, theClass); 234 } 235 } 236 catch (ClassNotFoundException e) { 237 log.error("Could not find the class: " + className + " when trying to resolve URI: " + uri, e); 238 } 239 return null; 240 } 241 242 243 /*** 244 * Creates a new instance of the given TagLibrary class or 245 * return null if it could not be instantiated. 246 */ 247 protected TagLibrary newInstance(String uri, Class theClass) { 248 try { 249 Object object = theClass.newInstance(); 250 if (object instanceof TagLibrary) { 251 return (TagLibrary) object; 252 } 253 else { 254 log.error( 255 "The tag library object mapped to: " 256 + uri 257 + " is not a TagLibrary. Object = " 258 + object); 259 } 260 } 261 catch (Exception e) { 262 log.error( 263 "Could not instantiate instance of class: " + theClass.getName() + ". Reason: " + e, 264 e); 265 } 266 return null; 267 } 268 269 }

This page was automatically generated by Maven