org.yestech.lib.hibernate.client.Proxy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of yeslib Show documentation
Show all versions of yeslib Show documentation
A collection of classes that can be used across yestech artifacts/components, but must not be dependant
on any yestech component. Most of the code is utility type code. When more than a few classes are
found to be in a package or the package start to handle more that a few reposibilities then a new
independant component is created and the existing code in yeslib is ported to the new component.
package org.yestech.lib.hibernate.client;
import java.io.ObjectStreamException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import net.sf.cglib.core.NamingPolicy;
import net.sf.cglib.core.Predicate;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;
import net.sf.cglib.proxy.NoOp;
/**
*
*
*/
public class Proxy
{
private static final Class[] CALLBACK_TYPES = new Class[]{InvocationHandler.class, NoOp.class};
private static final class CollectionProxy extends AbstractSet
{
private final CollectionReference reference;
private Set remote;
private CollectionProxy(CollectionReference reference)
{
super();
this.reference = reference;
}
Object writeReplare() throws ObjectStreamException
{
if (remote != null)
{
return remote;
}
else
{
return reference;
}
}
private Set load()
{
try
{
if (remote == null)
{
remote = (Set) ClientSession.getLoader().
initializeCollection(reference.getRole(), reference.getId());
}
}
catch (Exception e)
{
throw new RuntimeException(e);
}
return remote;
}
public int size()
{
return load().size();
}
public boolean isEmpty()
{
return load().isEmpty();
}
public Object[] toArray()
{
return load().toArray();
}
public boolean contains(Object o)
{
return load().contains(o);
}
public boolean containsAll(Collection c)
{
return load().containsAll(c);
}
public Iterator iterator()
{
return load().iterator();
}
public Object[] toArray(Object[] a)
{
return load().toArray(a);
}
}
public interface WriteReplace
{
Object writeReplace() throws ObjectStreamException;
}
private static final class Interceptor implements InvocationHandler
{
private Object entity;
private LazyReference ref;
Interceptor(LazyReference ref)
{
this.ref = ref;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
if (args.length == 0 &&
method.getDeclaringClass() == WriteReplace.class &&
method.getName().equals("writeReplace"))
{
if (entity != null)
{
return entity;
}
else
{
return ref;
}
}
if (entity == null)
{
entity = ClientSession.getLoader().initializeEntity(ref.getClassName(), ref.getId(), ref.getToken());
}
try
{
return method.invoke(entity, args);
}
catch (InvocationTargetException ite)
{
throw ite;
}
}
}
public static Object create(final LazyReference ref) throws ClassNotFoundException
{
Class cls = Class.forName(ref.getClassName(), false, Thread
.currentThread().getContextClassLoader());
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(cls);
enhancer.setCallbackTypes(CALLBACK_TYPES);
enhancer.setInterfaces(new Class[]{WriteReplace.class});
enhancer.setCallbackFilter(new CallbackFilter()
{
public int accept(Method m)
{
return Modifier.isPublic(m.getModifiers()) ? 0 : 1;
}
});
enhancer.setCallbacks(new Callback[]{new Interceptor(ref), NoOp.INSTANCE});
enhancer.setNamingPolicy(
new NamingPolicy()
{
public String getClassName(String arg0, String arg1, Object arg2, Predicate arg3)
{
return ref.getClassName() + "$ClientProxy";
}
}
);
return enhancer.create();
}
public static Set create(final CollectionReference reference)
{
Set set = new CollectionProxy(reference);
return Collections.unmodifiableSet(set);
}
}