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; } }