Author: dblevins
Date: Sat Jun  4 01:45:46 2011
New Revision: 1131304

URL: http://svn.apache.org/viewvc?rev=1131304&view=rev
Log:
Fixes OPENEJB-1567: Overriding of per-interface transaction attributes only 
supported for different method signatures

Added:
    
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/InterfaceTransactionTest.java
Modified:
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodInfoUtil.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
    
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/TransactionAttributesTest.java
    
openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java?rev=1131304&r1=1131303&r2=1131304&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
 Sat Jun  4 01:45:46 2011
@@ -41,6 +41,7 @@ import javax.ejb.Timer;
 import javax.naming.Context;
 import javax.persistence.EntityManagerFactory;
 
+import com.sun.istack.internal.Nullable;
 import org.apache.openejb.cdi.OWBInjector;
 import org.apache.openejb.core.ExceptionType;
 import org.apache.openejb.core.InstanceContext;
@@ -58,8 +59,6 @@ import org.apache.openejb.core.transacti
 import org.apache.openejb.core.transaction.TransactionType;
 import org.apache.openejb.util.Duration;
 import org.apache.openejb.util.Index;
-import org.apache.openejb.util.LogCategory;
-import org.apache.openejb.util.Logger;
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.xbean.recipe.ConstructionException;
 
@@ -126,6 +125,7 @@ public class BeanContext extends Deploym
     private final Map<Method, TransactionType> methodTransactionType = new 
HashMap<Method, TransactionType>();
     private final Map<Method, Method> methodMap = new HashMap<Method, 
Method>();
     private final Map<Method, MethodContext> methodContextMap = new 
HashMap<Method, MethodContext>();
+    private final Map<String, ViewContext> viewContextMap = new 
HashMap<String, ViewContext>();
 
     private Index<EntityManagerFactory,Map> extendedEntityManagerFactories;
 
@@ -412,36 +412,57 @@ public class BeanContext extends Deploym
     }
 
     public TransactionType getTransactionType(Method method) {
-        // Check the cache
-        TransactionType type = methodTransactionType.get(method);
-        if (type != null) {
-            return type;
-        }
+        return getTransactionType(method, null);
+    }
+
+    public TransactionType getTransactionType(Method method, InterfaceType 
interfaceType) {
+
+        MethodContext methodContext = null;
 
-        // Bean managed EJBs always get the BeanManaged policy
-        if (isBeanManagedTransaction) {
-            return TransactionType.BeanManaged;
+        if (interfaceType != null) {
+            methodContext = getViewMethodContext(method, 
interfaceType.getSpecName());
         }
 
-        // Check the matching bean method for the supplied method
-        Method beanMethod = getMatchingBeanMethod(method);
-        if (beanMethod != null){
-            type = methodTransactionType.get(beanMethod);
-            if (type != null) {
-                return type;
-            }
+        if (methodContext == null) methodContext = 
methodContextMap.get(method);
+
+        if (methodContext == null) {
+            final Method beanMethod = getMatchingBeanMethod(method);
+            methodContext = getMethodContext(beanMethod);
         }
 
-        // All transaction attributes should have been set during deployment, 
so log a message
-        Logger log = Logger.getInstance(LogCategory.OPENEJB, 
"org.apache.openejb.util.resources");
-        log.debug("The following method doesn't have a transaction policy 
assigned: " + method);
-
-        // default transaction policy is required
-        type = getTransactionType();
-
-        // cache this default to avoid extra log messages
-        methodTransactionType.put(method, type);
-        return type;
+        return methodContext.getTransactionType();
+
+//
+//        // Check the cache
+//        TransactionType type = methodTransactionType.get(method);
+//        if (type != null) {
+//            return type;
+//        }
+//
+//        // Bean managed EJBs always get the BeanManaged policy
+//        if (isBeanManagedTransaction) {
+//            return TransactionType.BeanManaged;
+//        }
+//
+//        // Check the matching bean method for the supplied method
+//        Method beanMethod = getMatchingBeanMethod(method);
+//        if (beanMethod != null){
+//            type = methodTransactionType.get(beanMethod);
+//            if (type != null) {
+//                return type;
+//            }
+//        }
+//
+//        // All transaction attributes should have been set during 
deployment, so log a message
+//        Logger log = Logger.getInstance(LogCategory.OPENEJB, 
"org.apache.openejb.util.resources");
+//        log.debug("The following method doesn't have a transaction policy 
assigned: " + method);
+//
+//        // default transaction policy is required
+//        type = getTransactionType();
+//
+//        // cache this default to avoid extra log messages
+//        methodTransactionType.put(method, type);
+//        return type;
     }
 
     public TransactionType getTransactionType() {
@@ -650,24 +671,41 @@ public class BeanContext extends Deploym
      * TODO: Move to MethodContext
      */
     public void setMethodTransactionAttribute(Method method, TransactionType 
transactionType) throws OpenEJBException {
+        setMethodTransactionAttribute(method, transactionType, null);
+    }
 
-        // Only the NOT_SUPPORTED and REQUIRED transaction attributes may be 
used for message-driven
-        // bean message listener methods. The use of the other transaction 
attributes is not meaningful
-        // for message-driven bean message listener methods because there is 
no pre-existing client transaction
-        // context(REQUIRES_NEW, SUPPORTS) and no client to handle exceptions 
(MANDATORY, NEVER).
-        if (componentType.isMessageDriven() && !isBeanManagedTransaction) {
-            if (transactionType != TransactionType.NotSupported && 
transactionType != TransactionType.Required) {
-
-                if ((method.equals(this.ejbTimeout) || 
methodContextMap.get(method).isAsynchronous()) && transactionType == 
TransactionType.RequiresNew) {
-                    // do nothing. This is allowed as the timer callback 
method for a message driven bean
-                    // can also have a transaction policy of RequiresNew Sec 
5.4.12 of Ejb 3.0 Core Spec
-                } else {
-                    throw new OpenEJBException("The transaction attribute " + 
transactionType + " is not supported for the method "
-                                               + method.getName() + " of the 
Message Driven Bean " + beanClass.getName());
-                }
-            }
+    /**
+     * TODO: Move to MethodContext
+     */
+    public void setMethodTransactionAttribute(Method method, TransactionType 
transactionType, String view) throws OpenEJBException {
+
+//        method = getMatchingBeanMethod(method);
+
+        if (view == null) {
+            getMethodContext(method).setTransactionType(transactionType);
+        } else {
+            initViewMethodContext(method, 
view).setTransactionType(transactionType);
         }
-        methodTransactionType.put(method, transactionType);
+
+        return;
+
+//        // Only the NOT_SUPPORTED and REQUIRED transaction attributes may be 
used for message-driven
+//        // bean message listener methods. The use of the other transaction 
attributes is not meaningful
+//        // for message-driven bean message listener methods because there is 
no pre-existing client transaction
+//        // context(REQUIRES_NEW, SUPPORTS) and no client to handle 
exceptions (MANDATORY, NEVER).
+//        if (componentType.isMessageDriven() && !isBeanManagedTransaction) {
+//            if (transactionType != TransactionType.NotSupported && 
transactionType != TransactionType.Required) {
+//
+//                if ((method.equals(this.ejbTimeout) || 
methodContextMap.get(method).isAsynchronous()) && transactionType == 
TransactionType.RequiresNew) {
+//                    // do nothing. This is allowed as the timer callback 
method for a message driven bean
+//                    // can also have a transaction policy of RequiresNew Sec 
5.4.12 of Ejb 3.0 Core Spec
+//                } else {
+//                    throw new OpenEJBException("The transaction attribute " 
+ transactionType + " is not supported for the method "
+//                                               + method.getName() + " of the 
Message Driven Bean " + beanClass.getName());
+//                }
+//            }
+//        }
+//        methodTransactionType.put(method, transactionType);
     }
 
     public List<Method> getRemoveMethods() {
@@ -1231,4 +1269,38 @@ public class BeanContext extends Deploym
         }
         return buffer.toString();
     }
+
+    private MethodContext getViewMethodContext(Method method, String view) {
+        ViewContext viewContext = this.viewContextMap.get(view);
+        return (viewContext == null) ? null : 
viewContext.getMethodContext(method);
+    }
+
+    private MethodContext initViewMethodContext(Method method, String view) {
+        ViewContext viewContext = this.viewContextMap.get(view);
+        if (viewContext == null) {
+            viewContext = new ViewContext();
+            viewContextMap.put(view, viewContext);
+        }
+
+        return viewContext.initMethodContext(method);
+    }
+
+    public class ViewContext {
+
+        private final Map<Method, MethodContext> methodContextMap = new 
HashMap<Method, MethodContext>();
+
+        public MethodContext getMethodContext(Method method) {
+            return methodContextMap.get(method);
+        }
+
+        public MethodContext initMethodContext(Method method) {
+            MethodContext methodContext = methodContextMap.get(method);
+            if (methodContext != null) return methodContext;
+
+            methodContext = new MethodContext(BeanContext.this, method);
+            methodContextMap.put(method, methodContext);
+
+            return methodContext;
+        }
+    }
 }

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodInfoUtil.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodInfoUtil.java?rev=1131304&r1=1131303&r2=1131304&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodInfoUtil.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodInfoUtil.java
 Sat Jun  4 01:45:46 2011
@@ -309,6 +309,105 @@ public class MethodInfoUtil {
         return attributes;
     }
 
+    public static Map<ViewMethod, MethodAttributeInfo> 
resolveViewAttributes(List<? extends MethodAttributeInfo> infos, BeanContext 
beanContext) {
+        Map<ViewMethod, MethodAttributeInfo> attributes = new 
LinkedHashMap<ViewMethod, MethodAttributeInfo>();
+
+        Method[] wildCardView = getWildCardView(beanContext).toArray(new 
Method[]{});
+
+        for (MethodAttributeInfo attributeInfo : infos) {
+            for (MethodInfo methodInfo : attributeInfo.methods) {
+
+                if (methodInfo.ejbName == null || 
methodInfo.ejbName.equals("*") || 
methodInfo.ejbName.equals(beanContext.getEjbName())) {
+
+                    List<Method> methods = new ArrayList<Method>();
+
+                    if (methodInfo.methodIntf == null) {
+                        methods.addAll(matchingMethods(methodInfo, 
wildCardView));
+                    } else if (methodInfo.methodIntf.equals("Home")) {
+                        methods.addAll(matchingMethods(methodInfo, 
beanContext.getHomeInterface()));
+                    } else if (methodInfo.methodIntf.equals("Remote")) {
+                        if (beanContext.getRemoteInterface() != null) {
+                            methods.addAll(matchingMethods(methodInfo, 
beanContext.getRemoteInterface()));
+                        }
+                        for (Class intf : 
beanContext.getBusinessRemoteInterfaces()) {
+                            methods.addAll(matchingMethods(methodInfo, intf));
+                        }
+                    } else if (methodInfo.methodIntf.equals("LocalHome")) {
+                        methods.addAll(matchingMethods(methodInfo, 
beanContext.getLocalHomeInterface()));
+                    } else if (methodInfo.methodIntf.equals("Local")) {
+                        if (beanContext.getLocalInterface() != null) {
+                            methods.addAll(matchingMethods(methodInfo, 
beanContext.getLocalInterface()));
+                        }
+                        for (Class intf : 
beanContext.getBusinessRemoteInterfaces()) {
+                            methods.addAll(matchingMethods(methodInfo, intf));
+                        }
+                    } else if 
(methodInfo.methodIntf.equals("ServiceEndpoint")) {
+                        methods.addAll(matchingMethods(methodInfo, 
beanContext.getServiceEndpointInterface()));
+                    }
+
+                    for (Method method : methods) {
+                        if (containerMethod(method)) {
+                            continue;
+                        }
+
+                        final ViewMethod viewMethod = new 
ViewMethod(methodInfo.methodIntf, method);
+                        attributes.put(viewMethod, attributeInfo);
+//                        List<MethodAttributeInfo> methodAttributeInfos = 
attributes.get(method);
+//                        if (methodAttributeInfos == null) {
+//                            methodAttributeInfos = new 
ArrayList<MethodAttributeInfo>();
+//                            attributes.put(method, methodAttributeInfos);
+//                        }
+//                        methodAttributeInfos.add(attributeInfo);
+                    }
+                }
+            }
+        }
+        return attributes;
+    }
+
+    public static class ViewMethod {
+        private final String view;
+        private final Method method;
+
+        public ViewMethod(String view, Method method) {
+            this.view = view;
+            this.method = method;
+        }
+
+        public String getView() {
+            return view;
+        }
+
+        public Method getMethod() {
+            return method;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            ViewMethod that = (ViewMethod) o;
+
+            if (!method.equals(that.method)) return false;
+            if (view != null ? !view.equals(that.view) : that.view != null) 
return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = view != null ? view.hashCode() : 0;
+            result = 31 * result + method.hashCode();
+            return result;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%s : %s(%s)", view, method.getName(), 
Join.join(", ", Classes.getSimpleNames(method.getParameterTypes())));
+        }
+    }
+
     private static boolean containerMethod(Method method) {
         return (method.getDeclaringClass() == EJBObject.class ||
                 method.getDeclaringClass() == EJBHome.class ||

Modified: 
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?rev=1131304&r1=1131303&r2=1131304&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java
 Sat Jun  4 01:45:46 2011
@@ -17,6 +17,7 @@
 package org.apache.openejb.assembler.classic;
 
 import static 
org.apache.openejb.assembler.classic.MethodInfoUtil.resolveAttributes;
+import static 
org.apache.openejb.assembler.classic.MethodInfoUtil.resolveViewAttributes;
 
 import org.apache.openejb.BeanContext;
 import org.apache.openejb.core.transaction.TransactionType;
@@ -50,25 +51,35 @@ public class MethodTransactionBuilder {
 
         methodTransactionInfos = normalize(methodTransactionInfos);
 
-        Map<Method, MethodAttributeInfo> attributes = 
resolveAttributes(methodTransactionInfos, beanContext);
+        final Map<MethodInfoUtil.ViewMethod, MethodAttributeInfo> attributes = 
resolveViewAttributes(methodTransactionInfos, beanContext);
 
         Logger log = 
Logger.getInstance(LogCategory.OPENEJB_STARTUP.createChild("attributes"), 
MethodTransactionBuilder.class);
-        if (log.isDebugEnabled()) {
-            for (Map.Entry<Method, MethodAttributeInfo> entry : 
attributes.entrySet()) {
-                Method method = entry.getKey();
-                MethodTransactionInfo value = (MethodTransactionInfo) 
entry.getValue();
-                log.debug("Transaction Attribute: " + method + " -- " + 
MethodInfoUtil.toString(value));
-            }
-        }
+        final boolean debug = log.isDebugEnabled();
+
+        for (Map.Entry<MethodInfoUtil.ViewMethod, MethodAttributeInfo> entry : 
attributes.entrySet()) {
+            final MethodInfoUtil.ViewMethod viewMethod = entry.getKey();
+            final Method method = viewMethod.getMethod();
+            final String view = viewMethod.getView();
+
+            MethodTransactionInfo transactionInfo = (MethodTransactionInfo) 
entry.getValue();
 
-        for (Map.Entry<Method, MethodAttributeInfo> entry : 
attributes.entrySet()) {
-            MethodTransactionInfo value = (MethodTransactionInfo) 
entry.getValue();
+            if (debug) log.debug("Transaction Attribute: " + method + " -- " + 
MethodInfoUtil.toString(transactionInfo));
 
-//            logger.info(entry.getKey().toString() +"  "+ 
value.transAttribute);
-            beanContext.setMethodTransactionAttribute(entry.getKey(), 
TransactionType.get(value.transAttribute));
+            beanContext.setMethodTransactionAttribute(method, 
TransactionType.get(transactionInfo.transAttribute), view);
         }
     }
 
+    private static String getMethodInterface(MethodTransactionInfo value) {
+        // We can only do this because we have previously processed all the
+        // MethodTransactionInfo objects so there is one per method
+        // It makes code like this easier to handle
+        for (MethodInfo methodInfo : value.methods) {
+            return methodInfo.methodIntf;
+        }
+
+        return null;
+    }
+
     /**
      * This method splits the MethodTransactionInfo objects so that there is
      * exactly one MethodInfo per MethodTransactionInfo.  A single 
MethodTransactionInfo

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java?rev=1131304&r1=1131303&r2=1131304&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java
 Sat Jun  4 01:45:46 2011
@@ -358,7 +358,7 @@ public class ManagedContainer implements
             createContext.setCurrentAllowedStates(null);
 
             // Start transaction
-            TransactionPolicy txPolicy = 
createTransactionPolicy(createContext.getBeanContext().getTransactionType(callMethod),
 createContext);
+            TransactionPolicy txPolicy = 
createTransactionPolicy(createContext.getBeanContext().getTransactionType(callMethod,
 interfaceType), createContext);
 
             Instance instance = null;
             try {
@@ -448,7 +448,7 @@ public class ManagedContainer implements
             }
 
             // Start transaction
-            TransactionPolicy txPolicy = 
createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod),
 callContext);
+            TransactionPolicy txPolicy = 
createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod,
 interfaceType), callContext);
 
             Object returnValue = null;
             boolean retain = false;
@@ -550,7 +550,7 @@ public class ManagedContainer implements
             checkAuthorization(callMethod, interfaceType);
 
             // Start transaction
-            TransactionPolicy txPolicy = 
createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod),
 callContext);
+            TransactionPolicy txPolicy = 
createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod,
 interfaceType), callContext);
 
             Object returnValue = null;
             Instance instance = null;

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java?rev=1131304&r1=1131303&r2=1131304&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
 Sat Jun  4 01:45:46 2011
@@ -214,7 +214,7 @@ public class SingletonContainer implemen
 
         Object returnValue;
         try {
-            TransactionPolicy txPolicy = 
createTransactionPolicy(beanContext.getTransactionType(callMethod), 
callContext);
+            TransactionPolicy txPolicy = 
createTransactionPolicy(beanContext.getTransactionType(callMethod, callType), 
callContext);
 
             returnValue = null;
             try {

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java?rev=1131304&r1=1131303&r2=1131304&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
 Sat Jun  4 01:45:46 2011
@@ -33,7 +33,6 @@ import javax.ejb.EJBContext;
 import javax.ejb.EJBException;
 import javax.ejb.EJBHome;
 import javax.ejb.EJBLocalHome;
-import javax.ejb.NoSuchEJBException;
 import javax.ejb.RemoveException;
 import javax.ejb.SessionBean;
 import javax.ejb.SessionContext;
@@ -369,7 +368,7 @@ public class StatefulContainer implement
             createContext.setCurrentAllowedStates(null);
 
             // Start transaction
-            TransactionPolicy txPolicy = 
createTransactionPolicy(createContext.getBeanContext().getTransactionType(callMethod),
 createContext);
+            TransactionPolicy txPolicy = 
createTransactionPolicy(createContext.getBeanContext().getTransactionType(callMethod,
 interfaceType), createContext);
 
             Instance instance = null;
             try {
@@ -459,7 +458,7 @@ public class StatefulContainer implement
             }
 
             // Start transaction
-            TransactionPolicy txPolicy = 
createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod),
 callContext);
+            TransactionPolicy txPolicy = 
createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod,
 interfaceType), callContext);
 
             Object returnValue = null;
             boolean retain = false;
@@ -561,7 +560,7 @@ public class StatefulContainer implement
             checkAuthorization(callMethod, interfaceType);
 
             // Start transaction
-            TransactionPolicy txPolicy = 
createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod),
 callContext);
+            TransactionPolicy txPolicy = 
createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod,
 interfaceType), callContext);
 
             Object returnValue = null;
             Instance instance = null;

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java?rev=1131304&r1=1131303&r2=1131304&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
 Sat Jun  4 01:45:46 2011
@@ -212,7 +212,7 @@ public class StatelessContainer implemen
 
         BeanContext beanContext = callContext.getBeanContext();
 
-        TransactionPolicy txPolicy = 
createTransactionPolicy(beanContext.getTransactionType(callMethod), 
callContext);
+        TransactionPolicy txPolicy = 
createTransactionPolicy(beanContext.getTransactionType(callMethod, type), 
callContext);
 
         Object returnValue = null;
         try {

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/TransactionAttributesTest.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/TransactionAttributesTest.java?rev=1131304&r1=1131303&r2=1131304&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/TransactionAttributesTest.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/TransactionAttributesTest.java
 Sat Jun  4 01:45:46 2011
@@ -20,7 +20,9 @@ import static org.apache.openejb.assembl
 import junit.framework.TestCase;
 import org.apache.openejb.BeanContext;
 import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.core.ThreadContext;
 import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.InterceptorBinding;
 import org.apache.openejb.jee.StatelessBean;
 import org.apache.openejb.jee.ContainerTransaction;
 import org.apache.openejb.jee.TransAttribute;
@@ -29,10 +31,18 @@ import static org.apache.openejb.assembl
 import org.apache.openejb.spi.ContainerSystem;
 import org.apache.openejb.loader.SystemInstance;
 
+import javax.ejb.EJBTransactionRequiredException;
 import javax.ejb.Local;
+import javax.ejb.LocalBean;
 import javax.ejb.Remote;
 import javax.ejb.TransactionAttribute;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.InvocationContext;
+import javax.transaction.TransactionRequiredException;
+
 import static javax.ejb.TransactionAttributeType.*;
+
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Map;
 import java.util.List;
@@ -42,6 +52,7 @@ import java.util.List;
  */
 public class TransactionAttributesTest extends TestCase {
     private Map<Method, MethodAttributeInfo> attributes;
+    private Object bean;
 
     public void test() throws Exception {
         Assembler assembler = new Assembler();
@@ -64,6 +75,8 @@ public class TransactionAttributesTest e
         declared.add(new ContainerTransaction(TransAttribute.NEVER, 
Red.class.getName(), "Scarlet", "red"));
         declared.add(new ContainerTransaction(TransAttribute.REQUIRED, 
"Scarlet", Scarlet.class.getMethod("scarlet")));
 
+        ejbJar.getAssemblyDescriptor().addInterceptorBinding(new 
InterceptorBinding("*", AttributeInterceptor.class.getName()));
+
         EjbJarInfo ejbJarInfo = config.configureApplication(ejbJar);
         assembler.createApplication(ejbJarInfo);
 
@@ -119,11 +132,29 @@ public class TransactionAttributesTest e
         BeanContext beanContext = system.getBeanContext(deploymentId);
         List<MethodTransactionInfo> infos = 
normalize(ejbJarInfo.methodTransactions);
         attributes = resolveAttributes(infos, beanContext);
+        bean = 
system.getBeanContext(deploymentId).getBusinessLocalBeanHome().create();
     }
 
-    private void assertAttribute(String attribute, Method method) {
+    private void assertAttribute(String attribute, Method method) throws 
Exception {
         MethodTransactionInfo info = (MethodTransactionInfo) 
attributes.get(method);
         assertEquals(method.toString(), attribute, info.transAttribute);
+
+        try {
+            final Object[] args = new 
Object[method.getParameterTypes().length];
+            final Object result = method.invoke(bean, args);
+            assertEquals(attribute, result);
+        } catch (InvocationTargetException e) {
+            assertEquals(attribute, "Mandatory");
+            assertTrue(e.getTargetException() instanceof 
EJBTransactionRequiredException);
+        }
+    }
+
+    public static class AttributeInterceptor {
+
+        @AroundInvoke
+        public Object invoke(InvocationContext context) throws Exception {
+            return 
ThreadContext.getThreadContext().getTransactionPolicy().getClass().getSimpleName().replace("Tx",
 "");
+        }
     }
 
     @Local
@@ -134,32 +165,33 @@ public class TransactionAttributesTest e
     public static interface ColorRemote {
     }
 
+    @LocalBean
     @TransactionAttribute(MANDATORY)
     public static class Color implements ColorLocal, ColorRemote {
 
 
         @TransactionAttribute(NEVER)
-        public void color(){}
+        public String color(){return null;}
 
 
         @TransactionAttribute(REQUIRES_NEW)
-        public void color(Object o){}
+        public String color(Object o){return null;}
 
-        public void color(String s){}
-        public void color(Boolean b){}
-        public void color(Integer i){}
+        public String color(String s){return null;}
+        public String color(Boolean b){return null;}
+        public String color(Integer i){return null;}
     }
 
 
     public static class Red extends Color {
 
-        public void color(Object o){super.color(o);}
+        public String color(Object o){return super.color(o);}
 
         @TransactionAttribute(REQUIRES_NEW)
-        public void red(){}
+        public String red(){return null;}
 
-        public void red(Object o){}
-        public void red(String s){}
+        public String red(Object o){return null;}
+        public String red(String s){return null;}
 
     }
 
@@ -167,22 +199,22 @@ public class TransactionAttributesTest e
     public static class Crimson extends Red {
 
 
-        public void color(){}
-        public void color(String s){}
+        public String color(){return null;}
+        public String color(String s){return null;}
 
         @TransactionAttribute(REQUIRES_NEW)
-        public void crimson(){}
+        public String crimson(){return null;}
 
-        public void crimson(String s){}
+        public String crimson(String s){return null;}
     }
 
     @TransactionAttribute(NOT_SUPPORTED)
     public static class Scarlet extends Red {
 
         @TransactionAttribute(REQUIRES_NEW)
-        public void scarlet(){}
+        public String scarlet(){return null;}
 
-        public void scarlet(String s){}
+        public String scarlet(String s){return null;}
     }
 
 }

Added: 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/InterfaceTransactionTest.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/InterfaceTransactionTest.java?rev=1131304&view=auto
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/InterfaceTransactionTest.java
 (added)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/InterfaceTransactionTest.java
 Sat Jun  4 01:45:46 2011
@@ -0,0 +1,97 @@
+/**
+ * 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.core.stateless;
+
+import junit.framework.TestCase;
+import org.apache.openejb.OpenEJB;
+import org.apache.openejb.jee.ContainerTransaction;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.Method;
+import org.apache.openejb.jee.MethodIntf;
+import org.apache.openejb.jee.StatelessBean;
+import org.apache.openejb.jee.TransAttribute;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.junit.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ejb.EJB;
+import javax.ejb.EJBException;
+import javax.ejb.Local;
+import javax.ejb.Remote;
+import javax.ejb.Stateless;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import java.util.List;
+
+/**
+ * @version $Rev$ $Date$
+ */
+@RunWith(ApplicationComposer.class)
+public class InterfaceTransactionTest extends TestCase {
+
+    @EJB
+    private OrangeRemote remote;
+
+    @EJB
+    private OrangeLocal local;
+
+    @Module
+    public EjbJar module() throws Exception {
+        final EjbJar ejbJar = new EjbJar();
+        ejbJar.addEnterpriseBean(new StatelessBean(OrangeBean.class));
+
+        final Method remoteMethod = new Method("OrangeBean", 
"isInTransaction").withInterface(MethodIntf.REMOTE);
+        final Method localMethod = new Method("OrangeBean", 
"isInTransaction").withInterface(MethodIntf.LOCAL);
+
+        final List<ContainerTransaction> transactions = 
ejbJar.getAssemblyDescriptor().getContainerTransaction();
+
+        transactions.add(new ContainerTransaction(TransAttribute.REQUIRED, 
remoteMethod));
+        transactions.add(new ContainerTransaction(TransAttribute.SUPPORTS, 
localMethod));
+
+        return ejbJar;
+    }
+
+    @Test
+    public void test() {
+
+        assertTrue(remote.isInTransaction());
+        assertFalse(local.isInTransaction());
+    }
+
+    @Local
+    public interface OrangeLocal {
+        public boolean isInTransaction();
+    }
+
+    @Remote
+    public static interface OrangeRemote extends OrangeLocal {
+    }
+
+    @Stateless
+    public static class OrangeBean implements OrangeLocal, OrangeRemote {
+
+        @Override
+        public boolean isInTransaction() {
+            try {
+                return Status.STATUS_ACTIVE == 
OpenEJB.getTransactionManager().getStatus();
+            } catch (SystemException e) {
+                throw new EJBException(e);
+            }
+        }
+    }
+}

Modified: 
openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java?rev=1131304&r1=1131303&r2=1131304&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java
 Sat Jun  4 01:45:46 2011
@@ -180,6 +180,11 @@ public class Method {
         this.methodIntf = value;
     }
 
+    public Method withInterface(MethodIntf methodIntf) {
+        setMethodIntf(methodIntf);
+        return this;
+    }
+
     public String getMethodName() {
         return methodName;
     }


Reply via email to