Package net.sf.jiga.xtended.kernel

Source Code of net.sf.jiga.xtended.kernel.ExtensionsClassLoader$ObjectInputStream

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package net.sf.jiga.xtended.kernel;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectStreamClass;
import java.io.Serializable;
import java.lang.IllegalArgumentException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import net.sf.jiga.xtended.JXAException;

/**
*
* @author www.b23prodtm.info
*/
public class ExtensionsClassLoader {

    private ExtensionsClassLoader(JXAenvUtils env) {
        ECL = new ExtensionsClassLoaderImpl(env);
        env.classLoader = ECL;
    }

    @Deprecated
    private ExtensionsClassLoader(JXAenvUtils env, boolean keepRemote) {
        env.keepReadingOnRemoteJarResources = keepRemote;
        ECL = new ExtensionsClassLoaderImpl(env);
        env.classLoader = ECL;
    }
    static AccessControlContext _acc = AccessController.getContext();
    private static ExtensionsClassLoader _INSTANCE;
    private ClassLoader ECL;

    public static ExtensionsClassLoader getInstance() {
        if (!isResourceLoaded()) {
            throw new JXAException(JXAException.LEVEL.SYSTEM, "classloader instance not loaded yet !! ECL INSTANCE is not ready. !!");
        }
        return _INSTANCE;
    }

    public ClassLoader getClassLoader() {
        return ECL;
    }

    /**
     * Loads a specific classPath context .
     *
     * @param topUrls urls classpath or null if default
     * @param env the environment to read from
     * ({@link JXAenvUtils#getJXAenvPath() classpath}). Ensure to have correctly
     * set {@link JXAenvUtils#setJXAenvPath() envpath} before !
     * @discuss seems like Mac OS JDK doesn'y store static field properly on
     * certain circumstances (booting runtime)
     */
    public static void _load(final JXAenvUtils env) {
        if (isResourceLoaded()) {
            throw new JXAException(JXAException.LEVEL.SYSTEM, "trying to change environment classloader, but it was already loaded");
        }
        _INSTANCE = new ExtensionsClassLoader(env);
        env._switchToClassLoader(_INSTANCE.ECL);
        AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                ThreadWorks.setGlobalClassLoaderContext(_INSTANCE.ECL);
                return null;
            }
        }, _acc);
    }

    @Deprecated
    public static void _load(final JXAenvUtils env, final boolean keepRemote) {
        env.keepReadingOnRemoteJarResources = keepRemote;
        _load(env);
    }

    /**
     * force resolving
     */
    public static Class<?> forName(String name) throws ClassNotFoundException {
        return Class.forName(name, true, _INSTANCE.ECL);
        /*return ((ExtensionsClassLoaderImpl) INSTANCE).loadClass(name, true);*/
    }

    /**
     *
     */
    public static InvocationHandler _proxyClassHandler(Object target) {
        return new ProxyClassHandler(target);
    }

    /**
     * Provides a way to cast external loaded classes (e.g. with
     * ExtensionsClassLoader) to kernel interfaces.
     *
     * @param clazz interfaces (ONLY, no class or primitives) to be casted to
     */
    public static <T> T _proxyClass(Object target, Class<T> clazz) {
        if (!clazz.isInterface()) {
            throw new IllegalArgumentException("Class " + clazz + " is not an interface");
        }
        return target == null ? null : (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz},
                _proxyClassHandler(target));
    }

    public static boolean isResourceLoaded() {
        return _INSTANCE != null;
    }

    /**
     * This class invokes corresponding methods on classes that were loaded by
     * the ExtensionsClassLoaderImpl for interfaces that are declared by another
     * classloader. Then it can be used by a ProxyClass to make correct class
     * castings.
     */
    static class ProxyClassHandler implements InvocationHandler, Serializable {

        /**
         * serial version uid of this class
         */
        private static final long serialVersionUID = 2323;
        Object target;

        public ProxyClassHandler(Object target) {
            this.target = target;
        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return target.getClass().getMethod(method.getName(), method.getParameterTypes()).invoke(target, args);
        }
    }

    /**
     * This is an Object deserializer used to resolve classes from a stream
     * ({@link JXAenvUtils.env#APP_REMOTE} must be on)
     *
     * @see SpritesCacheManager#JXA_ECLIO
     */
    class ObjectInputStream extends java.io.ObjectInputStream {

        public ObjectInputStream(InputStream in) throws IOException {
            super(in);
        }

        @Override
        protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
            if (!JXAenvUtils.env.APP_REMOTE.isEnv()) {
                if (DebugMap._getInstance().isDebugLevelEnabled(DebugMap._getInstance()._VOID)) {
                    System.out.println("resolveClass classloader " + Thread.currentThread().getContextClassLoader());
                }
                return super.resolveClass(desc);
            }
            if (DebugMap._getInstance().isDebugLevelEnabled(DebugMap._getInstance()._VOID)) {
                System.out.println("resolveClass classloader " + ECL);
            }
            String name = desc.getName();
            try {
                return Class.forName(name, false, ECL);
            } catch (ClassNotFoundException ex) {
                if (DebugMap._getInstance().isDebugLevelEnabled(DebugMap._getInstance()._VOID)) {
                    ex.printStackTrace();
                }
                return super.resolveClass(desc);
            }
        }

        @Override
        protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
            if (!JXAenvUtils.env.APP_REMOTE.isEnv()) {
                if (DebugMap._getInstance().isDebugLevelEnabled(DebugMap._getInstance()._VOID)) {
                    System.out.println("resolveProxyClass classloader " + Thread.currentThread().getContextClassLoader());
                }
                return super.resolveProxyClass(interfaces);
            }
            if (DebugMap._getInstance().isDebugLevelEnabled(DebugMap._getInstance()._VOID)) {
                System.out.println("resolveProxyClass classloader " + ECL);
            }
            Class<?>[] classes = new Class<?>[interfaces.length];
            for (int i = 0; i < interfaces.length; i++) {
                classes[i] = Class.forName(interfaces[i], false, ECL);
            }
            try {
                return Proxy.getProxyClass(ECL, classes);
            } catch (IllegalArgumentException ex) {
                if (DebugMap._getInstance().isDebugLevelEnabled(DebugMap._getInstance()._VOID)) {
                    ex.printStackTrace();
                }
                return super.resolveProxyClass(interfaces);
            }
        }
    }
}
TOP

Related Classes of net.sf.jiga.xtended.kernel.ExtensionsClassLoader$ObjectInputStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.