package org.jboss.ejb.plugins.cmp.bridge;
import java.lang.reflect.Method;
import java.util.Map;
import javax.ejb.EJBException;
import javax.ejb.FinderException;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.proxy.compiler.InvocationHandler;
public class EntityBridgeInvocationHandler implements InvocationHandler
{
private final Class beanClass;
private final Map fieldMap;
private final Map selectorMap;
private EntityEnterpriseContext ctx;
public EntityBridgeInvocationHandler(Map fieldMap, Map selectorMap, Class beanClass)
{
this.beanClass = beanClass;
this.fieldMap = fieldMap;
this.selectorMap = selectorMap;
}
public void setContext(EntityEnterpriseContext ctx)
{
if(ctx != null && !beanClass.isInstance(ctx.getInstance()))
{
throw new EJBException("Instance must be an instance of beanClass");
}
this.ctx = ctx;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws FinderException
{
String methodName = method.getName();
BridgeInvoker invoker = (BridgeInvoker) fieldMap.get(methodName);
if(invoker == null)
{
invoker = (BridgeInvoker) selectorMap.get(method);
if(invoker == null)
{
throw new EJBException("Method is not a known CMP field " +
"accessor, CMR field accessor, or ejbSelect method: " +
"methodName=" + methodName);
}
}
try
{
return invoker.invoke(ctx, method, args);
}
catch(RuntimeException e)
{
throw e;
}
catch(FinderException e)
{
throw e;
}
catch(Exception e)
{
throw new EJBException("Internal error", e);
}
}
public interface BridgeInvoker
{
Object invoke(EntityEnterpriseContext ctx, Method method, Object[] args) throws FinderException, Exception;
}
public static class FieldGetInvoker implements BridgeInvoker
{
private final FieldBridge field;
public FieldGetInvoker(FieldBridge field)
{
this.field = field;
}
public Object invoke(EntityEnterpriseContext ctx, Method method, Object[] args)
{
if(ctx == null)
{
throw new EJBException("EJB home methods are not allowed to " +
"access CMP or CMR fields: methodName=" + method.getName());
}
return field.getValue(ctx);
}
}
public static class FieldSetInvoker implements BridgeInvoker
{
private final FieldBridge field;
public FieldSetInvoker(FieldBridge field)
{
this.field = field;
}
public Object invoke(EntityEnterpriseContext ctx, Method method, Object[] args)
{
if(ctx == null)
{
throw new EJBException("EJB home methods are not allowed to " +
"access CMP or CMR fields: methodName=" + method.getName());
}
field.setValue(ctx, args[0]);
return null;
}
}
}