dain 2006/02/01 06:50:10
Modified: modules/core/src/java/org/openejb/transaction
BeanPolicy.java ContainerPolicy.java
TransactionContextInterceptor.java
TransactionPolicy.java
TransactionPolicyManager.java
TransactionPolicyType.java
Added: modules/core/src/java/org/openejb/transaction
MethodTransaction.java
Log:
Major refactor
Split container into an object to represent a deployed ejb and a set of
shared containers which process invocations
Introduced interface between CMP container and CMP engine
Revision Changes Path
1.11 +3 -3
openejb/modules/core/src/java/org/openejb/transaction/BeanPolicy.java
Index: BeanPolicy.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/transaction/BeanPolicy.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- BeanPolicy.java 1 Mar 2005 23:34:34 -0000 1.10
+++ BeanPolicy.java 1 Feb 2006 11:50:10 -0000 1.11
@@ -53,7 +53,7 @@
import org.apache.geronimo.core.service.InvocationResult;
import org.apache.geronimo.transaction.context.TransactionContext;
import org.apache.geronimo.transaction.context.TransactionContextManager;
-import org.openejb.EJBInvocation;
+import org.openejb.EjbInvocation;
/**
* @version $Revision$ $Date$
@@ -62,7 +62,7 @@
private static final Log log = LogFactory.getLog(BeanPolicy.class);
public static final BeanPolicy INSTANCE = new BeanPolicy();
- public InvocationResult invoke(Interceptor interceptor, EJBInvocation
ejbInvocation, TransactionContextManager transactionContextManager) throws
Throwable {
+ public InvocationResult invoke(Interceptor interceptor, EjbInvocation
ejbInvocation, TransactionContextManager transactionContextManager) throws
Throwable {
TransactionContext clientContext =
transactionContextManager.getContext();
if (clientContext != null) {
clientContext.suspend();
1.11 +8 -8
openejb/modules/core/src/java/org/openejb/transaction/ContainerPolicy.java
Index: ContainerPolicy.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/transaction/ContainerPolicy.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- ContainerPolicy.java 1 Mar 2005 23:34:35 -0000 1.10
+++ ContainerPolicy.java 1 Feb 2006 11:50:10 -0000 1.11
@@ -59,7 +59,7 @@
import org.apache.geronimo.core.service.InvocationResult;
import org.apache.geronimo.transaction.context.TransactionContext;
import org.apache.geronimo.transaction.context.TransactionContextManager;
-import org.openejb.EJBInvocation;
+import org.openejb.EjbInvocation;
/**
*
@@ -77,7 +77,7 @@
public static final TransactionPolicy Never = new TxNever();
private static final class TxNotSupported implements TransactionPolicy {
- public InvocationResult invoke(Interceptor interceptor,
EJBInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
+ public InvocationResult invoke(Interceptor interceptor,
EjbInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
TransactionContext callerContext =
transactionContextManager.getContext();
if (callerContext != null) {
callerContext.suspend();
@@ -111,7 +111,7 @@
}
private static final class TxRequired implements TransactionPolicy {
- public InvocationResult invoke(Interceptor interceptor,
EJBInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
+ public InvocationResult invoke(Interceptor interceptor,
EjbInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
TransactionContext callerContext =
transactionContextManager.getContext();
if (callerContext != null && callerContext.isInheritable()) {
try {
@@ -169,7 +169,7 @@
}
private static final class TxSupports implements TransactionPolicy {
- public InvocationResult invoke(Interceptor interceptor,
EJBInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
+ public InvocationResult invoke(Interceptor interceptor,
EjbInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
TransactionContext callerContext =
transactionContextManager.getContext();
if (callerContext != null && callerContext.isInheritable()) {
try {
@@ -221,7 +221,7 @@
}
private static final class TxRequiresNew implements TransactionPolicy {
- public InvocationResult invoke(Interceptor interceptor,
EJBInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
+ public InvocationResult invoke(Interceptor interceptor,
EjbInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
TransactionContext callerContext =
transactionContextManager.getContext();
if (callerContext != null) {
@@ -263,7 +263,7 @@
}
private static final class TxMandatory implements TransactionPolicy {
- public InvocationResult invoke(Interceptor interceptor,
EJBInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
+ public InvocationResult invoke(Interceptor interceptor,
EjbInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
TransactionContext callerContext =
transactionContextManager.getContext();
// If we don't have a transaction, throw an exception
@@ -300,7 +300,7 @@
}
private static final class TxNever implements TransactionPolicy {
- public InvocationResult invoke(Interceptor interceptor,
EJBInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
+ public InvocationResult invoke(Interceptor interceptor,
EjbInvocation ejbInvocation, TransactionContextManager
transactionContextManager) throws Throwable {
TransactionContext callerContext =
transactionContextManager.getContext();
// If we have a transaction, throw an exception
1.4 +8 -7
openejb/modules/core/src/java/org/openejb/transaction/TransactionContextInterceptor.java
Index: TransactionContextInterceptor.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/transaction/TransactionContextInterceptor.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- TransactionContextInterceptor.java 18 Jul 2004 22:32:26 -0000
1.3
+++ TransactionContextInterceptor.java 1 Feb 2006 11:50:10 -0000
1.4
@@ -52,7 +52,8 @@
import org.apache.geronimo.core.service.InvocationResult;
import org.apache.geronimo.transaction.context.TransactionContextManager;
import org.openejb.EJBInterfaceType;
-import org.openejb.EJBInvocation;
+import org.openejb.ExtendedEjbDeployment;
+import org.openejb.EjbInvocation;
/**
* @version $Revision$ $Date$
@@ -60,23 +61,23 @@
public class TransactionContextInterceptor implements Interceptor {
private final Interceptor next;
private final TransactionContextManager transactionContextManager;
- private final TransactionPolicyManager transactionPolicyManager;
- public TransactionContextInterceptor(Interceptor next,
TransactionContextManager transactionContextManager, TransactionPolicyManager
transactionPolicyManager) {
+ public TransactionContextInterceptor(Interceptor next,
TransactionContextManager transactionContextManager) {
this.next = next;
this.transactionContextManager = transactionContextManager;
- this.transactionPolicyManager = transactionPolicyManager;
}
public InvocationResult invoke(Invocation invocation) throws Throwable {
- EJBInvocation ejbInvocation = (EJBInvocation) invocation;
+ EjbInvocation ejbInvocation = (EjbInvocation) invocation;
+ ExtendedEjbDeployment deployment = (ExtendedEjbDeployment)
ejbInvocation.getEjbDeployment();
+ TransactionPolicyManager transactionPolicyManager =
deployment.getTransactionPolicyManager();
EJBInterfaceType invocationType = ejbInvocation.getType();
int methodIndex = ejbInvocation.getMethodIndex();
-
TransactionPolicy policy =
transactionPolicyManager.getTransactionPolicy(invocationType, methodIndex);
assert policy != null: "transaction policy array was not set up
correctly, no policy for " + invocation;
return policy.invoke(next, ejbInvocation, transactionContextManager);
}
+
}
1.4 +3 -3
openejb/modules/core/src/java/org/openejb/transaction/TransactionPolicy.java
Index: TransactionPolicy.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/transaction/TransactionPolicy.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- TransactionPolicy.java 18 Jul 2004 22:32:26 -0000 1.3
+++ TransactionPolicy.java 1 Feb 2006 11:50:10 -0000 1.4
@@ -52,7 +52,7 @@
import org.apache.geronimo.core.service.Interceptor;
import org.apache.geronimo.core.service.InvocationResult;
import org.apache.geronimo.transaction.context.TransactionContextManager;
-import org.openejb.EJBInvocation;
+import org.openejb.EjbInvocation;
/**
*
@@ -60,5 +60,5 @@
* @version $Revision$ $Date$
*/
public interface TransactionPolicy extends Serializable {
- InvocationResult invoke(Interceptor interceptor, EJBInvocation
ejbInvocation, TransactionContextManager transactionContextManager) throws
Throwable;
+ InvocationResult invoke(Interceptor interceptor, EjbInvocation
ejbInvocation, TransactionContextManager transactionContextManager) throws
Throwable;
}
1.7 +65 -5
openejb/modules/core/src/java/org/openejb/transaction/TransactionPolicyManager.java
Index: TransactionPolicyManager.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/transaction/TransactionPolicyManager.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- TransactionPolicyManager.java 15 Mar 2005 05:27:09 -0000 1.6
+++ TransactionPolicyManager.java 1 Feb 2006 11:50:10 -0000 1.7
@@ -49,22 +49,82 @@
import java.io.Serializable;
import java.util.Arrays;
+import java.util.SortedMap;
+import java.util.Iterator;
+import java.util.Map;
import org.openejb.EJBInterfaceType;
+import org.openejb.MethodSpec;
import org.openejb.dispatch.InterfaceMethodSignature;
/**
* @version $Revision$ $Date$
*/
public final class TransactionPolicyManager implements Serializable {
- private final TransactionPolicy[][] transactionPolicy;
+ private static final long serialVersionUID = -2039826921336518779L;
+ private final TransactionPolicyType[][] transactionPolicyType;
+ private final boolean beanManaged;
- public TransactionPolicyManager(TransactionPolicy[][] transactionPolicy)
{
- this.transactionPolicy = transactionPolicy;
+ public TransactionPolicyManager(boolean beanManaged, SortedMap
transactionPolicies, InterfaceMethodSignature[] signatures) {
+ this.beanManaged = beanManaged;
+ transactionPolicyType =
buildTransactionPolicyIndex(transactionPolicies, signatures);
+ }
+
+ public TransactionPolicyManager(TransactionPolicyType[][]
transactionPolicyType) {
+ this.transactionPolicyType = transactionPolicyType;
+ beanManaged = false;
}
public TransactionPolicy getTransactionPolicy(EJBInterfaceType
invocationType, int operationIndex) {
- return
transactionPolicy[invocationType.getOrdinal()][operationIndex];
+ TransactionPolicyType transactionPolicyType =
getTransactionPolicyType(invocationType, operationIndex);
+ TransactionPolicy transactionPolicy =
TransactionPolicies.getTransactionPolicy(transactionPolicyType);
+ return transactionPolicy;
+ }
+
+ public TransactionPolicyType getTransactionPolicyType(EJBInterfaceType
invocationType, int operationIndex) {
+ if (beanManaged) {
+ return TransactionPolicyType.Bean;
+ } else {
+ return
transactionPolicyType[invocationType.getOrdinal()][operationIndex];
+ }
+ }
+
+ private static TransactionPolicyType[][]
buildTransactionPolicyIndex(SortedMap transactionPolicies,
InterfaceMethodSignature[] signatures) {
+ TransactionPolicyType[][] transactionPolicyType = new
TransactionPolicyType[EJBInterfaceType.MAX_ORDINAL][];
+ transactionPolicyType[EJBInterfaceType.HOME.getOrdinal()] =
mapPolicies("Home", signatures, transactionPolicies);
+ transactionPolicyType[EJBInterfaceType.REMOTE.getOrdinal()] =
mapPolicies("Remote", signatures, transactionPolicies);
+ transactionPolicyType[EJBInterfaceType.LOCALHOME.getOrdinal()] =
mapPolicies("LocalHome", signatures, transactionPolicies);
+ transactionPolicyType[EJBInterfaceType.LOCAL.getOrdinal()] =
mapPolicies("Local", signatures, transactionPolicies);
+ transactionPolicyType[EJBInterfaceType.WEB_SERVICE.getOrdinal()] =
mapPolicies("ServiceEndpoint", signatures, transactionPolicies);
+ transactionPolicyType[EJBInterfaceType.TIMEOUT.getOrdinal()] = new
TransactionPolicyType[signatures.length];
+
Arrays.fill(transactionPolicyType[EJBInterfaceType.TIMEOUT.getOrdinal()],
TransactionPolicyType.Supports); //we control the transaction from the top of
the stack.
+
+ return transactionPolicyType;
+ }
+
+ private static TransactionPolicyType[] mapPolicies(String intfName,
InterfaceMethodSignature[] signatures, SortedMap transactionPolicies) {
+ TransactionPolicyType[] policies = new
TransactionPolicyType[signatures.length];
+ for (int index = 0; index < signatures.length; index++) {
+ InterfaceMethodSignature signature = signatures[index];
+ policies[index] = getTransactionPolicy(transactionPolicies,
intfName, signature);
+ }
+ return policies;
}
+ public static TransactionPolicyType getTransactionPolicy(SortedMap
transactionPolicies, String methodIntf, InterfaceMethodSignature signature) {
+ if (transactionPolicies != null) {
+ for (Iterator iterator =
transactionPolicies.entrySet().iterator(); iterator.hasNext();) {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ MethodSpec methodSpec = (MethodSpec) entry.getKey();
+ TransactionPolicyType transactionPolicyType =
(TransactionPolicyType) entry.getValue();
+
+ if (methodSpec.matches(methodIntf,
signature.getMethodName(), signature.getParameterTypes())) {
+ return transactionPolicyType;
+ }
+ }
+ }
+
+ //default
+ return TransactionPolicyType.Required;
+ }
}
1.2 +19 -2
openejb/modules/core/src/java/org/openejb/transaction/TransactionPolicyType.java
Index: TransactionPolicyType.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/transaction/TransactionPolicyType.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TransactionPolicyType.java 15 Mar 2005 05:27:09 -0000 1.1
+++ TransactionPolicyType.java 1 Feb 2006 11:50:10 -0000 1.2
@@ -16,12 +16,17 @@
*/
package org.openejb.transaction;
+import java.io.Serializable;
+import java.util.HashMap;
+
/**
* Enumeration of abstract transaction policies, with ordinals, for use as
index to determine concrete TransactionPolicies.
*
* @version $Rev: $ $Date$
*/
-public class TransactionPolicyType {
+public class TransactionPolicyType implements Serializable {
+ private static final long serialVersionUID = 613104784490732601L;
+ private static HashMap byName = new HashMap();
public static final TransactionPolicyType NotSupported = new
TransactionPolicyType("NotSupported");
public static final TransactionPolicyType Required = new
TransactionPolicyType("Required");
@@ -48,6 +53,7 @@
private TransactionPolicyType(String name) {
this.name = name;
this.index = last++;
+ byName.put(name, this);
}
public int getIndex() {
@@ -62,4 +68,15 @@
return values.length;
}
+ public String toString() {
+ return name;
+ }
+
+ public static TransactionPolicyType getByName(String name) {
+ return (TransactionPolicyType) byName.get(name);
+ }
+
+ protected Object readResolve() {
+ return values[index];
+ }
}
1.1
openejb/modules/core/src/java/org/openejb/transaction/MethodTransaction.java
Index: MethodTransaction.java
===================================================================
/**
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain copyright
* statements and notices. Redistributions must also contain a
* copy of this document.
*
* 2. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. The name "OpenEJB" must not be used to endorse or promote
* products derived from this Software without prior written
* permission of The OpenEJB Group. For written permission,
* please contact [EMAIL PROTECTED]
*
* 4. Products derived from this Software may not be called "OpenEJB"
* nor may "OpenEJB" appear in their names without prior written
* permission of The OpenEJB Group. OpenEJB is a registered
* trademark of The OpenEJB Group.
*
* 5. Due credit should be given to the OpenEJB Project
* (http://openejb.org/).
*
* THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2005 (C) The OpenEJB Group. All Rights Reserved.
*
* $Id: MethodTransaction.java,v 1.1 2006/02/01 11:50:10 dain Exp $
*/
package org.openejb.transaction;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
import org.openejb.transaction.TransactionPolicyType;
/**
* @version $Revision: 1.1 $ $Date: 2006/02/01 11:50:10 $
*/
public class MethodTransaction implements Comparable {
private static final int AFTER_OTHER = 1;
private static final int BEFORE_OTHER = -1;
private final static Map transactionPolicyMap;
static {
transactionPolicyMap = new HashMap();
transactionPolicyMap.put("NotSupported",
TransactionPolicyType.NotSupported);
transactionPolicyMap.put("Required", TransactionPolicyType.Required);
transactionPolicyMap.put("Supports", TransactionPolicyType.Supports);
transactionPolicyMap.put("RequiresNew",
TransactionPolicyType.RequiresNew);
transactionPolicyMap.put("Mandatory",
TransactionPolicyType.Mandatory);
transactionPolicyMap.put("Never", TransactionPolicyType.Never);
transactionPolicyMap.put("Stateless", TransactionPolicyType.Bean);
transactionPolicyMap.put("Stateful", TransactionPolicyType.Bean);
}
private final TransactionPolicyType transactionPolicyType;
private final String methodIntf;
private final String methodName;
private final String[] parameterTypes;
public MethodTransaction(TransactionPolicyType transactionPolicyType,
String methodIntf, String methodName, String[] parameterTypes) {
this.transactionPolicyType = transactionPolicyType;
this.methodIntf = methodIntf;
this.methodName = methodName;
this.parameterTypes = parameterTypes;
}
public TransactionPolicyType getTransactionPolicyType() {
return transactionPolicyType;
}
public String getMethodIntf() {
return methodIntf;
}
public String getMethodName() {
return methodName;
}
public String[] getParameterTypes() {
return parameterTypes;
}
public int compareTo(Object o) {
if (!(o instanceof MethodTransaction)) {
return -1;
}
if (this == o) {
return 0;
}
MethodTransaction other = (MethodTransaction) o;
if (parameterTypes != null) {
if (other.parameterTypes == null) {
//parameter types always come before no param types
return BEFORE_OTHER;
}
//both have param types
if (methodIntf != null) {
if (other.methodIntf == null) {
//method intf comes before no method intf.
return BEFORE_OTHER;
}
//both have method interfaces
int intfOrder = methodIntf.compareTo(other.methodIntf);
if (intfOrder != 0) {
return intfOrder;
}
//same interfaces
return compareMethod(other);
}
if (other.methodIntf != null) {
//they have method intf, we don't, they are first
return AFTER_OTHER;
}
//neither has methodIntf: sort by method name
return compareMethod(other);
}
//we don't have param types
if (other.parameterTypes != null) {
//they do, they are first
return AFTER_OTHER;
}
//neither has param types.
//explicit method name comes first
if (!methodName.equals("*")) {
if (other.methodName.equals("*")) {
return BEFORE_OTHER;
}
//both explicit method names.
//explicit method interface comes first
if (methodIntf != null) {
if (other.methodIntf == null) {
return BEFORE_OTHER;
}
//both explicit method intf. sort by intf, then methodName
int intfOrder = methodIntf.compareTo(other.methodIntf);
if (intfOrder != 0) {
return intfOrder;
}
//same interfaces
return methodName.compareTo(other.methodName);
}
if (other.methodIntf != null) {
//they have explicit method inft, we dont, they are first
return AFTER_OTHER;
}
//neither have explicit method intf.
return methodName.compareTo(other.methodName);
}
//we don't have explicit method name
if (!other.methodName.equals("*")) {
//they do, they are first
return AFTER_OTHER;
}
//neither has explicit method name
if (methodIntf != null) {
if (other.methodIntf == null) {
return BEFORE_OTHER;
}
return methodIntf.compareTo(other.methodIntf);
}
if (other.methodIntf != null) {
return AFTER_OTHER;
}
//neither has methodIntf or explicit methodName. problem.
throw new IllegalStateException("Cannot compare " + this + " and " +
other);
}
private int compareMethod(MethodTransaction other) {
int methodOrder = methodName.compareTo(other.methodName);
if (methodOrder != 0) {
return methodOrder;
}
//same method name, sort by params lexicographically
for (int i = 0; i < parameterTypes.length; i++) {
if (i == other.parameterTypes.length) {
//the other list is shorter, they are first
return AFTER_OTHER;
}
int paramOrder =
parameterTypes[i].compareTo(other.parameterTypes[i]);
if (paramOrder != 0) {
return paramOrder;
}
}
//our list is shorter, we are first
return BEFORE_OTHER;
}
public String toString() {
StringBuffer result = new StringBuffer("MethodTransaction: interface
").append(methodIntf).append(", methodName ").append(methodName).append(",
parameters: ");
if (parameterTypes != null) {
for (int i = 0; i < parameterTypes.length; i++) {
String parameterType = parameterTypes[i];
result.append(parameterType).append(", ");
}
}
result.append("transaction attribute:
").append(transactionPolicyType);
return result.toString();
}
public boolean matches(String methodIntf, String methodName, String[]
parameterTypes) {
assert methodIntf != null;
assert methodName != null;
assert parameterTypes != null;
if (this.methodIntf != null && !methodIntf.equals(this.methodIntf)) {
//definitely wrong interface
return false;
}
//our interface is not specified or matches.
if (this.methodName.equals("*")) {
return true;
}
if (!methodName.equals(this.methodName)) {
//explicitly different method names
return false;
}
//same method names.
if (this.parameterTypes == null) {
return true;
}
return Arrays.equals(parameterTypes, this.parameterTypes);
}
}