On Monday 16 February 2004 01:55, [EMAIL PROTECTED] wrote:
>...omissis... If you ever have the urge to contribute
> code, I'll be happy to check it over.
Dear David and friends,
I had the impression that the problem was limited to the
org.openejb.core.ivm.EjbHomeProxyHandler class only, so I tried to modify it
to support the feature I need. At least, it should have been faster than
downloading another EJB server, installing and configuring it, deploying my
test app, ecc. ecc.
In effect, it seems that I was right at first: the 'patched' version of the
class seems to work to me.
Whould you (and anybody else who may care) have a review at it?
I'm attaching it as a unified diff format. In both the OpenEJB revision
threads the class is the same, so the patch should be appliable to both.
Regards,
Giampaolo Tomassoni
PS: I'm sending this patch to the openejb-user thread too.
--- src/main/org/openejb/core/ivm/EjbHomeProxyHandler.java- 2002-10-04 00:09:34.000000000 +0200
+++ src/main/org/openejb/core/ivm/EjbHomeProxyHandler.java 2004-02-16 19:51:48.000000000 +0100
@@ -80,21 +80,68 @@
*
* @author <a href="mailto:[EMAIL PROTECTED]">David Blevins</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Richard Monson-Haefel</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Giampaolo Tomassoni</a>
* @see org.openejb.core.ivm.EjbObjectProxyHandler
* @see org.openejb.core.stateful.StatefulContainer
*/
public abstract class EjbHomeProxyHandler extends BaseEjbProxyHandler {
protected final static org.apache.log4j.Category logger = org.apache.log4j.Category.getInstance("OpenEJB");
- static final java.util.HashMap dispatchTable;
+ // This interface is an invoker helper, which helps method dispatching
+ // in costant time.
+ private interface InvokeHelper {
+ public Object invoke(Method method, Object[] args, Object proxy)
+ throws Throwable;
+ }
+
+ private final InvokeHelper ihFind = new InvokeHelper() {
+ public Object invoke(Method method, Object[] args, Object proxy)
+ throws Throwable
+ { return(findX(method, args, proxy)); }
+ };
+
+ private final InvokeHelper ihBusiness = new InvokeHelper() {
+ public Object invoke(Method method, Object[] args, Object proxy)
+ throws Throwable
+ { return(businessMethod(method, args, proxy)); }
+ };
// this table helps dispatching in constant time, instead of many expensive equals() calls
- static {
+ private java.util.HashMap dispatchTable;
+ {
dispatchTable = new java.util.HashMap();
- dispatchTable.put("create", new Integer(1));
- dispatchTable.put("getEJBMetaData", new Integer(2));
- dispatchTable.put("getHomeHandle", new Integer(3));
- dispatchTable.put("remove", new Integer(4));
+ dispatchTable.put(
+ "create",
+ new InvokeHelper() {
+ public Object invoke(Method method, Object[] args, Object proxy)
+ throws Throwable
+ { return(create(method, args, proxy)); }
+ }
+ );
+ dispatchTable.put(
+ "getEJBMetaData",
+ new InvokeHelper() {
+ public Object invoke(Method method, Object[] args, Object proxy)
+ throws Throwable
+ { return(getEJBMetaData(method, args, proxy)); }
+ }
+ );
+ dispatchTable.put(
+ "getHomeHandle",
+ new InvokeHelper() {
+ public Object invoke(Method method, Object[] args, Object proxy)
+ throws Throwable
+ { return(getHomeHandle(method, args, proxy)); }
+ }
+ );
+ dispatchTable.put(
+ "remove",
+ new InvokeHelper() {
+ public Object invoke(Method method, Object[] args, Object proxy)
+ throws Throwable
+ { return(removeMethod(method, args, proxy)); }
+ }
+ );
}
/**
@@ -113,7 +160,6 @@
}
protected Object createProxy(ProxyInfo proxyInfo){
-
if (proxyInfo instanceof SpecialProxyInfo) {
Object proxy = ((SpecialProxyInfo)proxyInfo).getProxy();
if (proxy == null) throw new RuntimeException("Could not create IVM proxy for "+proxyInfo.getInterface()+" interface");
@@ -135,50 +181,41 @@
protected abstract EjbObjectProxyHandler newEjbObjectHandler(RpcContainer container, Object pk, Object depID);
+ /**
+ * <P>
+ * Invokes a method in the javax.ejb.EnterpiseBean
+ * by yielding control to the appropriate proxy method invoker.
+ * </P>
+ * <P>
+ * In order to keep a linear search time for the proxy method
+ * to call given an Home Interface method, an hashtable mapping
+ * the Home Interface method names to the related proxy method
+ * is maintained.
+ * Each time an H.I. method name not yet in the hashtable
+ * is invoked, this function attempts mapping to the corresponding
+ * proxy method and saves the mapping in the hashtable.
+ * </P>
+ *
+ * @param proxy The Proxy object that represents this bean deployment's EJBObject or EJBHome.
+ * @param method The EJBHome method the caller is invoking.
+ * @param args The parameters to the method being invoked
+ * @return The result of invoking the appropriate method on the bean.
+ * @exception Throwable
+ */
protected Object _invoke(Object proxy, Method method, Object[] args) throws Throwable{
-
if (logger.isInfoEnabled()) {
logger.info("invoking method "+method.getName()+" on "+deploymentID);
}
String methodName = method.getName();
-
- try{
- java.lang.Object retValue;
- Integer operation = (Integer)dispatchTable.get(methodName);
-
- if(operation==null) {
- if ( methodName.startsWith("find") ){
- retValue = findX(method, args, proxy);
- } else {
- // Cannot return null. Must throw and exception instead.
- throw new UnsupportedOperationException("Unkown method: "+method);
+ InvokeHelper methodTarget = (InvokeHelper)dispatchTable.get(methodName);
+ if(methodTarget == null) {
+ methodTarget = (methodName.startsWith("find") ? ihFind : ihBusiness);
+ dispatchTable.put(methodName, methodTarget);
}
- }else {
- switch(operation.intValue()) {
- /*-- CREATE ------------- <HomeInterface>.create(<x>) ---*/
- case 1: retValue = create(method, args, proxy); break;
- /*-- GET EJB METADATA ------ EJBHome.getEJBMetaData() ---*/
- case 2: retValue = getEJBMetaData(method, args, proxy); break;
- /*-- GET HOME HANDLE -------- EJBHome.getHomeHandle() ---*/
- case 3: retValue = getHomeHandle(method, args, proxy); break;
- /*-- REMOVE ------------------------ EJBHome.remove() ---*/
- case 4: {
- Class type = method.getParameterTypes()[0];
- /*-- HANDLE ------- EJBHome.remove(Handle handle) ---*/
- if (javax.ejb.Handle.class.isAssignableFrom(type)) {
- retValue = removeWithHandle(method, args, proxy);
- } else {
- /*-- PRIMARY KEY ----- EJBHome.remove(Object key) ---*/
- retValue = removeByPrimaryKey(method, args, proxy);
- }
- break;
- }
- default:
- throw new RuntimeException("Inconsistent internal state: value "+operation.intValue()+" for operation "+methodName);
- }
- }
+ try{
+ java.lang.Object retValue = methodTarget.invoke(method, args, proxy);
if(logger.isDebugEnabled()) {
logger.debug("finished invoking method "+method.getName()+". Return value:"+retValue);
@@ -269,6 +306,44 @@
*/
protected abstract Object findX(Method method, Object[] args, Object proxy) throws Throwable;
+
+ /**
+ * <P>
+ * Invokes a Home Business method, i.e.: a
+ * Business method which doesn't depend on
+ * a specific instance of the Bean.
+ * </P>
+ * <P>
+ * Home Business methods are declared in the
+ * Home interface. Their support is mandatory
+ * (see 9.5.4 of ejb-2_1-fr spec).
+ * </P>
+ * <P>
+ * Checks if the caller is authorized to invoke the
+ * javax.ejb.EJBHome.getHomeHandle on the EJBHome of the
+ * deployment.
+ * </P>
+ *
+ * @param proxy The Proxy object that represents this bean deployment's EJBObject or EJBHome.
+ * @param method The EJBHome method the caller is invoking.
+ * @param args The parameters to the method being invoked
+ * @return Returns whatever the method declaration in the Home Interface dictates it shall return
+ * @exception Throwable
+ * @author <a href="mailto:[EMAIL PROTECTED]">Giampaolo Tomassoni</a>
+ */
+ protected Object businessMethod(Method method, Object[] args, Object proxy)
+ throws Throwable {
+ checkAuthorization(method);
+ return(
+ createProxy(
+ (ProxyInfo)container.invoke(
+ deploymentID, method, args, null,
+ getThreadSpecificSecurityIdentity()
+ )
+ )
+ );
+ }
+
/*-------------------------------------------------*/
/* EJBHome methods */
/*-------------------------------------------------*/
@@ -468,4 +543,35 @@
* @see javax.ejb.EJBHome#remove
*/
protected abstract Object removeByPrimaryKey(Method method, Object[] args, Object proxy) throws Throwable;
+
+ /**
+ * <P>
+ * This is a 'generic' version of the remove method,
+ * implementing logic act to detect whether or not
+ * the method is invoked on an handle, thereby
+ * yielding control to a more specialized version
+ * of the method itself.
+ * </P>
+ *
+ * @param method
+ * @param args
+ * @param proxy
+ * @return Whatever removeWithHandle or removeByPrimaryKey returns, that should be null
+ * @exception Throwable
+ * @see javax.ejb.EJBHome
+ * @see javax.ejb.EJBHome#remove
+ * @author <a href="mailto:[EMAIL PROTECTED]">Giampaolo Tomassoni</a>
+ */
+ private Object removeMethod(Method method, Object[] args, Object proxy)
+ throws Throwable {
+ return(
+ javax.ejb.Handle.class.isAssignableFrom(method.getParameterTypes()[0])
+ ?
+ /*-- HANDLE ------- EJBHome.remove(Handle handle) ---*/
+ removeWithHandle(method, args, proxy)
+ :
+ /*-- PRIMARY KEY ----- EJBHome.remove(Object key) ---*/
+ removeByPrimaryKey(method, args, proxy)
+ );
+ }
}