org.jboss.bpm.ri.model.impl.ProcessImpl 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;
//$Id: ProcessImpl.java 1983 2008-08-22 11:12:51Z [email protected] $
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.management.ObjectName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.bpm.InvalidProcessException;
import org.jboss.bpm.NotImplementedException;
import org.jboss.bpm.client.ExecutionManager;
import org.jboss.bpm.client.ProcessManager;
import org.jboss.bpm.model.Assignment;
import org.jboss.bpm.model.Constants;
import org.jboss.bpm.model.EndEvent;
import org.jboss.bpm.model.FlowObject;
import org.jboss.bpm.model.InputSet;
import org.jboss.bpm.model.Message;
import org.jboss.bpm.model.MutablePropertySupport;
import org.jboss.bpm.model.ObjectNameFactory;
import org.jboss.bpm.model.OutputSet;
import org.jboss.bpm.model.Process;
import org.jboss.bpm.model.Property;
import org.jboss.bpm.model.StartEvent;
import org.jboss.bpm.runtime.Attachments;
import org.jboss.util.id.UID;
/**
* A Process is any Activity performed within a company or organization.
*
* @author [email protected]
* @since 08-Jul-2008
*/
@SuppressWarnings("serial")
public class ProcessImpl extends SupportingElementImpl implements Process, MutablePropertySupport
{
// provide logging
private static final Log log = LogFactory.getLog(ProcessImpl.class);
// The required process name
private String name;
// The list of associated flow objects
private List flowObjects = new ArrayList();
// The list of associated messages
private List messages = new ArrayList();
// The process properties
private List props = new ArrayList();
// The process assignments
private List assignments = new ArrayList();
// the status of the process
private ProcessStatus status = ProcessStatus.None;
// The possible exception that caused the process to abort
private RuntimeException runtimeException;
@Override
public ObjectName getID()
{
if (id == null)
{
StringBuilder str = new StringBuilder(Constants.ID_DOMAIN + ":");
str.append("type=Process,name=" + getName() + ",id=" + new UID());
id = ObjectNameFactory.create(str.toString());
}
return id;
}
public ProcessImpl(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public List getAssignments()
{
return Collections.unmodifiableList(assignments);
}
public void addAssignment(AssignmentImpl assignment)
{
this.assignments.add(assignment);
}
public List getInputSets()
{
throw new NotImplementedException("JBPM-1644", "Process InputSets");
}
public List getOutputSets()
{
throw new NotImplementedException("JBPM-1645", "Process OutputSets");
}
public List getPerformers()
{
throw new NotImplementedException("JBPM-1646", "Process Performers");
}
public Process.ProcessType getProcessType()
{
throw new NotImplementedException("JBPM-1647", "Process Type");
}
public Property getProperty(String name)
{
for (Property prop : props)
{
if (prop.getName().equals(name))
return prop;
}
return null;
}
public Object getPropertyValue(String name)
{
Property prop = getProperty(name);
return prop != null ? prop.getValue() : null;
}
public T getPropertyValue(Class clazz, String name)
{
Property prop = getProperty(name);
return prop != null ? prop.getValue(clazz) : null;
}
public List getProperties()
{
return Collections.unmodifiableList(props);
}
public List getPropertyNames()
{
List names = new ArrayList();
for (Property prop : props)
{
names.add(prop.getName());
}
return names;
}
public void addProperty(Property prop)
{
props.add(prop);
}
public void addFlowObject(FlowObject flowObject)
{
flowObjects.add(flowObject);
}
public RuntimeException getRuntimeException()
{
return runtimeException;
}
public void setRuntimeException(RuntimeException rte)
{
this.runtimeException = rte;
setProcessStatus(ProcessStatus.Aborted);
}
public List getFlowObjects()
{
if (status == ProcessStatus.None)
return flowObjects;
return Collections.unmodifiableList(flowObjects);
}
public ObjectName startProcess()
{
return startProcessInternal(null);
}
public ObjectName startProcess(Attachments att)
{
return startProcessInternal(att);
}
private ObjectName startProcessInternal(Attachments att)
{
ExecutionManager em = ExecutionManager.locateExecutionManager();
em.startProcess(this, att);
return getID();
}
public void resetProcess()
{
log.debug("Reset process: " + this);
for (FlowObject fo : flowObjects)
{
FlowObjectImpl foImpl = (FlowObjectImpl)fo;
foImpl.reset();
}
status = ProcessStatus.Ready;
runtimeException = null;
}
public ProcessStatus waitForEnd()
{
return waitForEndInternal(0);
}
public ProcessStatus waitForEnd(long timeout)
{
return waitForEndInternal(timeout);
}
/**
* Wait for the Process to end. All Tokens that are generated at the Start Event for that Process must eventually
* arrive at an End Event. The Process will be in a running state until all Tokens are consumed. If the process was
* aborted this method throws the causing RuntimeException if avaialable.
*/
private ProcessStatus waitForEndInternal(long timeout)
{
ExecutionManager em = ExecutionManager.locateExecutionManager();
return em.waitForEnd(this, timeout);
}
public FlowObject getFlowObject(String name)
{
if (name == null)
throw new IllegalArgumentException("Cannot find flow object with name: null");
FlowObject flowObject = null;
for (FlowObject aux : flowObjects)
{
if (name.equals(aux.getName()))
{
flowObject = aux;
break;
}
}
return flowObject;
}
@SuppressWarnings("unchecked")
public List getFlowObjects(Class clazz)
{
List retFlowObjects = new ArrayList();
for (FlowObject fo : flowObjects)
{
if (clazz.isAssignableFrom(fo.getClass()))
retFlowObjects.add((T)fo);
}
return retFlowObjects;
}
public synchronized ProcessStatus getProcessStatus()
{
return status;
}
public synchronized void setProcessStatus(ProcessStatus status)
{
this.status = status;
}
public List getMessages()
{
return Collections.unmodifiableList(messages);
}
public void addMessage(Message msg)
{
if (getMessage(msg.getName()) != null)
throw new InvalidProcessException("Duplicate message: " + msg);
messages.add(msg);
}
public Message getMessage(String msgName)
{
for (Message msg : messages)
{
if (msg.getName().equals(msgName))
return msg;
}
return null;
}
@Override
public void create(Process proc)
{
if (status != ProcessStatus.None)
throw new IllegalStateException("Cannot initialize process in state: " + status);
// Initialize the Element
super.create(this);
// Set the anonymous default name
if (getName() == null)
{
ProcessManager pm = ProcessManager.locateProcessManager();
this.name = "AnonymousProcess#" + pm.getProcesses().size();
}
if (getFlowObjects(StartEvent.class).size() == 0)
throw new InvalidProcessException("Process does not have a start event");
if (getFlowObjects(EndEvent.class).size() == 0)
throw new InvalidProcessException("Process does not have end events");
// Initialize the flow objects
for (FlowObject fo : flowObjects)
{
FlowObjectImpl foImpl = (FlowObjectImpl)fo;
foImpl.create(this);
}
status = ProcessStatus.Ready;
}
@Override
public void register(Process proc)
{
super.register(proc);
for (FlowObject fo : flowObjects)
{
FlowObjectImpl foImpl = (FlowObjectImpl)fo;
foImpl.register(this);
}
}
@Override
public void unregister(Process proc)
{
for (FlowObject fo : flowObjects)
{
FlowObjectImpl foImpl = (FlowObjectImpl)fo;
foImpl.unregister(this);
}
super.unregister(proc);
}
@Override
public void destroy(Process proc)
{
for (FlowObject fo : flowObjects)
{
FlowObjectImpl foImpl = (FlowObjectImpl)fo;
foImpl.destroy(this);
}
super.destroy(proc);
}
protected void initializeMessageRef(Message msgRef)
{
String msgName = msgRef.getName();
MessageImpl procMsg = (MessageImpl)getMessage(msgName);
if (procMsg == null)
throw new IllegalStateException("Cannot obtain process message: " + msgName);
MessageImpl msgImpl = (MessageImpl)msgRef;
if (msgImpl.getFromRef() == null && procMsg.getFromRef() != null)
msgImpl.setFromRef(procMsg.getFromRef());
if (msgImpl.getToRef() == null && procMsg.getToRef() != null)
msgImpl.setToRef(procMsg.getToRef());
for (Property prop : procMsg.getProperties())
((MessageImpl)msgRef).addProperty(prop);
}
public String toString()
{
return "Process[" + getName() + ",status=" + getProcessStatus() + "]";
}
}