All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.bonita.pvm.internal.model.ExceptionHandlerImpl Maven / Gradle / Ivy

/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.ow2.bonita.pvm.internal.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.ow2.bonita.env.Environment;
import org.ow2.bonita.env.Transaction;
import org.ow2.bonita.pvm.internal.cmd.CommandService;
import org.ow2.bonita.pvm.internal.model.op.MoveToChildNode;
import org.ow2.bonita.pvm.internal.wire.Descriptor;
import org.ow2.bonita.pvm.listener.EventListener;
import org.ow2.bonita.pvm.model.OpenProcessDefinition;
import org.ow2.bonita.util.BonitaRuntimeException;
import org.ow2.bonita.util.ExceptionManager;
import org.ow2.bonita.util.Log;

/**
 * @author Tom Baeyens
 */
public class ExceptionHandlerImpl implements Serializable {

  private static final long serialVersionUID = 1L;
  static final Log log = Log.getLog(ExceptionHandlerImpl.class.getName());

  protected long dbid;
  protected int dbversion;
  protected String exceptionClassName;
  protected boolean isTransactional;
  protected boolean isRethrowMasked;
  protected List> eventListenerReferences;
  protected String transitionName; // mutually exclusive with nodeName
  protected String nodeName; // mutually exclusive with transitionName

  // construction methods /////////////////////////////////////////////////////

  public ObjectReference createEventListenerReference(
      EventListener eventListener) {
    ObjectReference eventListenerReference = createEventListenerReference();
    eventListenerReference.set(eventListener);
    return eventListenerReference;
  }

  public ObjectReference createEventListenerReference(
      Descriptor descriptor) {
    ObjectReference eventListenerReference = createEventListenerReference();
    eventListenerReference.setDescriptor(descriptor);
    return eventListenerReference;
  }

  public ObjectReference createActivityReference(
      String expression) {
    ObjectReference eventListenerReference = createEventListenerReference();
    eventListenerReference.setExpression(expression);
    return eventListenerReference;
  }

  public ObjectReference createEventListenerReference() {
    if (eventListenerReferences == null) {
      eventListenerReferences = new ArrayList>();
    }
    ObjectReference actionObjectReference = new ObjectReference();
    eventListenerReferences.add(actionObjectReference);
    return actionObjectReference;
  }

  public List getEventListeners() {
    if (eventListenerReferences == null) {
      return null;
    }
    List eventListeners = new ArrayList(
        eventListenerReferences.size());
    for (ObjectReference eventListenerReference : eventListenerReferences) {
      EventListener eventListener = eventListenerReference.get();
      eventListeners.add(eventListener);
    }
    return eventListeners;
  }

  // runtime behaviour methods ////////////////////////////////////////////////

  public boolean matches(Exception exception) {
    return matches(exception.getClass());
  }

  public boolean matches(Class exceptionClass) {
    if (exceptionClass == null) {
      return false;
    }
    if ((exceptionClassName == null)
        || (exceptionClass.getName().equals(exceptionClassName))) {
      return true;
    }
    Class superClass = exceptionClass.getSuperclass();
    if (superClass != null) {
      return matches(superClass);
    }
    return false;
  }

  public void handle(ExecutionImpl execution, Exception exception) {
    if (isTransactional) {
      Environment environment = Environment.getCurrent();
      Transaction transaction = (environment != null ? environment
          .get(Transaction.class) : null);
      if (transaction != null) {
        log.trace("registering exception handler to " + transaction);
        CommandService commandService = environment.get(CommandService.class);
        if (commandService == null) {
        	String message = ExceptionManager.getInstance().getFullMessage("bp_EHI_1");
          throw new BonitaRuntimeException(message, exception);
        }
        ExceptionHandlerSynchronization exceptionHandlerSynchronization = new ExceptionHandlerSynchronization(
            this, execution, exception, commandService);
        // registration of the synchronization is delegated to the
        // AfterTxCompletionListener
        // to avoid a dependency on class Synchronization
        exceptionHandlerSynchronization.register(transaction);
        log.trace("registering exception handler to " + transaction);
        String message = ExceptionManager.getInstance().getFullMessage("bp_EHI_2");
        throw new BonitaRuntimeException(message, exception);
      } else {
      	String message = ExceptionManager.getInstance().getFullMessage("bp_EHI_3");
        throw new BonitaRuntimeException(message, exception);
      }
    } else {
      executeHandler(execution, exception);
    }
  }

  void executeHandler(ExecutionImpl execution, Exception exception) {
    if (eventListenerReferences != null) {
      for (ObjectReference eventListenerReference : eventListenerReferences) {

        EventListener eventListener = eventListenerReference.get();

        log.trace("executing " + eventListener + " for " + this);
        try {
          eventListener.notify(execution);
        } catch (RuntimeException e) {
          throw e;
        } catch (Exception e) {
        	String message = ExceptionManager.getInstance().getFullMessage("bp_EHI_4");
          throw new BonitaRuntimeException(message, e);
        }
      }
    }

    if (transitionName != null) {
      NodeImpl node = execution.getNode();
      if (node == null) {
        // If the execution is not positioned in a node, it must be
        // positioned in a transition. In that case we check if the
        // transition is present on the enclosing node.

        // The weird way of getting checking and fetching the parent node
        // is because hibernate doesn't support instanceof. The
        // transition-->parent
        // relation is mapped as a ProcessElementImpl. So we can't cast it to
        // a NodeImpl. Ouch.
        // The workaround is to check if the parent is equal to the
        // process definition. If that is not the case, we can be sure
        // that the parent is a node. In that case we look up the node
        // from the process definition by name. OuchOuchSquare :-)

        TransitionImpl transition = execution.getTransition();
        log.trace("no current node.  searching for transition from parent of "
            + transition);
        if (transition != null) {
          OpenProcessDefinition processDefinition = transition
              .getProcessDefinition();
          ObservableElementImpl transitionParent = transition.getParent();

          if ((transitionParent != null)
              && (!transitionParent.equals(processDefinition))) {
            node = (NodeImpl) processDefinition.findNode(transitionParent
                .getName());
          }
        }
      }

      if (node != null) {
        TransitionImpl transition = node.findOutgoingTransition(transitionName);
        if (transition != null) {
          log.trace(toString() + " takes transition " + transitionName);
          execution.setTransition(transition);
          execution.performAtomicOperationSync(ExecutionImpl.TAKE_TRANSITION);
        } else {
          log.info("WARNING: " + toString() + " couldn't find transition "
              + transitionName + " on " + node);
        }
      } else {
        log.info("WARNING: " + toString()
            + " couldn't find current node to take transition "
            + transitionName);
      }

    } else if (nodeName != null) {
      // execute child node
      NodeImpl node = execution.getNode();
      NodeImpl childNode = (node != null ? node.getNode(nodeName) : null);
      if (childNode != null) {
        log.trace(toString() + " takes transition " + transitionName);
        execution.performAtomicOperationSync(new MoveToChildNode(childNode));
      } else {
        log.info("WARNING: " + toString() + " couldn't find child node "
            + nodeName);
      }
    }
  }

  public static void rethrow(Exception exception, String prefixMessage) {
    log.trace("rethrowing " + exception);
    if (exception instanceof RuntimeException) {
      throw (RuntimeException) exception;
    } else {
    	String message = ExceptionManager.getInstance().getFullMessage(
    			"bp_EHI_5", prefixMessage, exception.getMessage());
      throw new BonitaRuntimeException(message, exception);
    }
  }

  public String toString() {
    return (exceptionClassName != null ? "exception-handler("
        + exceptionClassName + ")" : "exception-handler");
  }

  // getters and setters //////////////////////////////////////////////////////

  public long getDbid() {
    return dbid;
  }

  public String getExceptionClassName() {
    return exceptionClassName;
  }

  public void setExceptionClassName(String exceptionClassName) {
    this.exceptionClassName = exceptionClassName;
  }

  public boolean isTransactional() {
    return isTransactional;
  }

  public void setTransactional(boolean isTransactional) {
    this.isTransactional = isTransactional;
  }

  public String getTransitionName() {
    return transitionName;
  }

  public void setTransitionName(String transitionName) {
    this.transitionName = transitionName;
  }

  public String getNodeName() {
    return nodeName;
  }

  public void setNodeName(String nodeName) {
    this.nodeName = nodeName;
  }

  public boolean isRethrowMasked() {
    return isRethrowMasked;
  }

  public void setRethrowMasked(boolean isRethrowMasked) {
    this.isRethrowMasked = isRethrowMasked;
  }

  public List> getEventListenerReferences() {
    return eventListenerReferences;
  }

  public void setEventListenerReferences(
      List> activityReferences) {
    this.eventListenerReferences = activityReferences;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy