| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.bsf.util.event; |
| |
| import java.util.Hashtable; |
| |
| import org.apache.bsf.util.event.generator.EventAdapterGenerator; |
| import org.apache.bsf.BSFManager; |
| |
| |
| /** |
| * The <em>EventAdapterRegistry</em> is the registry of event adapters. |
| * If a desired adapter is not found, the adapter will be dynamically |
| * generated when lookup is attempted. Set the <code>dynamic</code> property |
| * to <code>false</code> to disable this feature. |
| * <p> |
| * This implementation first looks for an adapter in its lookup table |
| * and if it doesn't find one looks for a standard implementation of |
| * that adapter in the org.apache.bsf.util.event.adapters package with a |
| * standard naming convention. The naming convention it assumes is the |
| * following: for event listener type {@code a.b.c.FooListener}, |
| * it loads an adapter of type |
| * {@code org.apache.bsf.util.event.adapters.a_b_c_FooAdapter}. |
| * If both the loading and the dynamic generation fail, then a |
| * <code>null</code> is returned. |
| * <p> |
| * |
| * @author Sanjiva Weerawarana |
| * @author Matthew J. Duftler |
| * @see EventAdapter |
| */ |
| |
| |
| /* changed: |
| 2012-01-29: Rony G. Flatscher, cf. [https://issues.apache.org/jira/browse/BSF-21]: |
| - take into account that a context class loader may not be set |
| |
| - new class loading sequence: |
| - Thread's context class loader |
| - settable class loader stored with EventAdapterRegistry |
| - BSFManager's defining class loader |
| */ |
| |
| public class EventAdapterRegistry { |
| private static Hashtable reg = new Hashtable (); |
| private static ClassLoader cl = null; |
| private static String adapterPackage = "org.apache.bsf.util.event.adapters"; |
| private static String adapterSuffix = "Adapter"; |
| private static boolean dynamic = true; |
| |
| public static Class lookup (final Class listenerType) { |
| final String key = listenerType.getName().replace ('.', '_'); |
| Class adapterClass = (Class) reg.get (key); |
| |
| if (adapterClass == null) { |
| final String en = key.substring (0, key.lastIndexOf ("Listener")); |
| final String cn = adapterPackage + "." + en + adapterSuffix; |
| |
| if (adapterClass==null) { // get Thread's context class loader |
| final ClassLoader tccl=Thread.currentThread().getContextClassLoader(); |
| if (tccl!=null) |
| { |
| try { // try supplied class loader |
| adapterClass=Thread.currentThread().getContextClassLoader().loadClass(cn); |
| } |
| catch (final ClassNotFoundException e02) {} |
| } |
| } |
| |
| try { // try ClassLoader set in this object (cf. this.setClassLoader()) |
| if (cl !=null) { |
| adapterClass=cl.loadClass(cn); |
| } |
| } |
| catch (final ClassNotFoundException e01) {} |
| |
| if (adapterClass==null) { // Defined CL |
| try { // try supplied class loader |
| final ClassLoader defCL=BSFManager.getDefinedClassLoader(); |
| if (cl != defCL) { |
| adapterClass=defCL.loadClass(cn); |
| } |
| } |
| catch (final ClassNotFoundException e03) {} |
| } |
| |
| if (adapterClass==null && dynamic) { |
| // Unable to resolve one, try to generate one. |
| adapterClass = // if second argument is set to 'true', then the class file will be stored in the filesystem: |
| EventAdapterGenerator.makeEventAdapterClass (listenerType, false); |
| } |
| |
| if (adapterClass != null) { |
| reg.put (key, adapterClass); |
| } |
| } |
| |
| return adapterClass; |
| } |
| |
| public static void register (final Class listenerType, final Class eventAdapterClass) { |
| final String key = listenerType.getName().replace('.', '_'); |
| reg.put (key, eventAdapterClass); |
| } |
| /** |
| * Class loader to use to load event adapter classes. |
| */ |
| public static void setClassLoader (final ClassLoader cloader) { |
| cl = cloader; |
| } |
| /** |
| * Indicates whether or not to dynamically generate adapters; default is |
| * <code>true</code>. |
| * <p> |
| * If the <code>dynamic</code> property is set to true, and the |
| * <code>ClassLoader</code> is unable to resolve an adapter, one will be |
| * dynamically generated. |
| * |
| * @param dynamic whether or not to dynamically generate adapters. |
| */ |
| public static void setDynamic (final boolean dynamic) { |
| EventAdapterRegistry.dynamic = dynamic; |
| } |
| } |