As we transition to the new Hyland Community, some post links may be temporarily disrupted as we finalize redirects. We apologize for the inconvenience and are working to resolve this as quickly as possible. Details.
var workflow = actions.create("start-workflow"); workflow.parameters.workflowName = "jbpm$wf:my_workflow"; workflow.parameters["bpm:workflowDescription"] = document.name; workflow.parameters["bpm:assignee"] = person; workflow.execute(document);
package org.alfresco.sample; import java.io.File; import java.io.Serializable; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import org.alfresco.model.ContentModel; import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowPath; import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; public class TagActionExecuter extends ActionExecuterAbstractBase { /** The name of the action */ public static final String PARAM_ASPECT_NAME = "aspect-name"; public static final String PARAM_WORKFLOW_NAME = "workflowName"; public static final String PARAM_END_START_TASK = "endStartTask"; public static final String PARAM_START_TASK_TRANSITION = "startTaskTransition"; public static final String JBPM_WORKFLOW_NAME = "jbpm$mywf:my_digitalpostbox_workflow"; public static final String HOME_DIGITAL_POST_BOX = "Digital Post Box"; public static final String UPLOAD_FOLDER_NAME = "Upload Area"; public static final String UPLOAD_FOLDER_LOCATION = "C:\\alfresco-examples\\"; /** Length of a day in ms. */ public static final long DAY_IN_MILLIS = 24 * 60 * 60 * 1000; /** Jobs will be due in 2 days. */ public static final Date DUE_HOURS = new Date(2 * DAY_IN_MILLIS); /** The node service */ private NodeService nodeService; /** The workflow service*/ private WorkflowService workflowService; /** The content service*/ private ContentService contentService; private static boolean DEBUG = true; /** * Saves typing System.out.println everywhere (I hate typing ;-) */ private static void pl(String str) { if (DEBUG) System.out.println(str); } /** * Saves typing System.out.print everywhere (I hate typing ;-) */ private static void p(String str) { if (DEBUG) System.out.print(str); } /** * On startup creates a NodeService handle. * @param nodeService */ public void setNodeService(NodeService nodeService) { pl("—– setNodeService"); this.nodeService = nodeService; } /** * On startup creates a WorkflowService handle. * @param workflowService */ public void setWorkflowService(WorkflowService workflowService) { pl("—– setWorkflowService"); this.workflowService = workflowService; } /** * On startup creates a ContentService handle. * @param contentService */ public void setContentService(ContentService contentService) { pl("—– setContentService"); this.contentService = contentService; } /* * public void setContentService(FileFolderService fileFolderService) { * System.out.output("—– setFileFolderService"); this.fileFolderService = * fileFolderService; } */ @Override protected void addParameterDefinitions(List<ParameterDefinition> paramList) { pl("—– addParameterDefinitions"); // Specify the parameters paramList.add(new ParameterDefinitionImpl(PARAM_WORKFLOW_NAME, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_WORKFLOW_NAME))); paramList.add(new ParameterDefinitionImpl(PARAM_END_START_TASK, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_END_START_TASK))); paramList.add(new ParameterDefinitionImpl(PARAM_START_TASK_TRANSITION, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_START_TASK_TRANSITION))); } /** * Convert fileName to a mime type. * @param fileName extension is used to determine which mimetype to return. * @return Mimetype, one of MimetypeMap.MIMETYPE_PDF etc. */ private String getMimeTypeFromStr(String fileName) { String fileNameLC = fileName.toLowerCase(); if (fileNameLC.endsWith(".pdf")) { return MimetypeMap.MIMETYPE_PDF; } else if (fileNameLC.endsWith(".ai")) { return MimetypeMap.MIMETYPE_BINARY; } else if (fileNameLC.endsWith(".indd")) { return MimetypeMap.MIMETYPE_BINARY; } else if (fileNameLC.endsWith(".fh5")) { return MimetypeMap.MIMETYPE_BINARY; } else if (fileNameLC.endsWith(".gif")) { return MimetypeMap.MIMETYPE_IMAGE_GIF; } else if (fileNameLC.endsWith(".png")) { return MimetypeMap.MIMETYPE_IMAGE_PNG; } else if (fileNameLC.endsWith(".jpg")) { return MimetypeMap.MIMETYPE_IMAGE_JPEG; } else if (fileNameLC.endsWith(".eps")) { return MimetypeMap.MIMETYPE_BINARY; } else if (fileNameLC.endsWith(".txt")) { return MimetypeMap.MIMETYPE_TEXT_PLAIN; } else if (fileNameLC.endsWith(".xml")) { return MimetypeMap.MIMETYPE_XML; } else { return MimetypeMap.MIMETYPE_BINARY; } } /** * Upload a file into the stores into Company Home|folderName|fileName * @param storeRef ref of stores. * @param fileName File to upload. * @return NodeRef to the stored item. */ public NodeRef createFile(StoreRef storeRef, String fileName) { // Get the Company Home node from which to hang the next level of nodes. NodeRef rootNodeRef = nodeService.getRootNode(storeRef); List<ChildAssociationRef> rootChildren = nodeService.getChildAssocs(rootNodeRef); int nbRootChildren = rootChildren.size(); int iRootChild; NodeRef rootChild = null; NodeRef companyHomeNode = null; String nodeId; for (iRootChild = 0; iRootChild < nbRootChildren; iRootChild++) { rootChild = rootChildren.get(iRootChild).getChildRef(); nodeId = rootChild.getId(); Serializable prop = nodeService.getProperty(rootChild, ContentModel.PROP_NAME); pl(fileName + " : " + prop.toString() + " = " + nodeId); if ("Company Home".equals(prop.toString()) || HOME_DIGITAL_POST_BOX.equals(prop.toString())) { companyHomeNode = rootChild; break; } } if (companyHomeNode == null) { pl(fileName + " : Company home is null"); return null; } pl(fileName + " : Company home = " + rootChild.toString()); // Search for filderName and create it if necessary. String folderName = UPLOAD_FOLDER_NAME; NodeRef folderRef = nodeService.getChildByName(companyHomeNode, ContentModel.ASSOC_CONTAINS, folderName); Map<QName, Serializable> nodeProperties = new HashMap<QName, Serializable>(7); if (folderRef == null) { pl(fileName + " : Cannot find folder : " + folderName); return null; } pl(fileName + " : Folder " + folderName + " = " + folderRef.toString()); // Create a file. nodeProperties.clear(); nodeProperties.put(ContentModel.PROP_NAME, fileName); ChildAssociationRef assocRef = nodeService.createNode(folderRef, ContentModel.ASSOC_CONTAINS, QName.createQName( NamespaceService.CONTENT_MODEL_PREFIX, QName.createValidLocalName(fileName)), ContentModel.TYPE_CONTENT, nodeProperties); NodeRef fileRef = assocRef.getChildRef(); pl(fileName + " : Create a file " + fileName); // Upload the files contents. ContentWriter writer = contentService.getWriter(fileRef, ContentModel.PROP_CONTENT, true); writer.setMimetype(getMimeTypeFromStr(fileName)); writer.setEncoding("UTF-8"); File iFile = new File(UPLOAD_FOLDER_LOCATION + fileName); writer.putContent(iFile); pl(fileName + " : Added content to " + fileName); return fileRef; } @Override protected void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef) { pl("————————————————————————"); pl("—– Starting Action"); pl("ruleAction.getId() = " + ruleAction.getId()); pl("ruleAction.toString() = " + ruleAction.toString()); pl("ruleAction.getCreator() = " + ruleAction.getCreator()); pl("ruleAction.getDesc() = " + ruleAction.getDescription()); pl("ruleAction.getTitle() = " + ruleAction.getTitle()); // List of the properties of the actionedUponNodeRef Map<QName, Serializable> propmap = nodeService.getProperties(actionedUponNodeRef); int mapsize = propmap.size(); Iterator<Entry<QName, Serializable>> keyValuePairs1 = propmap.entrySet().iterator(); for (int i = 0; i < mapsize; i++) { Map.Entry<QName, Serializable> entry = keyValuePairs1.next(); pl("Prop key/val = " + entry.getKey().toString() + " : " + entry.getValue().toString()); } pl("—– Get content of current node."); ContentReader readerCurNode = this.contentService.getReader(actionedUponNodeRef, ContentModel.PROP_CONTENT); if (readerCurNode != null) { String contentString = readerCurNode.getContentString(); pl("readerCurNode.toString() " + readerCurNode.toString()); String[] fileList = contentString.split("\\n"); for (int x = 0; x < fileList.length; x++) { fileList[x] = fileList[x].trim(); pl("Line " + x + " = " + fileList[x]); } pl("—– Updating contents of the file."); ContentWriter writer = contentService.getWriter(actionedUponNodeRef, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.setEncoding("UTF-8"); String oString = ""; // Build up the contents to place in the file (cannot add a line at a time). for (int x = 0; x < fileList.length; x++) { oString += "Read file: " + fileList[x] + "\n"; } p(oString); writer.putContent(oString); StoreRef storeRef = actionedUponNodeRef.getStoreRef(); NodeRef rootNode = this.nodeService.getRootNode(storeRef); pl("—– Add all of the files to alfresco."); pl("storeRef.toString = " + storeRef.toString()); pl("storeRef.getIdentifier = " + storeRef.getIdentifier()); pl("Root node String = " + rootNode.toString()); pl("Root node Id = " + rootNode.getId()); pl("Adding " + fileList.length + " files to alfresco"); NodeRef[] fileRefs = new NodeRef[fileList.length]; for (int x = 0; x < fileList.length; x++) { fileRefs[x] = createFile(storeRef, fileList[x]); } pl("—– Create workflow."); // Get a list of workflow definitions and search through them for the one we want. List<WorkflowDefinition> workflowDefs = workflowService.getDefinitions(); Iterator<WorkflowDefinition> workflowDefsIterator = workflowDefs.iterator(); WorkflowDefinition workflowDef = null; // Get a handle to the required workflow. while (workflowDefsIterator.hasNext()) { workflowDef = workflowDefsIterator.next(); if (workflowDef.name.equals(JBPM_WORKFLOW_NAME)) { break; } } // If we did not find the workflow error. if (!workflowDef.name.equals(JBPM_WORKFLOW_NAME)) { pl("Unable to find jBPM workflow : " + JBPM_WORKFLOW_NAME); return; } // All OK so print out some information. pl("Found jBPM workflow : " + JBPM_WORKFLOW_NAME); pl("Name = " + workflowDef.name); pl("Description = " + workflowDef.description); pl("Id = " + workflowDef.id); pl("Title = " + workflowDef.title); pl("Version = " + workflowDef.version); pl("—– Add all of the files."); // Add the files to the workflow. NodeRef workflowNodeRef = workflowService.createPackage(null); for (int x = 0; x < fileList.length; x++) { nodeService.addChild(workflowNodeRef, fileRefs[x], ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_PREFIX, "Advert within the workflow package")); } // Finally kick the workflow off. pl("—– Start workflow"); pl("Get full path and figure out the studio and team from this."); String fullPath = nodeService.getPath(actionedUponNodeRef).toDisplayPath(nodeService); pl("NAME = " + fullPath); String[] result = fullPath.split("/"); for (int x=0; x<result.length; x++) pl("Item[" + x + "] = " + result[x]); // Set the due date. Date dueDate = new Date(System.currentTimeMillis() + DUE_HOURS.getTime()); pl("Due date = now + " + (DUE_HOURS.getTime() / DAY_IN_MILLIS) + "days (" + dueDate.toString() + ")"); // To get the parameters passed to the action. Map<String, Serializable> pars = ruleAction.getParameterValues(); pl("pars string = " + pars.toString()); Set<String> keys = pars.keySet(); Iterator<String> i = keys.iterator(); while(i.hasNext()) { pl("pars key = " + i.next()); } pl("ruleAction.getActionDefinitionName = " + ruleAction.getActionDefinitionName()); pl("ruleAction.getTitle = " + ruleAction.getTitle()); // Get a list of properties. Map<QName, Serializable> m = this.nodeService.getProperties(actionedUponNodeRef); pl("m.toString() = " + m.toString()); Set<QName> mKeys = m.keySet(); Iterator<QName> mI = mKeys.iterator(); while(mI.hasNext()) { pl("pars key = " + mI.next()); } Map<QName, Serializable> parameters = new HashMap<QName, Serializable>(); parameters.put(WorkflowModel.ASSOC_PACKAGE, workflowNodeRef); parameters.put(WorkflowModel.ASSOC_ASSIGNEE, "admin"); parameters.put(WorkflowModel.PROP_DUE_DATE, dueDate); parameters.put(WorkflowModel.PROP_DESCRIPTION, "My description…."); parameters.put(WorkflowModel.PROP_WORKFLOW_DUE_DATE, dueDate); parameters.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, "My workflow description…."); WorkflowPath path = workflowService.startWorkflow(workflowDef.id, parameters); pl("Path.toString = " + path.toString()); pl("Path.id = " + path.id); pl("Path.active = " + (path.active ? "true" : "false")); StoreRef workflowStoreRef = workflowNodeRef.getStoreRef(); pl("workflowStoreRef.toString = " + workflowStoreRef.toString()); WorkflowTaskDefinition taskDef = workflowDef.getStartTaskDefinition(); TypeDefinition td = taskDef.metadata; pl("td.getDescription = " + td.getDescription()); pl("td.getName = " + td.getName()); pl("—– Ending Action"); pl("————————————————————————"); } } }
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="mywf:my_migration_workflow"> <!– ======================================================================= –> <!– Deploy to localhost 8080 /alfresco/jbpm/deployprocess –> <!– Swimlanes for the different users the advert may touch. –> <swimlane name="artistsPool"> <assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment"> <pooledactors>#{people.getGroup(mywf_assigneeInfo)}</pooledactors> </assignment> </swimlane> <swimlane name="artist"> <assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment"> <actor>#{mywf_artist}</actor> </assignment> </swimlane> <!– Need this for initial start task. From then on it belongs to an artist or reader. –> <swimlane name="initiator"> <assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment"> <actor>#{bpm_assignee}</actor> </assignment> </swimlane> <!– ======================================================================= –> <!– States the job goes through. –> <start-state name="Start"> <task name="mywf:allocateToStudioTask" swimlane="initiator"/> <transition name="Send to Artists" to="Waiting for Artist"> <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> <script> <variable name="mywf_assigneeInfo" access="write" /> <expression> mylog.info(person.properties.userName + " started " + mywf_orderNum); mywf_assigneeInfo = "GROUP_" + mywf_studio + "-" + mywf_team + "-Artists"; </expression> </script> </action> </transition> </start-state> <task-node name="Waiting for Artist"> <task name="mywf:waitingForArtistTask" swimlane="artistsPool" /> <transition name="Work this advert" to="Create"> <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> <script> <variable name="mywf_artist" access="write" /> <expression> var workDate = new Date(); var logLine = workDate.getFullYear() + "-" + utils.pad(workDate.getMonth()+1,2) + "-" + utils.pad(workDate.getDate(),2); logLine += " " + utils.pad(workDate.getHours(),2) + ":" + utils.pad(workDate.getMinutes(),2) + ":" + utils.pad(workDate.getSeconds(),2); logLine += " : Artist Working Advert "; logLine += "(" + mywf_orderNum; logLine += ", " + person.properties.userName; logLine += ", " + mywf_studio; logLine += ", " + mywf_team + ")\r\n"; var nodeParent = companyhome.childByNamePath("Completed"); var fileName = mywf_orderNum + ".log"; var logFile = nodeParent.childByNamePath(fileName); if (logFile == null) { logFile = nodeParent.createFile(fileName); } if (logFile != null) { logFile.content += logLine; } mylog.info(person.properties.userName + " working " + mywf_orderNum); mywf_artist = person.properties.userName; </expression> </script> </action> </transition> </task-node> <task-node name="Create"> <task name="mywf:createTask" swimlane="artist" /> <transition name="Complete Job" to="Approved"> <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> <script> <expression> var completedHome = companyhome.childByNamePath("Completed"); var completeDate = new Date(); var jobSpace = mywf_orderNum + "_" + completeDate.getFullYear() + utils.pad(completeDate.getMonth()+1,2) + utils.pad(completeDate.getDate(),2); jobSpace += "_" + utils.pad(completeDate.getHours(),2) + utils.pad(completeDate.getMinutes(),2) + utils.pad(completeDate.getSeconds(),2); var completedSpace = completedHome.createFolder(jobSpace); var doneFileContents = jobSpace + "\r\n"; doneFileContents += mywf_orderNum + ".log\r\n"; doneFileContents += mywf_orderNum + ".xml\r\n"; doneFileContents += mywf_orderNum + "_import.txt\r\n"; for (var i = 0; i < bpm_package.children.length; i++) { bpm_package.children[i].move(completedSpace); doneFileContents += bpm_package.children[i].name + "\r\n"; } var jobFile = companyhome.childByNamePath(mywf_studio + "/" + mywf_team + "/" + mywf_orderNum + "_import.txt"); if (jobFile != null) { jobFile.move(completedSpace); var completeLine = completeDate.getFullYear() + "-" + utils.pad(completeDate.getMonth()+1,2) + "-" + utils.pad(completeDate.getDate(),2); completeLine += " " + utils.pad(completeDate.getHours(),2) + ":" + utils.pad(completeDate.getMinutes(),2) + ":" + utils.pad(completeDate.getSeconds(),2); completeLine += " : Artist Completed Advert "; completeLine += "(" + mywf_orderNum; completeLine += ", " + person.properties.userName; completeLine += ", " + mywf_studio; completeLine += ", " + mywf_team + ")\r\n"; var completeFileName = mywf_orderNum + ".log"; var completeFile = completedHome.childByNamePath(completeFileName); if (completeFile == null) { completeFile = completedHome.createFile(completeFileName); } if (completeFile != null) { completeFile.content += completeLine; completeFile.move(completedSpace); var xmlFileName = mywf_orderNum + ".xml"; var uploadAreaSpace = companyhome.childByNamePath("UploadArea"); if (uploadAreaSpace == null) { mylog.error("Unable to move completed files for " + mywf_orderNum); } else { var xmlFile = uploadAreaSpace.childByNamePath(xmlFileName); if (xmlFile == null) { mylog.error("Unable to move completed files for " + mywf_orderNum); } else { xmlFile.move(completedSpace); var triggerFileName = mywf_orderNum + "_export.txt"; var triggerFile = completedSpace.childByNamePath(triggerFileName); if (triggerFile == null) { triggerFile = completedHome.createFile(triggerFileName); } if (triggerFile == null) { mylog.error("Unable to move completed files for " + mywf_orderNum); } else { triggerFile.content += doneFileContents; triggerFile.move(completedSpace); mylog.info(person.properties.userName + " completed " + mywf_orderNum + " : Into folder Completed/" + jobSpace); } } } } } </expression> </script> </action> </transition> </task-node> <end-state name="Approved" /> <!– ======================================================================= –> </process-definition>