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

Reply via email to