/*
 * 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 (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;
  }
}
