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 [EMAIL PROTECTED] 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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to