/*
* Created on Jul 30, 2004
*
*The Open SLEE project
*
* The source code contained in this file is in in the public domain.
* It can be used in any project or product without prior permission,
* license or royalty payments. There is no claim of correctness and
* NO WARRANTY OF ANY KIND provided with this code.
*
*/
package org.mobicents.slee.runtime.activity;
import javax.slee.SLEEException;
import javax.slee.SbbLocalObject;
import javax.slee.TransactionRequiredLocalException;
import javax.slee.TransactionRolledbackLocalException;
import javax.transaction.SystemException;
import org.apache.log4j.Logger;
import org.mobicents.slee.container.SleeContainer;
import org.mobicents.slee.runtime.eventrouter.EventContextImpl;
import org.mobicents.slee.runtime.sbb.SbbLocalObjectImpl;
import org.mobicents.slee.runtime.sbbentity.SbbEntity;
/**
*
* Activity context interface - default implementation. The Sbb deployer has to
* imbed an instance of this as a proxy object in each sbb ACI.
*
* This is the SLEE wrapper data structure for Activity Contexts. The Sbb gets
* to access this rather than the activity. The reason this exists is because
* the activity context can be at a different location than the activity context
* interface (does not need to be co-located in the same jvm. )
*
* @author M. Ranganathan
* @author Ralf Siedow
* @author martins
*
*/
public class ActivityContextInterfaceImpl implements ActivityContextInterface {
private static Logger logger = Logger
.getLogger(ActivityContextInterfaceImpl.class);
private static final SleeContainer sleeContainer = SleeContainer
.lookupFromJndi();
private final ActivityContext activityContext;
/**
* This is allocated by the Slee to wrap an incoming event (activity).
*
* @param activityContextHandle
*/
public ActivityContextInterfaceImpl(ActivityContext activityContext) {
this.activityContext = activityContext;
}
/*
* (non-Javadoc)
*
* @see javax.slee.ActivityContextInterface#getActivity()
*/
public Object getActivity() throws TransactionRequiredLocalException,
SLEEException {
sleeContainer.getTransactionManager().mandateTransaction();
return activityContext.getActivityContextHandle().getActivity();
}
/*
* (non-Javadoc)
*
* @see javax.slee.ActivityContextInterface#attach(javax.slee.SbbLocalObject)
*/
public void attach(SbbLocalObject sbbLocalObject)
throws NullPointerException, TransactionRequiredLocalException,
TransactionRolledbackLocalException, SLEEException {
if (sbbLocalObject == null)
throw new NullPointerException("null SbbLocalObject !");
sleeContainer.getTransactionManager().mandateTransaction();
SbbLocalObjectImpl sbbLocalObjectImpl = (SbbLocalObjectImpl) sbbLocalObject;
String sbbeId = sbbLocalObjectImpl.getSbbEntityId();
boolean attached = getActivityContext().attachSbbEntity(sbbeId);
if (logger.isDebugEnabled()) {
logger
.debug("ActivityContextInterface.attach(): ACI attach Called for "
+ sbbLocalObject
+ " AC = "
+ getActivityContext()
+ " SbbEntityId "
+ sbbeId);
}
boolean setRollbackAndThrowException = false;
if (attached) {
try {
SbbEntity sbbEntity = sbbLocalObjectImpl.getSbbEntity();
if (sbbEntity.isRemoved()) {
setRollbackAndThrowException = true;
} else {
// attach entity from ac
sbbEntity.afterACAttach(getActivityContext().getActivityContextHandle());
}
} catch (Exception e) {
setRollbackAndThrowException = true;
}
}
if (setRollbackAndThrowException) {
try {
sleeContainer.getTransactionManager().setRollbackOnly();
} catch (SystemException e) {
logger
.warn(
"failed to set rollback flag while asserting valid sbb entity",
e);
}
throw new TransactionRolledbackLocalException(
"Failed to attach invalid sbb entity. SbbID " + sbbeId);
}
if (attached) {
// JSLEE 1.0 Spec, Section 8.5.8 excerpt:
// The SLEE delivers the event to an SBB entity that stays attached once. The SLEE may deliver the
// event to the same SBB entity more than once if it has been detached and then re -attached.
EventContextImpl eventContextImpl = sleeContainer.getEventRouter().getEventRouterActivity(
getActivityContext().getActivityContextHandle()).getCurrentEventContext();
if (eventContextImpl != null && eventContextImpl.getSbbEntitiesThatHandledEvent().remove(sbbeId)) {
if (logger.isDebugEnabled()) {
logger
.debug("Removed the SBB Entity ["
+ sbbeId
+ "] from the delivered set of activity context ["
+ getActivityContext().getActivityContextHandle()
+ "]. Seems to be a reattachment after detachment in the same event delivery transaction. See JSLEE 1.0 Spec, Section 8.5.8.");
}
}
}
}
/*
* (non-Javadoc)
*
* @see javax.slee.ActivityContextInterface#detach(javax.slee.SbbLocalObject)
*/
public void detach(SbbLocalObject sbbLocalObject)
throws NullPointerException, TransactionRequiredLocalException,
TransactionRolledbackLocalException, SLEEException {
if (logger.isDebugEnabled()) {
logger.debug("ACI detach called for : " + sbbLocalObject + " AC = "
+ getActivityContext().getActivityContextHandle());
}
if (sbbLocalObject == null)
throw new NullPointerException("null SbbLocalObject !");
sleeContainer.getTransactionManager().mandateTransaction();
SbbLocalObjectImpl sbbLocalObjectImpl = (SbbLocalObjectImpl) sbbLocalObject;
String sbbeId = sbbLocalObjectImpl.getSbbEntityId();
// detach ac from entity
final ActivityContext ac = getActivityContext();
ac.detachSbbEntity(sbbeId);
boolean setRollbackAndThrowException = false;
try {
SbbEntity sbbEntity = sbbLocalObjectImpl.getSbbEntity();
if (sbbEntity.isRemoved()) {
setRollbackAndThrowException = true;
} else {
// detach entity from ac
sbbEntity.afterACDetach(getActivityContext().getActivityContextHandle());
}
} catch (Exception e) {
setRollbackAndThrowException = true;
}
if (setRollbackAndThrowException) {
try {
sleeContainer.getTransactionManager().setRollbackOnly();
} catch (SystemException e) {
logger
.warn(
"failed to set rollback flag while asserting valid sbb entity",
e);
}
throw new TransactionRolledbackLocalException(
"Failed to detach invalid sbb entity. SbbID " + sbbeId);
}
}
/*
* (non-Javadoc)
*
* @see javax.slee.ActivityContextInterface#isEnding()
*/
public boolean isEnding() throws TransactionRequiredLocalException,
SLEEException {
sleeContainer.getTransactionManager().mandateTransaction();
return getActivityContext().isEnding();
}
public ActivityContext getActivityContext() {
return activityContext;
}
@Override
public int hashCode() {
return activityContext.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj != null && obj.getClass() == this.getClass()) {
return ((ActivityContextInterfaceImpl) obj).activityContext
.equals(this.activityContext);
} else {
return false;
}
}
/**
* @see javax.slee.ActivityContextInterface#isAttached(SbbLocalObject)
*/
public boolean isAttached(SbbLocalObject sbbLocalObject) throws NullPointerException,
TransactionRequiredLocalException,
TransactionRolledbackLocalException, SLEEException {
if (sbbLocalObject == null) {
throw new NullPointerException("null sbbLocalObject");
}
sleeContainer.getTransactionManager().mandateTransaction();
if (sbbLocalObject instanceof SbbLocalObjectImpl) {
SbbLocalObjectImpl sbbLocalObjectImpl = (SbbLocalObjectImpl) sbbLocalObject;
SbbEntity sbbEntity = sbbLocalObjectImpl.getSbbEntity();
if (sbbEntity != null && !sbbEntity.isRemoved()) {
return sbbEntity.isAttached(activityContext.getActivityContextHandle());
}
}
try {
sleeContainer.getTransactionManager().setRollbackOnly();
} catch (Exception e) {
throw new SLEEException(e.getMessage(),e);
}
throw new TransactionRolledbackLocalException("the sbbLocalObject argument must represent a valid SBB entity");
}
}