001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.core.stateful;
017:
018: import javax.transaction.Status;
019: import javax.transaction.Transaction;
020:
021: import org.apache.openejb.ApplicationException;
022: import org.apache.openejb.OpenEJBException;
023: import org.apache.openejb.SystemException;
024: import org.apache.openejb.ContainerType;
025: import org.apache.openejb.core.transaction.TransactionContainer;
026: import org.apache.openejb.core.transaction.TransactionContext;
027: import org.apache.openejb.core.transaction.TransactionPolicy;
028:
029: public class StatefulBeanManagedTxPolicy extends TransactionPolicy {
030: public StatefulBeanManagedTxPolicy(TransactionContainer container) {
031: super (Type.BeanManaged, container);
032: if (container.getContainerType() != ContainerType.STATEFUL) {
033: throw new IllegalArgumentException(
034: "Container is not an StatefulContainer");
035: }
036: }
037:
038: public void beforeInvoke(Object instance, TransactionContext context)
039: throws SystemException, ApplicationException {
040: try {
041: StatefulInstanceManager instanceManager = ((StatefulContainer) container)
042: .getInstanceManager();
043:
044: // suspend any transaction currently associated with this thread
045: // if no transaction ---> suspend returns null
046: context.clientTx = suspendTransaction(context);
047:
048: // Resume previous Bean transaction if there was one
049: Transaction beanTransaction = instanceManager
050: .getBeanTransaction(context.callContext);
051: if (beanTransaction != null) {
052: context.currentTx = beanTransaction;
053: resumeTransaction(context, context.currentTx);
054: }
055: } catch (OpenEJBException e) {
056: handleSystemException(e.getRootCause(), instance, context);
057: }
058: }
059:
060: public void afterInvoke(Object instance, TransactionContext context)
061: throws ApplicationException, SystemException {
062: try {
063: // Get the transaction after the method invocation
064: context.currentTx = context.getTransactionManager()
065: .getTransaction();
066:
067: // If it is not complete, suspend the transaction
068: if (context.currentTx != null) {
069: int status = context.currentTx.getStatus();
070: if (status != Status.STATUS_COMMITTED
071: && status != Status.STATUS_ROLLEDBACK) {
072: suspendTransaction(context);
073: } else {
074: // transaction is complete, so there is no need to maintain a referecne to it
075: context.clientTx = null;
076: }
077: }
078:
079: // Update the user transaction reference in the bean instance data
080: StatefulInstanceManager instanceManager = ((StatefulContainer) container)
081: .getInstanceManager();
082: instanceManager.setBeanTransaction(context.callContext,
083: context.currentTx);
084: } catch (OpenEJBException e) {
085: handleSystemException(e.getRootCause(), instance, context);
086: } catch (javax.transaction.SystemException e) {
087: handleSystemException(e, instance, context);
088: } catch (Throwable e) {
089: handleSystemException(e, instance, context);
090: } finally {
091: resumeTransaction(context, context.clientTx);
092: }
093: }
094:
095: public void handleApplicationException(Throwable appException,
096: boolean rollback, TransactionContext context)
097: throws ApplicationException, SystemException {
098: if (rollback && context.currentTx != null)
099: markTxRollbackOnly(context.currentTx);
100: throw new ApplicationException(appException);
101: }
102:
103: public void handleSystemException(Throwable sysException,
104: Object instance, TransactionContext context)
105: throws ApplicationException, SystemException {
106: logSystemException(sysException, context);
107:
108: if (context.currentTx != null)
109: markTxRollbackOnly(context.currentTx);
110:
111: discardBeanInstance(instance, context.callContext);
112:
113: throwExceptionToServer(sysException);
114: }
115: }
|