169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit.
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version
669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with
769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License.  Alternatively, the contents of this file may be used under
869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later.
969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis,
1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the
1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License.
1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.util.proxy;
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.Serializable;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.ObjectStreamException;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.security.AccessController;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.security.PrivilegedActionException;
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.security.PrivilegedExceptionAction;
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.security.ProtectionDomain;
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A proxy object is converted into an instance of this class
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * when it is written to an output stream.
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see RuntimeSupport#makeSerializedProxy(Object)
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalclass SerializedProxy implements Serializable {
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private String superClass;
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private String[] interfaces;
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private byte[] filterSignature;
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private MethodHandler handler;
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    SerializedProxy(Class proxy, byte[] sig, MethodHandler h) {
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        filterSignature = sig;
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        handler = h;
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        superClass = proxy.getSuperclass().getName();
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Class[] infs = proxy.getInterfaces();
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int n = infs.length;
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        interfaces = new String[n - 1];
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String setterInf = ProxyObject.class.getName();
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (int i = 0; i < n; i++) {
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String name = infs[i].getName();
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (!name.equals(setterInf))
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                interfaces[i] = name;
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Load class.
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param className the class name
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return loaded class
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws ClassNotFoundException for any error
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected Class loadClass(final String className) throws ClassNotFoundException {
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return (Class)AccessController.doPrivileged(new PrivilegedExceptionAction(){
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                public Object run() throws Exception{
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    ClassLoader cl = Thread.currentThread().getContextClassLoader();
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return Class.forName(className, true, cl);
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            });
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (PrivilegedActionException pae) {
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("cannot load the class: " + className, pae.getException());
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    Object readResolve() throws ObjectStreamException {
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int n = interfaces.length;
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            Class[] infs = new Class[n];
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            for (int i = 0; i < n; i++)
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                infs[i] = loadClass(interfaces[i]);
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ProxyFactory f = new ProxyFactory();
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            f.setSuperclass(loadClass(superClass));
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            f.setInterfaces(infs);
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ProxyObject proxy = (ProxyObject)f.createClass(filterSignature).newInstance();
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            proxy.setHandler(handler);
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return proxy;
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (ClassNotFoundException e) {
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new java.io.InvalidClassException(e.getMessage());
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (InstantiationException e2) {
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new java.io.InvalidObjectException(e2.getMessage());
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (IllegalAccessException e3) {
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new java.io.InvalidClassException(e3.getMessage());
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
98