All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.arjuna.ats.internal.arjuna.common.ClassloadingUtility Maven / Gradle / Ivy

Go to download

JBossTS - JBoss Transaction Service. JTA, JTS and XTS (WS-AT, WS-BA)

There is a newer version: 4.16.6.Final
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2010, Red Hat, Inc. and/or its affiliates,
 * and individual contributors as indicated by the @author tags.
 * See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License, v. 2.1.
 * This program is distributed in the hope that it will be useful, but WITHOUT A
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License,
 * v.2.1 along with this distribution; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 *
 * (C) 2010,
 * @author JBoss, by Red Hat.
 */
package com.arjuna.ats.internal.arjuna.common;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import com.arjuna.ats.arjuna.logging.tsLogger;
import com.arjuna.common.internal.util.propertyservice.BeanPopulator;

/**
 * Utility functions, used mainly by the EnvironmentBeans, for managing dynamic classloading.
 *
 * @author Jonathan Halliday ([email protected]) 2010-04
 */
public class ClassloadingUtility
{
    // this really belongs in common...

    /**
     * Load a class. No instantiation.
     * 
     * In the event of error (ClassNotFound etc) this method will log the error and return null.
     *
     * @param className the name of the class to load and instantiate.
     * @return the specified Class, or null.
     */
    public static Class loadClass(String className) {

        // This should be pretty much the only point in the codebase that actually does classloading.
        // Once upon a time it used TCCL, but that does not play nice with AS and is fairly pointless
        // anyhow, so we changed it... JBTM-828 and JBTM-735

        Class clazz;
        try
        {
            //clazz = Thread.currentThread().getContextClassLoader().loadClass( className ) ;
            clazz = Class.forName( className );
        } catch(ClassNotFoundException e) {
            tsLogger.i18NLogger.warn_common_ClassloadingUtility_2(className, e);
            return null;
        }
        return clazz;
    }

    /**
     * Load and return the named class, which is expected to be an implementation of the specified interface.
     *
     * In the event of error (ClassNotFound, ClassCast, ...) this method will log the error and return null.
     *
     * @param iface the expected interface type.
     * @param className the name of the class to load and instantiate.
     * @return the specified class, or null.
     */
    public static  Class loadClass(Class iface, String className)
    {
        if (tsLogger.logger.isTraceEnabled()) {
            tsLogger.logger.trace("Loading class " + className);
        }

        if (className == null) {
            tsLogger.i18NLogger.warn_common_ClassloadingUtility_1();
            return null;
        }

        Class clazz = loadClass( className );
        if(clazz == null) {
            return null;
        }

        try {
            Class clazz2 = clazz.asSubclass(iface);
            return clazz2;
        } catch (ClassCastException e) {
            tsLogger.i18NLogger.warn_common_ClassloadingUtility_3(className, iface.getName(), e);
            return null;
        }
    }

    /**
     * Load, instantiate and return an instance of the named class, which is expected to be an implementation of
     * the specified interface.
     *
     * In the event of error (ClassNotFound, ClassCast, can't instantiate, ...) this method will log the error and return null.
     *
     *
     * @param iface the expected interface type.
     * @param className the name of the class to load and instantiate.
     * @param environmentBeanInstanceName When the class ctor requires a *EnvironmentBean instance, the name of the bean.
     *   null for default ctor or default bean instance..
     * @return an instance of the specified class, or null.
     */
    public static  T loadAndInstantiateClass(Class iface, String className, String environmentBeanInstanceName)
    {
        T instance = null;

        try {
            Class clazz = loadClass(iface, className);
            if(clazz == null) {
                return null;
            }

            Constructor[] ctors = clazz.getConstructors();
            Class environmentBeanClass = null;
            for(Constructor constructor : ctors) {
                if(constructor.getParameterTypes().length == 1 &&
                        constructor.getParameterTypes()[0].getCanonicalName().endsWith("EnvironmentBean")) {
                    environmentBeanClass = constructor.getParameterTypes()[0];
                    Object envBean = BeanPopulator.getNamedInstance(environmentBeanClass, environmentBeanInstanceName);
                    instance = (T)constructor.newInstance(envBean);
                    break;
                }
            }
            if(environmentBeanClass == null && environmentBeanInstanceName == null) {
                // no bean ctor, try default ctor
                instance = clazz.newInstance();
            }

        } catch (InstantiationException e) {
            tsLogger.i18NLogger.warn_common_ClassloadingUtility_4(className, e);
        } catch (IllegalAccessException e) {
            tsLogger.i18NLogger.warn_common_ClassloadingUtility_5(className, e);
        } catch(InvocationTargetException e) {
            tsLogger.i18NLogger.warn_common_ClassloadingUtility_4(className, e);
        }

        return instance;
    }

    public static  List loadAndInstantiateClasses(Class iface, List classNames)
    {
        List instances = new ArrayList();

        if(classNames != null) {
            for(String className : classNames)
            {
                T instance = loadAndInstantiateClass(iface, className, null);
                if(instance != null)
                {
                    instances.add(instance);
                }
            }
        }

        return instances;
    }


    public static  List loadAndInstantiateClassesWithInit(Class iface, List classNamesWithOptionalInitParams)
    {
        List instances = new ArrayList();

        if(classNamesWithOptionalInitParams != null) {
            for(String theClassAndParameter : classNamesWithOptionalInitParams)
            {
                // see if there is a string parameter

                int breakPosition = theClassAndParameter.indexOf(BREAKCHARACTER);

                String theClass = null;
                String theParameter = null;

                if (breakPosition != -1)
                {
                    theClass = theClassAndParameter.substring(0, breakPosition);
                    theParameter = theClassAndParameter.substring(breakPosition + 1);
                }
                else
                {
                    theClass = theClassAndParameter;
                }

                T instance = loadAndInstantiateClass(iface, theClass, null);


                if (theClass != null && theParameter != null)
                {
                    try {
                        Method method = instance.getClass().getMethod("initialise", new Class[] {String.class}); // yup, UK English spelling
                        method.invoke(instance, theParameter);
                    } catch(Exception e) {
                        tsLogger.i18NLogger.warn_common_ClassloadingUtility_6(theClassAndParameter, e);
                        continue;
                    }
                }

                if(instance != null)
                {
                    instances.add(instance);
                }
            }
        }

        return instances;
    }

    /**
     * Reverse mapping - obtain the class name for a given Object.
     *
     * @param instance the Object of interest
     * @return the class name of the Object, or null.
     */
    public static String getNameForClass(Object instance)
    {
        if(instance == null) {
            return null;
        }

        return instance.getClass().getName();
    }

    /**
     * Reverse mapping - obtain the class names from a given set of Objects.
     *
     * If the input list is null a zero length list is returned.
     * If the input list contains nulls, these will not be present in the returned list.
     *
     * @param instances a list of Objects of interest.
     * @return a non-null list of zero or more elements, being class names of the Objects.
     */
    public static List getNamesForClasses(List instances)
    {
        List names = new ArrayList();

        if(instances != null)
        {
            for(Object instance : instances)
            {
                String name = getNameForClass(instance);
                if(name != null) {
                    names.add(name);
                }

            }
        }

        return names;
    }

    private static final char BREAKCHARACTER = ';';
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy