/*
* 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) 2002,
*
* Arjuna Technologies Limited,
* Newcastle upon Tyne,
* Tyne and Wear,
* UK.
*
* $Id: ACCoordinator.java,v 1.5 2005/05/19 12:13:32 nmcl Exp $
*/
package com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore;
import com.arjuna.mw.wscf.logging.wscfLogger;
import com.arjuna.ats.arjuna.common.Uid;
import com.arjuna.ats.arjuna.coordinator.*;
import com.arjuna.mw.wscf.common.Qualifier;
import com.arjuna.mw.wscf.common.CoordinatorId;
import com.arjuna.mw.wscf.model.as.coordinator.twophase.common.*;
import com.arjuna.mw.wscf.model.as.coordinator.Participant;
import com.arjuna.mw.wscf.model.as.coordinator.Coordinator;
import com.arjuna.mw.wscf.model.as.coordinator.Message;
import com.arjuna.mw.wsas.activity.Outcome;
import com.arjuna.mw.wsas.completionstatus.CompletionStatus;
import com.arjuna.mw.wsas.exceptions.SystemException;
import com.arjuna.mw.wsas.exceptions.WrongStateException;
import com.arjuna.mw.wsas.exceptions.ProtocolViolationException;
import com.arjuna.mw.wscf.exceptions.*;
/**
* This class represents a specific coordination instance. It is essentially an
* ArjunaCore TwoPhaseCoordinator, which gives us access to two-phase with
* synchronization support but without thread management.
*
* @author Mark Little (mark.little@arjuna.com)
* @version $Id: ACCoordinator.java,v 1.5 2005/05/19 12:13:32 nmcl Exp $
* @since 1.0.
*/
public class ACCoordinator extends TwoPhaseCoordinator implements
com.arjuna.mw.wscf.model.as.coordinator.Coordinator
{
public ACCoordinator ()
{
super();
_theId = new CoordinatorIdImple(get_uid());
}
public ACCoordinator (Uid recovery)
{
super(recovery);
_theId = new CoordinatorIdImple(get_uid());
}
/**
* If the application requires and if the coordination protocol supports it,
* then this method can be used to execute a coordination protocol on the
* currently enlisted participants at any time prior to the termination of
* the coordination scope.
*
* This implementation only supports coordination at the end of the
* activity.
*
* @param CompletionStatus
* cs The completion status to use when determining how to
* execute the protocol.
*
* @exception WrongStateException
* Thrown if the coordinator is in a state the does not allow
* coordination to occur.
* @exception ProtocolViolationException
* Thrown if the protocol is violated in some manner during
* execution.
* @exception SystemException
* Thrown if any other error occurs.
*
* @return The result of executing the protocol, or null.
*/
public Outcome coordinate (CompletionStatus cs) throws WrongStateException,
ProtocolViolationException, SystemException
{
return null;
}
/**
* Enrol the specified participant with the coordinator associated with the
* current thread. If the coordinator supports a priority ordering of
* participants, then that ordering can also be specified. Any qualifiers
* that are to be associated with the participant are also provided.
*
* @param Participant
* act The participant.
* @param int
* priority The priority to associate with the participant in the
* coordinator's list. The two-phase coordinator only supports
* two types of priority, defined in the Priorities class:
* Synchronizations and Participants.
* @param Qualifier[]
* quals Any qualifiers to be associated with the participant.
*
* @exception WrongStateException
* Thrown if the coordinator is not in a state that allows
* participants to be enrolled.
* @exception DuplicateParticipantException
* Thrown if the participant has already been enrolled and
* the coordination protocol does not support multiple
* entries.
* @exception InvalidParticipantException
* Thrown if the participant is invalid.
* @exception SystemException
* Thrown if any other error occurs.
*
* @see com.arjuna.mw.wscf.model.as.coordinator.twophase.common.Priorities
*/
public void addParticipant (Participant act, int priority, Qualifier[] quals)
throws WrongStateException, DuplicateParticipantException,
InvalidParticipantException, SystemException
{
if (act == null)
throw new InvalidParticipantException();
if (priority == Priorities.SYNCHRONIZATION)
{
SynchronizationRecord rec = new SynchronizationRecord(act,
new Uid(), priority, quals);
if (addSynchronization(rec) != AddOutcome.AR_ADDED)
throw new WrongStateException();
}
else
{
AbstractRecord rec = new ParticipantRecord(act, new Uid(),
priority, quals);
if (add(rec) != AddOutcome.AR_ADDED)
throw new WrongStateException();
}
}
/**
* Remove the specified participant from the coordinator's list. This
* operation may not be supported by all coordination protocols.
*
* @exception InvalidParticipantException
* Thrown if the participant is not known of by the
* coordinator.
* @exception WrongStateException
* Thrown if the state of the coordinator does not allow the
* participant to be removed (e.g., in a two-phase protocol
* the coordinator is committing.)
* @exception SystemException
* Thrown if any other error occurs.
*
* @message com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_1
* [com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_1] -
* ArjunaCore does not support removeParticipant
*/
public void removeParticipant (Participant act)
throws InvalidParticipantException, WrongStateException,
SystemException
{
if (act == null)
throw new InvalidParticipantException();
else
throw new WrongStateException(
wscfLogger.log_mesg.getString("com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_1"));
}
/**
* Some coordination protocol messages may have asynchronous responses or it
* may be possible for participants to autonomously generate responses to
* messages that have not yet been producted by the coordinator. As such,
* this method allows a response from a participant to be passed to the
* coordinator. In order to ensure that the protocol remains valid, it is
* necessary for the participant to specify what message produced the
* response: if the response was autonomously generated by the participant
* on the assumption it would receive this message from the coordinator and
* the coordinator subsequently decides not to produce such a message, then
* the action taken by the participant is invalid and hence so is the
* response.
*
* @param String
* id the unique participant identification.
* @param Message
* notification the message the participant got/assumed when
* producing the response.
* @param Outcome
* response the actual response.
* @param Qualifier[]
* quals any qualifiers associated with the response.
*
* @exception InvalidParticipantException
* Thrown if the coordinator has no knowledge of the
* participant.
* @exception WrongStateException
* Thrown if the coordinator is in a state that does not
* allow it to accept responses at all or this specific type
* of response.
* @exception SystemException
* Thrown if any other error occurs.
*
* @message com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_2
* [com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_1_2] -
* Invalid id:
* @message com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_3
* [com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_1_3] -
* Unknown participant:
* @message com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_4
* [com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_1_4] -
* Participant is not of correct type!
*/
public void setResponse (String id, Message notification, Outcome response, Qualifier[] quals)
throws InvalidParticipantException, WrongStateException,
SystemException
{
Uid participant = new Uid(id);
if (!participant.valid())
throw new InvalidParticipantException(
wscfLogger.log_mesg.getString("com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_2")
+ id);
synchronized (this)
{
if ((status() == ActionStatus.COMMITTED)
|| (status() == ActionStatus.ABORTED))
{
throw new WrongStateException();
}
boolean found = false;
RecordList intentionsList = pendingList; // what about other
// lists?
AbstractRecord rec = intentionsList.peekFront();
while (rec != null)
{
if (rec.order().equals(participant))
{
found = true;
break;
}
else
rec = intentionsList.peekNext(rec);
}
if (!found)
throw new InvalidParticipantException(
wscfLogger.log_mesg.getString("com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_3")
+ id);
else
{
if (rec instanceof com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ParticipantRecord)
{
com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ParticipantRecord theRecord = (com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ParticipantRecord) rec;
theRecord.setResponse(notification, response);
}
else
throw new InvalidParticipantException(
wscfLogger.log_mesg.getString("com.arjuna.mwlabs.wscf.model.as.coordinator.arjunacore.ACCoordinator_4"));
}
}
}
/**
* @exception SystemException
* Thrown if any error occurs.
*
* @return a reference to the current coordinators' parent if it is nested,
* null otherwise.
*/
public Coordinator getParentCoordinator () throws SystemException
{
return (Coordinator) parent();
}
/**
* @exception SystemException
* Thrown if any error occurs.
*
* @return the complete list of qualifiers that have been registered with
* the current coordinator.
*/
public Qualifier[] qualifiers () throws SystemException
{
return null;
}
/**
* @exception SystemException
* Thrown if any error occurs.
*
* @return The unique identity of the current coordinator.
*/
public CoordinatorId identifier () throws SystemException
{
return _theId;
}
private CoordinatorIdImple _theId;
}