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

org.enhydra.xml.xmlc.deferredparsing.DynamicClassLoader Maven / Gradle / Ivy

The newest version!
/*
 * Enhydra Java Application Server Project
 * 
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site ( http://www.enhydra.org/ ).
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific terms governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Enhydra Application Server is David
 * Li.
 *
 * The Enhydra Application Server and portions created by Lutris
 * Technologies, Inc. are Copyright Lutris Technologies, Inc.  All
 * Rights Reserved.
 * 
 * Contributor(s): 
 * David Li
 * Jacob Kjome
 *
 * $Id: DynamicClassLoader.java,v 1.8 2005/11/02 06:16:52 jkjome Exp $
 */
package org.enhydra.xml.xmlc.deferredparsing;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.enhydra.xml.xmlc.StreamXMLCLogger;
import org.enhydra.xml.xmlc.XMLCError;
import org.enhydra.xml.xmlc.XMLCLogger;

public class DynamicClassLoader extends ClassLoader {

    private ClassLoader delegateLoader = null;
    private XMLCLogger logger = null;
    private Map classMap;
    Constructor dhcConstructor;

    DynamicClassLoader(ClassLoader parent) {
        this(parent, null);
    }

    DynamicClassLoader(ClassLoader parent, XMLCLogger logger) {
        super(parent);
        if (logger != null) {
            this.logger = logger;
        } else {
            this.logger = new StreamXMLCLogger();
        }
        classMap = Collections.synchronizedMap(new HashMap());
    }

    /**
     * Add a delegate be used in class loading.
     * 
     * @param delegate the loader to be used as delegate
     */
    public void setDelegate(ClassLoader delegate) {
        delegateLoader = delegate;
    }

    /**
     * load class,
     */
    public Class loadClass(String className) throws ClassNotFoundException {
        Class clazz = null;
        ClassLoader loader = null;
        try {
            if (delegateLoader != null) {
                loader = delegateLoader;
            } else {
                loader = getParent();
            }
            clazz = loader.loadClass(className);
        } catch (ClassNotFoundException e) {
            if (loader != getParent()) {
                clazz = getParent().loadClass(className);
            } else {
                throw e;
            }
        }
        return clazz;
    }

    /**
     * Generate a class based on the class name
     * 
     * @param className class name for the class to be generated
     */
    Class createClass(String className, String path) {
        if (logger.debugEnabled()) {
            logger.logDebug(">>>Request to create class " + className + " from document " + path);
        }
        Class clazz = (Class) classMap.get(className);
        if (clazz == null) {
            synchronized (classMap) {
                clazz = (Class) classMap.get(className);
                if (clazz == null) {
                    DynamicMLCreator dhc = null;
                    if (dhcConstructor == null) {
                        Class dhcClazz = null;
                        try {
                            dhcClazz = loadClass("org.enhydra.xml.xmlc.deferredparsing.DynamicMLCreatorASM2Impl");
                            if (logger.infoEnabled()) logger.logInfo(">>>Using ASM2 for dynamic loading of markup");
                        } catch (NoClassDefFoundError ncdfe) {
                            try {
                                dhcClazz = loadClass("org.enhydra.xml.xmlc.deferredparsing.DynamicMLCreatorBCELImpl");
                                if (logger.infoEnabled()) logger.logInfo(">>>Using BCEL for dynamic loading of markup");
                            } catch (NoClassDefFoundError ncdfe2) {
                                String errMsg = "Tried using ASM2 and BCEL (in that order) bytecode manipulation frameworks for XMLC dynamic loading, but neither were found.  No other implementation available to try!";
                                if (logger.errorEnabled()) logger.logError(errMsg);
                                throw new XMLCError(errMsg);
                            } catch (ClassNotFoundException cnfe2) {} // should never happen
                        } catch (ClassNotFoundException cnfe) {} // should never happen
                        try {
                            dhcConstructor = dhcClazz.getConstructor(new Class[] { String.class, String.class });
                        } catch (NoSuchMethodException nsme) {} // should never happen
                    }
                    try {
                        dhc = (DynamicMLCreator) dhcConstructor.newInstance(new Object[] { className, path });
                    } catch (IllegalAccessException iae) {} catch (InstantiationException ie) {} catch (InvocationTargetException ite) {}
                    byte[] buf = dhc.getByteArrayForClass();
                    clazz = defineClass(null, buf, 0, buf.length);
                    /*
                     * try { //dump class to file system for decompile comparison OutputStream
                     * stream = new FileOutputStream("D:/dev/xmlctest.class"); stream.write(buf);
                     * stream.flush(); stream.close(); } catch (Exception e) {
                     * System.err.println("failed to write class!!!!"); }
                     */
                    classMap.put(className, clazz);
                }
            }
        } else {
            if (logger.debugEnabled()) {
                logger.logDebug(">>>Got class " + className + "from cache");
            }
        }
        return clazz;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy