/*
* JBoss, Home of Professional Open Source
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* (C) 2005-2006,
* @author JBoss Inc.
*/
/*
* Copyright (C) 1998, 1999, 2000, 2001,
*
* Arjuna Solutions Limited,
* Newcastle upon Tyne,
* Tyne and Wear,
* UK.
*
* $Id: ActivationRecord.java 2342 2006-03-30 13:06:17Z $
*/
package com.arjuna.ats.internal.arjuna.abstractrecords;
import java.io.PrintWriter;
import com.arjuna.ats.arjuna.ObjectStatus;
import com.arjuna.ats.arjuna.ObjectType;
import com.arjuna.ats.arjuna.StateManager;
import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
import com.arjuna.ats.arjuna.coordinator.BasicAction;
import com.arjuna.ats.arjuna.coordinator.RecordType;
import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome;
import com.arjuna.ats.arjuna.logging.tsLogger;
import com.arjuna.ats.arjuna.state.InputObjectState;
import com.arjuna.ats.arjuna.state.OutputObjectState;
public class ActivationRecord extends AbstractRecord
{
/*
* This constructor is used to create a new instance of an ActivationRecord.
*/
public ActivationRecord(int st, StateManager sm, BasicAction action)
{
super(sm.get_uid(), sm.type(), ObjectType.ANDPERSISTENT);
objectAddr = sm;
actionHandle = action;
state = st;
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActivationRecord::ActivationRecord(" + state + ", "
+ sm.get_uid() + ")");
}
}
public int typeIs ()
{
return RecordType.ACTIVATION;
}
public Object value ()
{
return (Object) new Integer(state);
}
public void setValue (Object v)
{
tsLogger.i18NLogger.warn_ActivationRecord_1();
}
/**
* nestedAbort causes the reset_state function of the object to be invoked
* passing it the saved ObjectStatus.
*/
public int nestedAbort ()
{
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActivationRecord::nestedAbort() for " + order());
}
int outcome = TwoPhaseOutcome.FINISH_ERROR;
if ((objectAddr != null) && (actionHandle != null))
outcome = (StateManagerFriend.forgetAction(objectAddr, actionHandle, false, RecordType.ACTIVATION) ? TwoPhaseOutcome.FINISH_OK
: TwoPhaseOutcome.FINISH_ERROR);
return outcome;
}
/**
* nestedCommit does nothing since the passing of the state up to the parent
* action is handled by the record list merging system. In fact since
* nested_prepare returns PREPARE_READONLY this function should never
* actually be called.
*/
public int nestedCommit ()
{
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActivationRecord::nestedCommit() for " + order());
}
return TwoPhaseOutcome.FINISH_OK;
}
public int nestedPrepare ()
{
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActivationRecord::nestedPrepare() for " + order());
}
if ((objectAddr != null) && (actionHandle != null))
{
int state = objectAddr.status();
if (StateManagerFriend.forgetAction(objectAddr, actionHandle, true, RecordType.ACTIVATION))
{
actionHandle = actionHandle.parent();
if (StateManagerFriend.rememberAction(objectAddr, actionHandle, RecordType.ACTIVATION, state))
return TwoPhaseOutcome.PREPARE_READONLY;
}
}
return TwoPhaseOutcome.FINISH_ERROR;
}
/**
* topLevelAbort for Activation records is exactly like a nested abort.
*/
public int topLevelAbort ()
{
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActivationRecord::topLevelAbort() for " + order());
}
return nestedAbort(); /* i.e., same as nested case */
}
/*
* topLevelCommit has little to do for ActivationRecords other than to
* ensure the object is forgotten by the object.
*/
public int topLevelCommit ()
{
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActivationRecord::topLevelCommit() for " + order());
}
if ((objectAddr != null) && (actionHandle != null))
{
return (StateManagerFriend.forgetAction(objectAddr, actionHandle, true, RecordType.ACTIVATION) ? TwoPhaseOutcome.FINISH_OK
: TwoPhaseOutcome.FINISH_ERROR);
}
return TwoPhaseOutcome.FINISH_ERROR;
}
public int topLevelPrepare ()
{
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActivationRecord::topLevelPrepare() for " + order());
}
if (objectAddr == null)
return TwoPhaseOutcome.PREPARE_NOTOK;
else
return TwoPhaseOutcome.PREPARE_OK;
}
/**
* Saving of ActivationRecords is only undertaken during the Prepare phase
* of the top level 2PC.
*/
public boolean restore_state (InputObjectState os, int v)
{
tsLogger.i18NLogger.warn_ActivationRecord_2(type(), order());
return false;
}
public boolean save_state (OutputObjectState os, ObjectType v)
{
return true;
}
public void print (PrintWriter strm)
{
super.print(strm);
strm.println("ActivationRecord with state:\n" + state);
}
public String type ()
{
return "/StateManager/AbstractRecord/ActivationRecord";
}
public void merge (AbstractRecord a)
{
}
public void alter (AbstractRecord a)
{
}
/*
* should_merge and should_replace are invoked by the record list manager to
* determine if two records should be merged together or if the 'newer'
* should replace the older. shouldAdd determines if the new record should
* be added in addition to the existing record and is currently only invoked
* if both of should_merge and should_replace return FALSE Default
* implementations here always return FALSE - ie new records do not override
* old
*/
public boolean shouldAdd (AbstractRecord a)
{
return false;
}
public boolean shouldAlter (AbstractRecord a)
{
return false;
}
public boolean shouldMerge (AbstractRecord a)
{
return false;
}
public boolean shouldReplace (AbstractRecord a)
{
return false;
}
public ActivationRecord()
{
super();
objectAddr = null;
actionHandle = null;
state = ObjectStatus.PASSIVE;
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActivationRecord::ActivationRecord()");
}
}
private StateManager objectAddr;
private BasicAction actionHandle;
private int state;
}