Package de.danet.an.workflow.domain

Source Code of de.danet.an.workflow.domain.AbstractExecutionObject

/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* $Id: AbstractExecutionObject.java 2576 2007-11-02 16:00:34Z drmlipp $
*
* $Log$
* Revision 1.13  2007/09/21 07:57:12  drmlipp
* Removed superfluous import.
*
* Revision 1.12  2007/09/21 06:19:35  mlipp
* Fixed problem with NamingException during process deletion.
*
* Revision 1.11  2007/05/03 21:58:19  mlipp
* Internal refactoring for making better use of local EJBs.
*
*/

package de.danet.an.workflow.domain;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import de.danet.an.workflow.api.ProcessDefinition;
import de.danet.an.workflow.api.Activity.ClosedCompletedState;
import de.danet.an.workflow.apix.ExtActivity;
import de.danet.an.workflow.apix.ExtProcess;
import de.danet.an.workflow.internalapi.ExtExecutionObjectLocal;
import de.danet.an.workflow.localcoreapi.WfExecutionObjectLocal;
import de.danet.an.workflow.omgcore.AlreadySuspendedException;
import de.danet.an.workflow.omgcore.CannotResumeException;
import de.danet.an.workflow.omgcore.CannotStopException;
import de.danet.an.workflow.omgcore.CannotSuspendException;
import de.danet.an.workflow.omgcore.HistoryNotAvailableException;
import de.danet.an.workflow.omgcore.InvalidControlOperationException;
import de.danet.an.workflow.omgcore.InvalidDataException;
import de.danet.an.workflow.omgcore.InvalidPriorityException;
import de.danet.an.workflow.omgcore.InvalidStateException;
import de.danet.an.workflow.omgcore.NotRunningException;
import de.danet.an.workflow.omgcore.NotSuspendedException;
import de.danet.an.workflow.omgcore.ProcessData;
import de.danet.an.workflow.omgcore.ResultNotAvailableException;
import de.danet.an.workflow.omgcore.SourceNotAvailableException;
import de.danet.an.workflow.omgcore.TransitionNotAllowedException;
import de.danet.an.workflow.omgcore.UpdateNotAllowedException;
import de.danet.an.workflow.omgcore.WfAuditEvent;
import de.danet.an.workflow.omgcore.WfExecutionObject;
import de.danet.an.workflow.omgcore.WfStateAuditEvent;
import de.danet.an.workflow.omgcore.WfExecutionObject.ClosedState;
import de.danet.an.workflow.omgcore.WfExecutionObject.NotRunningState;
import de.danet.an.workflow.omgcore.WfExecutionObject.OpenState;
import de.danet.an.workflow.omgcore.WfExecutionObject.State;

/**
* <code>AbstractExecutionObject</code> represents a base
* implementation of the interface {@link
* de.danet.an.workflow.api.ExecutionObject
* <code>ExecutionObject</code>}.<P>
*
* With logger level <code>DEBUG</code>, event handling information
* will be logged.
*/
public abstract class AbstractExecutionObject
    implements WfExecutionObjectLocal, ExtExecutionObjectLocal {
   
    private static final org.apache.commons.logging.Log logger
  = org.apache.commons.logging.LogFactory.getLog
  (AbstractExecutionObject.class);

    // Make sure that loading this class loads the new states
    static {
  State s = RunningState.RUNNING;
  s = DebugState.ABORTING;
  s = SuspendedState.SUSPENDED;
  s = ClosedCompletedState.NORMAL;
    }

    //
    // Persistent attribute accessors and associated methods
    //

    /**
     * The getter method for the persistent attribute <code>key</code>.
     *
     * @return the value of key.
     */
    protected abstract String getPaKey();

    /**
     * The getter method for the persistent attribute <code>name</code>.
     *
     * @return the value of name.
     * @see #setPaName
     */
    protected abstract String getPaName();

    /**
     * The setter method for the persistent attribute <code>name</code>.
     *
     * @param newName the new value of name.
     * @see #getPaName
     */
    protected abstract void setPaName(String newName);

    /**
     * The getter method for the persistent attribute <code>description</code>.
     *
     * @return the value of description.
     * @see #setPaDescription
     */
    protected abstract String getPaDescription();

    /**
     * The setter method for the persistent attribute <code>description</code>.
     *
     * @param newDescription the new value of description.
     * @see #getPaDescription
     */
    protected abstract void setPaDescription(String newDescription);

    /**
     * The getter method for the persistent attribute <code>priority</code>.
     *
     * @return the value of priority.
     * @see #setPaPriority
     */
    protected abstract Priority getPaPriority();

    /**
     * The setter method for the persistent attribute <code>priority</code>.
     *
     * @param newPriority the new value of priority.
     * @see #getPaPriority
     */
    protected abstract void setPaPriority(Priority newPriority);

    /**
     * The getter method for the persistent attribute
     * <code>lastStateTime</code>.  This attribute holds the time when
     * the state was last changed. This may happen from an explicit
     * action like the <code>complete()</code> method or via a state
     * change propagation from another WfmExecutionObject.
     *
     * @return the value of lastStateTime.
     * @see #setPaLastStateTime
     */
    protected abstract Date getPaLastStateTime();

    /**
     * The setter method for the persistent attribute
     * <code>lastStateTime</code>.
     *
     * @param newLastStateTime the new value of lastStateTime.
     * @see #getPaLastStateTime
     */
    protected abstract void setPaLastStateTime(Date newLastStateTime);

    /**
     * The getter method for the persistent attribute
     * <code>typedState</code>.
     *
     * @return the value of typedState.
     * @see #setPaTypedState
     */
    protected abstract State getPaTypedState();

    /**
     * The setter method for the persistent attribute
     * <code>typedState</code>.
     *
     * @param newTypedState the new value of typedState.
     * @see #getPaTypedState
     */
    protected abstract void setPaTypedState(State newTypedState);

    /**
     * The getter method for the persistent attribute <code>debug</code>.
     *
     * @return the value of debug.
     * @see #setPaDebug
     */
    protected abstract boolean getPaDebug();

    /**
     * The setter method for the persistent attribute <code>debug</code>.
     *
     * @param newDebug the new value of debug.
     * @see #getPaDebug
     */
    protected abstract void setPaDebug(boolean newDebug);

    /**
     * The getter method for the persistent attribute
     * <code>auditEventSelection</code>.
     *
     * @return the value of auditEventSelection.
     * @see #setPaAuditEventSelection
     */
    protected abstract int getPaAuditEventSelection();

    /**
     * The setter method for the persistent attribute
     * <code>auditEventSelection</code>.
     *
     * @param newAuditEventSelection the new value of
     * auditEventSelection.
     * @see #getPaAuditEventSelection
     */
    protected abstract void
  setPaAuditEventSelection (int newAuditEventSelection);

    /**
     * The getter method for the persistent attribute
     * <code>storeAuditEvents</code>.
     *
     * @return the value of storeAuditEvents.
     * @see #setPaStoreAuditEvents
     */
    protected abstract boolean getPaStoreAuditEvents();

    /**
     * The setter method for the persistent attribute
     * <code>storeAuditEvents</code>.
     *
     * @param newStoreAuditEvents the new value of storeAuditEvents.
     * @see #getPaStoreAuditEvents
     */
    protected abstract void setPaStoreAuditEvents(boolean newStoreAuditEvents);

    /**
     * Initializes the class, i.e. resets all attributes to default
     * values. Note that
     * {@link #refresh <code>refresh</code>} will be called subsequently.
     *
     * @see #dispose
     */
    protected void init () {
  setPaLastStateTime (new Date());
  setPaPriority (Priority.NORMAL);
  setPaDebug (false);
    }

    /**
     * Called after change of persistent attributes. May be used to
     * synchronise state derived from persistent attributes with
     * the new values.
     *
     * @see #init
     */
    protected void refresh () {
    }

    /**
     * Releases all allocated resources. The object will be in an
     * unusable state until resources are reallocated by calling
     * {@link #init <code>init</code>} and
     * {@link #refresh <code>refresh</code>}.
     */
    protected void dispose () {
    }

    //
    // Domain methods
    //

    /**
     * Returns a hash code value for this object.<P>
     *
     * Note that stubs do not in general implement
     * <code>hashCode</code> correctly, so even if two execution
     * objects are equal (<code>this.equals(obj)</code> is
     * <code>true</code>) <code>this.hashCode()</code> need not be
     * equal to <code>obj.hashCode()</code>.
     *
     * @return the hash code value.
     */
    public int hashCode () {
  try {
      return getPaKey().hashCode();
  } catch (NullPointerException e) {
      // workaround for jboss bug #634362
      return 1;
  }
    }

    /**
     * Returns the name of the execution object.
     * @return name of the execution object
     */
    public String name () {
  return getPaName();
    }

    /**
     * Set a new name of the execution object.
     * @param newValue new name.
     * @see #name
     */
    public void setName (String newValue) {
  setPaName (newValue);
    }

    /**
     * Returns the key of the execution object.
     * @return key of the execution object
     */
    public String key () {
  return getPaKey();
    }

    /**
     * Returns the description of the execution object.
     * @return description of the execution object
     */
    public String description () {
  return getPaDescription();
    }

    /**
     * Set a new description of the execution object.
     * @param newValue new description
     * @see #description
     */
    public void setDescription (String newValue) {
  setPaDescription (newValue);
    }

    /**
     * Updates process context of the execution object.
     * @param newValues the name-value pairs to be set.
     * @throws InvalidDataException If a name or value type does not match
     * the signature of this process.
     * @throws UpdateNotAllowedException If the update is not allowed.
     */
     public void setProcessContext (ProcessData newValues) throws
   InvalidDataException, UpdateNotAllowedException {
   throw new UpdateNotAllowedException("Not implemented.");
     }

    /**
     * Returns the priority of the execution object.
     * @return priority of the execution object
     */
    public int priority () {
  return getPaPriority().toInt();
    }
   
    /**
     * For the first iteration throws an
     * <code>UpdateNotAllowedException</code>.
     * @param newValue new priority
     * @throws InvalidPriorityException when the specified priority is out of
     * range.
     * @throws UpdateNotAllowedException when the priority cannot be updated.
     */
    public void setPriority (int newValue)
        throws InvalidPriorityException, UpdateNotAllowedException {
  setPaPriority (Priority.fromInt (newValue));
    }

    /**
     * Enable or disable debugging of the execution object.
     * @param debug if the execution object is to be debugged
     * @throws InvalidStateException if changing debug mode is not
     * allowed
     */
    public void setDebugEnabled (boolean debug) throws InvalidStateException {
  setPaDebug (debug);
    }

    /**
     * Checks if the execution object is in debugging mode.
     *
     * @return <code>true</code> if the execution object is in
     * debugging mode
     */
    public boolean debugEnabled () {
  return getPaDebug ();
    }

    //
    // state handling
    //

    /**
     * Returns the last state time of the execution object.
     * @return last state time of the execution object
     */
    public Date lastStateTime () {
  return getPaLastStateTime();
    }

    /**
     * Returns a list of all the valid states (as <code>State</code> objects)
     * that can be reached
     * from the current state. If there is no valid state, the collection
     * will be empty.
     * @return list of all the valid states
     */
    protected Collection validTypedStates () {
  Collection c = (Collection)getStateTransitionMap()
      .get(getPaTypedState());
  if (c == null) {
      return new ArrayList(0);
  }
  return c;
    }

    /**
     * Returns a list of all the valid states as strings that can be reached
     * from the current state. If there is no valid state, the collection
     * will be empty.
     * @return list of all the valid states
     */
    public Collection validStates () {
  Collection c = (Collection)getStateTransitionMap()
      .get(getPaTypedState());
  if (c == null) {
      return new ArrayList(0);
  }
  Collection cs = new ArrayList();
  for (Iterator i = c.iterator(); i.hasNext();) {
      cs.add(((State)i.next()).toString());
  }
  return cs;
    }

    /**
     * Returns the {@link java.util.Map <code>Map</code>} that maps
     * the execution object states to a {@link java.util.Map
     * <code>List</code>} of reachable process states. <P>
     *
     * The map returns the state transitions allowed as parameters of
     * {@link
     * de.danet.an.workflow.localcoreapi.WfExecutionObjectLocal#changeState
     * <code>changeState</code>} only. I.e. the map does not reflect
     * all possible transitions, there may be more, but those are only
     * accessible to the workflow engine itself.
     * @return the resulting map.
     */
    protected abstract Map getStateTransitionMap ();

    /**
     * Updates the current state of the execution object. As a result
     * the state of execution objects associated with this execution
     * object might be updated, too. This implementation effectively
     * calls {@link ExecutionObjectLocal#changeState
     * <code>changeState(State)</code>} after converting the argument
     * to <code>State</code>. Derived classes therefore only need to
     * override <code>changeState(State)</code>.
     *
     * @param newState State to change to.
     * @throws InvalidStateException If <code>newState</code> is an invalid
     * state for the execution object.
     * @throws TransitionNotAllowedException If the transition from the current
     * state to <code>newState</code> is not allowed.
     */
    public void changeState (String newState)
        throws InvalidStateException, TransitionNotAllowedException
  changeState (State.fromString (newState));
    }

    /**
     * Returns the internal state, i.e. the state represented as
     * <code>State</code> object.
     * @return internal state.
     * @see #updateState
     */
    public State typedState () {
  return getPaTypedState();
    }

    /**
     * Updates the current state of the execution object. As a result
     * the state of execution objects associated with this execution object
     * may be updated, too. This method uses
     * the <code>State</code> class to represent states.
     *
     * @param newState the new state.
     * @throws InvalidStateException If <code>newState</code> is an invalid
     * state for the execution object.
     * @throws TransitionNotAllowedException If the transition from the current
     * state to <code>newState</code> is not allowed.
     */
    public void changeState (State newState)
  throws InvalidStateException,
         TransitionNotAllowedException {
  try {
      if (newState.isSameOrSubState(NotRunningState.SUSPENDED)) {
    suspend ();
    return;
      }
      if (newState == OpenState.RUNNING) {
    resume ();
    return;
      }
      if (newState == ClosedState.TERMINATED) {
    terminate ();
    return;
      }
      if (newState == ClosedState.ABORTED) {
    abort ();
    return;
      }
  } catch (NotRunningException e) {
      throw new TransitionNotAllowedException
    (e.getClass().getName() + ": " + e.getMessage());
  } catch (InvalidControlOperationException e) {
      throw new TransitionNotAllowedException
    (e.getClass().getName() + ": " + e.getMessage());
  }
  throw new TransitionNotAllowedException
      (toString() + " from " + state() + " to " + newState.toString());
    }
   
    /**
     * Sets the state of this object. The method updates the last
     * state time and fires a state change event.
     *
     * @param newState new state.
     * @see #typedState
     */
    protected void updateState(State newState) {
  State oldState = getPaTypedState();
  setPaLastStateTime (new Date());
  setPaTypedState (newState);
        int auditSel = getPaAuditEventSelection();
        // base event information
  WfAuditEvent event = auditEventBase
            ((this instanceof AbstractProcess)
             ? WfAuditEvent.PROCESS_STATE_CHANGED
             : WfAuditEvent.ACTIVITY_STATE_CHANGED);
        // Now add general or specific information to the event. Note that we
        // must always fire a state audit event if a process closes (see below),
        // but we have to add result information only if the event is to be
        // published.
        if ((this instanceof AbstractProcess)
            && newState.isSameOrSubState(State.CLOSED)
            && (auditSel == ProcessDefinition.AUDIT_SELECTION_ALL_EVENTS
                || auditSel == ProcessDefinition
                                    .AUDIT_SELECTION_STATE_EVENTS_ONLY
                || auditSel == ProcessDefinition
                                .AUDIT_SELECTION_PROCESS_CLOSED_EVENTS_ONLY)) {
            try {
                event = new DefaultProcessClosedAuditEvent
                    (event, oldState.toString(), newState.toString(),
                     ((AbstractProcess)this).result());
            } catch (ResultNotAvailableException e) {
                // Cannot happen, see implementation
                logger.debug ("Unexpected exception: " + e.getMessage(), e);
            }
        } else {
            event = new DefaultStateAuditEvent
                (event, oldState.toString(), newState.toString());
        }
  // Note that process closed events
  // (case AUDIT_SELECTION_PROCESS_CLOSED_EVENTS_ONLY) are fired
  // because they are handled by the process
  if (auditSel == ProcessDefinition.AUDIT_SELECTION_ALL_EVENTS
      || auditSel==ProcessDefinition.AUDIT_SELECTION_STATE_EVENTS_ONLY
      || AbstractActivity.isHandled(event)
      || AbstractProcess.isHandled(event)) {
      fireAuditEvent (event);
  }
    }

    /**
     * Like {@link #updateState <code>updateState</code>} this method
     * sets the state of this object and fires a state change
     * event. The state change event will, however, not be fed back to
     * the engine, i.e. it will not lead to follow up activities and
     * the last state time will not be updated.<P>
     *
     * The method is intended to be used for an interim state change,
     * i.e. the caller knows that the state will change again before
     * the transaction is completed.
     *
     * @param newState new state.
     * @see #typedState
     */
    protected void updateInterim(State newState) {
        doUpdateNoFeedback(newState, false);
    }

    /**
     * Like {@link #updateState <code>updateState</code>} this method
     * sets the state of this object and fires a state change
     * event. The state change event will, however, not be fed back to
     * the engine, i.e. it will not lead to follow up activities.<P>
     *
     * The method is intended to be used in cases where the engine triggers
     * a state change itself and also performs all actions that are usually
     * done in the event handling method.
     *
     * @param newState new state.
     * @see #typedState
     */
    protected void updateImmediate(State newState) {
        doUpdateNoFeedback(newState, true);
    }

    private void doUpdateNoFeedback (State newState, boolean updateStateTime) {
        State oldState = getPaTypedState();
        setPaTypedState (newState);
        if (updateStateTime) {
            setPaLastStateTime (new Date());
        }
        int auditSel = getPaAuditEventSelection();
        if (auditSel == ProcessDefinition.AUDIT_SELECTION_ALL_EVENTS
            || auditSel==ProcessDefinition.AUDIT_SELECTION_STATE_EVENTS_ONLY) {
            fireAuditEvent
                (new DefaultStateAuditEvent
                 (auditEventBase
                  ((this instanceof AbstractProcess)
                   ? WfAuditEvent.PROCESS_STATE_CHANGED
                   : WfAuditEvent.ACTIVITY_STATE_CHANGED),
                  oldState.toString(), newState.toString(), true));
        }
    }
   
    /**
     * Returns the workflow state.
     * @return the workflow state.
     */
    public State workflowState () {
  return getPaTypedState().workflowState();
    }

    /**
     * Returns the workflow substate for open execution objects.
     * @return the workflow substate.
     */
    public State whileOpen () {
  return getPaTypedState().whileOpenState();
    }

    /**
     * Returns the workflow substate for open, not running
     * execution objects.
     * @return the workflow substate.
     */
    public State whyNotRunning () {
  return getPaTypedState().whyNotRunningState();
    }

    /**
     * Returns the workflow substate for closed
     * execution objects.
     * @return the workflow substate.
     */
    public State howClosed () {
  return getPaTypedState().howClosedState();
    }
   
    /**
     * Returns the string representation of the state.
     * @return string representation of the state.
     */
    public String state () {
  return getPaTypedState().toString();
    }

    /* Comment copied from Interface. */
    public void suspend () throws CannotSuspendException, NotRunningException,
  AlreadySuspendedException {
  if (typedState().isSameOrSubState(NotRunningState.SUSPENDED)) {
      throw new AlreadySuspendedException (toString());
  }
  if (!typedState().isSameOrSubState(OpenState.RUNNING)) {
      throw new NotRunningException (toString() + " is " + state());
  }
  if (!validTypedStates().contains (NotRunningState.SUSPENDED)) {
      throw new CannotSuspendException(toString() + " is " + state());
  }
  updateState (SuspendedState.SUSPENDED);
    }

    /* Comment copied from Interface. */
    public void resume ()
        throws CannotResumeException, NotRunningException,
            NotSuspendedException {
  if (!typedState().isSameOrSubState(OpenState.RUNNING)
      && !typedState().isSameOrSubState(SuspendedState.SUSPENDED)) {
      throw new NotRunningException (toString() + " is " + state());
  }
  if (!typedState().isSameOrSubState(NotRunningState.SUSPENDED)) {
      throw new NotSuspendedException (toString());
  }
  if (!validTypedStates().contains (OpenState.RUNNING)) {
      throw new CannotResumeException(toString() + " is " + state());
  }
  updateState (RunningState.RUNNING);
    }

    /* Comment copied from Interface. */
    public void terminate () throws CannotStopException, NotRunningException {
  throw new CannotStopException(toString() + " cannot be terminated.");
    }

    /* Comment copied from Interface. */
    public void abort () throws CannotStopException, NotRunningException {
  throw new CannotStopException(toString() + " cannot be aborted.");
    }

    /* Comment copied from Interface. */
    public abstract Collection history ()
  throws HistoryNotAvailableException;

    //
    // Audit handling
    //
 
    /**
     * Returns a <code>WfAuditEvent</code> containing information about the
     * execution object.
     * @param eventType event type
     * @return the event containing the required information.
     */
    protected abstract WfAuditEvent auditEventBase (String eventType);

    private static ThreadLocal queuingEvents
  = new ThreadLocal() {
    protected Object initialValue() {
        return Boolean.FALSE;
    }
      };
    private static ThreadLocal eventQueue
  = new ThreadLocal() {
    protected Object initialValue() {
        return new ArrayList();
    }
      };

    /**
     * Process newly generated event. This fall-back implementation
     * logs the event with level <code>DEBUG</code> and calls handlers
     * for state change events. If the event source is an
     * <code>AbstractProcess</code> its <code>handleAuditEvent</code>
     * is called. If the event source is an
     * <code>AbstractActivity</code> both the activity's and the
     * process' handler are called.<P>
     *
     * This implementation is mainly intended for unit tests on the
     * domain level. It must be overridden by the derived classes.
     *
     * @param event Event
     */
    protected void fireAuditEvent(WfAuditEvent event) {
  logger.debug (event.toString());
  List eq = (List)eventQueue.get();
  eq.add (event);
  if (((Boolean)queuingEvents.get()).booleanValue()) {
      return;
  }
  queuingEvents.set(Boolean.TRUE);
  while (eq.size() > 0) {
      event = (WfAuditEvent)eq.remove(0);
      if ((event instanceof WfStateAuditEvent)
    || (event instanceof ImplCompleteAuditEvent)) {
    try {
        WfExecutionObject eo = event.source();
        if (eo instanceof ExtProcess) {
      ((ExtProcess)eo).handleAuditEvent (event);
        } else if (eo instanceof ExtActivity) {
      ExtActivity aAct = (ExtActivity)eo;
      aAct.handleAuditEvent (event);
      if (!(event instanceof ImplCompleteAuditEvent)) {
          ((ExtProcess)aAct
           .container()).handleAuditEvent (event);
      }
        }
    } catch (SourceNotAvailableException e) {
        // can't do anything about this
        logger.error ("Event discarded: " + e.getMessage(), e);
    } catch (RemoteException e) {
        // shouldn't really happen on domain level
        logger.error (e.getMessage(), e);
    }
      }
  }
  queuingEvents.set(Boolean.FALSE);
    }

    /**
     * Handles the given audit event. The fall back implementation
     * simply calls
     * <code>AbstractExecutionObject.handleStateAuditEvent</code> if
     * the event source is this object and the event is a
     * <code>WfStateAuditEvent</code> or a
     * <code>ToolCompletedAuditEvent</code> .
     * @param event the event.
     * @ejb.interface-method view-type="remote"
     */
    public void handleAuditEvent (WfAuditEvent event) {
  if (logger.isDebugEnabled()) {
      logger.debug ("Got event: " + event.toString());
  }
  // Is this the target?
  if (event.activityKey() == null) {
      if (!(this instanceof AbstractProcess)
                || !event.processKey().equals(getPaKey())) {
          return;
      }
  } else {
      if (!(this instanceof AbstractActivity)
          || !event.activityKey().equals(getPaKey())) {
          return;
      }
  }
  if (event instanceof ToolInvocationFailedAuditEvent) {
      handleToolInvocationFailedAuditEvent
          ((ToolInvocationFailedAuditEvent)event);
      return;
  }
  if ((event instanceof WfStateAuditEvent)
      || (event instanceof ImplCompleteAuditEvent)) {
      handleStateAuditEvent (event);
  }
    }

    /**
     * Handles a tool invocation failed audit event. The default
     * implementation does nothing.
     * @param event the event.
     */
    protected void handleToolInvocationFailedAuditEvent
  (ToolInvocationFailedAuditEvent event) {
    }

    /**
     * Handles a state audit event, this includes
     * <code>ImplCompleteAuditEvent</code>s. This implementation
     * simply calls the appropriate handler method
     * <code>handle<i>Transition</i>Event</code>.
     * @param event the event.
     */
    protected void handleStateAuditEvent (WfAuditEvent event) {
  try {
      if (event instanceof ImplCompleteAuditEvent) {
    handleImplCompletedEvent ((ImplCompleteAuditEvent)event);
    return;
      }
      WfStateAuditEvent evt = (WfStateAuditEvent)event;
      State oldState = State.fromString (evt.oldState());
      State newState = State.fromString (evt.newState());
      if (oldState.isSameOrSubState(NotRunningState.NOT_STARTED)) {
    if (newState == RunningState.RUNNING) {
        handleStartedEvent (evt);
        return;
    }
    if (newState == ClosedState.TERMINATED) {
        handleTerminatedEvent (evt);
        return;
    }
      } else if (oldState.isSameOrSubState(NotRunningState.SUSPENDED)) {
    if (newState == RunningState.RUNNING) {
        handleResumedEvent (evt);
        return;
    }
    if (newState == ClosedState.ABORTED) {
        handleAbortedEvent (evt);
        return;
    }
      } else if (oldState.isSameOrSubState(OpenState.RUNNING)) {
    if (newState == SuspendedState.SUSPENDED) {
        handleSuspendedEvent (evt);
        return;
    }   
    if (newState == ClosedCompletedState.NORMAL) {
        handleCompletedEvent (evt);
        return;
    }   
    if (newState == ClosedState.TERMINATED) {
        handleTerminatedEvent (evt);
        return;
    }   
      }
      logger.warn
    ("Cannot handle undefined state transition from "
     + oldState.toString() + " to " + newState.toString()
                 + " for " + this);
  } catch (InvalidStateException e) {
      // can't do much about this, shouldn't happen
      logger.error (e.getMessage(), e);
  }
    }   

    /**
     * Handles a tool completed audit event. The default
     * implementation does nothing.
     * @param event the event.
     */
    protected void handleImplCompletedEvent (ImplCompleteAuditEvent event) {
    }

    /**
     * Handles a started audit event. The default
     * implementation does nothing.
     * @param event the event.
     */
    protected void handleStartedEvent (WfStateAuditEvent event) {
    }

    /**
     * Handles a terminated audit event. The default
     * implementation does nothing.
     * @param event the event.
     */
    protected void handleTerminatedEvent (WfStateAuditEvent event) {
    }

    /**
     * Handles a resumed audit event. The default
     * implementation does nothing.
     * @param event the event.
     */
    protected void handleResumedEvent (WfStateAuditEvent event) {
    }

    /**
     * Handles a aborting audit event. The default
     * implementation does nothing.
     * @param event the event.
     */
    protected void handleAbortedEvent (WfStateAuditEvent event) {
    }

    /**
     * Handles a suspended audit event. The default
     * implementation does nothing.
     * @param event the event.
     */
    protected void handleSuspendedEvent (WfStateAuditEvent event) {
    }

    /**
     * Handles a completed audit event. The default
     * implementation does nothing.
     * @param event the event.
     */
    protected void handleCompletedEvent (WfStateAuditEvent event) {
    }

}
TOP

Related Classes of de.danet.an.workflow.domain.AbstractExecutionObject

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.