You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2007/08/02 08:21:52 UTC

svn commit: r562026 - in /openejb/trunk/openejb3/container/openejb-core/src: main/java/org/apache/openejb/assembler/classic/ main/java/org/apache/openejb/config/ main/java/org/apache/openejb/core/ivm/ test/java/org/apache/openejb/assembler/classic/

Author: dblevins
Date: Wed Aug  1 23:21:51 2007
New Revision: 562026

URL: http://svn.apache.org/viewvc?view=rev&rev=562026
Log:
Fix for OPENEJB-623: Apply container-transaction delcarations in proper order

Added:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/MethodTransactionInfoComparatorTest.java
Modified:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AssemblerTool.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?view=diff&rev=562026&r1=562025&r2=562026
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Wed Aug  1 23:21:51 2007
@@ -407,10 +407,10 @@
                     jaccPermissionsBuilder.install(policyContext);
                 }
 
+                MethodTransactionBuilder methodTransactionBuilder = new MethodTransactionBuilder();
+                methodTransactionBuilder.build(deployments, ejbJar.methodTransactions);
 
-                // process transaction attributes
                 for (DeploymentInfo deploymentInfo : deployments.values()) {
-                    applyTransactionAttributes((CoreDeploymentInfo) deploymentInfo, ejbJar.methodTransactions);
                     containerSystem.addDeployment(deploymentInfo);
                 }
 

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AssemblerTool.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AssemblerTool.java?view=diff&rev=562026&r1=562025&r2=562026
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AssemblerTool.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AssemblerTool.java Wed Aug  1 23:21:51 2007
@@ -52,78 +52,6 @@
         System.setProperty("noBanner", "true");
     }
 
-    public static void applyTransactionAttributes(CoreDeploymentInfo deploymentInfo, List<MethodTransactionInfo> mtis) throws OpenEJBException {
-        /*TODO: Add better exception handling.  This method doesn't throws any exceptions!!
-         there is a lot of complex code here, I'm sure something could go wrong the user
-         might want to know about.
-         */
-        for (MethodTransactionInfo transInfo : mtis) {
-            for (MethodInfo methodInfo : transInfo.methods) {
-
-                if (methodInfo.ejbDeploymentId == null || methodInfo.ejbDeploymentId.equals(deploymentInfo.getDeploymentID())) {
-                    if (!deploymentInfo.isBeanManagedTransaction()) {
-
-                        List<Method> methods = new ArrayList<Method>();
-
-                        if (methodInfo.methodIntf == null) {
-                            resolveMethods(methods, deploymentInfo.getBeanClass(), methodInfo);
-                            if (deploymentInfo.getRemoteInterface() != null) {
-                                resolveMethods(methods, deploymentInfo.getRemoteInterface(), methodInfo);
-                            }
-                            if (deploymentInfo.getHomeInterface() != null) {
-                                resolveMethods(methods, deploymentInfo.getHomeInterface(), methodInfo);
-                            }
-                            if (deploymentInfo.getLocalInterface() != null) {
-                                resolveMethods(methods, deploymentInfo.getLocalInterface(), methodInfo);
-                            }
-                            if (deploymentInfo.getLocalHomeInterface() != null) {
-                                resolveMethods(methods, deploymentInfo.getLocalHomeInterface(), methodInfo);
-                            }
-                            if(deploymentInfo.getMdbInterface() != null) {
-                            	resolveMethods(methods, deploymentInfo.getMdbInterface(), methodInfo);
-                            }
-                            if(deploymentInfo.getServiceEndpointInterface() != null) {
-                            	resolveMethods(methods, deploymentInfo.getServiceEndpointInterface(), methodInfo);
-                            }
-                            for (Class intf : deploymentInfo.getBusinessRemoteInterfaces()) {
-                                resolveMethods(methods, intf, methodInfo);
-                            }
-                            for (Class intf : deploymentInfo.getBusinessLocalInterfaces()) {
-                                resolveMethods(methods, intf, methodInfo);
-                            }
-                        } else if (methodInfo.methodIntf.equals("Home")) {
-                            resolveMethods(methods, deploymentInfo.getHomeInterface(), methodInfo);
-                        } else if (methodInfo.methodIntf.equals("Remote")) {
-                            resolveMethods(methods, deploymentInfo.getRemoteInterface(), methodInfo);
-                            for (Class intf : deploymentInfo.getBusinessRemoteInterfaces()) {
-                                resolveMethods(methods, intf, methodInfo);
-                            }
-                        } else if (methodInfo.methodIntf.equals("LocalHome")) {
-                            resolveMethods(methods, deploymentInfo.getLocalHomeInterface(), methodInfo);
-                        } else if (methodInfo.methodIntf.equals("Local")) {
-                            resolveMethods(methods, deploymentInfo.getLocalInterface(), methodInfo);
-                            for (Class intf : deploymentInfo.getBusinessRemoteInterfaces()) {
-                                resolveMethods(methods, intf, methodInfo);
-                            }
-                        } else if (methodInfo.methodIntf.equals("ServiceEndpoint")) {
-                            resolveMethods(methods, deploymentInfo.getServiceEndpointInterface(), methodInfo);
-                        }
-
-                        for (Method method : methods) {
-                            if ((method.getDeclaringClass() == javax.ejb.EJBObject.class ||
-                                    method.getDeclaringClass() == javax.ejb.EJBHome.class) &&
-                                    !method.getName().equals("remove")) {
-                                continue;
-                            }
-                            deploymentInfo.setMethodTransactionAttribute(method, transInfo.transAttribute);
-                        }
-                    }
-                }
-            }
-        }
-
-    }
-
     protected static void resolveMethods(List<Method> methods, Class intrface, MethodInfo mi)
             throws SecurityException {
         /*TODO: Add better exception handling. There is a lot of complex code here, I'm sure something could go wrong the user

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java?view=auto&rev=562026
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java Wed Aug  1 23:21:51 2007
@@ -0,0 +1,166 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.assembler.classic;
+
+import org.apache.openejb.core.CoreDeploymentInfo;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.DeploymentInfo;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.lang.reflect.Method;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MethodTransactionBuilder {
+
+    public void build(HashMap<String, DeploymentInfo> deployments, List<MethodTransactionInfo> methodTransactions) throws OpenEJBException {
+        for (DeploymentInfo deploymentInfo : deployments.values()) {
+            applyTransactionAttributes((CoreDeploymentInfo) deploymentInfo, methodTransactions);
+        }
+    }
+
+    public static void applyTransactionAttributes(CoreDeploymentInfo deploymentInfo, List<MethodTransactionInfo> mtis) throws OpenEJBException {
+        /*TODO: Add better exception handling.  This method doesn't throws any exceptions!!
+        there is a lot of complex code here, I'm sure something could go wrong the user
+        might want to know about.
+        */
+
+        mtis = normalize(mtis);
+
+        for (MethodTransactionInfo transInfo : mtis) {
+            for (MethodInfo methodInfo : transInfo.methods) {
+
+                if (methodInfo.ejbDeploymentId == null || methodInfo.ejbDeploymentId.equals(deploymentInfo.getDeploymentID())) {
+                    if (!deploymentInfo.isBeanManagedTransaction()) {
+
+                        List<Method> methods = new ArrayList<Method>();
+
+                        if (methodInfo.methodIntf == null) {
+                            AssemblerTool.resolveMethods(methods, deploymentInfo.getBeanClass(), methodInfo);
+                            if (deploymentInfo.getRemoteInterface() != null) {
+                                AssemblerTool.resolveMethods(methods, deploymentInfo.getRemoteInterface(), methodInfo);
+                            }
+                            if (deploymentInfo.getHomeInterface() != null) {
+                                AssemblerTool.resolveMethods(methods, deploymentInfo.getHomeInterface(), methodInfo);
+                            }
+                            if (deploymentInfo.getLocalInterface() != null) {
+                                AssemblerTool.resolveMethods(methods, deploymentInfo.getLocalInterface(), methodInfo);
+                            }
+                            if (deploymentInfo.getLocalHomeInterface() != null) {
+                                AssemblerTool.resolveMethods(methods, deploymentInfo.getLocalHomeInterface(), methodInfo);
+                            }
+                            if(deploymentInfo.getMdbInterface() != null) {
+                                AssemblerTool.resolveMethods(methods, deploymentInfo.getMdbInterface(), methodInfo);
+                            }
+                            if(deploymentInfo.getServiceEndpointInterface() != null) {
+                                AssemblerTool.resolveMethods(methods, deploymentInfo.getServiceEndpointInterface(), methodInfo);
+                            }
+                            for (Class intf : deploymentInfo.getBusinessRemoteInterfaces()) {
+                                AssemblerTool.resolveMethods(methods, intf, methodInfo);
+                            }
+                            for (Class intf : deploymentInfo.getBusinessLocalInterfaces()) {
+                                AssemblerTool.resolveMethods(methods, intf, methodInfo);
+                            }
+                        } else if (methodInfo.methodIntf.equals("Home")) {
+                            AssemblerTool.resolveMethods(methods, deploymentInfo.getHomeInterface(), methodInfo);
+                        } else if (methodInfo.methodIntf.equals("Remote")) {
+                            AssemblerTool.resolveMethods(methods, deploymentInfo.getRemoteInterface(), methodInfo);
+                            for (Class intf : deploymentInfo.getBusinessRemoteInterfaces()) {
+                                AssemblerTool.resolveMethods(methods, intf, methodInfo);
+                            }
+                        } else if (methodInfo.methodIntf.equals("LocalHome")) {
+                            AssemblerTool.resolveMethods(methods, deploymentInfo.getLocalHomeInterface(), methodInfo);
+                        } else if (methodInfo.methodIntf.equals("Local")) {
+                            AssemblerTool.resolveMethods(methods, deploymentInfo.getLocalInterface(), methodInfo);
+                            for (Class intf : deploymentInfo.getBusinessRemoteInterfaces()) {
+                                AssemblerTool.resolveMethods(methods, intf, methodInfo);
+                            }
+                        } else if (methodInfo.methodIntf.equals("ServiceEndpoint")) {
+                            AssemblerTool.resolveMethods(methods, deploymentInfo.getServiceEndpointInterface(), methodInfo);
+                        }
+
+                        for (Method method : methods) {
+                            if ((method.getDeclaringClass() == javax.ejb.EJBObject.class ||
+                                    method.getDeclaringClass() == javax.ejb.EJBHome.class) &&
+                                    !method.getName().equals("remove")) {
+                                continue;
+                            }
+                            deploymentInfo.setMethodTransactionAttribute(method, transInfo.transAttribute);
+                        }
+                    }
+                }
+            }
+        }
+
+    }
+
+    public static enum Level {
+        PACKAGE, CLASS, OVERLOADED_METHOD, EXACT_METHOD
+    }
+
+    /**
+     * This method splits the MethodTransactionInfo objects so that there is
+     * exactly one MethodInfo per MethodTransactionInfo.  A single MethodTransactionInfo
+     * with three MethodInfos would be expanded into three MethodTransactionInfo with
+     * one MethodInfo each.
+     *
+     * The MethodTransactionInfo list is then sorted from least to most specific.
+     *
+     * @param infos
+     * @return a normalized list of new MethodTransactionInfo objects
+     */
+    public static List<MethodTransactionInfo> normalize(List<MethodTransactionInfo> infos){
+        List<MethodTransactionInfo> normalized = new ArrayList<MethodTransactionInfo>();
+        for (MethodTransactionInfo oldInfo : infos) {
+            for (MethodInfo methodInfo : oldInfo.methods) {
+                MethodTransactionInfo newInfo = new MethodTransactionInfo();
+                newInfo.description = oldInfo.description;
+                newInfo.methods.add(methodInfo);
+                newInfo.transAttribute = oldInfo.transAttribute;
+
+                normalized.add(newInfo);
+            }
+        }
+
+        Collections.sort(normalized, new MethodTransactionComparator());
+
+        return normalized;
+    }
+
+    public static class MethodTransactionComparator implements Comparator<MethodTransactionInfo> {
+        public int compare(MethodTransactionInfo a, MethodTransactionInfo b) {
+            Level levelA = level(a);
+            Level levelB = level(b);
+
+            return levelA.ordinal() - levelB.ordinal();
+        }
+    }
+
+    private static Level level(MethodTransactionInfo info) {
+        MethodInfo methodInfo = info.methods.get(0);
+        if (methodInfo.ejbName.equals("*")) return Level.PACKAGE;
+        if (methodInfo.methodName == null || methodInfo.methodName.equals("*")) return Level.CLASS;
+        if (methodInfo.methodParams == null) return Level.OVERLOADED_METHOD;
+        return Level.EXACT_METHOD;
+    }
+
+}

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java?view=diff&rev=562026&r1=562025&r2=562026
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java Wed Aug  1 23:21:51 2007
@@ -128,7 +128,7 @@
         if (debuggableVmHackery.equalsIgnoreCase("true")){
             chain.add(new DebuggableVmHackery());
         }
-        
+
         chain.add(new CmpJpaConversion());
         chain.add(new OpenEjb2Conversion());
         chain.add(new SunConversion());

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java?view=diff&rev=562026&r1=562025&r2=562026
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java Wed Aug  1 23:21:51 2007
@@ -90,10 +90,10 @@
     */
     protected boolean doIntraVmCopy;
     protected boolean doCrossClassLoaderCopy;
-    protected final InterfaceType interfaceType;
-    private final WeakReference<List<Class>> interfaces;
     private static final boolean REMOTE_COPY_ENABLED = parseRemoteCopySetting();
-    private final WeakReference<Class> mainInterface;
+    protected final InterfaceType interfaceType;
+    private transient WeakReference<List<Class>> interfaces;
+    private transient WeakReference<Class> mainInterface;
 
     public BaseEjbProxyHandler(DeploymentInfo deploymentInfo, Object pk, InterfaceType interfaceType, List<Class> interfaces) {
         this.container = (RpcContainer) deploymentInfo.getContainer();
@@ -176,19 +176,6 @@
         return value == null || !value.equalsIgnoreCase("FALSE");
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException, NoSuchMethodException {
-
-        in.defaultReadObject();
-
-        ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
-        setDeploymentInfo((CoreDeploymentInfo) containerSystem.getDeploymentInfo(deploymentID));
-        container = (RpcContainer) getDeploymentInfo().getContainer();
-
-        if (IntraVmCopyMonitor.isCrossClassLoaderOperation()) {
-            doCrossClassLoaderCopy = true;
-        }
-    }
-
     protected void checkAuthorization(Method method) throws org.apache.openejb.OpenEJBException {
     }
 
@@ -561,6 +548,29 @@
             deploymentInfo.set(ProxyRegistry.class, proxyRegistry);
         }
         return proxyRegistry.liveHandleRegistry;
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+        out.defaultWriteObject();
+
+        out.writeObject(interfaces.get());
+        out.writeObject(mainInterface.get());
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+
+        in.defaultReadObject();
+
+        ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
+        setDeploymentInfo((CoreDeploymentInfo) containerSystem.getDeploymentInfo(deploymentID));
+        container = (RpcContainer) getDeploymentInfo().getContainer();
+
+        if (IntraVmCopyMonitor.isCrossClassLoaderOperation()) {
+            doCrossClassLoaderCopy = true;
+        }
+
+        interfaces = new WeakReference<List<Class>>((List<Class>) in.readObject());
+        mainInterface = new WeakReference<Class>((Class) in.readObject());
     }
 
 }

Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/MethodTransactionInfoComparatorTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/MethodTransactionInfoComparatorTest.java?view=auto&rev=562026
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/MethodTransactionInfoComparatorTest.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/MethodTransactionInfoComparatorTest.java Wed Aug  1 23:21:51 2007
@@ -0,0 +1,85 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.assembler.classic;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MethodTransactionInfoComparatorTest extends TestCase {
+
+    public void testOrdering() throws Exception {
+
+        ArrayList<MethodTransactionInfo> expected = new ArrayList<MethodTransactionInfo>();
+
+        MethodTransactionInfo info = null;
+        MethodInfo method = null;
+
+        // Package Interceptors (aka Default Interceptors) ///////////////
+        info = add(expected, new MethodTransactionInfo());
+        info.transAttribute = "Required";
+        method = new MethodInfo();
+        method.ejbName = "*";
+        info.methods.add(method);
+
+        // Class Interceptors ////////////////////////////////////////////
+        info = add(expected, new MethodTransactionInfo());
+        info.transAttribute = "Required";
+        method = new MethodInfo();
+        method.ejbName = "*";
+        info.methods.add(method);
+
+        // Method Interceptors (no params) ///////////////////////////////
+        info = add(expected, new MethodTransactionInfo());
+        info.transAttribute = "Required";
+        method = new MethodInfo();
+        method.ejbName = "PingEJB";
+        method.methodName = "ping";
+        info.methods.add(method);
+
+        // Method Interceptors (params)    ///////////////////////////////
+        info = add(expected, new MethodTransactionInfo());
+        info.transAttribute = "Required";
+        method = new MethodInfo();
+        method.ejbName = "PingEJB";
+        method.methodName = "ping";
+        method.methodParams = new ArrayList<String>();
+        method.methodParams.add("java.lang.String");
+        info.methods.add(method);
+
+        ArrayList<MethodTransactionInfo> actual = new ArrayList<MethodTransactionInfo>(expected);
+        Collections.shuffle(actual);
+        Collections.sort(actual, new MethodTransactionBuilder.MethodTransactionComparator());
+
+        for (int i = 0; i < actual.size(); i++) {
+            MethodTransactionInfo a = actual.get(i);
+            MethodTransactionInfo e = expected.get(i);
+            assertSame(e, a);
+        }
+    }
+
+
+    private MethodTransactionInfo add(List list, MethodTransactionInfo bindingInfo) {
+        list.add(bindingInfo);
+        return bindingInfo;
+    }
+}