package com.github.dynamicextensionsalfresco.workflow; import com.github.dynamicextensionsalfresco.resources.BootstrapService; import com.github.dynamicextensionsalfresco.resources.ContentCompareStrategy; import com.github.dynamicextensionsalfresco.resources.ResourceHelper; import com.google.common.collect.ImmutableMap; import org.alfresco.model.ContentModel; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.dictionary.RepositoryLocation; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import java.io.Serializable; import java.util.Map; import static org.alfresco.repo.security.authentication.AuthenticationUtil.runAs; /** * Service that inspect the {@link WorkflowDefinitionRegistrar#workflowLocationPattern} to find workflow definitions and * stores them in the Data Dictionary to enable update detection. * <br/> * Know issue: Alfresco has policies in place to deploy workflow definitions from the Data Dictionary / Workflow Definitions * folder. However these show up as <i>(Nameless deployment)</i> in the Activiti admin console. * * @author Laurent Van der Linden */ public class WorkflowDefinitionRegistrar implements InitializingBean { private static final String workflowLocationPattern = "osgibundle:/META-INF/alfresco/workflows/*.bpmn20.xml"; private final static Logger logger = LoggerFactory.getLogger(WorkflowDefinitionRegistrar.class); @Autowired protected RepositoryLocation customWorkflowDefsRepositoryLocation; @Autowired protected ResourceHelper resourceHelper; @Autowired protected BootstrapService bootstrapService; @Autowired protected NodeService nodeService; @Autowired protected TransactionService transactionService; @Override public void afterPropertiesSet() throws Exception { runAs(new AuthenticationUtil.RunAsWork<Object>() { @Override public Object doWork() throws Exception { try { transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Object>() { @Override public Object execute() throws Throwable { final Map<Resource,NodeRef> deployed = bootstrapService.deployResources( workflowLocationPattern, customWorkflowDefsRepositoryLocation, new ContentCompareStrategy(resourceHelper), "UTF-8", MimetypeMap.MIMETYPE_XML, WorkflowModel.TYPE_WORKFLOW_DEF ); for (Map.Entry<Resource, NodeRef> entry : deployed.entrySet()) { final NodeRef nodeRef = entry.getValue(); if (!Boolean.TRUE.equals(nodeService.getProperty(nodeRef, WorkflowModel.PROP_WORKFLOW_DEF_DEPLOYED))) { final Resource workflowDefinition = entry.getKey(); final String fileName = workflowDefinition.getFilename(); nodeService.setProperty(nodeRef, WorkflowModel.PROP_WORKFLOW_DEF_ENGINE_ID, "activiti"); nodeService.setProperty(nodeRef, WorkflowModel.PROP_WORKFLOW_DEF_NAME, fileName); nodeService.setProperty(nodeRef, WorkflowModel.PROP_WORKFLOW_DEFINITION_NAME, fileName); nodeService.addAspect(nodeRef, ContentModel.ASPECT_TITLED, ImmutableMap.<QName, Serializable>builder() .put(ContentModel.PROP_TITLE, fileName) .build() ); nodeService.setProperty(nodeRef, WorkflowModel.PROP_WORKFLOW_DEF_DEPLOYED, true); } } return null; } }, false, false); } catch (Exception e) { logger.error("tx error", e); } return null; } }, AuthenticationUtil.getSystemUserName()); } }