/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package javassist.util.proxy;
import java.io.
IOException;
import java.io.
InputStream;
import java.io.
ObjectInputStream;
import java.io.
ObjectStreamClass;
/**
* An input stream class which knows how to deserialize proxies created via {@link ProxyFactory} and
* serializedo via a {@link ProxyObjectOutputStream}. It must be used when deserialising proxies created
* from a proxy factory configured with {@link ProxyFactory#useWriteReplace} set to false.
*
* @author Andrew Dinn
*/
public class
ProxyObjectInputStream extends
ObjectInputStream
{
/**
* create an input stream which can be used to deserialize an object graph which includes proxies created
* using class ProxyFactory. the classloader used to resolve proxy superclass and interface names
* read from the input stream will default to the current thread's context class loader or the system
* classloader if the context class loader is null.
* @param in
* @throws java.io.StreamCorruptedException whenever ObjectInputStream would also do so
* @throws IOException whenever ObjectInputStream would also do so
* @throws SecurityException whenever ObjectInputStream would also do so
* @throws NullPointerException if in is null
*/
public
ProxyObjectInputStream(
InputStream in) throws
IOException
{
super(
in);
loader =
Thread.
currentThread().
getContextClassLoader();
if (
loader == null) {
loader =
ClassLoader.
getSystemClassLoader();
}
}
/**
* Reset the loader to be
* @param loader
*/
public void
setClassLoader(
ClassLoader loader)
{
if (
loader != null) {
this.
loader =
loader;
} else {
loader =
ClassLoader.
getSystemClassLoader();
}
}
protected
ObjectStreamClass readClassDescriptor() throws
IOException,
ClassNotFoundException {
boolean
isProxy =
readBoolean();
if (
isProxy) {
String name = (
String)
readObject();
Class superClass =
loader.
loadClass(
name);
int
length =
readInt();
Class[]
interfaces = new
Class[
length];
for (int
i = 0;
i <
length;
i++) {
name = (
String)
readObject();
interfaces[
i] =
loader.
loadClass(
name);
}
length =
readInt();
byte[]
signature = new byte[
length];
read(
signature);
ProxyFactory factory = new
ProxyFactory();
// we must always use the cache and never use writeReplace when using
// ProxyObjectOutputStream and ProxyObjectInputStream
factory.
setUseCache(true);
factory.
setUseWriteReplace(false);
factory.
setSuperclass(
superClass);
factory.
setInterfaces(
interfaces);
Class proxyClass =
factory.
createClass(
signature);
return
ObjectStreamClass.
lookup(
proxyClass);
} else {
return super.readClassDescriptor();
}
}
/**
* the loader to use to resolve classes for proxy superclass and interface names read
* from the stream. defaults to the context class loader of the thread which creates
* the input stream or the system class loader if the context class loader is null.
*/
private
ClassLoader loader;
}