You are viewing a plain text version of this content. The canonical link for it is here.
Posted to kandula-dev@ws.apache.org by da...@apache.org on 2007/06/18 22:11:22 UTC
svn commit: r548474 -
/webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/
Author: dasarath
Date: Mon Jun 18 13:11:21 2007
New Revision: 548474
URL: http://svn.apache.org/viewvc?view=rev&rev=548474
Log:
Hannes Erven, Georg Hicker
Added:
webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/InvalidStateException.java
webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/ProtocolType.java
webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/State.java
webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionFault.java
webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionIgnore.java
webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionResend.java
webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionResendPreviousState.java
webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionState.java
webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/WrongMethodCallException.java
Added: webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/InvalidStateException.java
URL: http://svn.apache.org/viewvc/webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/InvalidStateException.java?view=auto&rev=548474
==============================================================================
--- webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/InvalidStateException.java (added)
+++ webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/InvalidStateException.java Mon Jun 18 13:11:21 2007
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * @author Hannes Erven, Georg Hicker
+ */
+package org.apache.kandula.coordinator.ba;
+
+/**
+ * This exception is raised when a message is received that is forbidden
+ * in the current state of the transaction.
+ *
+ * @author Hannes Erven, Georg Hicker (C) 2006
+ *
+ */
+public class InvalidStateException extends Exception {
+
+ /**
+ * Generated serialUID
+ */
+ private static final long serialVersionUID = 7561709791825071749L;
+
+ /**
+ *
+ */
+ public InvalidStateException() {
+ super();
+ }
+
+ /**
+ * @param message
+ */
+ public InvalidStateException(String message) {
+ super(message);
+ }
+
+ /**
+ * @param cause
+ */
+ public InvalidStateException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public InvalidStateException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
Added: webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/ProtocolType.java
URL: http://svn.apache.org/viewvc/webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/ProtocolType.java?view=auto&rev=548474
==============================================================================
--- webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/ProtocolType.java (added)
+++ webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/ProtocolType.java Mon Jun 18 13:11:21 2007
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * @author Hannes Erven, Georg Hicker
+ */
+package org.apache.kandula.coordinator.ba;
+
+import javax.xml.namespace.QName;
+
+/**
+ * This class provides fields and convenience methods for handling protocol types and protocol type QNames.
+ *
+ * @author Hannes Erven, Georg Hicker (C) 2006
+ *
+ */
+public class ProtocolType {
+ /**
+ * The QName used to identify the BA with Participant Completion protocol.
+ */
+ public final static QName PROTOCOL_ID_PC = QName.valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba/}ParticipantCompletion");
+
+ /**
+ * The QName used to identify the BA with Coordinator Completion protocol.
+ */
+ public final static QName PROTOCOL_ID_CC = QName.valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba/}CoordinatorCompletion");
+
+ private final QName protocol;
+
+
+ /**
+ * Default Constructor. Stores the chosen protocol
+ * @param xprotocol The chosen protocol
+ * @throws IllegalArgumentException if an invalid protocol is passed
+ */
+ public ProtocolType(final String xprotocol) throws IllegalArgumentException {
+ if (xprotocol.equals(PROTOCOL_ID_CC.toString())
+ || xprotocol.equals(PROTOCOL_ID_CC.getNamespaceURI()+PROTOCOL_ID_CC.getLocalPart())
+ ) {
+ this.protocol = PROTOCOL_ID_CC;
+ } else if (xprotocol.equals(PROTOCOL_ID_PC.toString())
+ || xprotocol.equals(PROTOCOL_ID_PC.getNamespaceURI()+PROTOCOL_ID_PC.getLocalPart())
+ ) {
+ this.protocol = PROTOCOL_ID_PC;
+ } else {
+ throw new IllegalArgumentException(
+ "The specified protocol '"+xprotocol+"' is not available!\n"
+ + "Choose one of the following:\n"
+ + "\t" + PROTOCOL_ID_PC.toString() + "\n"
+ + "\t" + PROTOCOL_ID_CC.toString());
+ }
+ }
+ /**
+ * @return Returns the protocol.
+ */
+ public QName getProtocol() {
+ return this.protocol;
+ }
+
+}
Added: webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/State.java
URL: http://svn.apache.org/viewvc/webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/State.java?view=auto&rev=548474
==============================================================================
--- webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/State.java (added)
+++ webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/State.java Mon Jun 18 13:11:21 2007
@@ -0,0 +1,661 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * @author Hannes Erven, Georg Hicker
+ */
+
+package org.apache.kandula.coordinator.ba;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis.AxisFault;
+
+/**
+ * Abstract Class for State handling.</br> </br> Participant must handle
+ * ParticipantState</br> Coordinator must handle CoordinationState
+ *
+ * @author Hannes Erven, Georg Hicker (C) 2006
+ *
+ */
+public abstract class State {
+
+ /**
+ * The protocol this state table is configured for.
+ */
+ protected final QName protocolIdentifier;
+
+ /**
+ * Default constructor. </br> Stores protocol identifier into final local
+ * variable for state transitions.
+ *
+ * @param xprotocolIdentifier The protocol the state table will be configured for.
+ */
+ public State(final QName xprotocolIdentifier) {
+ if (!xprotocolIdentifier.equals(ProtocolType.PROTOCOL_ID_CC)
+ || !xprotocolIdentifier.equals(ProtocolType.PROTOCOL_ID_PC)) {
+ this.protocolIdentifier = xprotocolIdentifier;
+ } else
+ throw new IllegalArgumentException("Protocoltype is unknown: "
+ + xprotocolIdentifier.toString());
+ }
+
+ /**
+ * Return an invalid state soap fault.
+ * as a troubleshooting help.
+ * @return The ready made exception.
+ */
+ public static AxisFault GET_INVALID_STATE_SOAP_FAULT(){
+ return new AxisFault(
+ new QName("http://schemas.xmlsoap.org/ws/2004/10/wscoor",
+ "InvalidState"),
+ "The message was invalid for the current state of the activity.",
+ null, null);
+ }
+
+ /**
+ * Return an invalid state soap fault, but include the current state
+ * as a troubleshooting help.
+ * @param currentState The current state.
+ * @return The ready made exception.
+ */
+ public static AxisFault GET_INVALID_STATE_SOAP_FAULT(final QName currentState) {
+ return new AxisFault(
+ new QName("http://schemas.xmlsoap.org/ws/2004/10/wscoor",
+ "InvalidState"),
+ "The message was invalid for the current state of the activity."+
+ " Current state was: "+currentState.toString(),
+ null, null);
+ }
+
+ /**
+ * Return a new AxisFault, ready configured as wscoor:MessageUnknown invalid message fault.
+ * If axis is configured to include a stack trace, calling this as a method instead of providing a
+ * static field will ensure the stack trace is correct.
+ * @return wscoor:UnknownMessage
+ */
+ public static AxisFault GET_INVALID_MESSAGE_SOAP_FAULT(){
+ return new AxisFault(
+ new QName("http://schemas.xmlsoap.org/ws/2004/10/wscoor",
+ "MessageUnknown"),
+ "The message was not known for the current state of the activity.",
+ null, null);
+ }
+
+ /*
+ * All possible states.
+ */
+
+ /**
+ * The WSBA:Active State.
+ */
+ public static final QName STATE_ACTIVE = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Active");
+
+ /**
+ * The WSBA:Cancelling State.
+ */
+ public static final QName STATE_CANCELLING = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Canceling");
+
+ /**
+ * The WSBA:Canceling-Active State.
+ */
+ public static final QName STATE_CANCELLING_ACTIVE = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Canceling-Active");
+
+ /**
+ * The WSBA:Canceling-Completing State.
+ */
+ public static final QName STATE_CANCELLING_COMPLETING = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Canceling-Completing");
+
+ /**
+ * The WSBA:Completing State.
+ */
+ public static final QName STATE_COMPLETING = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Completing");
+
+ /**
+ * The WSBA:Completed State.
+ */
+ public static final QName STATE_COMPLETED = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Completed");
+
+ /**
+ * The WSBA:Closing State.
+ */
+ public static final QName STATE_CLOSING = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Closing");
+
+ /**
+ * The WSBA:Compensating State.
+ */
+ public static final QName STATE_COMPENSATING = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Compensating");
+
+ /**
+ * The WSBA:Faulting State.
+ */
+ public static final QName STATE_FAULTING = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Faulting");
+
+ /**
+ * The WSBA:Faulting-Active State.
+ */
+ public static final QName STATE_FAULTING_ACTIVE = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Faulting-Active");
+
+ /**
+ * The WSBA:Faulting-Compensating State.
+ */
+ public static final QName STATE_FAULTING_COMPENSATING = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Faulting-Compensating");
+
+ /**
+ * The WSBA:Exiting State.
+ */
+ public static final QName STATE_EXITING = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Exiting");
+
+ /**
+ * The WSBA:Ended State.
+ */
+ public static final QName STATE_ENDED = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Ended");
+
+ /*
+ * All possible messages.
+ */
+ /**
+ * The WSBA:Cancel Message.
+ */
+ public static final QName MESSAGE_CANCEL = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Cancel");
+
+ /**
+ * The WSBA:Canceled Message.
+ */
+ public static final QName MESSAGE_CANCELED = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Canceled");
+
+ /**
+ * The WSBA:Close Message.
+ */
+ public static final QName MESSAGE_CLOSE = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Close");
+
+ /**
+ * The WSBA:Closed Message.
+ */
+ public static final QName MESSAGE_CLOSED = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Closed");
+
+ /**
+ * The WSBA:Compensate Message.
+ */
+ public static final QName MESSAGE_COMPENSATE = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Compensate");
+
+ /**
+ * The WSBA:Compensated Message.
+ */
+ public static final QName MESSAGE_COMPENSATED = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Compensated");
+
+ /**
+ * The WSBA:Complete Message.
+ */
+ public static final QName MESSAGE_COMPLETE = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Complete");
+
+ /**
+ * The WSBA:Completed Message.
+ */
+ public static final QName MESSAGE_COMPLETED = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Completed");
+
+ /**
+ * The WSBA:Exit Message.
+ */
+ public static final QName MESSAGE_EXIT = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Exit");
+
+ /**
+ * The WSBA:Exited Message.
+ */
+ public static final QName MESSAGE_EXITED = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Exited");
+
+ /**
+ * The WSBA:Fault Message.
+ */
+ public static final QName MESSAGE_FAULT = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Fault");
+
+ /**
+ * The WSBA:Faulted Message.
+ */
+ public static final QName MESSAGE_FAULTED = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Faulted");
+
+ /**
+ * The WSBA:Status Message.
+ */
+ public static final QName MESSAGE_STATUS = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}Status");
+
+ /**
+ * The WSBA:GetStatus Message.
+ */
+ public static final QName MESSAGE_GETSTATUS = QName
+ .valueOf("{http://schemas.xmlsoap.org/ws/2004/10/wsba}GetStatus");
+
+ /**
+ * The current state QName.
+ */
+ protected QName currState = null;
+
+ /**
+ * A list of the previous states.
+ */
+ protected final Vector previousStates = new Vector();
+
+ /**
+ * Fetch the state map.
+ * @return The <State, <Message, AbstractStateTransition>> map
+ */
+ abstract protected Map getStates();
+
+ /**
+ * Method for getting the StateTransition initiated by the received Message
+ * in the current ProtocolType.
+ *
+ * This method never returns null.
+ *
+ * @param message The incoming message type QName.
+ *
+ * @return The state transition for the incoming message.
+ */
+ private AbstractStateTransition getStateTransition(final QName message) {
+ final HashMap temp = (HashMap) ((HashMap) getStates().get(
+ this.protocolIdentifier)).get(this.currState);
+ final AbstractStateTransition returnStateTransition = (AbstractStateTransition) temp
+ .get(message);
+ if (returnStateTransition != null)
+ return returnStateTransition;
+ return new StateTransitionIgnore();
+ }
+
+ /**
+ * Fetch the state table from the "other" side, that is: if we have the
+ * participant's states, returns the coordination's states; if we have the
+ * coordinations's states, returns the participant's states.
+ *
+ * This method is used by
+ *
+ * @see #getMessageForTransition(QName, QName) to determine which message makes the
+ * peer transist from the previous state to the current state. This is
+ * done when we receive a message that is consistent with the previous
+ * state, but not the current one: then we need to resend our last
+ * message, but since we didn't store it, we need to check what it was.
+ * @return Our counterpart's state table.
+ */
+ protected abstract HashMap getOtherStates();
+
+ /**
+ * Method for getting the Message to be received in order to transist from a
+ * given previous state to the current state in the current ProtocolType. In
+ * order to be able to correctly translate the last state (state before the
+ * current state) <code>lastState</code> the second last state (state
+ * before the last state) <code>secondLastState</code> has to be passed.
+ *
+ * @param lastState
+ * @param secondLastState
+ * @return <code>null</code>, if it is not possible to transist with some
+ * message from a given previous state to the current state
+ */
+ public QName getMessageForTransition(QName lastState, final QName secondLastState) {
+ this.translateState(lastState, secondLastState);
+ final HashMap temp = (HashMap) ((HashMap) getOtherStates().get(
+ this.protocolIdentifier)).get(lastState);
+
+ final Set messages = temp.keySet();
+
+ for (final Iterator it = messages.iterator(); it.hasNext();) {
+ final QName message = (QName) it.next();
+ final AbstractStateTransition stateTrans = (AbstractStateTransition) temp
+ .get(message);
+
+ if (stateTrans instanceof StateTransitionState) {
+ final StateTransitionState possibleTrans = (StateTransitionState) stateTrans;
+ try {
+ if (possibleTrans.getState() == getCurrentState()) {
+ return message;
+ }
+ } catch (WrongMethodCallException e) {
+ // Can be ignored.
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the currentState.
+ *
+ * @return The current state.
+ */
+ public QName getCurrentState() {
+ return this.currState;
+ }
+
+ /**
+ * Get the result state.
+ * When the participant is in state ENDED,
+ * returns one of the following states that were passed:
+ * <ul>
+ * <li>Exiting</li>
+ * <li>Canceling</li>
+ * <li>Closing</li>
+ * <li>Compensating</li>
+ * <li>Faulting</li>
+ * </ul>
+ *
+ * If the participant is in COMPLETED, return COMPLETED.
+ *
+ * Else, returns ACTIVE.
+ *
+ *
+ * @return Returns the state characterizing the participant's result best.
+ */
+ public QName getResultState(){
+ if (State.STATE_ENDED.equals(this.currState)){
+ return this.getLastState();
+ }
+ if (false
+ || State.STATE_COMPLETED.equals(this.currState)
+ || State.STATE_CLOSING.equals(this.currState)
+ || State.STATE_COMPENSATING.equals(this.currState)
+ || State.STATE_FAULTING_COMPENSATING.equals(this.currState)
+ ){
+ return State.STATE_COMPLETED;
+ }
+ return State.STATE_ACTIVE;
+ }
+
+ /**
+ * Setter for CurrentState
+ *
+ * @param xcurrState Set the current state.
+ */
+ protected synchronized void setCurrentState(final QName xcurrState) {
+ if (xcurrState == null) {
+ throw new NullPointerException("cannot set current state to 'null'");
+ }
+ if (xcurrState.equals(this.currState))
+ return;
+
+ if (this.currState != null)
+ this.previousStates.add(this.currState);
+
+ // DEBUG debugoutput
+ System.out.println("*** State changed to " + xcurrState + " from "
+ + this.currState);
+
+ this.currState = xcurrState;
+ }
+
+ /**
+ * Getter for the last known state before the current state.
+ *
+ * @return Return the previous state; null, if there is none.
+ */
+ public QName getLastState() {
+ if (this.previousStates.size() > 0) {
+ return (QName) this.previousStates.lastElement();
+ }
+ return null;
+ }
+
+ /**
+ * Getter for the state before the last state.
+ *
+ * @return the second last state; null, if there is none.
+ */
+ public QName getSecondLastState() {
+ if (this.previousStates.size() >= 2) {
+ return (QName) this.previousStates.get(this.previousStates.size()-2);
+ }
+ return null;
+ }
+
+ /**
+ * Revert the current state to the last known state.
+ */
+ public void revertState() {
+ if (this.previousStates.size() > 0) {
+ this.currState = (QName) this.previousStates.lastElement();
+ this.previousStates.remove(this.previousStates.size() - 1);
+ } else {
+ /*
+ * TODO GH throw Exception???
+ */
+ }
+ }
+
+ /**
+ * Method for transiting the State as specified by the HashMap
+ *
+ * @param message
+ * The message received
+ * @return Method only returns an AbstractStateTransition in case of needed
+ * resend of message of current state (state is unchanged)
+ * @throws AxisFault
+ * thrown in case that the received Message is not allowed for
+ * the current state or the message is not known for the current
+ * state
+ * @throws WrongMethodCallException
+ * thrown if a method on an instance of AbstactStateTransition
+ * is called, that is not allowed for this instance
+ * @throws IllegalArgumentException
+ * thrown if the stateTransition is of no known instance
+ */
+ public synchronized AbstractStateTransition transistStateByMessage(
+ final QName message) throws AxisFault, WrongMethodCallException {
+ final AbstractStateTransition stateTransition = this
+ .getStateTransition(message);
+ if (stateTransition instanceof StateTransitionFault) {
+ final StateTransitionFault stateTransitionFault = (StateTransitionFault) stateTransition;
+ throw stateTransitionFault.getAxisFault();
+ } else if (stateTransition instanceof StateTransitionResend) {
+ final StateTransitionResend stateTransitionResend = (StateTransitionResend) stateTransition;
+ return stateTransitionResend;
+ } else if (stateTransition instanceof StateTransitionIgnore) {
+ return null;
+ } else if (stateTransition instanceof StateTransitionState) {
+ final StateTransitionState stateTransitionState = (StateTransitionState) stateTransition;
+ this.setCurrentState(stateTransitionState.getState());
+ return stateTransitionState;
+ } else if (stateTransition instanceof StateTransitionResendPreviousState) {
+ final StateTransitionResendPreviousState stateTransitionResendPrevState = (StateTransitionResendPreviousState) stateTransition;
+ return stateTransitionResendPrevState;
+ } else {
+ // stateTransition is of no known type
+ throw new IllegalArgumentException(
+ "The StateTransition is of an unknown instance:"
+ + stateTransition.getClass().getName());
+ }
+ }
+
+ /**
+ * Tests if the passed message is allowed in the current state and if so
+ * resets the current state to the state after sending the message.
+ *
+ * @param message
+ * the message to test
+ * @return <code>true</code> if the message is possible in the current
+ * state which is the last state when returned to calling method,
+ * else <code>false</code>
+ */
+ public synchronized boolean handleOutgoingMessage(final QName message) {
+ final AbstractStateTransition possibleTrans = this
+ .isMessagePossible(message);
+ if (possibleTrans instanceof StateTransitionState) {
+ final StateTransitionState transition = (StateTransitionState) possibleTrans;
+ try {
+ this.setCurrentState(
+ this.reverseTranslateState(
+ transition.getState(),
+ this.getCurrentState()
+ )
+ );
+ } catch (WrongMethodCallException e) {
+ // This Exception can not occur here since we ensure that it is
+ // a StateTransitionState which implements this method without
+ // throwing the error
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Tests with the Hashmap of the other side (CoordinatorState in case of
+ * ParticipantState and viceversa) if the message can be receipt.
+ *
+ * @param message
+ * the message to test
+ * @return <code>true</code> if the message can be receipt by the other
+ * side in the current state, else <code>false</code>
+ */
+ protected AbstractStateTransition isMessagePossible(final QName message) {
+ final HashMap otherSide = (HashMap) ((HashMap) getOtherStates().get(
+ this.protocolIdentifier)).get(this.translateState(
+ this.getCurrentState(), this.getLastState()));
+ return (AbstractStateTransition) otherSide.get(message);
+ }
+
+
+ /**
+ * If the protocol is CoordinationCompletion and the state (<code>state</code>)
+ * is either <code>STATE_CANCELLING_ACTIVE</code> or
+ * <code>STATE_CANCELLING_COMPLETING</code> then the variable state has to
+ * be changed to reference <code>STATE_CANCELLING</code> since
+ * <code>ParticipantState</code> is called.
+
+ * @param state
+ * The current state.
+ *
+ * @param prevState
+ * The previous state.
+ *
+ * @return The translated state.
+ *
+ * @see org.apache.kandula.coordinator.ba.State#translateState(javax.xml.namespace.QName,
+ * javax.xml.namespace.QName)
+ */
+ protected abstract QName translateState(final QName state, final QName prevState);
+
+ /**
+ * If the protocol is CoordinationCompletion and the state (<code>state</code>)
+ * is <code>STATE_CANCELLING</code> then the variable state has to be
+ * changed to reference <code>STATE_CANCELLING_ACTIVE</code> or
+ * <code>STATE_CANCELLING_COMPLETING</code> since this is
+ * <code>CoordinationState</code>.
+ *
+ * @param state
+ * The current state.
+ *
+ * @param prevState
+ * The previous state.
+ *
+ * @return
+ * The translated state.
+ *
+ * @see org.apache.kandula.coordinator.ba.State#reverseTranslateState(javax.xml.namespace.QName,
+ * javax.xml.namespace.QName)
+ */
+ protected abstract QName reverseTranslateState(QName state, final QName prevState);
+
+ /**
+ * Translate the given states to participant view.
+ * (In fact does this method no more that to simplify CANCELLING_ACTIVE
+ * and CANCELLING_COMPLETING into CANCELLING.)
+ *
+ * @param state The current state of the participant.
+ * @param prevState The previous state of the participant.
+ * @return The current state, translated for the participant's view.
+ */
+ public static QName translateStateToParticipantView(final QName state, final QName prevState) {
+ /*
+ * dirty hack to remove warning
+ */
+ if (prevState != null) {
+ prevState.toString();
+ }
+
+ final QName returnState;
+ if (false
+ || state.equals(STATE_CANCELLING_ACTIVE)
+ || state.equals(STATE_CANCELLING_COMPLETING)) {
+ returnState = STATE_CANCELLING;
+ }else{
+ returnState = state;
+ }
+ return returnState;
+ }
+
+
+ /**
+ * Translate the given states to coordinator view view.
+ * (In fact does this method no more that to split CANCELLING into
+ * CANCELLING_ACTIVE and CANCELLING_COMPLETING .)
+ *
+ * @param protocol The current protocol type.
+ * @param state The current state of the participant.
+ * @param prevState The previous state of the participant.
+ * @return The current state, translated for the coordinator's view.
+ */
+ public static QName translateStateToCoordinatorView(
+ final QName protocol,
+ final QName state,
+ final QName prevState
+ ) {
+ final QName returnState;
+
+ if (ProtocolType.PROTOCOL_ID_CC.equals(protocol)
+ && state.equals(STATE_CANCELLING)) {
+ if (prevState.equals(STATE_ACTIVE)) {
+ returnState = STATE_CANCELLING_ACTIVE;
+ } else if (prevState.equals(STATE_COMPLETING)) {
+ returnState = STATE_CANCELLING_COMPLETING;
+ } else {
+ throw new InternalError("no possible state");
+ }
+ }else{
+ returnState = state;
+ }
+
+ return returnState;
+ }
+
+
+}
Added: webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionFault.java
URL: http://svn.apache.org/viewvc/webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionFault.java?view=auto&rev=548474
==============================================================================
--- webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionFault.java (added)
+++ webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionFault.java Mon Jun 18 13:11:21 2007
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * @author Hannes Erven, Georg Hicker
+ */
+
+package org.apache.kandula.coordinator.ba;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis.AxisFault;
+
+/**
+ * This class represents faulted state transitions, used when a participant's message
+ * cannot be received in its current state.
+ *
+ * @author Hannes Erven, Georg Hicker (C) 2006
+ *
+ */
+public class StateTransitionFault extends AbstractStateTransition {
+
+ /**
+ * Default constructor. Throw back the given exception.
+ * @param axisFault The fault to throw back.
+ */
+ public StateTransitionFault(final AxisFault axisFault) {
+ super(null, axisFault);
+ }
+
+ /**
+ * Return the target state. (Not applicable!)
+ *
+ * @throws WrongMethodCallException Exception, if this method is not applicable to this state transition.
+ * @return The state.
+ */
+ public QName getState() throws WrongMethodCallException {
+ throw new WrongMethodCallException("Calling getState is not allowed on a StateTransitionFault");
+ }
+
+}
Added: webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionIgnore.java
URL: http://svn.apache.org/viewvc/webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionIgnore.java?view=auto&rev=548474
==============================================================================
--- webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionIgnore.java (added)
+++ webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionIgnore.java Mon Jun 18 13:11:21 2007
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * @author Hannes Erven, Georg Hicker
+ */
+
+package org.apache.kandula.coordinator.ba;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis.AxisFault;
+
+/**
+ * This class represents state transitions where no action is needed. This is typically the case
+ * when a duplicate message from a participant is received.
+ *
+ * @author Hannes Erven, Georg Hicker (C) 2006
+ *
+ */
+public class StateTransitionIgnore extends AbstractStateTransition {
+
+ /**
+ * Default constructor. As nothing should be done, there are
+ * no arguments needed.
+ */
+ public StateTransitionIgnore() {
+ super(null, null);
+ }
+
+ /**
+ * Not applicable.
+ * @see org.apache.kandula.coordinator.ba.AbstractStateTransition#getAxisFault()
+ * @throws WrongMethodCallException Exception, if this method is not applicable to this state transition.
+ */
+ public AxisFault getAxisFault() throws WrongMethodCallException{
+ throw new WrongMethodCallException("Calling getAxisFault is not allowed on a StateTransitionState");
+ }
+
+ /**
+ * Not applicable.
+ * @throws WrongMethodCallException Exception, if this method is not applicable to this state transition.
+ * @see org.apache.kandula.coordinator.ba.AbstractStateTransition#getState()
+ */
+ public QName getState() throws WrongMethodCallException {
+ throw new WrongMethodCallException("Calling getState is not allowed on a StateTransitionFault");
+ }
+
+}
Added: webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionResend.java
URL: http://svn.apache.org/viewvc/webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionResend.java?view=auto&rev=548474
==============================================================================
--- webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionResend.java (added)
+++ webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionResend.java Mon Jun 18 13:11:21 2007
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * @author Hannes Erven, Georg Hicker
+ */
+
+package org.apache.kandula.coordinator.ba;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis.AxisFault;
+
+/**
+ * A state transition that shall only resend an already sent message to the peer. No further
+ * action is required.
+ * This transition is typically used when a duplicate message from a participant is received
+ * and the coordinator shall resend its most recent (possibly lost) message again.
+ *
+ * @author Hannes Erven, Georg Hicker (C) 2006
+ *
+ */
+public class StateTransitionResend extends AbstractStateTransition {
+
+ /**
+ * The message to send
+ */
+ private final QName messageToResend;
+
+ /**
+ * Create a new State Transition with Message Resend
+ * @param pMessageToResend
+ */
+ public StateTransitionResend(final QName pMessageToResend) {
+ super(null, null);
+
+ this.messageToResend = pMessageToResend;
+ }
+
+
+ /**
+ * Throws a WrongMethodCallException
+ * @see AbstractStateTransition#getAxisFault()
+ */
+ public AxisFault getAxisFault() throws WrongMethodCallException{
+ throw new WrongMethodCallException(
+ "Calling getAxisFault is not allowed on a StateTransitionState");
+ }
+
+ /**
+ * Throws a WrongMethodCallException
+ * @see AbstractStateTransition#getState()
+ */
+ public QName getState() throws WrongMethodCallException {
+ throw new WrongMethodCallException(
+ "Calling getState is not allowed on a StateTransitionState");
+ }
+
+ /**
+ * The message to resend.
+ * @return The message to resend. @see State
+ */
+ public QName getMessageToResend() {
+ return this.messageToResend;
+ }
+}
\ No newline at end of file
Added: webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionResendPreviousState.java
URL: http://svn.apache.org/viewvc/webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionResendPreviousState.java?view=auto&rev=548474
==============================================================================
--- webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionResendPreviousState.java (added)
+++ webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionResendPreviousState.java Mon Jun 18 13:11:21 2007
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * @author Hannes Erven, Georg Hicker
+ */
+
+package org.apache.kandula.coordinator.ba;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis.AxisFault;
+
+/**
+ * This state transition is used when the participant needs to resend a possibly lost
+ * notification to the coordinator, due to a duplicate incoming message.
+ * In contrast to @see {@link StateTransitionResend} the participant needs to look
+ * two states back to determine which message to send.
+ *
+ * The typical use case is a duplicate incoming "CANCEL" message when already in state "ENDED":
+ * the participant must resend its "CANCELED" message.
+ *
+ * @author Hannes Erven, Georg Hicker (C) 2006
+ *
+ */
+public class StateTransitionResendPreviousState extends AbstractStateTransition {
+
+ /**
+ * Create a new State Transition with the info to Resend Message of previous
+ * state.
+ */
+ public StateTransitionResendPreviousState() {
+ super(null, null);
+ }
+
+ /**
+ * Throws a WrongMethodCallException
+ * @see AbstractStateTransition#getAxisFault()
+ */
+ public AxisFault getAxisFault() throws WrongMethodCallException {
+ throw new WrongMethodCallException(
+ "Calling getAxisFault is not allowed on a StateTransitionResendPreviousState");
+ }
+
+ /**
+ * Throws a WrongMethodCallException
+ * @see AbstractStateTransition#getState()
+ */
+ public QName getState() throws WrongMethodCallException {
+ throw new WrongMethodCallException(
+ "Calling getState is not allowed on a StateTransitionResendPreviousState");
+ }
+}
Added: webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionState.java
URL: http://svn.apache.org/viewvc/webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionState.java?view=auto&rev=548474
==============================================================================
--- webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionState.java (added)
+++ webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/StateTransitionState.java Mon Jun 18 13:11:21 2007
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * @author Hannes Erven, Georg Hicker
+ */
+
+package org.apache.kandula.coordinator.ba;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis.AxisFault;
+
+/**
+ * This is the most common state transition: the participant simply changes its state
+ * due to an incoming message.
+ *
+ * @author Hannes Erven, Georg Hicker (C) 2006
+ *
+ */
+public class StateTransitionState extends AbstractStateTransition {
+
+ /**
+ * Default constructor.
+ * @param state The state the participant has now reached.
+ */
+ public StateTransitionState(final QName state) {
+ super(state, null);
+ }
+
+ /**
+ * @throws WrongMethodCallException Exception, if this method is not applicable to this state transition.
+ * @see org.apache.kandula.coordinator.ba.AbstractStateTransition#getAxisFault()
+ */
+ public AxisFault getAxisFault() throws WrongMethodCallException{
+ throw new WrongMethodCallException("Calling getAxisFault is not allowed on a StateTransitionState");
+ }
+
+}
Added: webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/WrongMethodCallException.java
URL: http://svn.apache.org/viewvc/webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/WrongMethodCallException.java?view=auto&rev=548474
==============================================================================
--- webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/WrongMethodCallException.java (added)
+++ webservices/kandula/branches/Kandula_1/src/java/org/apache/kandula/coordinator/ba/WrongMethodCallException.java Mon Jun 18 13:11:21 2007
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * @author Hannes Erven, Georg Hicker
+ */
+
+package org.apache.kandula.coordinator.ba;
+
+/**
+ * This exception signals that something went wrong while performing a state transition.
+ * This may happen, when incorrect code queries fields on @see org.apache.kandula.coordinator.ba.AbstractStateTransition
+ * which are not available in that subclass.
+ *
+ * @author Hannes Erven, Georg Hicker (C) 2006
+ *
+ */
+public class WrongMethodCallException extends Exception {
+
+ /**
+ * Generated SerialVersionUID
+ */
+ private static final long serialVersionUID = -8654599203638284959L;
+
+ /**
+ *
+ */
+ public WrongMethodCallException() {
+ super();
+ }
+
+ /**
+ * @param message
+ */
+ public WrongMethodCallException(String message) {
+ super(message);
+ }
+
+ /**
+ * @param cause
+ */
+ public WrongMethodCallException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public WrongMethodCallException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: kandula-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: kandula-dev-help@ws.apache.org