This brought some ejb tx regressions on geronimo tck.  I can't dig into it
because of my poor apache svn connection  for now.

---------- Forwarded message ----------
From: <[email protected]>
Date: Sat, Jun 4, 2011 at 9:45 AM
Subject: svn commit: r1131304 - in /openejb/trunk/openejb3/container:
openejb-core/src/main/java/org/apache/openejb/
openejb-core/src/main/java/org/apache/openejb/assembler/classic/
openejb-core/src/main/java/org/apache/openejb/core/managed/
openejb-core/src/ma...
To: [email protected]


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





-- 
Shawn

Reply via email to