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