diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml index 7c300ec6e7..97cf25064a 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml @@ -98,7 +98,7 @@ - + @@ -111,6 +111,9 @@ + + + @@ -203,7 +206,7 @@ class="org.alfresco.module.org_alfresco_module_rm.forms.RecordsManagementNodeFormFilter"> - + + + + + + RECORD + + + + + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-workflow-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-workflow-context.xml new file mode 100644 index 0000000000..3f3f30d59d --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-workflow-context.xml @@ -0,0 +1,30 @@ + + + + + + + + + activiti + alfresco/workflow/requestInfo.bpmn20.xml + text/xml + false + + + + + + alfresco/workflow/rmWorkflowModel.xml + + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/workflow/requestInfo.bpmn20.xml b/rm-server/config/alfresco/workflow/requestInfo.bpmn20.xml new file mode 100644 index 0000000000..9731a15c90 --- /dev/null +++ b/rm-server/config/alfresco/workflow/requestInfo.bpmn20.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/workflow/rmWorkflowModel.xml b/rm-server/config/alfresco/workflow/rmWorkflowModel.xml new file mode 100644 index 0000000000..7ee9da4b23 --- /dev/null +++ b/rm-server/config/alfresco/workflow/rmWorkflowModel.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + bpm:workflowTask + + + d:text + true + + + d:text + true + + + + + + rmwf:workflowTask + + + + false + false + + + cm:authority + true + true + + + + + + + rmwf:workflowTask + + + + rmwf:workflowTask + + + false + + + + + + \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoAssignmentHandler.java b/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoAssignmentHandler.java new file mode 100644 index 0000000000..e707859a0c --- /dev/null +++ b/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoAssignmentHandler.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2005-2013 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.workflow.requestInfo; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.activiti.engine.delegate.DelegateTask; +import org.activiti.engine.delegate.TaskListener; +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.workflow.activiti.ActivitiScriptNode; +import org.alfresco.repo.workflow.activiti.ActivitiScriptNodeList; +import org.alfresco.util.ParameterCheck; + +/** + * An assignment handler for the request info workflow. + * An RM manager/admin can select one or more user(s) and/or + * one or more group(s) when starting the request info workflow. + * This assignment handler assigns for everyone a task (it is a pooled task). + * + * @author Tuna Aksoy + * @since 2.1 + */ +public class RequestInfoAssignmentHandler implements TaskListener +{ + /** + * @see org.activiti.engine.delegate.TaskListener#notify(org.activiti.engine.delegate.DelegateTask) + */ + @Override + public void notify(DelegateTask delegateTask) + { + ParameterCheck.mandatory("delegateTask", delegateTask); + + // Set the workflow description for the task + // FIXME: I18N!!! + // FIXME: Record name!!! + delegateTask.setVariable("bpm_workflowDescription", "Information requested for record '" + "test.doc" + "'"); + + // Get the list of user(s) and/or group(s) + ActivitiScriptNodeList usersAndGroups = (ActivitiScriptNodeList) delegateTask.getVariable("rmwf_mixedAssignees"); + + // Check if it was possible to extract the user(s) and/or group(s) + if (usersAndGroups == null) + { + throw new AlfrescoRuntimeException("It was not possible to extract the user(s) and/or group(s)!!!"); + } + + // Define lists for candidate user(s)/group(s) + List candidateUsers = new ArrayList(); + List candidateGroups = new ArrayList(); + + // Iterate through the list add user(s)/group(s) to the lists + for (ActivitiScriptNode activitiScriptNode : usersAndGroups) + { + // Get the node type + String type = activitiScriptNode.getType(); + // Get the properties + Map properties = activitiScriptNode.getProperties(); + + // Check if it is a user or a group + if (type.equalsIgnoreCase(ContentModel.TYPE_PERSON.toString())) + { + // Add the user + candidateUsers.add((String) properties.get(ContentModel.PROP_USERNAME.toString())); + } + else if (type.equalsIgnoreCase(ContentModel.TYPE_AUTHORITY_CONTAINER.toString())) + { + // Add the group + candidateGroups.add((String) properties.get(ContentModel.PROP_AUTHORITY_NAME.toString())); + } + else + { + throw new AlfrescoRuntimeException("The type '" + type + "' is neither a user nor a group!!!"); + } + } + + // Check if there is at least one user or one group + if (candidateUsers.size() == 0 && candidateGroups.size() == 0) + { + throw new AlfrescoRuntimeException("Neither a user nor a group was found!!!"); + } + + // Add the user(s) to the task + if (candidateUsers.size() > 0) + { + delegateTask.addCandidateUsers(candidateUsers); + } + + // Add the group(s) to the task + if (candidateGroups.size() > 0) + { + delegateTask.addCandidateGroups(candidateGroups); + } + } +} diff --git a/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoNotifier.java b/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoNotifier.java new file mode 100644 index 0000000000..3a20323b79 --- /dev/null +++ b/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoNotifier.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2005-2013 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.workflow.requestInfo; + +import org.activiti.engine.delegate.DelegateTask; +import org.activiti.engine.delegate.TaskListener; +import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.activiti.engine.impl.context.Context; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.notification.EMailNotificationProvider; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.workflow.activiti.ActivitiConstants; +import org.alfresco.repo.workflow.activiti.ActivitiScriptNode; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.notification.NotificationContext; +import org.alfresco.util.ParameterCheck; + +/** + * Request info workflow notifier. + * After the pooled task has been finished the initiator of the workflow will + * get a task to verify the information. The initiator will also receive an email. + * + * @author Tuna Aksoy + * @since v2.1 + */ +public class RequestInfoNotifier implements TaskListener +{ + /** + * @see org.activiti.engine.delegate.TaskListener#notify(org.activiti.engine.delegate.DelegateTask) + */ + @Override + public void notify(DelegateTask delegateTask) + { + ParameterCheck.mandatory("delegateTask", delegateTask); + + // Set the workflow description for the task + // FIXME: I18N!!! + // FIXME: Record name!!! + delegateTask.setVariable("bpm_workflowDescription", "Information provided for record '" + "test.doc" + "'"); + + // Assign the task to the initiator + String initiator = getInitiator(delegateTask); + delegateTask.setAssignee(initiator); + + // Create the context and send an email to the initiator + NotificationContext notificationContext = new NotificationContext(); + notificationContext.setAsyncNotification(true); + notificationContext.setIgnoreNotificationFailure(true); + notificationContext.addTo(initiator); + // FIXME: I18N!!! and get the record name and the user name who provided the information + notificationContext.setSubject("Information provided for the record '" + "" + "'."); + notificationContext.setBody("The user '" + "' has provided the needed information for the record '" + "" + "'."); + + // Send the email + getServiceRegistry().getNotificationService().sendNotification(EMailNotificationProvider.NAME, notificationContext); + } + + /** + * Helper method to extract the initiator from the task + * + * @param delegateTask The delegate task + * @return Returns the initiator of the workflow. If the initiator does not exist the admin user will be returned. + */ + private String getInitiator(DelegateTask delegateTask) + { + String userName = null; + ActivitiScriptNode initiator = (ActivitiScriptNode) delegateTask.getVariable("initiator"); + if (initiator.exists()) + { + userName = (String) initiator.getProperties().get(ContentModel.PROP_USERNAME.toString()); + } + else + { + userName = AuthenticationUtil.getAdminUserName(); + } + return userName; + } + + //FIXME: Is there a better way to call services? + + /** + * Helper method for getting the service registry in order to call services + * + * @return Returns the service registry + */ + private ServiceRegistry getServiceRegistry() + { + ProcessEngineConfigurationImpl config = Context.getProcessEngineConfiguration(); + if (config != null) + { + // Fetch the registry that is injected in the activiti spring-configuration + ServiceRegistry registry = (ServiceRegistry) config.getBeans().get(ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY); + if (registry == null) + { + throw new RuntimeException( + "Service-registry not present in ProcessEngineConfiguration beans, expected ServiceRegistry with key" + + ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY); + } + return registry; + } + throw new IllegalStateException("No ProcessEngineCOnfiguration found in active context"); + } +} diff --git a/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoVariableHandler.java b/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoVariableHandler.java new file mode 100644 index 0000000000..7a3b592fd0 --- /dev/null +++ b/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoVariableHandler.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2005-2013 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.workflow.requestInfo; + +import org.activiti.engine.delegate.DelegateExecution; +import org.activiti.engine.delegate.DelegateTask; +import org.activiti.engine.delegate.TaskListener; +import org.alfresco.util.ParameterCheck; + +/** + * A variable handler for saving the task variables to the execution context. + * Some of the information will be needed in other tasks (e.g. "rmwf_message"). + * This variable handler saves the local task variable to the execution context. + * + * @author Tuna Aksoy + * @since 2.1 + */ +public class RequestInfoVariableHandler implements TaskListener +{ + /** + * @see org.activiti.engine.delegate.TaskListener#notify(org.activiti.engine.delegate.DelegateTask) + */ + @Override + public void notify(DelegateTask delegateTask) + { + ParameterCheck.mandatory("delegateTask", delegateTask); + + // Save the variable from the task + DelegateExecution execution = delegateTask.getExecution(); + execution.setVariable("rmwf_message", delegateTask.getVariable("rmwf_message")); + } +} \ No newline at end of file