diff --git a/config/alfresco/avm-services-context.xml b/config/alfresco/avm-services-context.xml
index 99ac4cdce0..cd6f46c106 100644
--- a/config/alfresco/avm-services-context.xml
+++ b/config/alfresco/avm-services-context.xml
@@ -172,7 +172,7 @@
-
+
@@ -262,6 +262,12 @@
${avm.remote.port}
+
+
+
+
+
+
diff --git a/config/alfresco/workflow/submit_processdefinition.xml b/config/alfresco/workflow/submit_processdefinition.xml
index 4c0715557a..baa7f06707 100644
--- a/config/alfresco/workflow/submit_processdefinition.xml
+++ b/config/alfresco/workflow/submit_processdefinition.xml
@@ -14,8 +14,15 @@
-
-
+
+
+
+
+
+
+
+
+
-
-
+
-
-
-
-
-
-
#{wcmwf_reviewType == "Parallel"}
@@ -119,10 +119,12 @@
-
+
+
+
- #{wcmwf_approveCnt == wcmwf_reviewerCnt}
-
+ #{wcmwf_approveCnt == wcmwf_reviewerCnt}
+
@@ -142,5 +144,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/workflow/wcmWorkflowModel.xml b/config/alfresco/workflow/wcmWorkflowModel.xml
index 1ee759c49e..447d47e687 100644
--- a/config/alfresco/workflow/wcmWorkflowModel.xml
+++ b/config/alfresco/workflow/wcmWorkflowModel.xml
@@ -142,6 +142,16 @@
+
+
+
+ Workflow Instance Id
+ d:text
+ true
+
+
+
+
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/avm/wf/AVMClearSubmittedHandler.java b/source/java/org/alfresco/repo/avm/wf/AVMClearSubmittedHandler.java
new file mode 100644
index 0000000000..f084127938
--- /dev/null
+++ b/source/java/org/alfresco/repo/avm/wf/AVMClearSubmittedHandler.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2006 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.avm.wf;
+
+import java.util.List;
+
+import org.alfresco.repo.avm.AVMNodeConverter;
+import org.alfresco.repo.workflow.jbpm.JBPMNode;
+import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
+import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
+import org.alfresco.service.cmr.avm.AVMService;
+import org.alfresco.service.cmr.avmsync.AVMDifference;
+import org.alfresco.service.cmr.avmsync.AVMSyncService;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.util.Pair;
+import org.jbpm.graph.exe.ExecutionContext;
+import org.springframework.beans.factory.BeanFactory;
+
+
+/**
+ * Clear "submitted" mark from (source of) items within the WCM Workflow Package
+ *
+ * @author davidc
+ */
+public class AVMClearSubmittedHandler extends JBPMSpringActionHandler
+{
+ private static final long serialVersionUID = 4113360751217684995L;
+
+ /**
+ * The AVMService instance.
+ */
+ private AVMService fAVMService;
+
+ /**
+ * The AVMSyncService instance.
+ */
+ private AVMSyncService fAVMSyncService;
+
+ /**
+ * The AVMSubmittedAspect instance.
+ */
+ private AVMSubmittedAspect fAVMSubmittedAspect;
+
+
+
+ /**
+ * Initialize service references.
+ * @param factory The BeanFactory to get references from.
+ */
+ @Override
+ protected void initialiseHandler(BeanFactory factory)
+ {
+ fAVMService = (AVMService)factory.getBean("AVMService");
+ fAVMSyncService = (AVMSyncService)factory.getBean("AVMSyncService");
+ fAVMSubmittedAspect = (AVMSubmittedAspect)factory.getBean("AVMSubmittedAspect");
+ }
+
+ /**
+ * Do the actual work.
+ * @param executionContext The context to get stuff from.
+ */
+ public void execute(ExecutionContext executionContext) throws Exception
+ {
+ // TODO: Allow submit parameters to be passed into this action handler
+ // rather than pulling directly from execution context
+
+ // NOTE: Submitted items can only be marked as "submitted" if we know where they came from
+ String from = (String)executionContext.getContextInstance().getVariable("wcmwf_fromPath");
+ if (from != null && from.length() > 0)
+ {
+ // retrieve list of changes in submitted package
+ NodeRef pkg = ((JBPMNode)executionContext.getContextInstance().getVariable("bpm_package")).getNodeRef();
+ Pair pkgPath = AVMNodeConverter.ToAVMVersionPath(pkg);
+ AVMNodeDescriptor pkgDesc = fAVMService.lookup(pkgPath.getFirst(), pkgPath.getSecond());
+ String targetPath = pkgDesc.getIndirection();
+ List diffs = fAVMSyncService.compare(pkgPath.getFirst(), pkgPath.getSecond(), -1, targetPath, null);
+
+ // for each change, mark original as submitted
+ for (AVMDifference diff : diffs)
+ {
+ String submittedPath = from + diff.getSourcePath().substring(pkgPath.getSecond().length());
+ fAVMSubmittedAspect.clearSubmitted(-1, submittedPath);
+ }
+ }
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java b/source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java
index ca493d49b5..e71fad75f6 100644
--- a/source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java
+++ b/source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2006 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.avm.wf;
import java.io.Serializable;
@@ -31,6 +47,11 @@ public class AVMSubmitPackageHandler extends JBPMSpringActionHandler implements
*/
private AVMSyncService fAVMSyncService;
+ /**
+ * The AVMSubmittedAspect instance.
+ */
+ private AVMSubmittedAspect fAVMSubmittedAspect;
+
/**
* Initialize service references.
@@ -41,6 +62,7 @@ public class AVMSubmitPackageHandler extends JBPMSpringActionHandler implements
{
fAVMService = (AVMService)factory.getBean("AVMService");
fAVMSyncService = (AVMSyncService)factory.getBean("AVMSyncService");
+ fAVMSubmittedAspect = (AVMSubmittedAspect)factory.getBean("AVMSubmittedAspect");
}
/**
@@ -49,7 +71,7 @@ public class AVMSubmitPackageHandler extends JBPMSpringActionHandler implements
*/
public void execute(ExecutionContext executionContext) throws Exception
{
- // TODO: Allow submit parameters to passed into this action handler
+ // TODO: Allow submit parameters to be passed into this action handler
// rather than pulling directly from execution context
NodeRef pkg = ((JBPMNode)executionContext.getContextInstance().getVariable("bpm_package")).getNodeRef();
@@ -60,13 +82,23 @@ public class AVMSubmitPackageHandler extends JBPMSpringActionHandler implements
String tag = (String)executionContext.getContextInstance().getVariable("wcmwf_label");
AVMNodeDescriptor pkgDesc = fAVMService.lookup(pkgPath.getFirst(), pkgPath.getSecond());
String targetPath = pkgDesc.getIndirection();
- List diff = fAVMSyncService.compare(pkgPath.getFirst(), pkgPath.getSecond(), -1, targetPath, null);
- fAVMSyncService.update(diff, null, false, false, true, true, tag, description);
+ List stagingDiffs = fAVMSyncService.compare(pkgPath.getFirst(), pkgPath.getSecond(), -1, targetPath, null);
+ for (AVMDifference diff : stagingDiffs)
+ {
+ fAVMSubmittedAspect.clearSubmitted(diff.getSourceVersion(), diff.getSourcePath());
+ }
+ fAVMSyncService.update(stagingDiffs, null, false, false, true, true, tag, description);
// flatten source folder where changes were submitted from
String from = (String)executionContext.getContextInstance().getVariable("wcmwf_fromPath");
if (from != null && from.length() > 0)
{
+ // first, submit changes back to sandbox forcing addition of edits in workflow (and submission
+ // flag removal). second, flatten sandbox, removing modified items that have been submitted
+ // TODO: Without locking on the sandbox, it's possible that a change to a "submitted" item
+ // may get lost when the item is finally approved
+ List sandboxDiffs = fAVMSyncService.compare(pkgPath.getFirst(), pkgPath.getSecond(), -1, from, null);
+ fAVMSyncService.update(sandboxDiffs, null, false, false, true, true, tag, description);
AVMDAOs.Instance().fAVMNodeDAO.flush();
fAVMSyncService.flatten(from, targetPath);
}
diff --git a/source/java/org/alfresco/repo/avm/wf/AVMSubmittedAspect.java b/source/java/org/alfresco/repo/avm/wf/AVMSubmittedAspect.java
new file mode 100644
index 0000000000..f4f6f4c17e
--- /dev/null
+++ b/source/java/org/alfresco/repo/avm/wf/AVMSubmittedAspect.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2006 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.avm.wf;
+
+import org.alfresco.repo.domain.PropertyValue;
+import org.alfresco.service.cmr.avm.AVMService;
+import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
+import org.alfresco.service.cmr.workflow.WorkflowException;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.ParameterCheck;
+
+
+/**
+ * Aspect to represent a node is currently taking part in a workflow.
+ *
+ * @author davidc
+ */
+public class AVMSubmittedAspect
+{
+
+ private final static String NAMESPACE_URI = "http://www.alfresco.org/model/wcmworkflow/1.0";
+
+ public final static QName ASPECT = QName.createQName(NAMESPACE_URI, "submitted");
+ public final static QName PROP_WORKFLOW_INSTANCE_ID = QName.createQName(NAMESPACE_URI, "workflowInstanceId");
+
+
+ // Dependencies
+ private AVMService avmService;
+
+
+ /**
+ * Sets the AVM Service
+ *
+ * @param avmService
+ */
+ public void setAvmService(AVMService avmService)
+ {
+ this.avmService = avmService;
+ }
+
+
+ /**
+ * Mark an item as submitted via a workflow
+ *
+ * @param version
+ * @param path
+ * @param workflowInstanceId
+ */
+ public void markSubmitted(int version, String path, String workflowInstanceId)
+ {
+ String existingWorkflowInstanceId = getWorkflowInstance(version, path);
+ if (existingWorkflowInstanceId != null)
+ {
+ throw new WorkflowException("Node " + path + "[" + version + "] already submitted in workflow " + existingWorkflowInstanceId);
+ }
+
+ ParameterCheck.mandatoryString("workflowInstanceId", workflowInstanceId);
+ avmService.addAspect(path, ASPECT);
+ avmService.setNodeProperty(path, PROP_WORKFLOW_INSTANCE_ID, new PropertyValue(DataTypeDefinition.TEXT, workflowInstanceId));
+ }
+
+
+ /**
+ * Unmark an submitted item
+ *
+ * @param version
+ * @param path
+ */
+ public void clearSubmitted(int version, String path)
+ {
+ if (avmService.hasAspect(version, path, ASPECT))
+ {
+ avmService.removeAspect(path, ASPECT);
+ }
+ }
+
+
+ /**
+ * Gets the submitted workflow instances for the specified item
+ *
+ * @param version
+ * @param path
+ * @return workflow instance (or null, if not submitted)
+ */
+ public String getWorkflowInstance(int version, String path)
+ {
+ String workflowInstanceId = null;
+ PropertyValue value = avmService.getNodeProperty(version, path, PROP_WORKFLOW_INSTANCE_ID);
+ if (value != null)
+ {
+ workflowInstanceId = value.getStringValue();
+ }
+ return workflowInstanceId;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JBPMSpringActionHandler.java b/source/java/org/alfresco/repo/workflow/jbpm/JBPMSpringActionHandler.java
index fd7d1449dd..ad6a30cf98 100644
--- a/source/java/org/alfresco/repo/workflow/jbpm/JBPMSpringActionHandler.java
+++ b/source/java/org/alfresco/repo/workflow/jbpm/JBPMSpringActionHandler.java
@@ -16,7 +16,9 @@
*/
package org.alfresco.repo.workflow.jbpm;
+import org.alfresco.repo.workflow.BPMEngineRegistry;
import org.jbpm.graph.def.ActionHandler;
+import org.jbpm.graph.exe.ExecutionContext;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference;
@@ -50,4 +52,17 @@ public abstract class JBPMSpringActionHandler implements ActionHandler
*/
protected abstract void initialiseHandler(BeanFactory factory);
+
+ /**
+ * Gets the workflow instance id of the currently executing workflow
+ *
+ * @param context jBPM execution context
+ * @return workflow instance id
+ */
+ protected String getWorkflowInstanceId(ExecutionContext context)
+ {
+ String id = new Long(context.getProcessInstance().getId()).toString();
+ return BPMEngineRegistry.createGlobalId("jbpm", id);
+ }
+
}