
org.ow2.bonita.util.ProcessUtil Maven / Gradle / Ivy
The newest version!
/**
* Copyright (C) 2009-2013 BonitaSoft S.A.
* BonitaSoft, 31 rue Gustave Eiffel - 38000 Grenoble
* This library 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
* version 2.1 of the License.
* This library 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
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.
**/
package org.ow2.bonita.util;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.ow2.bonita.definition.activity.ConnectorExecutor;
import org.ow2.bonita.deployment.DeploymentRuntimeException;
import org.ow2.bonita.facade.def.InternalProcessDefinition;
import org.ow2.bonita.facade.def.element.AttachmentDefinition;
import org.ow2.bonita.facade.def.element.EventDefinition;
import org.ow2.bonita.facade.def.element.HookDefinition;
import org.ow2.bonita.facade.def.element.IncomingEventDefinition;
import org.ow2.bonita.facade.def.majorElement.ActivityDefinition;
import org.ow2.bonita.facade.def.majorElement.EventProcessDefinition;
import org.ow2.bonita.facade.exception.DocumentAlreadyExistsException;
import org.ow2.bonita.facade.exception.DocumentNotFoundException;
import org.ow2.bonita.facade.exception.DocumentationCreationException;
import org.ow2.bonita.facade.exception.ProcessNotFoundException;
import org.ow2.bonita.facade.impl.FacadeUtil;
import org.ow2.bonita.facade.runtime.InitialAttachment;
import org.ow2.bonita.facade.runtime.ProcessInstance;
import org.ow2.bonita.facade.runtime.impl.InternalProcessInstance;
import org.ow2.bonita.facade.uuid.ActivityDefinitionUUID;
import org.ow2.bonita.facade.uuid.ActivityInstanceUUID;
import org.ow2.bonita.facade.uuid.ProcessDefinitionUUID;
import org.ow2.bonita.facade.uuid.ProcessInstanceUUID;
import org.ow2.bonita.runtime.event.EventConstants;
import org.ow2.bonita.runtime.event.EventInstance;
import org.ow2.bonita.runtime.event.IncomingEventInstance;
import org.ow2.bonita.runtime.event.Job;
import org.ow2.bonita.runtime.event.JobBuilder;
import org.ow2.bonita.runtime.model.Execution;
import org.ow2.bonita.services.Document;
import org.ow2.bonita.services.DocumentationManager;
import org.ow2.bonita.services.EventService;
import org.ow2.bonita.services.Recorder;
import org.ow2.bonita.type.Variable;
/**
*
* @author Charles Souillard, Matthieu Chaffotte
*
*/
public class ProcessUtil {
static final Logger LOG = Logger.getLogger(ProcessUtil.class.getName());
public static void removeAllInstanceEvents(final ProcessInstance instance) {
final EventService eventService = EnvTool.getEventService();
eventService.removeSubscriptions(instance.getUUID());
eventService.removeFiredEvents(instance.getUUID());
eventService.removeJobs(instance.getUUID());
eventService.removeLock(instance.getRootInstanceUUID());
}
public static void removeInternalInstanceEvents(final ProcessInstanceUUID instanceUUID) {
final EventService eventService = EnvTool.getEventService();
eventService.removeSubscriptions(instanceUUID);
eventService.removeJobs(instanceUUID);
eventService.removeLock(instanceUUID);
}
public static Date getTimerDate(final String condition, final ProcessDefinitionUUID definitionUUID,
final long lastTime) throws GroovyException {
return getTimerDate(condition, definitionUUID, null, lastTime);
}
public static Date getTimerDate(final String condition, final ActivityInstanceUUID activityUUID)
throws GroovyException {
return getTimerDate(condition, null, activityUUID, 0);
}
private static Date getTimerDate(final String condition, final ProcessDefinitionUUID definitionUUID,
final ActivityInstanceUUID activityUUID, final long lastTime) throws GroovyException {
Misc.checkArgsNotNull(condition);
Date dueDate = null;
String evaluatedCondition = condition;
if (Misc.isJustAGroovyExpression(condition)) {
Object value = null;
if (activityUUID != null) {
value = GroovyUtil.evaluate(condition, null, activityUUID, false, false);
} else {
final Map context = new HashMap();
context.put(BonitaConstants.TIMER_LAST_EXECUTION, lastTime);
value = GroovyUtil.evaluate(condition, context, definitionUUID, false);
}
if (value instanceof Date) {
dueDate = (Date) value;
} else {
if (value instanceof String) {
evaluatedCondition = (String) value;
} else if (value instanceof Long) {
evaluatedCondition = ((Long) value).toString();
} else if (value instanceof Integer) {
evaluatedCondition = ((Integer) value).toString();
}
}
}
if (dueDate == null) {
try {
final Long date = Long.parseLong(evaluatedCondition);
if (activityUUID != null) {
dueDate = new Date(System.currentTimeMillis() + date);
} else if (lastTime < 0) {
dueDate = new Date(System.currentTimeMillis() + date);
} else {
dueDate = new Date(date);
}
} catch (final NumberFormatException e1) {
try {
dueDate = DateUtil.parseDate(evaluatedCondition);
} catch (final IllegalArgumentException e2) {
throw new BonitaRuntimeException("Timer condition '" + evaluatedCondition
+ "' is neither a Long nor a formatted date", e2);
}
}
}
return dueDate;
}
public static Execution createProcessInstance(final ProcessDefinitionUUID processUUID,
final Map variables, final Collection attachments,
final ProcessInstanceUUID parentInstanceUUID, final ProcessInstanceUUID rootInstanceUUID,
final ActivityDefinitionUUID activityUUID, final ActivityInstanceUUID parentActivityUUID)
throws ProcessNotFoundException {
final InternalProcessDefinition process = FacadeUtil.getProcessDefinition(processUUID);
final Execution rootExecution = createProcessInstance(process, rootInstanceUUID);
final InternalProcessInstance instance = rootExecution.getInstance();
final Recorder recorder = EnvTool.getRecorder();
final Map givenVariables = VariableUtil.createVariableMap(processUUID, variables);
final Map processVariables = VariableUtil.createVariables(process.getDataFields(), null,
variables);
final Map initialVariables = new HashMap();
if (processVariables != null) {
initialVariables.putAll(processVariables);
}
if (givenVariables != null) {
initialVariables.putAll(givenVariables);
}
instance.setParentUUIDs(parentInstanceUUID, parentActivityUUID);
instance.setInitialVaribales(initialVariables);
String initiator = EnvTool.getUserId();
if (parentInstanceUUID != null) {
final InternalProcessInstance parentInstance = EnvTool.getJournalQueriers()
.getProcessInstance(parentInstanceUUID);
initiator = parentInstance.getStartedBy();
}
final DocumentationManager manager = EnvTool.getDocumentationManager();
final Set runtimeAttachmentNames = new HashSet();
if (attachments != null) {
for (final InitialAttachment attachment : attachments) {
final Document createDocument;
try {
final byte[] content = attachment.getContent();
if (content != null) {
String mimeType = attachment.getMetaData().get("content-type");
if (mimeType == null) {
mimeType = DocumentService.DEFAULT_MIME_TYPE;
}
createDocument = manager.createDocument(attachment.getName(), processUUID, instance.getUUID(),
attachment.getFileName(), mimeType, content);
} else {
createDocument = manager.createDocument(attachment.getName(), processUUID, instance.getUUID());
}
if (rootInstanceUUID != null && !rootInstanceUUID.equals(instance.getUUID())) {
final InternalProcessInstance rootProcessInstance = FacadeUtil.getInstance(rootInstanceUUID, null);
if (rootProcessInstance != null && rootProcessInstance.getProcessDefinitionUUID() != null) {
try {
final long nbOfDocuments = manager.getNbOfDocuments(rootProcessInstance.getProcessInstanceUUID(),
createDocument.getName());
if (nbOfDocuments == 0) {
manager.attachDocumentTo(rootProcessInstance.getProcessDefinitionUUID(), rootInstanceUUID,
createDocument.getId());
}
} catch (final DocumentNotFoundException e) {
throw new BonitaRuntimeException(e);
}
}
}
} catch (final DocumentAlreadyExistsException e) {
throw new BonitaRuntimeException(e);
} catch (final DocumentationCreationException e) {
throw new BonitaRuntimeException(e);
}
runtimeAttachmentNames.add(attachment.getName());
}
// Keep mapping with number of attachments.
instance.setNbOfAttachments(attachments.size());
} else {
// Keep mapping with number of attachments.
instance.setNbOfAttachments(0);
}
int previousNbOfAttachments;
final Collection values = process.getAttachments().values();
if (values != null && !values.isEmpty()) {
final List documents = DocumentService.getDocuments(manager, processUUID);
Document document = null;
for (final AttachmentDefinition attachmentDefinition : values) {
final Iterator iterator = documents.iterator();
document = null;
final String attachmentName = attachmentDefinition.getName();
if (!runtimeAttachmentNames.contains(attachmentName)) {
try {
while (iterator.hasNext() && document == null) {
final Document next = iterator.next();
if (attachmentName.equals(next.getName())) {
document = next;
iterator.remove();
break;
}
}
if (document == null) {
throw new BonitaRuntimeException("Cannot retrieve document");
}
final byte[] content = manager.getContent(document);
manager.createDocument(attachmentDefinition.getName(), processUUID, instance.getUUID(),
attachmentDefinition.getFileName(), DocumentService.DEFAULT_MIME_TYPE, content);
// Keep mapping of number of attachments
previousNbOfAttachments = instance.getNbOfAttachments();
if (previousNbOfAttachments <= 0) {
instance.setNbOfAttachments(1);
} else {
instance.setNbOfAttachments(previousNbOfAttachments + 1);
}
} catch (final Exception e) {
throw new BonitaRuntimeException(e);
}
}
}
}
recorder.recordInstanceStarted(instance, initiator);
if (instance.getUUID().equals(instance.getRootInstanceUUID())) {
final EventService eventService = EnvTool.getEventService();
eventService.lockRootInstance(instance.getUUID());
}
ConnectorExecutor.executeConnectors(rootExecution, HookDefinition.Event.instanceOnStart);
return rootExecution;
}
public static void startEventSubProcesses(final ProcessInstance instance) throws ProcessNotFoundException {
final ProcessInstanceUUID instanceUUID = instance.getUUID();
final InternalProcessDefinition process = FacadeUtil.getProcessDefinition(instance.getProcessDefinitionUUID());
final EventService eventService = EnvTool.getEventService();
for (final EventProcessDefinition eventSubProcess : process.getEventSubProcesses()) {
final InternalProcessDefinition eventProcess = EnvTool.getJournalQueriers().getProcess(eventSubProcess.getName(),
eventSubProcess.getVersion());
if (eventProcess == null) {
throw new ProcessNotFoundException("bs_PU_1", eventSubProcess.getName(), eventSubProcess.getVersion());
}
final ActivityDefinition startEvent = getStartEvent(eventProcess);
if (startEvent.isTimer()) {
final String eventName = BonitaConstants.TIMER_EVENT_PREFIX + startEvent.getUUID();
final String condition = startEvent.getTimerCondition();
try {
final Date date = getTimerDate(condition, process.getUUID(), -1);
final long enableTime = date.getTime();
final Job timer = JobBuilder.startTimerJob(eventName, startEvent.getUUID(), condition, enableTime);
timer.setEventSubProcessRootInstanceUUID(instanceUUID);
eventService.storeJob(timer);
} catch (final GroovyException e) {
throw new DeploymentRuntimeException(e.getMessage(), e.getCause());
}
} else if (startEvent.isCatchingSignalEvent()) {
final String eventName = startEvent.getTimerCondition();
final IncomingEventInstance signalEventInstance = new IncomingEventInstance(eventName, null, null,
startEvent.getUUID(), null, eventProcess.getName(), startEvent.getName(), null,
EventConstants.SIGNAL_START_EVENT, -1, false);
signalEventInstance.setPermanent(true);
signalEventInstance.setEventSubProcessRootInstanceUUID(instanceUUID);
eventService.subscribe(signalEventInstance);
} else if (startEvent.isReceiveEvent()) {
final IncomingEventDefinition event = startEvent.getIncomingEvent();
if (event != null) {
final IncomingEventInstance eventInstance = new IncomingEventInstance(event.getName(), event.getExpression(),
null, startEvent.getUUID(), null, eventProcess.getName(), startEvent.getName(), null,
EventConstants.MESSAGE_START_EVENT, System.currentTimeMillis(), false);
eventInstance.setPermanent(true);
eventInstance.setEventSubProcessRootInstanceUUID(instanceUUID);
addCorrelationKeys(event, eventInstance, instance.getUUID());
eventService.subscribe(eventInstance);
}
}
}
}
private static ActivityDefinition getStartEvent(final InternalProcessDefinition eventProcess) {
for (final ActivityDefinition activity : eventProcess.getActivities()) {
if (activity.getIncomingTransitions().isEmpty()) {
return activity;
}
}
return null;
}
private static Execution createProcessInstance(final InternalProcessDefinition process,
final ProcessInstanceUUID rootInstanceUUID) {
final ProcessDefinitionUUID processUUID = process.getUUID();
final long instanceNb = EnvTool.getUUIDService().getNewProcessInstanceNb(processUUID);
final ProcessInstanceUUID instanceUUID = new ProcessInstanceUUID(processUUID, instanceNb);
ProcessInstanceUUID theRootInstanceUUID = null;
if (rootInstanceUUID == null) {
theRootInstanceUUID = instanceUUID;
} else {
theRootInstanceUUID = rootInstanceUUID;
}
final InternalProcessInstance instance = new InternalProcessInstance(instanceUUID, process, theRootInstanceUUID,
instanceNb);
final Execution processInstance = instance.getRootExecution();
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("creating new execution for process '" + process.getName() + "'");
}
return processInstance;
}
public static String getEvaluatedCorrelationKey(final ProcessInstanceUUID processInstanceUUID,
final String correlationKeyName, final String correlationKeyExpression) {
if (correlationKeyExpression != null) {
try {
final String expression = GroovyUtil.evaluate(correlationKeyExpression, null, processInstanceUUID, false, false).toString();
return correlationKeyName.concat("||||").concat(expression);
} catch (final GroovyException e) {
throw new BonitaRuntimeException(e);
}
}
return null;
}
public static String getEvaluatedCorrelationKey(final ProcessDefinitionUUID definitionUUID,
final String correlationKeyName, final String correlationKeyExpression) {
if (correlationKeyExpression != null) {
try {
final String expression = GroovyUtil.evaluate(correlationKeyExpression, null, definitionUUID, false).toString();
return correlationKeyName.concat("||||").concat(expression);
} catch (final GroovyException e) {
throw new BonitaRuntimeException(e);
}
}
return null;
}
public static void addCorrelationKeys(final EventDefinition eventDefinition, final EventInstance eventInstance,
final ProcessDefinitionUUID definitionUUID) {
String correlationKeyName = eventDefinition.getCorrelationKeyName1();
if (correlationKeyName != null) {
final String correlationKey = getEvaluatedCorrelationKey(definitionUUID, correlationKeyName,
eventDefinition.getCorrelationKeyExpression1());
eventInstance.setCorrelationKey1(correlationKey);
}
correlationKeyName = eventDefinition.getCorrelationKeyName2();
if (correlationKeyName != null) {
final String correlationKey = getEvaluatedCorrelationKey(definitionUUID, correlationKeyName,
eventDefinition.getCorrelationKeyExpression2());
eventInstance.setCorrelationKey2(correlationKey);
}
correlationKeyName = eventDefinition.getCorrelationKeyName3();
if (correlationKeyName != null) {
final String correlationKey = getEvaluatedCorrelationKey(definitionUUID, correlationKeyName,
eventDefinition.getCorrelationKeyExpression3());
eventInstance.setCorrelationKey3(correlationKey);
}
correlationKeyName = eventDefinition.getCorrelationKeyName4();
if (correlationKeyName != null) {
final String correlationKey = getEvaluatedCorrelationKey(definitionUUID, correlationKeyName,
eventDefinition.getCorrelationKeyExpression4());
eventInstance.setCorrelationKey4(correlationKey);
}
correlationKeyName = eventDefinition.getCorrelationKeyName5();
if (correlationKeyName != null) {
final String correlationKey = getEvaluatedCorrelationKey(definitionUUID, correlationKeyName,
eventDefinition.getCorrelationKeyExpression5());
eventInstance.setCorrelationKey5(correlationKey);
}
}
public static void addCorrelationKeys(final EventDefinition eventDefinition, final EventInstance eventInstance,
final ProcessInstanceUUID instanceUUID) {
String correlationKeyName = eventDefinition.getCorrelationKeyName1();
if (correlationKeyName != null) {
final String correlationKey = getEvaluatedCorrelationKey(instanceUUID, correlationKeyName,
eventDefinition.getCorrelationKeyExpression1());
eventInstance.setCorrelationKey1(correlationKey);
}
correlationKeyName = eventDefinition.getCorrelationKeyName2();
if (correlationKeyName != null) {
final String correlationKey = getEvaluatedCorrelationKey(instanceUUID, correlationKeyName,
eventDefinition.getCorrelationKeyExpression2());
eventInstance.setCorrelationKey2(correlationKey);
}
correlationKeyName = eventDefinition.getCorrelationKeyName3();
if (correlationKeyName != null) {
final String correlationKey = getEvaluatedCorrelationKey(instanceUUID, correlationKeyName,
eventDefinition.getCorrelationKeyExpression3());
eventInstance.setCorrelationKey3(correlationKey);
}
correlationKeyName = eventDefinition.getCorrelationKeyName4();
if (correlationKeyName != null) {
final String correlationKey = getEvaluatedCorrelationKey(instanceUUID, correlationKeyName,
eventDefinition.getCorrelationKeyExpression4());
eventInstance.setCorrelationKey4(correlationKey);
}
correlationKeyName = eventDefinition.getCorrelationKeyName5();
if (correlationKeyName != null) {
final String correlationKey = getEvaluatedCorrelationKey(instanceUUID, correlationKeyName,
eventDefinition.getCorrelationKeyExpression5());
eventInstance.setCorrelationKey5(correlationKey);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy