package jfun.yan.util.deserializer;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import jfun.yan.ComponentInstantiationException;
/**
* A thread local store that is made serializable
* and uses the default constructor of a class to
* create the initial value.
* <p>
* @author Ben Yu
* Feb 3, 2006 11:56:51 AM
*/
final class DefaultConstructedThreadLocalSerializable
implements java.io.Serializable{
public Object get(){
return store.get();
}
private static Constructor getDefaultConstructor(final Class type){
try{
return type.getConstructor(null);
}
catch(NoSuchMethodException e){
throw new IllegalArgumentException("default constructor of "+type
+ " not found.");
}
}
private static final class ThreadLocalStore extends ThreadLocal{
private final Constructor ctor;
ThreadLocalStore(Class type) {
this.ctor = getDefaultConstructor(type);
}
public String toString(){
return ctor.getDeclaringClass().getName();
}
protected Object initialValue() {
try{
return ctor.newInstance(null);
}
catch(InstantiationException e){
throw new IllegalArgumentException("failed to invoke default constructor of "
+ ctor.getDeclaringClass());
}
catch(IllegalAccessException e){
throw new IllegalArgumentException("cannot access default constructor of "
+ ctor.getDeclaringClass());
}
catch(InvocationTargetException e){
throw new ComponentInstantiationException("default constructor failed.",
e.getTargetException());
}
}
}
public String toString(){
return type.getName();
}
private final Class type;
private transient ThreadLocalStore store;
private void readObject(java.io.ObjectInputStream in)
throws ClassNotFoundException, java.io.IOException{
in.defaultReadObject();
store = new ThreadLocalStore(type);
}
public DefaultConstructedThreadLocalSerializable(Class type){
this.type = type;
this.store = new ThreadLocalStore(type);
}
}