diff --git a/config/alfresco/bootstrap-context.xml b/config/alfresco/bootstrap-context.xml
index a1b78152ca..142ec70343 100644
--- a/config/alfresco/bootstrap-context.xml
+++ b/config/alfresco/bootstrap-context.xml
@@ -120,6 +120,20 @@
+
+
+
+
+
+
+ jbpm
+ org/alfresco/repo/workflow/jbpm/review_and_approve_processdefinition.xml
+ text/xml
+
+
+
+
+
diff --git a/config/alfresco/model/workflowModel.xml b/config/alfresco/model/workflowModel.xml
new file mode 100644
index 0000000000..22f27518cc
--- /dev/null
+++ b/config/alfresco/model/workflowModel.xml
@@ -0,0 +1,59 @@
+
+
+
+
+ Content-oriented Workflows Model
+ Alfresco
+ 0.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Submit Review Task
+ bpm:workflowTask
+
+
+
+
+ Review Due Date
+ d:date
+
+
+
+
+
+
+
+ Reviewers
+
+ false
+ false
+
+
+ cm:person
+ true
+ false
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/workflow-context.xml b/config/alfresco/workflow-context.xml
index 4ce9da7ac3..9f7ce0a272 100644
--- a/config/alfresco/workflow-context.xml
+++ b/config/alfresco/workflow-context.xml
@@ -4,16 +4,23 @@
-
+
alfresco/model/bpmModel.xml
+ alfresco/model/workflowModel.xml
+
+
+
+
+
+
@@ -41,11 +48,6 @@
-
-
-
-
-
@@ -57,11 +59,8 @@
+
+
-
-
-
-
-
diff --git a/source/java/org/alfresco/repo/content/MimetypeMap.java b/source/java/org/alfresco/repo/content/MimetypeMap.java
index 08b9d49f24..272c1cb89d 100644
--- a/source/java/org/alfresco/repo/content/MimetypeMap.java
+++ b/source/java/org/alfresco/repo/content/MimetypeMap.java
@@ -57,6 +57,7 @@ public class MimetypeMap implements MimetypeService
public static final String MIMETYPE_IMAGE_JPEG = "image/jpeg";
public static final String MIMETYPE_IMAGE_RGB = "image/x-rgb";
public static final String MIMETYPE_JAVASCRIPT = "application/x-javascript";
+ public static final String MIMETYPE_ZIP = "application/zip";
// Open Document
public static final String MIMETYPE_OPENDOCUMENT_TEXT = "application/vnd.oasis.opendocument.text";
public static final String MIMETYPE_OPENDOCUMENT_TEXT_TEMPLATE = "application/vnd.oasis.opendocument.text-template";
diff --git a/source/java/org/alfresco/repo/workflow/WorkflowDefinitionComponent.java b/source/java/org/alfresco/repo/workflow/WorkflowDefinitionComponent.java
index 5fd9ef849b..db0530f7f1 100644
--- a/source/java/org/alfresco/repo/workflow/WorkflowDefinitionComponent.java
+++ b/source/java/org/alfresco/repo/workflow/WorkflowDefinitionComponent.java
@@ -34,10 +34,23 @@ public interface WorkflowDefinitionComponent
* Deploy a Workflow Definition
*
* @param workflowDefinition the content object containing the definition
+ * @param mimetype (optional) the mime type of the workflow definition
* @return workflow definition
*/
- public WorkflowDefinition deployDefinition(InputStream workflowDefinition);
+ public WorkflowDefinition deployDefinition(InputStream workflowDefinition, String mimetype);
+ /**
+ * Is the specified Workflow Definition already deployed?
+ *
+ * Note: the notion of "already deployed" may differ between bpm engines. For example,
+ * different versions of the same process may be considered equal.
+ *
+ * @param workflowDefinition the definition to check
+ * @param mimetype the mimetype of the definition
+ * @return true => already deployed
+ */
+ public boolean isDefinitionDeployed(InputStream workflowDefinition, String mimetype);
+
/**
* Undeploy an exisiting Workflow Definition
*
diff --git a/source/java/org/alfresco/repo/workflow/WorkflowDeployer.java b/source/java/org/alfresco/repo/workflow/WorkflowDeployer.java
new file mode 100644
index 0000000000..faf01522ba
--- /dev/null
+++ b/source/java/org/alfresco/repo/workflow/WorkflowDeployer.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.workflow;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Properties;
+
+import javax.transaction.UserTransaction;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+import org.alfresco.repo.security.authentication.AuthenticationComponent;
+import org.alfresco.service.cmr.view.ImporterException;
+import org.alfresco.service.cmr.workflow.WorkflowDefinition;
+import org.alfresco.service.cmr.workflow.WorkflowException;
+import org.alfresco.service.cmr.workflow.WorkflowService;
+import org.alfresco.service.transaction.TransactionService;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.core.io.ClassPathResource;
+
+
+/**
+ * Alfresco bootstrap Process deployment.
+ *
+ * @author davidc
+ */
+public class WorkflowDeployer implements ApplicationListener
+{
+ // Logging support
+ private static Log logger = LogFactory.getLog("org.alfresco.repo.workflow");
+
+ // Workflow Definition Properties (used in setWorkflowDefinitions)
+ public static final String ENGINE_ID = "engineId";
+ public static final String LOCATION = "location";
+ public static final String MIMETYPE = "mimetype";
+
+ // Dependencies
+ private TransactionService transactionService;
+ private WorkflowService workflowService;
+ private AuthenticationComponent authenticationComponent;
+ private List workflowDefinitions;
+
+
+ /**
+ * Sets the Transaction Service
+ *
+ * @param userTransaction the transaction service
+ */
+ public void setTransactionService(TransactionService transactionService)
+ {
+ this.transactionService = transactionService;
+ }
+
+ /**
+ * Sets the namespace service
+ *
+ * @param namespaceService the namespace service
+ */
+ public void setWorkflowService(WorkflowService workflowService)
+ {
+ this.workflowService = workflowService;
+ }
+
+ /**
+ * Set the authentication component
+ *
+ * @param authenticationComponent
+ */
+ public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
+ {
+ this.authenticationComponent = authenticationComponent;
+ }
+
+ /**
+ * Sets the Workflow Definitions
+ *
+ * @param workflowDefinitions
+ */
+ public void setWorkflowDefinitions(List workflowDefinitions)
+ {
+ this.workflowDefinitions = workflowDefinitions;
+ }
+
+ /**
+ * Deploy the Workflow Definitions
+ */
+ public void deploy()
+ {
+ if (transactionService == null)
+ {
+ throw new ImporterException("Transaction Service must be provided");
+ }
+ if (authenticationComponent == null)
+ {
+ throw new ImporterException("Authentication Component must be provided");
+ }
+ if (workflowService == null)
+ {
+ throw new ImporterException("Workflow Service must be provided");
+ }
+
+ UserTransaction userTransaction = transactionService.getUserTransaction();
+ authenticationComponent.setSystemUserAsCurrentUser();
+
+ try
+ {
+ userTransaction.begin();
+
+ // bootstrap the workflow definitions
+ if (workflowDefinitions != null)
+ {
+ for (Properties workflowDefinition : workflowDefinitions)
+ {
+ // retrieve workflow specification
+ String engineId = workflowDefinition.getProperty(ENGINE_ID);
+ if (engineId == null || engineId.length() == 0)
+ {
+ throw new WorkflowException("Workflow Engine Id must be provided");
+ }
+ String location = workflowDefinition.getProperty(LOCATION);
+ if (location == null || location.length() == 0)
+ {
+ throw new WorkflowException("Workflow definition location must be provided");
+ }
+ String mimetype = workflowDefinition.getProperty(MIMETYPE);
+
+ // retrieve input stream on workflow definition
+ ClassPathResource workflowResource = new ClassPathResource(location);
+
+ // deploy workflow definition
+ if (workflowService.isDefinitionDeployed(engineId, workflowResource.getInputStream(), mimetype))
+ {
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("Workflow deployer: Definition '" + location + "' already deployed");
+ }
+ }
+ else
+ {
+ WorkflowDefinition def = workflowService.deployDefinition(engineId, workflowResource.getInputStream(), mimetype);
+ if (logger.isInfoEnabled())
+ {
+ logger.info("Workflow deployer: Deployed process definition '" + def.name + "' (version " + def.version + ") from '" + location + "'");
+ }
+ }
+ }
+ }
+
+ userTransaction.commit();
+ }
+ catch(Throwable e)
+ {
+ // rollback the transaction
+ try { if (userTransaction != null) {userTransaction.rollback();} } catch (Exception ex) {}
+ try {authenticationComponent.clearCurrentSecurityContext(); } catch (Exception ex) {}
+ throw new AlfrescoRuntimeException("Workflow deployment failed", e);
+ }
+ finally
+ {
+ authenticationComponent.clearCurrentSecurityContext();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
+ */
+ public void onApplicationEvent(ApplicationEvent event)
+ {
+ if (event instanceof ContextRefreshedEvent)
+ {
+ deploy();
+ }
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java b/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java
index c7b10a776c..406db91cb7 100644
--- a/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java
+++ b/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java
@@ -16,6 +16,7 @@
*/
package org.alfresco.repo.workflow;
+import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
@@ -55,6 +56,24 @@ public class WorkflowServiceImpl implements WorkflowService
}
+ /* (non-Javadoc)
+ * @see org.alfresco.service.cmr.workflow.WorkflowService#deployDefinition(java.lang.String, java.io.InputStream, java.lang.String)
+ */
+ public WorkflowDefinition deployDefinition(String engineId, InputStream workflowDefinition, String mimetype)
+ {
+ WorkflowDefinitionComponent component = getWorkflowDefinitionComponent(engineId);
+ return component.deployDefinition(workflowDefinition, mimetype);
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.service.cmr.workflow.WorkflowService#isDefinitionDeployed(java.lang.String, java.io.InputStream, java.lang.String)
+ */
+ public boolean isDefinitionDeployed(String engineId, InputStream workflowDefinition, String mimetype)
+ {
+ WorkflowDefinitionComponent component = getWorkflowDefinitionComponent(engineId);
+ return component.isDefinitionDeployed(workflowDefinition, mimetype);
+ }
+
/* (non-Javadoc)
* @see org.alfresco.service.cmr.workflow.WorkflowService#deployDefinition(org.alfresco.service.cmr.repository.NodeRef)
*/
@@ -67,10 +86,11 @@ public class WorkflowServiceImpl implements WorkflowService
/* (non-Javadoc)
* @see org.alfresco.service.cmr.workflow.WorkflowService#undeployDefinition(java.lang.String)
*/
- public void undeployDefinition(String processDefinitionId)
+ public void undeployDefinition(String workflowDefinitionId)
{
- // TODO
- throw new UnsupportedOperationException();
+ String engineId = BPMEngineRegistry.getEngineId(workflowDefinitionId);
+ WorkflowDefinitionComponent component = getWorkflowDefinitionComponent(engineId);
+ component.undeployDefinition(workflowDefinitionId);
}
/* (non-Javadoc)
@@ -275,5 +295,5 @@ public class WorkflowServiceImpl implements WorkflowService
}
return component;
}
-
+
}
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
index d7d50aedb3..b41087abd7 100644
--- a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
+++ b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
@@ -16,6 +16,7 @@
*/
package org.alfresco.repo.workflow.jbpm;
+import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
@@ -25,8 +26,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.zip.ZipInputStream;
import org.alfresco.model.ContentModel;
+import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.workflow.BPMEngine;
import org.alfresco.repo.workflow.TaskComponent;
@@ -144,19 +147,90 @@ public class JBPMEngine extends BPMEngine
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.WorkflowDefinitionComponent#deployDefinition(java.io.InputStream)
*/
- public WorkflowDefinition deployDefinition(InputStream workflowDefinition)
+ public WorkflowDefinition deployDefinition(final InputStream workflowDefinition, final String mimetype)
{
- // TODO
- throw new UnsupportedOperationException();
+ try
+ {
+ return (WorkflowDefinition)jbpmTemplate.execute(new JbpmCallback()
+ {
+ public Object doInJbpm(JbpmContext context)
+ {
+ // construct process definition
+ ProcessDefinition def = createProcessDefinition(workflowDefinition, mimetype);
+
+ // deploy the parsed definition
+ context.deployProcessDefinition(def);
+
+ // return deployed definition
+ WorkflowDefinition workflowDef = createWorkflowDefinition(def);
+ return workflowDef;
+ }
+ });
+ }
+ catch(JbpmException e)
+ {
+ throw new WorkflowException("Failed to deploy workflow definition", e);
+ }
}
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.workflow.WorkflowDefinitionComponent#isDefinitionDeployed(java.io.InputStream, java.lang.String)
+ */
+ public boolean isDefinitionDeployed(final InputStream workflowDefinition, final String mimetype)
+ {
+ try
+ {
+ return (Boolean) jbpmTemplate.execute(new JbpmCallback()
+ {
+ public Boolean doInJbpm(JbpmContext context)
+ {
+ // create process definition from input stream
+ ProcessDefinition processDefinition = createProcessDefinition(workflowDefinition, mimetype);
+
+ // retrieve process definition from Alfresco Repository
+ GraphSession graphSession = context.getGraphSession();
+ ProcessDefinition existingDefinition = graphSession.findLatestProcessDefinition(processDefinition.getName());
+ return (existingDefinition == null) ? false : true;
+ }
+ });
+ }
+ catch(JbpmException e)
+ {
+ throw new WorkflowException("Failed to determine if workflow definition is already deployed", e);
+ }
+ }
+
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.WorkflowDefinitionComponent#undeployDefinition(java.lang.String)
*/
- public void undeployDefinition(String workflowDefinitionId)
+ public void undeployDefinition(final String workflowDefinitionId)
{
- // TODO
- throw new UnsupportedOperationException();
+ try
+ {
+ jbpmTemplate.execute(new JbpmCallback()
+ {
+ public Object doInJbpm(JbpmContext context)
+ {
+ // retrieve process definition
+ GraphSession graphSession = context.getGraphSession();
+ ProcessDefinition processDefinition = graphSession.loadProcessDefinition(getJbpmId(workflowDefinitionId));
+ // NOTE: if not found, should throw an exception
+
+ // undeploy
+ // NOTE: jBPM deletes all "in-flight" processes too
+ // TODO: Determine if there's a safer undeploy we can expose via the WorkflowService contract
+ graphSession.deleteProcessDefinition(processDefinition);
+
+ // we're done
+ return null;
+ }
+ });
+ }
+ catch(JbpmException e)
+ {
+ throw new WorkflowException("Failed to deploy workflow definition", e);
+ }
}
/* (non-Javadoc)
@@ -674,6 +748,58 @@ public class JBPMEngine extends BPMEngine
// Helpers...
//
+ /**
+ * Construct a Process Definition from the provided Process Definition stream
+ *
+ * @param workflowDefinition stream to create process definition from
+ * @param mimetype mimetype of stream
+ * @return process definition
+ */
+ protected ProcessDefinition createProcessDefinition(InputStream definitionStream, String mimetype)
+ {
+ String actualMimetype = (mimetype == null) ? MimetypeMap.MIMETYPE_ZIP : mimetype;
+ ProcessDefinition def = null;
+
+ // parse process definition from jBPM process archive file
+
+ if (actualMimetype.equals(MimetypeMap.MIMETYPE_ZIP))
+ {
+ ZipInputStream zipInputStream = null;
+ try
+ {
+ zipInputStream = new ZipInputStream(definitionStream);
+ def = ProcessDefinition.parseParZipInputStream(zipInputStream);
+ }
+ catch(Exception e)
+ {
+ throw new JbpmException("Failed to parse process definition from jBPM zip archive stream", e);
+ }
+ finally
+ {
+ if (zipInputStream != null)
+ {
+ try { zipInputStream.close(); } catch(IOException e) {};
+ }
+ }
+ }
+
+ // parse process definition from jBPM xml file
+
+ else if (actualMimetype.equals(MimetypeMap.MIMETYPE_XML))
+ {
+ try
+ {
+ def = ProcessDefinition.parseXmlInputStream(definitionStream);
+ }
+ catch(Exception e)
+ {
+ throw new JbpmException("Failed to parse process definition from jBPM xml stream", e);
+ }
+ }
+
+ return def;
+ }
+
/**
* Gets the Task definition of the specified Task
*
@@ -1013,11 +1139,14 @@ public class JBPMEngine extends BPMEngine
// TODO: Is there a formal way of determing if task node?
workflowNode.isTaskNode = workflowNode.type.equals("TaskNode");
List transitions = node.getLeavingTransitions();
- workflowNode.transitions = new String[transitions.size()];
- int i = 0;
- for (Transition transition : (List)transitions)
+ workflowNode.transitions = new String[(transitions == null) ? 0 : transitions.size()];
+ if (transitions != null)
{
- workflowNode.transitions[i++] = transition.getName();
+ int i = 0;
+ for (Transition transition : (List)transitions)
+ {
+ workflowNode.transitions[i++] = transition.getName();
+ }
}
return workflowNode;
}
@@ -1047,6 +1176,7 @@ public class JBPMEngine extends BPMEngine
{
WorkflowDefinition workflowDef = new WorkflowDefinition();
workflowDef.id = createGlobalId(new Long(definition.getId()).toString());
+ workflowDef.version = new Integer(definition.getVersion()).toString();
workflowDef.name = definition.getName();
Task startTask = definition.getTaskMgmtDefinition().getStartTask();
if (startTask != null)
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java
index 0f9d53b058..dcb4d35d35 100644
--- a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java
+++ b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map;
import org.alfresco.model.ContentModel;
+import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.workflow.BPMEngineRegistry;
import org.alfresco.repo.workflow.TaskComponent;
import org.alfresco.repo.workflow.WorkflowComponent;
@@ -39,6 +40,7 @@ import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.BaseSpringTest;
+import org.springframework.core.io.ClassPathResource;
/**
@@ -51,6 +53,7 @@ public class JBPMEngineTest extends BaseSpringTest
WorkflowDefinitionComponent workflowDefinitionComponent;
WorkflowComponent workflowComponent;
TaskComponent taskComponent;
+ WorkflowDefinition testWorkflowDef;
//@Override
@@ -60,6 +63,15 @@ public class JBPMEngineTest extends BaseSpringTest
workflowDefinitionComponent = registry.getWorkflowDefinitionComponent("jbpm");
workflowComponent = registry.getWorkflowComponent("jbpm");
taskComponent = registry.getTaskComponent("jbpm");
+
+ // deploy test process definition
+ ClassPathResource processDef = new ClassPathResource("org/alfresco/repo/workflow/jbpm/test_processdefinition.xml");
+ assertFalse(workflowDefinitionComponent.isDefinitionDeployed(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML));
+ testWorkflowDef = workflowDefinitionComponent.deployDefinition(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML);
+ assertNotNull(testWorkflowDef);
+ assertEquals("Test", testWorkflowDef.name);
+ assertEquals("1", testWorkflowDef.version);
+ assertTrue(workflowDefinitionComponent.isDefinitionDeployed(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML));
}
@@ -71,6 +83,16 @@ public class JBPMEngineTest extends BaseSpringTest
}
+ public void testDeployWorkflow() throws Exception
+ {
+ ClassPathResource processDef = new ClassPathResource("org/alfresco/repo/workflow/jbpm/test_processdefinition.xml");
+ testWorkflowDef = workflowDefinitionComponent.deployDefinition(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML);
+ assertNotNull(testWorkflowDef);
+ assertEquals("Test", testWorkflowDef.name);
+ assertEquals("2", testWorkflowDef.version);
+ }
+
+
public void testStartWorkflow()
{
try
@@ -321,16 +343,7 @@ public class JBPMEngineTest extends BaseSpringTest
*/
private WorkflowDefinition getTestDefinition()
{
- List workflowDefs = workflowDefinitionComponent.getDefinitions();
- for (WorkflowDefinition workflowDef : workflowDefs)
- {
- if (workflowDef.name.equals("Review and Approve"))
- {
- return workflowDef;
- }
- }
- fail("Test Workflow Definition not found");
- return null;
+ return testWorkflowDef;
}
}
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/review_and_approve_processdefinition.xml b/source/java/org/alfresco/repo/workflow/jbpm/review_and_approve_processdefinition.xml
new file mode 100644
index 0000000000..1b242cb5ba
--- /dev/null
+++ b/source/java/org/alfresco/repo/workflow/jbpm/review_and_approve_processdefinition.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/test_processdefinition.xml b/source/java/org/alfresco/repo/workflow/jbpm/test_processdefinition.xml
index 1b242cb5ba..b4ad00f47f 100644
--- a/source/java/org/alfresco/repo/workflow/jbpm/test_processdefinition.xml
+++ b/source/java/org/alfresco/repo/workflow/jbpm/test_processdefinition.xml
@@ -1,9 +1,9 @@
-
+
-
+
diff --git a/source/java/org/alfresco/service/cmr/workflow/WorkflowDefinition.java b/source/java/org/alfresco/service/cmr/workflow/WorkflowDefinition.java
index d427ecf63f..04651de5a4 100644
--- a/source/java/org/alfresco/service/cmr/workflow/WorkflowDefinition.java
+++ b/source/java/org/alfresco/service/cmr/workflow/WorkflowDefinition.java
@@ -27,6 +27,9 @@ public class WorkflowDefinition
/** Workflow Definition unique id */
public String id;
+ /** Workflow Definition version */
+ public String version;
+
/** Workflow Definition name */
public String name;
@@ -39,6 +42,6 @@ public class WorkflowDefinition
*/
public String toString()
{
- return "WorkflowDefinition[id=" + id + ",name=" + name + ",startTask=" + startTaskDefinition.toString() + "]";
+ return "WorkflowDefinition[id=" + id + ",version=" + version + ",name=" + name + ",startTask=" + startTaskDefinition.toString() + "]";
}
}
diff --git a/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java b/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java
index fe573799b0..40ac0fb6ce 100644
--- a/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java
+++ b/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java
@@ -16,6 +16,7 @@
*/
package org.alfresco.service.cmr.workflow;
+import java.io.InputStream;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
@@ -37,6 +38,29 @@ public interface WorkflowService
// Workflow Definition Management
//
+ /**
+ * Deploy a Workflow Definition to the Alfresco Repository
+ *
+ * @param engineId the bpm engine id
+ * @param workflowDefinition the workflow definition
+ * @param overwrite true => redeploy, if process definition already exists
+ * @return mimetype the mimetype of the workflow definition
+ */
+ public WorkflowDefinition deployDefinition(String engineId, InputStream workflowDefinition, String mimetype);
+
+ /**
+ * Is the specified Workflow Definition already deployed?
+ *
+ * Note: the notion of "already deployed" may differ between bpm engines. For example,
+ * different versions of the same process may be considered equal.
+ *
+ * @param engineId the bpm engine id
+ * @param workflowDefinition the definition to check
+ * @param mimetype the mimetype of the definition
+ * @return true => already deployed
+ */
+ public boolean isDefinitionDeployed(String engineId, InputStream workflowDefinition, String mimetype);
+
/**
* Deploy a Workflow Definition to the Alfresco Repository
*