/*
 *
 * 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.qpid.client.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.lang.reflect.Proxy;
import java.util.HashMap;


/**
 * <code>ClassLoadingAwareObjectInputStream</code> is an Extention of Object input stream to be used
 * to de-serialize JMS Object Messages.
 *
 * <p>This was introduced to resolve the class loading issues which can happen when we use the client
 * libraries in a complex class loading Environment.</p>
 */
public class ClassLoadingAwareObjectInputStream extends ObjectInputStream
{
    /** <p>Class loader instance which loaded this class.
     * It will be used to load classes when we failed to load classes from dynamic class loading</p> */
    private static final ClassLoader _ON_FAULT_CLASS_LOADER =
            ClassLoadingAwareObjectInputStream.class.getClassLoader();

    /** <p>Maps primitive type names to corresponding class objects.</p> */
    private static final HashMap<String, Class> _primitives = new HashMap<String, Class>(8, 1.0F);
    private final TrustedClassFilter _securityFilter;

    /**
     * Security Filter used to filter classes that the application deems to be insecure, this filter
     * is not applied to the class instances for the primitive types.
     */
    public interface TrustedClassFilter
    {
        boolean isTrusted(Class<?> clazz);
    }

    public ClassLoadingAwareObjectInputStream(InputStream in, TrustedClassFilter filter) throws IOException
    {
        super(in);
        _securityFilter = filter;
    }

    @Override
    protected Class resolveClass(ObjectStreamClass classDesc)
            throws IOException, ClassNotFoundException
    {

        // Here we use TTCL as our primary class loader to load the classes
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        Class<?> clazz = load(classDesc.getName(), cl);
        return checkSecurity(clazz);
    }

    @Override
    protected Class resolveProxyClass(String[] interfaces)
            throws IOException, ClassNotFoundException
    {
         // Here we use TTCL as our primary class loader to load the classes
        ClassLoader cl = Thread.currentThread().getContextClassLoader();

        Class[] cinterfaces = new Class[interfaces.length];
        for (int i = 0; i < interfaces.length; i++)
        {
            cinterfaces[i] = load(interfaces[i], cl);
        }


        Class<?> clazz = null;
        Throwable failureCause = null;

        try
        {
            clazz = Proxy.getProxyClass(cl, cinterfaces);
        }
        catch (IllegalArgumentException e)
        {
            failureCause = e;

            try
            {
                clazz = Proxy.getProxyClass(_ON_FAULT_CLASS_LOADER, cinterfaces);
            }
            catch (IllegalArgumentException e2)
            {
            }
        }

        if (clazz != null)
        {
            return checkSecurity(clazz);
        }

        throw new ClassNotFoundException("Failed find class.", failureCause);
    }

    private Class<?> checkSecurity(Class<?> clazz) throws ClassNotFoundException
    {
        if (!clazz.isPrimitive() && _securityFilter != null)
        {
            if (!_securityFilter.isTrusted(clazz))
            {
                throw new ClassNotFoundException("Forbidden " + clazz + "! " +
                                                 "This class is not trusted to be deserialized from ObjectMessage payloads.");
            }
        }

        return clazz;
    }

    /**
     * <p>
     * Method we used to load class that are needed to de-serialize the objects. </p>
     * <p>
     * Here we first look up for the objects from the given class loader and if its not there
     * we will be using the class loader of this class.
     * </p>
     * @param className Class name to lookup
     * @param cl primary class loader which we 1st use to lookup
     * @return Class instance we are looking for
     * @throws ClassNotFoundException if both primary and secondary lockup's failed.
     */
    private Class load(String className, ClassLoader cl)
            throws ClassNotFoundException
    {
        try
        {
            return Class.forName(className, false, cl);
        }
        catch (ClassNotFoundException e)
        {
            final Class clazz = _primitives.get(className);

            if (clazz != null)
            {
                return clazz;
            }
            else
            {
                return Class.forName(className, false, _ON_FAULT_CLASS_LOADER);
            }
        }
    }

    static
    {
        _primitives.put("boolean", boolean.class);
        _primitives.put("byte", byte.class);
        _primitives.put("char", char.class);
        _primitives.put("short", short.class);
        _primitives.put("int", int.class);
        _primitives.put("long", long.class);
        _primitives.put("float", float.class);
        _primitives.put("double", double.class);
        _primitives.put("void", void.class);
    }
}
