/*
 * 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.openjpa.lib.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import serp.bytecode.lowlevel.ConstantPoolTable;

/**
 * ClassLoader implementation that allows classes to be temporarily
 * loaded and then thrown away. Useful for the enhancer to be able
 * to run against a class without first loading(and thus polluting)
 * the parent ClassLoader.
 *
 * @author Marc Prud'hommeaux
 */
public class TemporaryClassLoader extends ClassLoader {

    public TemporaryClassLoader(ClassLoader parent) {
        super(parent);
    }

    @Override
    public Class loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }

    @Override
    protected Class loadClass(String name, boolean resolve)
        throws ClassNotFoundException {
        // see if we've already loaded it
        Class c = findLoadedClass(name);
        if (c != null)
            return c;

        // bug #283. defer to system if the name is a protected name.
        // "sun." is required for JDK 1.4, which has an access check for
        // sun.reflect.GeneratedSerializationConstructorAccessor1
        if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("jakarta.")
            || name.startsWith("sun.") || name.startsWith("jdk.")) {
            return Class.forName(name, resolve, getClass().getClassLoader());
        }

        String resourceName = name.replace('.', '/') + ".class";
        InputStream resource = getResourceAsStream(resourceName);
        if (resource == null) {
            throw new ClassNotFoundException(name);
        }

        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        try {
            for (int n = 0; (n = resource.read(b, 0, b.length)) != -1;
                bout.write(b, 0, n))
                ;
            byte[] classBytes = bout.toByteArray();
            // To avoid classloader issues with the JVM (Sun and IBM), we
            // will not load Enums via the TemporaryClassLoader either.
            // Reference JIRA Issue OPENJPA-646 for more information.
            if (isAnnotation(classBytes) || isEnum(classBytes)) {
                try {
                    Class<?> frameworkClass = Class.forName(name, resolve,
                            getClass().getClassLoader());
                    return frameworkClass;
                } catch (ClassNotFoundException e) {
                    // OPENJPA-1121 continue, as it must be a user-defined class
                }
            }

            try {
                return defineClass(name, classBytes, 0, classBytes.length);
            } catch (SecurityException e) {
                // possible prohibited package: defer to the parent
                return super.loadClass(name, resolve);
            }
        } catch (IOException ioe) {
            // defer to the parent
            return super.loadClass(name, resolve);
        }
    }

    /**
     * Fast-parse the given class bytecode to determine if it is an
     * annotation class.
     */
    private static boolean isAnnotation(byte[] b) {
        if (JavaVersions.VERSION < 5)
            return false;
        int idx = ConstantPoolTable.getEndIndex(b);
        int access = ConstantPoolTable.readUnsignedShort(b, idx);
        return (access & 0x2000) != 0; // access constant for annotation type
    }

    /**
     * Fast-parse the given class bytecode to determine if it is an
     * enum class.
     */
    private static boolean isEnum(byte[] b) {
        if (JavaVersions.VERSION < 5)
            return false;
        int idx = ConstantPoolTable.getEndIndex(b);
        int access = ConstantPoolTable.readUnsignedShort(b, idx);
        return (access & 0x4000) != 0; // access constant for enum type
    }
}