blob: 4839be8cdc49372985d75b29c1cdbd76cc8d370e [file] [log] [blame]
/*
* 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 <tt>a.b.c.FooListener</tt>,
* it loads an adapter of type
* <tt>org.apache.bsf.util.event.adapters.a_b_c_FooAdapter</tt>.
* 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 (Class listenerType) {
String key = listenerType.getName().replace ('.', '_');
Class adapterClass = (Class) reg.get (key);
if (adapterClass == null) {
String en = key.substring (0, key.lastIndexOf ("Listener"));
String cn = adapterPackage + "." + en + adapterSuffix;
if (adapterClass==null) { // get Thread's context class loader
ClassLoader tccl=Thread.currentThread().getContextClassLoader();
if (tccl!=null)
{
try { // try supplied class loader
adapterClass=Thread.currentThread().getContextClassLoader().loadClass(cn);
}
catch (ClassNotFoundException e02) {}
}
}
try { // try ClassLoader set in this object (cf. this.setClassLoader())
if (cl !=null) {
adapterClass=cl.loadClass(cn);
}
}
catch (ClassNotFoundException e01) {}
if (adapterClass==null) { // Defined CL
try { // try supplied class loader
ClassLoader defCL=BSFManager.getDefinedClassLoader();
if (cl != defCL) {
adapterClass=defCL.loadClass(cn);
}
}
catch (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 (Class listenerType, Class eventAdapterClass) {
String key = listenerType.getName().replace('.', '_');
reg.put (key, eventAdapterClass);
}
/**
* Class loader to use to load event adapter classes.
*/
public static void setClassLoader (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 (boolean dynamic) {
EventAdapterRegistry.dynamic = dynamic;
}
}