169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2010 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.IOException; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.InputStream; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.ObjectInputStream; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.ObjectStreamClass; 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * An input stream class which knows how to deserialize proxies created via {@link ProxyFactory} and 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * serializedo via a {@link ProxyObjectOutputStream}. It must be used when deserialising proxies created 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * from a proxy factory configured with {@link ProxyFactory#useWriteReplace} set to false. 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @author Andrew Dinn 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class ProxyObjectInputStream extends ObjectInputStream 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal{ 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * create an input stream which can be used to deserialize an object graph which includes proxies created 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * using class ProxyFactory. the classloader used to resolve proxy superclass and interface names 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * read from the input stream will default to the current thread's context class loader or the system 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * classloader if the context class loader is null. 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param in 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws java.io.StreamCorruptedException whenever ObjectInputStream would also do so 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws IOException whenever ObjectInputStream would also do so 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws SecurityException whenever ObjectInputStream would also do so 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws NullPointerException if in is null 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ProxyObjectInputStream(InputStream in) throws IOException 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(in); 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal loader = Thread.currentThread().getContextClassLoader(); 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (loader == null) { 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal loader = ClassLoader.getSystemClassLoader(); 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Reset the loader to be 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param loader 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setClassLoader(ClassLoader loader) 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (loader != null) { 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this.loader = loader; 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } else { 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal loader = ClassLoader.getSystemClassLoader(); 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean isProxy = readBoolean(); 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (isProxy) { 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String name = (String)readObject(); 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Class superClass = loader.loadClass(name); 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int length = readInt(); 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Class[] interfaces = new Class[length]; 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < length; i++) { 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal name = (String)readObject(); 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal interfaces[i] = loader.loadClass(name); 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal length = readInt(); 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] signature = new byte[length]; 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal read(signature); 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ProxyFactory factory = new ProxyFactory(); 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // we must always use the cache and never use writeReplace when using 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // ProxyObjectOutputStream and ProxyObjectInputStream 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal factory.setUseCache(true); 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal factory.setUseWriteReplace(false); 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal factory.setSuperclass(superClass); 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal factory.setInterfaces(interfaces); 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Class proxyClass = factory.createClass(signature); 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return ObjectStreamClass.lookup(proxyClass); 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } else { 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return super.readClassDescriptor(); 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the loader to use to resolve classes for proxy superclass and interface names read 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * from the stream. defaults to the context class loader of the thread which creates 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the input stream or the system class loader if the context class loader is null. 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private ClassLoader loader; 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}