package org.jboss.seam.persistence;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.jboss.seam.security.permission.PermissionManager;
/**
* InvocationHandler that Proxies the EntityManager, and implements EL
* interpolation in JPA-QL
*
* @author Gavin King
* @author Mike Youngstrom
*/
public class EntityManagerInvocationHandler implements InvocationHandler, Serializable
{
private EntityManager delegate;
public EntityManagerInvocationHandler(EntityManager delegate)
{
this.delegate = delegate;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
try
{
if ("createQuery".equals(method.getName()) && method.getParameterTypes().length > 0 && method.getParameterTypes()[0].equals(String.class))
{
return handleCreateQueryWithString(method, args);
}
if ("getDelegate".equals(method.getName()))
{
return handleGetDelegate(method, args);
}
if ("remove".equals(method.getName()) && method.getParameterTypes().length > 0)
{
return handleRemove(method, args);
}
return method.invoke(delegate, args);
}
catch (InvocationTargetException e)
{
throw e.getTargetException();
}
}
protected Object handleCreateQueryWithString(Method method, Object[] args) throws Throwable
{
if (args[0] == null)
{
return method.invoke(delegate, args);
}
String ejbql = (String) args[0];
if (ejbql.indexOf('#') > 0)
{
QueryParser qp = new QueryParser(ejbql);
Object[] newArgs = args.clone();
newArgs[0] = qp.getEjbql();
Query query = (Query) method.invoke(delegate, newArgs);
for (int i = 0; i < qp.getParameterValueBindings().size(); i++)
{
query.setParameter(QueryParser.getParameterName(i), qp.getParameterValueBindings().get(i).getValue());
}
return query;
}
else
{
return method.invoke(delegate, args);
}
}
protected Object handleGetDelegate(Method method, Object[] args) throws Throwable
{
return PersistenceProvider.instance().proxyDelegate(method.invoke(delegate, args));
}
protected Object handleRemove(Method method, Object[] args) throws Throwable
{
if (args.length == 0)
{
return method.invoke(delegate, args);
}
Object result = method.invoke(delegate, args);
PermissionManager.instance().clearPermissions(args[0]);
return result;
}
}