Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * JBoss, Home of Professional Open Source
    * Copyright 2006, Red Hat Middleware LLC, and individual contributors
    * as indicated by the @author tags. 
    * See the copyright.txt in the distribution for a full listing 
    * of individual contributors.
    * This copyrighted material is made available to anyone wishing to use,
    * modify, copy, or redistribute it subject to the terms and conditions
    * of the GNU Lesser General Public License, v. 2.1.
   * This program is distributed in the hope that it will be useful, but WITHOUT A
   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
   * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
   * You should have received a copy of the GNU Lesser General Public License,
   * v.2.1 along with this distribution; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   * MA  02110-1301, USA.
   * 
   * (C) 2005-2006,
   * @author JBoss Inc.
   */
  package com.arjuna.wst11.messaging.engines;
  
  import  org.jboss.ws.api.addressing.MAP;
  
The participant completion participant state engine

Author(s):
kevin
  
  {
    
The participant id.
  
      private final String id ;
    
The instance identifier.
  
      private final InstanceIdentifier instanceIdentifier ;
    
The coordinator endpoint reference.
  
      private final W3CEndpointReference coordinator ;
    
The associated participant
  
The current state.
  
      private State state ;
    
The associated timer task or null.
  
      private TimerTask timerTask ;

    
the time which will elapse before the next message resend. this is incrementally increased until it reaches RESEND_PERIOD_MAX
  
      private long resendPeriod;

    
the initial period we will allow between resends.
  
      private long initialResendPeriod;

    
the maximum period we will allow between resends. n.b. the coordinator uses the value returned by getTransportTimeout as the limit for how long it waits for a response. however, we can still employ a max resend period in excess of this value. if a message comes in after the coordinator has given up it will catch it on the next retry.
  
      private long maxResendPeriod;

    
the amount of time we will wait for a response to a dispatched message
 
     private long timeout;

    
true if this participant has been recovered otherwise false
 
     private boolean recovered;

    
true if this participant's recovery details have been logged to disk otherwise false
 
     private boolean persisted;

    
true if the participant should send getstatus rather than resend a completed message
 
     private boolean checkStatus;

    
Construct the initial engine for the participant.

Parameters:
id The participant id.
coordinator The coordinator endpoint reference.
participant The participant.
 
     public ParticipantCompletionParticipantEngine(final String idfinal W3CEndpointReference coordinator,
         final BusinessAgreementWithParticipantCompletionParticipant participant)
     {
         this(idcoordinatorparticipant.false) ;
     }

    
Construct the engine for the participant in a specified state.

Parameters:
id The participant id.
coordinator The coordinator endpoint reference.
participant The participant.
state The initial state.
recovered true if the engine has been recovered from th elog otherwise false
 
     public ParticipantCompletionParticipantEngine(final String idfinal W3CEndpointReference coordinator,
         final BusinessAgreementWithParticipantCompletionParticipant participantfinal State stateboolean recovered)
     {
         this. = id ;
         this. = new InstanceIdentifier(id) ;
         this. = coordinator ;
         this. = participant ;
         this. = state ;
         this. = recovered;
         this. = recovered;
         this. = TransportTimer.getTransportPeriod();
         this. = TransportTimer.getMaximumTransportPeriod();
         this. = TransportTimer.getTransportTimeout();
         this. = ;
         // we always check the status of a recovered participant and we always start off sending completed
         // if the participant is not recovered
         this. = recovered;
     }

    
Handle the cancel event.

Parameters:
cancel The cancel notification.
map The addressing context.
arjunaContext The arjuna context. Active -> Canceling Canceling -> Canceling Completed -> Completed (resend Completed) Closing -> Closing Compensating -> Compensating Failing-Active -> Failing-Active (resend Fail) Failing-Canceling -> Failing-Canceling (resend Fail) Failing-Compensating -> Failing-Compensating NotCompleting -> NotCompleting (resend CannotComplete) Exiting -> Exiting (resend Exit) Ended -> Ended (resend Cancelled)
 
     public void cancel(final NotificationType cancelfinal MAP mapfinal ArjunaContext arjunaContext)
     {
         final State current ;
         synchronized(this)
         {                                      
             current =  ;
             if (current == .)
             {
                 changeState(.) ;
             }
         }
 
         if (current == .)
         {
             executeCancel() ;
         }
         else if (current == .)
         {
             sendCompleted() ;
         }
         else if ((current == .) || (current == .))
         {
             sendFail(current.getValue()) ;
         }
         else if (current == .)
         {
             sendCannotComplete() ;
         }
         else if (current == .)
         {
             sendExit() ;
         }
         else if (current == .)
         {
             sendCancelled() ;
         }
     }

    
Handle the close event.

Parameters:
close The close notification.
map The addressing context.
arjunaContext The arjuna context. Active -> Active (invalid state) Canceling -> Canceling (invalid state) Completed -> Closing Closing -> Closing Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended (send Closed)
 
     public void close(final NotificationType closefinal MAP mapfinal ArjunaContext arjunaContext)
     {
         final State current ;
         synchronized(this)
         {
             current =  ;
             if (current == .)
             {
                 changeState(.) ;
             }
         }
 
         if (current == .)
         {
             if ( != null)
             {
                 .cancel() ;
             }
             executeClose() ;
         }
         else if (current == .)
         {
             sendClosed() ;
         }
     }

    
Handle the compensate event.

Parameters:
compensate The compensate notification.
map The addressing context.
arjunaContext The arjuna context. Active -> Active (invalid state) Canceling -> Canceling (invalid state) Completed -> Compensating Closing -> Closing (invalid state) Compensating -> Compensating Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (resend Fail) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended (send Compensated)
 
     public void compensate(final NotificationType compensatefinal MAP mapfinal ArjunaContext arjunaContext)
     {
         final State current ;
         synchronized(this)
         {
             current =  ;
             if (current == .)
             {
                 changeState(.) ;
             }
         }
 
         if (current == .)
         {
             if ( != null)
             {
                 .cancel() ;
             }
             executeCompensate() ;
         }
         else if (current == .)
         {
             sendFail(current.getValue()) ;
         }
         else if (current == .)
         {
             sendCompensated() ;
         }
     }

    
Handle the exited event.

Parameters:
exited The exited notification.
map The addressing context.
arjunaContext The arjuna context. Active -> Active (invalid state) Canceling -> Canceling (invalid state) Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Ended Ended -> Ended
 
     public void exited(final NotificationType exitedfinal MAP mapfinal ArjunaContext arjunaContext)
     {
         final State current ;
         synchronized(this)
         {
             current =  ;
             if (current == .)
             {
                 ended() ;
             }
         }
     }

    
Handle the failed event.

Parameters:
failed The failed notification.
map The addressing context.
arjunaContext The arjuna context. Active -> Active (invalid state) Canceling -> Canceling (invalid state) Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Compensating (invalid state) Failing-Active -> Ended Failing-Canceling -> Ended Failing-Compensating -> Ended NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended
 
     public void failed(final NotificationType failed,  final MAP mapfinal ArjunaContext arjunaContext)
     {
         final State current ;
         boolean deleteRequired = false;
         synchronized(this)
         {
             current =  ;
             if ((current == .) || (current == .) ||
                 (current == .))
             {
                 deleteRequired = ;
             }
         }
         // if we just ended the participant ensure any log record gets deleted
 
         if (deleteRequired) {
             if (!XTSBARecoveryManager.getRecoveryManager().deleteParticipantRecoveryRecord()) {
                 // hmm, could not delete entry -- nothing more we can do than log a message
             } 
         }
         // now the log record has been deleted we can safely end this participant
         if ((current == .) || (current == .) ||
             (current == .))
         {
             ended();
         }
     }

    
Handle the not completed event.

Parameters:
notCompleted The notCompleted notification.
map The addressing context.
arjunaContext The arjuna context. Active -> Active (invalid state) Canceling -> Canceling (invalid state) Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> Ended Exiting -> Exiting (invalid state) Ended -> Ended
 
     public void notCompleted(final NotificationType notCompletedfinal MAP mapfinal ArjunaContext arjunaContext)
     {
         final State current ;
         synchronized(this)
         {
             current =  ;
             if (current == .)
             {
         	ended() ;
             }
         }
     }

    
Handle the getStatus event.

Parameters:
getStatus The getStatus notification.
map The addressing context.
arjunaContext The arjuna context.
 
     public void getStatus(final NotificationType getStatusfinal MAP mapfinal ArjunaContext arjunaContext)
     {
 	final State current ;
 	synchronized(this)
 	{
 	    current =  ;
 	}
 	sendStatus(current) ;
     }

    
Handle the status event.

Parameters:
status The status type.
map The addressing context.
arjunaContext The arjuna context.
 
     public void status(final StatusType statusfinal MAP mapfinal ArjunaContext arjunaContext)
     {
         // TODO --  check that the status is actually what we expect
 
         // revert to sending completed messages and reset the resend period to the initial period
          = false;
         updateResendPeriod(false);
     }

    
Handle the recovery event. Active -> Active (invalid state) Canceling -> Canceling (invalid state) Completed -> Completed (resend completed) Closing -> Closing (invalid state) Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended (invalid state)
 
     public void recovery()
     {
         final State current ;
         synchronized(this)
         {
             current =  ;
         }
 
         if (current == .)
         {
             sendCompleted(true);
         }
     }

    
Handle the soap fault event.

Parameters:
soapFault The soap fault.
map The addressing context.
arjunaContext The arjuna context.
 
     public void soapFault(final SoapFault soapFaultfinal MAP mapfinal ArjunaContext arjunaContext)
     {
         boolean deleteRequired;
         boolean checkingStatus;
         synchronized(this) {
             deleteRequired = ;
             // make sure delete is attempted only once
              = false;
             checkingStatus = ( == . && );
             ended() ;
         }
         // TODO -- update doc in interface and user guide.
         try
         {
             boolean isInvalidState = soapFault.getSubcode().equals(.);
             if (checkingStatus && isInvalidState) {
                 // coordinator must have died before reaching close so just cancel
                 .compensate();
             } else {
                 // hmm, something went wrong -- notify the participant of the error
                 .error();
             }
         }
         catch (final Throwable th) {} // ignore
         // if we just ended the participant ensure any log record gets deleted
         if (deleteRequired) {
             if (!XTSBARecoveryManager.getRecoveryManager().deleteParticipantRecoveryRecord()) {
                 // hmm, could not delete entry -- nothing more we can do than log a message
             }
         }
     }

    
Handle the completed event. Active -> Completed Canceling -> Canceling (invalid state) Completed -> Completed Closing -> Closing (invalid state) Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended (invalid state)
 
     public State completed()
     {
         State current ;
         boolean failRequired  = false;
         boolean deleteRequired  = false;
         boolean confirm = ( instanceof ConfirmCompletedParticipant);
         synchronized(this)
         {
             current =  ;
 
             // we have to do this synchronized so that we don't try writing the participant details twice
 
             if (current == .) {
                 // ok we need to write the participant details to disk because it has just completed
                 BAParticipantRecoveryRecord recoveryRecord = new BAParticipantRecoveryRecord(true);
 
                 if (XTSBARecoveryManager.getRecoveryManager().writeParticipantRecoveryRecord(recoveryRecord)) {
                     changeState(.);
                      = true;
                     // if necessary notify the client now. n.b. this has to be done synchronized because
                     // if we release the lock then a resent COMPLETE may result in a COMPLETED being
                     // sent back and we cannot allow that until after the confirm
                     if (confirm) {
                         ((ConfirmCompletedParticipant).confirmCompleted(true);
                     }
                 } else {
                     // hmm, could not write entry log warning
                     // we need to fail this transaction
                     failRequired = true;
                 }
             }
         }
 
         // check to see if we need to send a fail or delete the log record before going ahead to complete
 
         if (failRequired) {
             current = fail(.);
             // we can safely do this now
             if (confirm) {
                 ((ConfirmCompletedParticipant).confirmCompleted(false);
             }
         } else if ((current == .) || (current == .)) {
             sendCompleted() ;
         }
 
         return current ;
     }

    
Handle the exit event. Active -> Exiting Canceling -> Canceling (invalid state) Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting Ended -> Ended (invalid state)
 
     public State exit()
     {
         final State current ;
         synchronized (this)
         {
             current =  ;
             if (current == .)
             {
                 changeState(.) ;
             }
         }
 
         if ((current == .) || (current == .))
         {
             sendExit() ;
         }
 
         return waitForState(.) ;
     }

    
Handle the fail event. Active -> Failing-Active Canceling -> Failing-Canceling Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Failing-Compensating Failing-Active -> Failing-Active Failing-Canceling -> Failing-Canceling Failing-Compensating -> Failing-Compensating NotCompleting -> NotCompleting (invalid state) Exiting -> Exiting (invalid state) Ended -> Ended (invalid state)
 
     public State fail(final QName exceptionIdentifier)
     {
         final State current ;
         synchronized (this)
         {
             current =  ;
             if (current == .)
             {
                 changeState(.) ;
             }
             else if (current == .)
             {
             }
             else if (current == .)
             {
                 changeState(.) ;
             }
         }
 
         if ((current == .) || (current == .))
         {
             sendFail(exceptionIdentifier) ;
             return waitForState(.) ;
         }
         else if ((current == .) || (current == .))
         {
             sendFail(exceptionIdentifier) ;
             return waitForState(.) ;
         }
         else if ((current == .) || (current == .))
         {
             sendFail(exceptionIdentifier) ;
             return waitForState(.) ;
         }
 
         return current ;
     }

    
Handle the cannot complete event. Active -> NotCompleting Canceling -> Canceling (invalid state) Completed -> Completed (invalid state) Closing -> Closing (invalid state) Compensating -> Compensating (invalid state) Failing-Active -> Failing-Active (invalid state) Failing-Canceling -> Failing-Canceling (invalid state) Failing-Compensating -> Failing-Compensating (invalid state) NotCompleting -> NotCompleting Exiting -> Exiting (invalid state) Ended -> Ended (invalid state)
 
     public State cannotComplete()
     {
         final State current ;
         synchronized (this)
         {
             current =  ;
             if (current == .)
             {
                 changeState(.) ;
             }
         }
 
         if ((current == .) || (current == .))
         {
             sendCannotComplete() ;
             return waitForState(.) ;
         }
         return current ;
     }

    
Handle the comms timeout event. Completed -> Completed (resend Completed)
 
     private void commsTimeout(TimerTask caller)
     {
         final State current ;
         synchronized(this)
         {
             if (!.equals(caller)) {
                 // the timer was cancelled but it went off before it could be cancelled
 
                 return;
             }
 
             current =  ;
         }
 
         if (current == .)
         {
             sendCompleted(true) ;
         }
     }

    
Send the exit message.
 
     private void sendExit()
     {
         final MAP map = createContext() ;
         try
         {
             ParticipantCompletionCoordinatorClient.getClient().sendExit(map) ;
         }
         catch (final Throwable th)
         {
             if (..isTraceEnabled())
             {
                 ..tracev("Unexpected exception while sending Exit"th) ;
             }
         }
     }

    
Send the completed message
 
 
     private void sendCompleted()
     {
         sendCompleted(false);
     }

    
Send the completed message.

Parameters:
timedOut true if this is in response to a comms timeout
 
     private void sendCompleted(boolean timedOut)
     {
         final MAP map = createContext() ;
         try
         {
             // if we are trying to reestablish the participant state then send getStatus otherwise send completed 
             if (timedOut && ) {
                 ParticipantCompletionCoordinatorClient.getClient().sendGetStatus(map); ;
             } else {
                 ParticipantCompletionCoordinatorClient.getClient().sendCompleted(map) ;
             }
         }
         catch (final Throwable th)
         {
             if (..isTraceEnabled())
             {
                 ..tracev("Unexpected exception while sending Completed"th) ;
             }
         }
 
         // if we timed out the increase the resend period otherwise make sure it is reset to the
         // initial resend period
 
         updateResendPeriod(timedOut);
 
         initiateTimer() ;
     }
 
     private synchronized void updateResendPeriod(boolean timedOut)
     {
         // if we timed out then we multiply the resend period by ~= sqrt(2) up to the maximum
         // if not we make sure it is reset to the initial period
 
         if (timedOut) {
             if ( < ) {
                 long newPeriod  =  * 14 / 10;  // approximately doubles every two resends
 
                 if (newPeriod > ) {
                     newPeriod = ;
                 }
                  = newPeriod;
             } else {
                 // ok, we hit our maximum period last time -- this time switch to sending getStatus
                  = true;
             }
         } else {
             if ( > ) {
                  = ;
             }
             // if we were previously checking status we need to revert to sending Completed
             if () {
                  = false;
             }
         }
     }

    
Send the fail message.

Parameters:
message The fail message.
 
     private void sendFail(final QName message)
     {
         final MAP map = createContext() ;
         try
         {
             ParticipantCompletionCoordinatorClient.getClient().sendFail(mapmessage) ;
         }
         catch (final Throwable th)
         {
             if (..isTraceEnabled())
             {
                 ..tracev("Unexpected exception while sending Fault"th) ;
             }
         }
     }

    
Send the cancelled message.
 
     private void sendCancelled()
     {
         final MAP map = createContext() ;
         try
         {
             ParticipantCompletionCoordinatorClient.getClient().sendCancelled(map) ;
         }
         catch (final Throwable th)
         {
             if (..isTraceEnabled())
             {
                 ..tracev("Unexpected exception while sending Cancelled"th) ;
             }
         }
     }

    
Send the closed message.
 
     private void sendClosed()
     {
         final MAP map = createContext() ;
         try
         {
             ParticipantCompletionCoordinatorClient.getClient().sendClosed(map) ;
         }
         catch (final Throwable th)
         {
             if (..isTraceEnabled())
             {
                 ..tracev("Unexpected exception while sending Closed"th) ;
             }
         }
     }

    
Send the compensated message.
 
     private void sendCompensated()
     {
         final MAP map = createContext() ;
         try
         {
             ParticipantCompletionCoordinatorClient.getClient().sendCompensated(map) ;
         }
         catch (final Throwable th)
         {
             if (..isTraceEnabled())
             {
                 ..tracev("Unexpected exception while sending Compensated"th) ;
             }
         }
     }

    
Send the status message.

Parameters:
state The state.
 
     private void sendStatus(final State state)
     {
         final MAP map = createContext() ;
         try
         {
             ParticipantCompletionCoordinatorClient.getClient().sendStatus(mapstate.getValue()) ;
         }
         catch (final Throwable th)
         {
             if (..isTraceEnabled())
             {
                 ..tracev("Unexpected exception while sending Status"th) ;
             }
         }
     }

    
Send the cannot complete message.
 
     private void sendCannotComplete()
     {
         final MAP map = createContext() ;
         try
         {
             ParticipantCompletionCoordinatorClient.getClient().sendCannotComplete(map) ;
         }
         catch (final Throwable th)
         {
             if (..isTraceEnabled())
             {
                 ..tracev("Unexpected exception while sending Status"th) ;
             }
         }
     }

    
Get the coordinator id.

Returns:
The coordinator id.
 
     public String getId()
     {
         return  ;
     }

    
Get the coordinator endpoint reference

Returns:
The coordinator endpoint reference
 
     {
         return  ;
     }

    
Get the associated participant.

Returns:
The associated participant.
 
     {
         return  ;
     }

    
check whether this participant's details have been recovered from the log

Returns:
true if the participant is recovered otherwise false
 
     public boolean isRecovered()
     {
         return ;
     }

    
Change the state and notify any listeners.

Parameters:
state The new state.
 
     private synchronized void changeState(final State state)
     {
         if (this. != state)
         {
             this. = state ;
             notifyAll() ;
         }
     }

    
Wait for the state to change from the specified state.

Parameters:
origState The original state.
delay The maximum time to wait for (in milliseconds).
Returns:
The current state.
 
     private State waitForState(final State origStatefinal long delay)
     {
         final long end = System.currentTimeMillis() + delay ;
        synchronized(this)
        {
            while( == origState)
            {
                final long remaining = end - System.currentTimeMillis() ;
                if (remaining <= 0)
                {
                    break ;
                }
                try
                {
                    wait(remaining) ;
                }
                catch (final InterruptedException ie) {} // ignore
            }
            return  ;
        }
    }

    
Execute the cancel transition.
    private void executeCancel()
    {
        try
        {
            .cancel() ;
        }
        catch (final FaultedException fe)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Faulted exception from participant cancel for WS-BA participant {0}"new Object[] { }, fe) ;
            }
            // fail here because the participant doesn't want to retry the cancel
            return;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception from participant cancel for WS-BA participant {0}"new Object[] { }, th) ;
            }
            /*
             * we only get here in from state ACTIVE so if we are stll in state CANCELING then roll back the
             * state allowing a retry of the cancel
             */
            synchronized (this) {
                if ( == .) {
                    changeState(.);
                }
            }
            return ;
        }
        sendCancelled() ;
        ended() ;
    }

    
Execute the close transition.
    private void executeClose()
    {
        try
        {
            .close() ;
        }
        catch (final Throwable th)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception from participant close for WS-BA participant {0}"th) ;
            }
            // restore previous state so we can retry the close otherwise we get stuck in state closing forever
            changeState(.);
            initiateTimer();
            return ;
        }
        // delete any log record for the participant
        if () {
            // if we cannot delete the participant record we effectively drop the close message
            // here in the hope that we have better luck next time..
            if (!XTSBARecoveryManager.getRecoveryManager().deleteParticipantRecoveryRecord()) {
                // hmm, could not delete entry -- leave it so we can maybe retry later
                // restore previous state so we can retry the close otherwise we get stuck in state closing forever
                changeState(.);
                initiateTimer();
                return;
            }
        }
        sendClosed() ;
        ended() ;
    }

    
Execute the compensate transition.
    private void executeCompensate()
    {
        try
        {
            .compensate() ;
        }
        catch (final FaultedException fe)
        {
            if (..isTraceEnabled())
            {
                ..tracev("Faulted exception from participant compensate for WS-BA participant {0}"new Object[] { }, fe) ;
            }
            // fail here because the participant doesn't want to retry the compensate
            return;
        }
        catch (final Throwable th)
        {
            final State current ;
            synchronized (this)
            {
                current =  ;
                if (current == .)
                {
                    changeState(.) ;
                }
            }
            if (current == .)
            {
                initiateTimer() ;
            }
            if (..isTraceEnabled())
            {
                ..tracev("Unexpected exception from participant compensate for WS-BA participant {0}"new Object[] {  }, th) ;
            }
            return ;
        }
        final State current ;
        boolean failRequired = false;
        synchronized (this)
        {
            current =  ;
            // need to do this while synchronized so no fail calls can get in on between
            if (current == .)
            {
                if () {
                    if (!XTSBARecoveryManager.getRecoveryManager().deleteParticipantRecoveryRecord()) {
                        // we have to fail since we don't want to run the compensate method again
                        failRequired = true;
                        changeState(.);
                    }
                }
                // if we did not fail then we can decommission the participant now avoiding any further races
                // we will send the compensate after we exit the synchronized block
                if (!failRequired) {
                    ended();
                }
            }
        }
        if (failRequired) {
        } else if (current == .) {
            sendCompensated() ;
        }
    }

    
End the current participant.
    private void ended()
    {
        ParticipantCompletionParticipantProcessor.getProcessor().deactivateParticipant(this) ;
    }

    
Initiate the timer.
    private synchronized void initiateTimer()
    {
        if ( != null)
        {
            .cancel() ;
        }
        if ( == .)
        {
             = new TimerTask() {
                public void run() {
                    commsTimeout(this) ;
                }
            } ;
            TransportTimer.getTimer().schedule() ;
        }
        else
        {
             = null ;
        }
    }

    
Create a context for the outgoing message.

Returns:
The addressing context.
    private MAP createContext()
    {
        final String messageId = MessageId.getMessageId() ;
        return AddressingHelper.createNotificationContext(messageId) ;
    }
New to GrepCode? Check out our FAQ X