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

org.jboss.bpm.ri.model.impl.FlowObjectImpl Maven / Gradle / Ivy

The newest version!
/*
 * 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.jboss.bpm.ri.model.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.jboss.bpm.InvalidProcessException;
import org.jboss.bpm.NameNotUniqueException;
import org.jboss.bpm.model.Assignment;
import org.jboss.bpm.model.ConnectingObject;
import org.jboss.bpm.model.Expression;
import org.jboss.bpm.model.FlowObject;
import org.jboss.bpm.model.Gate;
import org.jboss.bpm.model.Gateway;
import org.jboss.bpm.model.Process;
import org.jboss.bpm.model.SingleInFlowSupport;
import org.jboss.bpm.model.SingleOutFlowSupport;
import org.jboss.bpm.model.Assignment.AssignTime;
import org.jboss.bpm.runtime.ExecutionContext;
import org.jboss.bpm.runtime.ExecutionHandler;
import org.jboss.bpm.runtime.FlowHandler;
import org.jboss.bpm.runtime.SignalHandler;
import org.jboss.bpm.runtime.Token;
import org.jboss.bpm.runtime.TokenExecutor;

//$Id: FlowObjectImpl.java 1982 2008-08-22 10:09:27Z [email protected] $

/**
 * A Flow Object is one of the set of following graphical objects: Event, Activity, and 
 * 
 * @author [email protected]
 * @since 08-Jul-2008
 */
@SuppressWarnings("serial")
public abstract class FlowObjectImpl extends GraphicalElementImpl implements FlowObject, HandlerSetterSupport
{
  private String name;
  private Process proc;
  private FlowHandler flowHandler;
  private SignalHandler signalHandler;
  private ExecutionHandler executionHandler;
  private List assignments = new ArrayList();

  public FlowObjectImpl(String name)
  {
    this.name = name;
  }

  public Process getProcess()
  {
    return proc;
  }

  public String getName()
  {
    return name;
  }

  public void setName(String name)
  {
    this.name = name;
  }

  public List getAssignments()
  {
    return Collections.unmodifiableList(assignments);
  }

  public void addAssignment(Assignment assignment)
  {
    this.assignments.add(assignment);
  }

  public ExecutionHandler getExecutionHandler()
  {
    return executionHandler;
  }

  public void setExecutionHandler(ExecutionHandler executionHandler)
  {
    this.executionHandler = executionHandler;
  }

  public FlowHandler getFlowHandler()
  {
    return flowHandler;
  }

  public void setFlowHandler(FlowHandler flowHandler)
  {
    this.flowHandler = flowHandler;
  }

  public SignalHandler getSignalHandler()
  {
    return signalHandler;
  }

  public void setSignalHandler(SignalHandler signalHandler)
  {
    this.signalHandler = signalHandler;
  }

  /**
   * Execute this FlowObject
   */
  public void execute(Token token)
  {
    // Process the start time assignments
    startTimeAssignments(token);

    // Call the ExecutionHandler
    ExecutionHandler exHandler = getExecutionHandler();
    if (exHandler != null)
    {
      exHandler.execute(token);
    }
    else
    {
      defaultExecution(token);
    }

    // Process the end time assignments
    endTimeAssignments(token);
  }

  protected void startTimeAssignments(Token token)
  {
    for (Assignment ass : getAssignments())
    {
      if (ass.getAssignTime() == AssignTime.Start)
        processAssignment(ass, token);
    }
  }

  protected void endTimeAssignments(Token token)
  {
    for (Assignment ass : getAssignments())
    {
      if (ass.getAssignTime() == AssignTime.End)
        processAssignment(ass, token);
    }
  }
  
  protected void processAssignment(Assignment ass, Token token)
  {
    Expression expr = ass.getFrom();
    ExpressionEvaluator exprEvaluator = new ExpressionEvaluator(expr);
    Object result = exprEvaluator.evaluateExpression(token);
    String propName = ass.getTo().getName();
    ExecutionContext exContext = token.getExecutionContext();
    exContext.addAttachment(propName, result);
  }

  /**
   * Execute the FlowHandler. Keep final, it should not be necessary to override this.
   */
  public final void executeFlowHandler(TokenExecutor tokenExecutor, Token token)
  {
    // Call the ExecutionHandler
    FlowHandler flowHandler = getFlowHandler();
    if (flowHandler != null)
    {
      flowHandler.execute(tokenExecutor, token);
    }
    else
    {
      defaultFlowHandler(tokenExecutor, token);
    }
  }

  /**
   * Overwrite to provide an implementation
   */
  protected void defaultExecution(Token token)
  {
    // noting to do
  }

  /**
   * Overwrite to provide an implementation
   */
  protected abstract void defaultFlowHandler(TokenExecutor tokenExecutor, Token token);

  /**
   * Reset the FlowObject's state
   */
  public void reset()
  {
    // noting to do
  }

  @Override
  protected void create(Process proc)
  {
    super.create(proc);
    this.proc = proc;

    // Check required name
    if (name == null)
      throw new InvalidProcessException("Name is required for: " + this);

    // Check name uniqueness
    for (FlowObject aux : proc.getFlowObjects())
    {
      String auxName = aux.getName();
      if (aux != this && name.equals(auxName))
        throw new NameNotUniqueException(toString());
    }

    // Initialize in/out flows
    ConnectingObject outFlow = null;
    if (this instanceof SingleOutFlowSupport)
    {
      SingleOutFlowSupport sof = (SingleOutFlowSupport)this;
      outFlow = sof.getOutFlow();
      initFlow(proc, (SequenceFlowImpl)outFlow);
    }
    else if (this instanceof MultipleOutFlowSupport)
    {
      MultipleOutFlowSupport mof = (MultipleOutFlowSupport)this;
      for (ConnectingObject flow : mof.getOutFlows())
      {
        outFlow = flow;
        initFlow(proc, (SequenceFlowImpl)outFlow);
      }
    }
    else if (this instanceof Gateway)
    {
      Gateway gateway = (Gateway)this;
      for (Gate gate : gateway.getGates())
      {
        outFlow = gate.getOutgoingSequenceFlow();
        initFlow(proc, (SequenceFlowImpl)outFlow);
      }
    }

    ConnectingObject inFlow = null;
    if (this instanceof SingleInFlowSupport)
    {
      SingleInFlowSupport sif = (SingleInFlowSupport)this;
      inFlow = sif.getInFlow();
    }
    else if (this instanceof MultipleInFlowSupport)
    {
      MultipleInFlowSupport mif = (MultipleInFlowSupport)this;
      for (ConnectingObject flow : mif.getInFlows())
      {
        inFlow = flow;
      }
    }

    if (inFlow == null && outFlow == null)
      throw new InvalidProcessException("Unconnected flow object: " + this);
  }

  private void initFlow(Process proc, SequenceFlowImpl flow)
  {
    if (flow != null)
    {
      String name = flow.getTargetName();
      FlowObject target = proc.getFlowObject(name);
      if (target == null)
        throw new InvalidProcessException("Cannot find target for out flow: " + name);

      if (target instanceof SingleInFlowSetterSupport)
      {
        SingleInFlowSetterSupport sif = (SingleInFlowSetterSupport)target;
        sif.setInFlow(flow);
      }
      else if (target instanceof MultipleInFlowSetterSupport)
      {
        MultipleInFlowSetterSupport mif = (MultipleInFlowSetterSupport)target;
        mif.addInFlow(flow);
      }
      else
      {
        throw new InvalidProcessException("Target does not support in flow: " + target);
      }

      flow.setSourceRef(this);
      flow.setTargetRef(target);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy