mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
First cut of the start workflow wizard
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3483 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -901,10 +901,23 @@ old_password=Old Password
|
|||||||
new_password=New Password
|
new_password=New Password
|
||||||
|
|
||||||
# Workflow messages
|
# Workflow messages
|
||||||
|
start_workflow=Start Workflow
|
||||||
|
start_workflow_wizard=Start New Workflow Wizard
|
||||||
|
start_workflow_desc=This wizard helps you start a workflow for an item in the repository.
|
||||||
|
available_workflows=Available workflows
|
||||||
|
step_choose_workflow=Choose Workflow
|
||||||
|
start_workflow_choose_title=Choose Workflow
|
||||||
|
start_workflow_choose_desc=Choose the workflow you want to start
|
||||||
|
step_workflow_options=Workflow Options
|
||||||
|
start_workflow_options_title=Workflow Options
|
||||||
|
start_workflow_options_desc=Select options for the workflow
|
||||||
|
start_workflow_finish_instruction=To start the workflow press Finish. To review or change your selections click Back.
|
||||||
|
start_workflow_no_metadata=There is no metadata to collect for this particular workflow.
|
||||||
|
users_and_roles=Users and their Roles
|
||||||
manage_workitem=Manage WorkItem
|
manage_workitem=Manage WorkItem
|
||||||
manage_workitem_title=Manage WorkItem
|
manage_workitem_title=Manage WorkItem
|
||||||
manage_workitem_desc=This dialog allows the workitem to be managed
|
manage_workitem_desc=This dialog allows the workitem to be managed
|
||||||
reassign=Reassign Task
|
reassign=Reassign
|
||||||
|
|
||||||
# Admin Console messages
|
# Admin Console messages
|
||||||
title_admin_console=Administration Console
|
title_admin_console=Administration Console
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
<value>classpath:alfresco/web-client-config-properties.xml</value>
|
<value>classpath:alfresco/web-client-config-properties.xml</value>
|
||||||
<value>classpath:alfresco/web-client-config-navigation.xml</value>
|
<value>classpath:alfresco/web-client-config-navigation.xml</value>
|
||||||
<value>classpath:alfresco/web-client-config-actions.xml</value>
|
<value>classpath:alfresco/web-client-config-actions.xml</value>
|
||||||
|
<value>classpath:alfresco/web-client-config-workflow.xml</value>
|
||||||
<value>classpath:alfresco/web-client-config-forum-actions.xml</value>
|
<value>classpath:alfresco/web-client-config-forum-actions.xml</value>
|
||||||
<value>classpath:alfresco/extension/web-client-config-custom.xml</value>
|
<value>classpath:alfresco/extension/web-client-config-custom.xml</value>
|
||||||
</list>
|
</list>
|
||||||
|
@@ -182,6 +182,31 @@
|
|||||||
</step>
|
</step>
|
||||||
</wizard>
|
</wizard>
|
||||||
|
|
||||||
|
<wizard name="startWorkflow" managed-bean="StartWorkflowWizard"
|
||||||
|
title-id="start_workflow_wizard" description-id="start_workflow_desc"
|
||||||
|
icon="/images/icons/users_large.gif">
|
||||||
|
<step name="choose-workflow" title-id="step_choose_workflow"
|
||||||
|
description-id="start_workflow_choose_desc">
|
||||||
|
<page path="/jsp/workflow/start-workflow-wizard/choose-workflow.jsp"
|
||||||
|
title-id="start_workflow_choose_title"
|
||||||
|
description-id="start_workflow_choose_desc"
|
||||||
|
instruction-id="default_instruction" />
|
||||||
|
</step>
|
||||||
|
<step name="options" title-id="step_workflow_options"
|
||||||
|
description-id="start_workflow_options_desc">
|
||||||
|
<page path="/jsp/workflow/start-workflow-wizard/workflow-options.jsp"
|
||||||
|
title-id="start_workflow_options_title"
|
||||||
|
description-id="start_workflow_options_desc"
|
||||||
|
instruction-id="default_instruction" />
|
||||||
|
</step>
|
||||||
|
<step name="summary" title-id="summary" description-id="summary_step_description">
|
||||||
|
<page path="/jsp/wizard/summary.jsp"
|
||||||
|
title-id="summary"
|
||||||
|
description-id="summary_desc"
|
||||||
|
instruction-id="start_workflow_finish_instruction" />
|
||||||
|
</step>
|
||||||
|
</wizard>
|
||||||
|
|
||||||
</wizards>
|
</wizards>
|
||||||
</config>
|
</config>
|
||||||
|
|
||||||
|
40
config/alfresco/web-client-config-workflow.xml
Normal file
40
config/alfresco/web-client-config-workflow.xml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<alfresco-config>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Properties -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<config evaluator="node-type" condition="wf:submitReviewTask">
|
||||||
|
<property-sheet>
|
||||||
|
<separator name="sep1" display-label-id="general" component-generator="HeaderSeparatorGenerator" />
|
||||||
|
<show-property name="wf:reviewDueDate" ignore-if-missing="false" />
|
||||||
|
<separator name="sep2" display-label-id="users_and_roles" component-generator="HeaderSeparatorGenerator" />
|
||||||
|
<show-association name="wf:reviewer" ignore-if-missing="false" />
|
||||||
|
</property-sheet>
|
||||||
|
</config>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Actions -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<config>
|
||||||
|
<actions>
|
||||||
|
<action id="start-workflow">
|
||||||
|
<label-id>start_workflow</label-id>
|
||||||
|
<image>/images/icons/create_forum.gif</image>
|
||||||
|
<action>wizard:startWorkflow</action>
|
||||||
|
<action-listener>#{WizardManager.setupParameters}</action-listener>
|
||||||
|
<params>
|
||||||
|
<param name="id">#{actionContext.id}</param>
|
||||||
|
</params>
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<action-group id="document_browse_menu">
|
||||||
|
<action idref="start-workflow" />
|
||||||
|
</action-group>
|
||||||
|
-->
|
||||||
|
</actions>
|
||||||
|
</config>
|
||||||
|
|
||||||
|
</alfresco-config>
|
@@ -36,8 +36,6 @@ import org.alfresco.service.cmr.security.PermissionService;
|
|||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lighweight client side representation of a node held in the repository.
|
* Lighweight client side representation of a node held in the repository.
|
||||||
@@ -48,28 +46,25 @@ public class Node implements Serializable
|
|||||||
{
|
{
|
||||||
private static final long serialVersionUID = 3544390322739034169L;
|
private static final long serialVersionUID = 3544390322739034169L;
|
||||||
|
|
||||||
protected static final Log logger = LogFactory.getLog(Node.class);
|
|
||||||
|
|
||||||
protected NodeRef nodeRef;
|
protected NodeRef nodeRef;
|
||||||
private String name;
|
protected String name;
|
||||||
private QName type;
|
protected QName type;
|
||||||
private String path;
|
protected String path;
|
||||||
private String id;
|
protected String id;
|
||||||
private Set<QName> aspects = null;
|
protected Set<QName> aspects = null;
|
||||||
private Map<String, Boolean> permissions;
|
protected Map<String, Boolean> permissions;
|
||||||
private Boolean locked = null;
|
protected Boolean locked = null;
|
||||||
private Boolean workingCopyOwner = null;
|
protected Boolean workingCopyOwner = null;
|
||||||
protected QNameNodeMap<String, Object> properties;
|
protected QNameNodeMap<String, Object> properties;
|
||||||
protected boolean propsRetrieved = false;
|
protected boolean propsRetrieved = false;
|
||||||
protected ServiceRegistry services = null;
|
protected ServiceRegistry services = null;
|
||||||
|
protected boolean childAssocsRetrieved = false;
|
||||||
|
protected QNameNodeMap childAssociations;
|
||||||
|
protected boolean assocsRetrieved = false;
|
||||||
|
protected QNameNodeMap associations;
|
||||||
|
|
||||||
private boolean childAssocsRetrieved = false;
|
|
||||||
private QNameNodeMap childAssociations;
|
|
||||||
private Map<String, Map<String, ChildAssociationRef>> childAssociationsAdded;
|
private Map<String, Map<String, ChildAssociationRef>> childAssociationsAdded;
|
||||||
private Map<String, Map<String, ChildAssociationRef>> childAssociationsRemoved;
|
private Map<String, Map<String, ChildAssociationRef>> childAssociationsRemoved;
|
||||||
|
|
||||||
private boolean assocsRetrieved = false;
|
|
||||||
private QNameNodeMap associations;
|
|
||||||
private Map<String, Map<String, AssociationRef>> associationsAdded;
|
private Map<String, Map<String, AssociationRef>> associationsAdded;
|
||||||
private Map<String, Map<String, AssociationRef>> associationsRemoved;
|
private Map<String, Map<String, AssociationRef>> associationsRemoved;
|
||||||
|
|
||||||
@@ -94,7 +89,7 @@ public class Node implements Serializable
|
|||||||
/**
|
/**
|
||||||
* @return All the properties known about this node.
|
* @return All the properties known about this node.
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> getProperties()
|
public final Map<String, Object> getProperties()
|
||||||
{
|
{
|
||||||
if (this.propsRetrieved == false)
|
if (this.propsRetrieved == false)
|
||||||
{
|
{
|
||||||
@@ -120,7 +115,7 @@ public class Node implements Serializable
|
|||||||
{
|
{
|
||||||
if (this.assocsRetrieved == false)
|
if (this.assocsRetrieved == false)
|
||||||
{
|
{
|
||||||
associations = new QNameNodeMap(getServiceRegistry().getNamespaceService(), this);
|
this.associations = new QNameNodeMap(getServiceRegistry().getNamespaceService(), this);
|
||||||
|
|
||||||
List<AssociationRef> assocs = getServiceRegistry().getNodeService().getTargetAssocs(this.nodeRef, RegexQNamePattern.MATCH_ALL);
|
List<AssociationRef> assocs = getServiceRegistry().getNodeService().getTargetAssocs(this.nodeRef, RegexQNamePattern.MATCH_ALL);
|
||||||
|
|
||||||
@@ -341,7 +336,7 @@ public class Node implements Serializable
|
|||||||
*
|
*
|
||||||
* @return true if the permission is applied to the node for this user, false otherwise
|
* @return true if the permission is applied to the node for this user, false otherwise
|
||||||
*/
|
*/
|
||||||
public final boolean hasPermission(String permission)
|
public boolean hasPermission(String permission)
|
||||||
{
|
{
|
||||||
Boolean valid = null;
|
Boolean valid = null;
|
||||||
if (permissions != null)
|
if (permissions != null)
|
||||||
|
@@ -16,15 +16,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.web.bean.repository;
|
package org.alfresco.web.bean.repository;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||||
import org.alfresco.service.namespace.QNameMap;
|
import org.alfresco.service.namespace.QNameMap;
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A extension of the repo QNameMap to provide custom property resolving support for Node wrappers.
|
* A extension of the repo QNameMap to provide custom property resolving support for Node wrappers.
|
||||||
@@ -86,6 +82,7 @@ public final class QNameNodeMap<K,V> extends QNameMap implements Map, Cloneable
|
|||||||
/**
|
/**
|
||||||
* @see java.util.Map#get(java.lang.Object)
|
* @see java.util.Map#get(java.lang.Object)
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public Object get(Object key)
|
public Object get(Object key)
|
||||||
{
|
{
|
||||||
String qnameKey = Repository.resolveToQNameString(key.toString());
|
String qnameKey = Repository.resolveToQNameString(key.toString());
|
||||||
@@ -120,6 +117,7 @@ public final class QNameNodeMap<K,V> extends QNameMap implements Map, Cloneable
|
|||||||
/**
|
/**
|
||||||
* Shallow copy the map by copying keys and values into a new QNameNodeMap
|
* Shallow copy the map by copying keys and values into a new QNameNodeMap
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public Object clone()
|
public Object clone()
|
||||||
{
|
{
|
||||||
QNameNodeMap map = new QNameNodeMap(this.resolver, this.parent);
|
QNameNodeMap map = new QNameNodeMap(this.resolver, this.parent);
|
||||||
|
141
source/java/org/alfresco/web/bean/repository/TransientNode.java
Normal file
141
source/java/org/alfresco/web/bean/repository/TransientNode.java
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
package org.alfresco.web.bean.repository;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||||
|
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||||
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||||
|
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.util.GUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a transient node i.e. it is not and will not be present in the repository.
|
||||||
|
* <p>
|
||||||
|
* This type of node is typically used to drive the property sheet when data collection
|
||||||
|
* is required for a type but the node does not need to be stored in the repository. An
|
||||||
|
* example use is the workflow, transient nodes are used to collect workitem metadata.
|
||||||
|
*
|
||||||
|
* @author gavinc
|
||||||
|
*/
|
||||||
|
public class TransientNode extends Node
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 2140554155948154106L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* <p>
|
||||||
|
* NOTE: The name is NOT automatically added to the map of properties,
|
||||||
|
* if you need the name of this node to be in the map then add it to
|
||||||
|
* the map passed in to this constructor.
|
||||||
|
*
|
||||||
|
* @param type The type this node will represent
|
||||||
|
* @param name The name of the node
|
||||||
|
* @param data The properties and associations this node will have
|
||||||
|
*/
|
||||||
|
public TransientNode(QName type, String name, Map<QName, Serializable> data)
|
||||||
|
{
|
||||||
|
// create a dummy NodeRef to pass to the constructor
|
||||||
|
super(new NodeRef(Repository.getStoreRef(), GUID.generate()));
|
||||||
|
|
||||||
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
|
|
||||||
|
// initialise the node
|
||||||
|
initNode(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialises the node.
|
||||||
|
*
|
||||||
|
* @param data The properties and associations to initialise the node with
|
||||||
|
*/
|
||||||
|
protected void initNode(Map<QName, Serializable> data)
|
||||||
|
{
|
||||||
|
// setup the transient node so that the super class methods work
|
||||||
|
// and do not need to go back to the repository
|
||||||
|
|
||||||
|
DictionaryService ddService = this.getServiceRegistry().getDictionaryService();
|
||||||
|
|
||||||
|
// marshall the given properties and associations into the internal maps
|
||||||
|
this.associations = new QNameNodeMap(getServiceRegistry().getNamespaceService(), this);
|
||||||
|
this.childAssociations = new QNameNodeMap(getServiceRegistry().getNamespaceService(), this);
|
||||||
|
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
// go through all data items and allocate to the correct internal list
|
||||||
|
for (QName item : data.keySet())
|
||||||
|
{
|
||||||
|
PropertyDefinition propDef = ddService.getProperty(item);
|
||||||
|
if (propDef != null)
|
||||||
|
{
|
||||||
|
this.properties.put(item, data.get(item));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// see if the item is either type of association
|
||||||
|
AssociationDefinition assocDef = ddService.getAssociation(item);
|
||||||
|
if (assocDef != null)
|
||||||
|
{
|
||||||
|
if (assocDef.isChild())
|
||||||
|
{
|
||||||
|
this.childAssociations.put(item, data.get(item));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.associations.put(item, data.get(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// show that the maps have been initialised
|
||||||
|
this.propsRetrieved = true;
|
||||||
|
this.assocsRetrieved = true;
|
||||||
|
this.childAssocsRetrieved = true;
|
||||||
|
|
||||||
|
// setup the list of aspects the node would have
|
||||||
|
TypeDefinition typeDef = ddService.getType(this.type);
|
||||||
|
if (typeDef == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Failed to find type definition for start task: " + this.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.aspects = new HashSet<QName>();
|
||||||
|
for (AspectDefinition aspectDef : typeDef.getDefaultAspects())
|
||||||
|
{
|
||||||
|
this.aspects.add(aspectDef.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup remaining variables
|
||||||
|
this.path = "";
|
||||||
|
this.locked = Boolean.FALSE;
|
||||||
|
this.workingCopyOwner = Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(String permission)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
// don't reset anything otherwise we'll lose our data
|
||||||
|
// with no way of getting it back!!
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "Transient node of type: " + getType() +
|
||||||
|
"\nProperties: " + this.getProperties().toString();
|
||||||
|
}
|
||||||
|
}
|
@@ -187,6 +187,18 @@ public class WizardManager
|
|||||||
{
|
{
|
||||||
return Integer.toString(this.currentStep);
|
return Integer.toString(this.currentStep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the current step, wizards should use
|
||||||
|
* the name of the step rather than the step number to discover
|
||||||
|
* the position as extra steps can be added via configuration.
|
||||||
|
*
|
||||||
|
* @return The name of the current step
|
||||||
|
*/
|
||||||
|
public String getCurrentStepName()
|
||||||
|
{
|
||||||
|
return ((StepConfig)this.steps.get(this.currentStep-1)).getName();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of UIListItems representing the steps of the wizard
|
* Returns a list of UIListItems representing the steps of the wizard
|
||||||
|
@@ -0,0 +1,286 @@
|
|||||||
|
package org.alfresco.web.bean.workflow;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
import javax.faces.model.SelectItem;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
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.WorkflowTask;
|
||||||
|
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
|
||||||
|
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.web.app.Application;
|
||||||
|
import org.alfresco.web.bean.repository.Node;
|
||||||
|
import org.alfresco.web.bean.repository.Repository;
|
||||||
|
import org.alfresco.web.bean.repository.TransientNode;
|
||||||
|
import org.alfresco.web.bean.wizard.BaseWizardBean;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean implementation for the Start Workflow Wizard.
|
||||||
|
*
|
||||||
|
* @author gavinc
|
||||||
|
*/
|
||||||
|
public class StartWorkflowWizard extends BaseWizardBean
|
||||||
|
{
|
||||||
|
protected String selectedWorkflow;
|
||||||
|
protected List<SelectItem> availableWorkflows;
|
||||||
|
protected Map<String, WorkflowDefinition> workflows;
|
||||||
|
protected WorkflowService workflowService;
|
||||||
|
protected Node startTaskNode;
|
||||||
|
protected boolean nextButtonDisabled = false;
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(StartWorkflowWizard.class);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
// Wizard implementation
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Map<String, String> parameters)
|
||||||
|
{
|
||||||
|
super.init(parameters);
|
||||||
|
|
||||||
|
// reset the selected workflow
|
||||||
|
if (this.availableWorkflows != null && this.availableWorkflows.size() > 0)
|
||||||
|
{
|
||||||
|
this.selectedWorkflow = (String)this.availableWorkflows.get(0).getValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.selectedWorkflow = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.startTaskNode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String finishImpl(FacesContext context, String outcome)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
// TODO: Deal with workflows that don't require any data
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Starting workflow with params: " + this.startTaskNode.getProperties());
|
||||||
|
|
||||||
|
// start the workflow to get access to the start task
|
||||||
|
WorkflowPath path = this.workflowService.startWorkflow(this.selectedWorkflow, prepareTaskParams());
|
||||||
|
if (path != null)
|
||||||
|
{
|
||||||
|
// extract the start task
|
||||||
|
List<WorkflowTask> tasks = this.workflowService.getTasksForWorkflowPath(path.id);
|
||||||
|
if (tasks.size() == 1)
|
||||||
|
{
|
||||||
|
WorkflowTask startTask = tasks.get(0);
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Found start task:" + startTask);
|
||||||
|
|
||||||
|
if (startTask.state == WorkflowTaskState.IN_PROGRESS)
|
||||||
|
{
|
||||||
|
// end the start task to trigger the first 'proper'
|
||||||
|
// task in the workflow
|
||||||
|
this.workflowService.endTask(startTask.id, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Started workflow: " + this.selectedWorkflow);
|
||||||
|
}
|
||||||
|
|
||||||
|
return outcome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String next()
|
||||||
|
{
|
||||||
|
String stepName = Application.getWizardManager().getCurrentStepName();
|
||||||
|
|
||||||
|
if ("options".equals(stepName) && this.startTaskNode == null)
|
||||||
|
{
|
||||||
|
// retrieve the start task for the selected workflow, get the task
|
||||||
|
// definition and create a transient node to allow the property
|
||||||
|
// sheet to collect the required data.
|
||||||
|
|
||||||
|
WorkflowDefinition flowDef = this.workflows.get(this.selectedWorkflow);
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Starting workflow: "+ flowDef);
|
||||||
|
|
||||||
|
WorkflowTaskDefinition taskDef = flowDef.startTaskDefinition;
|
||||||
|
if (taskDef != null)
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Start task definition: " + taskDef);
|
||||||
|
|
||||||
|
// create an instance of a task from the data dictionary
|
||||||
|
this.startTaskNode = new TransientNode(taskDef.metadata.getName(),
|
||||||
|
"task_" + System.currentTimeMillis(), null);
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Created node for task: " + this.startTaskNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getNextButtonDisabled()
|
||||||
|
{
|
||||||
|
return this.nextButtonDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
// Bean Getters and Setters
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the workflow selected by the user
|
||||||
|
*
|
||||||
|
* @return The selected workflow
|
||||||
|
*/
|
||||||
|
public String getSelectedWorkflow()
|
||||||
|
{
|
||||||
|
return selectedWorkflow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the selected workflow
|
||||||
|
*
|
||||||
|
* @param selectedWorkflow The workflow selected
|
||||||
|
*/
|
||||||
|
public void setSelectedWorkflow(String selectedWorkflow)
|
||||||
|
{
|
||||||
|
this.selectedWorkflow = selectedWorkflow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Node representing the start task metadata required
|
||||||
|
*
|
||||||
|
* @return The Node for the start task
|
||||||
|
*/
|
||||||
|
public Node getTaskMetadataNode()
|
||||||
|
{
|
||||||
|
return this.startTaskNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the summary data for the wizard.
|
||||||
|
*/
|
||||||
|
public String getSummary()
|
||||||
|
{
|
||||||
|
ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance());
|
||||||
|
|
||||||
|
String workflowName = null;
|
||||||
|
for (SelectItem item : this.availableWorkflows)
|
||||||
|
{
|
||||||
|
if (item.getValue().equals(this.selectedWorkflow))
|
||||||
|
{
|
||||||
|
workflowName = item.getLabel();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildSummary(
|
||||||
|
new String[] {bundle.getString("start_workflow")},
|
||||||
|
new String[] {workflowName});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of workflows that can be started.
|
||||||
|
*
|
||||||
|
* @return List of SelectItem objects representing the workflows
|
||||||
|
*/
|
||||||
|
public List<SelectItem> getStartableWorkflows()
|
||||||
|
{
|
||||||
|
if (this.availableWorkflows == null)
|
||||||
|
{
|
||||||
|
this.availableWorkflows = new ArrayList<SelectItem>(4);
|
||||||
|
this.workflows = new HashMap<String, WorkflowDefinition>(4);
|
||||||
|
|
||||||
|
List<WorkflowDefinition> workflowDefs = this.workflowService.getDefinitions();
|
||||||
|
for (WorkflowDefinition workflowDef : workflowDefs)
|
||||||
|
{
|
||||||
|
this.availableWorkflows.add(new SelectItem(workflowDef.id, workflowDef.name));
|
||||||
|
this.workflows.put(workflowDef.id, workflowDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the initial selected workflow to the first in the list, unless there are no
|
||||||
|
// workflows, in which disable the next button
|
||||||
|
if (this.availableWorkflows.size() > 0)
|
||||||
|
{
|
||||||
|
this.selectedWorkflow = (String)this.availableWorkflows.get(0).getValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.nextButtonDisabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableWorkflows;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the workflow service to use
|
||||||
|
*
|
||||||
|
* @param workflowService WorkflowService instance
|
||||||
|
*/
|
||||||
|
public void setWorkflowService(WorkflowService workflowService)
|
||||||
|
{
|
||||||
|
this.workflowService = workflowService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<QName, Serializable> prepareTaskParams()
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> params = new HashMap<QName, Serializable>();
|
||||||
|
|
||||||
|
// marshal the properties and associations captured by the property sheet
|
||||||
|
// back into a Map to pass to the workflow service
|
||||||
|
|
||||||
|
// go through all the properties in the transient node and add them to
|
||||||
|
// params map
|
||||||
|
Map<String, Object> props = this.startTaskNode.getProperties();
|
||||||
|
for (String propName : props.keySet())
|
||||||
|
{
|
||||||
|
QName propQName = Repository.resolveToQName(propName);
|
||||||
|
params.put(propQName, (Serializable)props.get(propName));
|
||||||
|
}
|
||||||
|
|
||||||
|
// go through any associations that have been added to the start task
|
||||||
|
// and build a list of NodeRefs representing the targets
|
||||||
|
Map<String, Map<String, AssociationRef>> assocs = this.startTaskNode.getAddedAssociations();
|
||||||
|
for (String assocName : assocs.keySet())
|
||||||
|
{
|
||||||
|
QName assocQName = Repository.resolveToQName(assocName);
|
||||||
|
|
||||||
|
// get the associations added and create list of targets
|
||||||
|
Map<String, AssociationRef> addedAssocs = assocs.get(assocName);
|
||||||
|
List<NodeRef> targets = new ArrayList<NodeRef>(addedAssocs.size());
|
||||||
|
for (AssociationRef assoc : addedAssocs.values())
|
||||||
|
{
|
||||||
|
targets.add(assoc.getTargetRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the targets for this particular association
|
||||||
|
params.put(assocQName, (Serializable)targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
// String reviewer = (String)this.startTaskNode.getProperties().get(
|
||||||
|
// ContentModel.PROP_NAME);
|
||||||
|
// Map<QName, Serializable> params = new HashMap<QName, Serializable>(1);
|
||||||
|
// params.put(QName.createQName(NamespaceService.DEFAULT_URI, "reviewer"), reviewer);
|
||||||
|
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
}
|
@@ -35,6 +35,7 @@ import org.alfresco.config.Config;
|
|||||||
import org.alfresco.config.ConfigLookupContext;
|
import org.alfresco.config.ConfigLookupContext;
|
||||||
import org.alfresco.config.ConfigService;
|
import org.alfresco.config.ConfigService;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
import org.alfresco.web.app.servlet.FacesHelper;
|
import org.alfresco.web.app.servlet.FacesHelper;
|
||||||
import org.alfresco.web.bean.repository.Node;
|
import org.alfresco.web.bean.repository.Node;
|
||||||
@@ -626,8 +627,13 @@ public class UIPropertySheet extends UIPanel implements NamingContainer
|
|||||||
// create the property component
|
// create the property component
|
||||||
UIProperty propComp = (UIProperty)context.getApplication().
|
UIProperty propComp = (UIProperty)context.getApplication().
|
||||||
createComponent(RepoConstants.ALFRESCO_FACES_PROPERTY);
|
createComponent(RepoConstants.ALFRESCO_FACES_PROPERTY);
|
||||||
FacesHelper.setupComponentId(context, propComp, PROP_ID_PREFIX + propertyName);
|
|
||||||
propComp.setName(propertyName);
|
// get the property name in it's prefix form
|
||||||
|
QName qname = QName.createQName(propertyName);
|
||||||
|
String prefixPropName = qname.toPrefixString();
|
||||||
|
|
||||||
|
FacesHelper.setupComponentId(context, propComp, PROP_ID_PREFIX + prefixPropName);
|
||||||
|
propComp.setName(prefixPropName);
|
||||||
|
|
||||||
// if this property sheet is set as read only, set all properties to read only
|
// if this property sheet is set as read only, set all properties to read only
|
||||||
if (isReadOnly())
|
if (isReadOnly())
|
||||||
@@ -642,7 +648,7 @@ public class UIPropertySheet extends UIPanel implements NamingContainer
|
|||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Created property component " + propComp + "(" +
|
logger.debug("Created property component " + propComp + "(" +
|
||||||
propComp.getClientId(context) +
|
propComp.getClientId(context) +
|
||||||
") for '" + propertyName +
|
") for '" + prefixPropName +
|
||||||
"' and added it to property sheet " + this);
|
"' and added it to property sheet " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,8 +660,13 @@ public class UIPropertySheet extends UIPanel implements NamingContainer
|
|||||||
String assocName = (String)iter.next();
|
String assocName = (String)iter.next();
|
||||||
UIAssociation assocComp = (UIAssociation)context.getApplication().
|
UIAssociation assocComp = (UIAssociation)context.getApplication().
|
||||||
createComponent(RepoConstants.ALFRESCO_FACES_ASSOCIATION);
|
createComponent(RepoConstants.ALFRESCO_FACES_ASSOCIATION);
|
||||||
FacesHelper.setupComponentId(context, assocComp, ASSOC_ID_PREFIX + assocName);
|
|
||||||
assocComp.setName(assocName);
|
// get the association name in it's prefix form
|
||||||
|
QName qname = QName.createQName(assocName);
|
||||||
|
String prefixAssocName = qname.toPrefixString();
|
||||||
|
|
||||||
|
FacesHelper.setupComponentId(context, assocComp, ASSOC_ID_PREFIX + prefixAssocName);
|
||||||
|
assocComp.setName(prefixAssocName);
|
||||||
|
|
||||||
// if this property sheet is set as read only, set all properties to read only
|
// if this property sheet is set as read only, set all properties to read only
|
||||||
if (isReadOnly())
|
if (isReadOnly())
|
||||||
@@ -670,7 +681,7 @@ public class UIPropertySheet extends UIPanel implements NamingContainer
|
|||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Created association component " + assocComp + "(" +
|
logger.debug("Created association component " + assocComp + "(" +
|
||||||
assocComp.getClientId(context) +
|
assocComp.getClientId(context) +
|
||||||
") for '" + assocName +
|
") for '" + prefixAssocName +
|
||||||
"' and added it to property sheet " + this);
|
"' and added it to property sheet " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1739,6 +1739,44 @@
|
|||||||
</managed-property>
|
</managed-property>
|
||||||
</managed-bean>
|
</managed-bean>
|
||||||
|
|
||||||
|
<managed-bean>
|
||||||
|
<managed-bean-name>StartWorkflowWizard</managed-bean-name>
|
||||||
|
<managed-bean-class>org.alfresco.web.bean.workflow.StartWorkflowWizard</managed-bean-class>
|
||||||
|
<managed-bean-scope>session</managed-bean-scope>
|
||||||
|
<managed-property>
|
||||||
|
<property-name>nodeService</property-name>
|
||||||
|
<value>#{NodeService}</value>
|
||||||
|
</managed-property>
|
||||||
|
<managed-property>
|
||||||
|
<property-name>fileFolderService</property-name>
|
||||||
|
<value>#{FileFolderService}</value>
|
||||||
|
</managed-property>
|
||||||
|
<managed-property>
|
||||||
|
<property-name>searchService</property-name>
|
||||||
|
<value>#{SearchService}</value>
|
||||||
|
</managed-property>
|
||||||
|
<managed-property>
|
||||||
|
<property-name>navigator</property-name>
|
||||||
|
<value>#{NavigationBean}</value>
|
||||||
|
</managed-property>
|
||||||
|
<managed-property>
|
||||||
|
<property-name>browseBean</property-name>
|
||||||
|
<value>#{BrowseBean}</value>
|
||||||
|
</managed-property>
|
||||||
|
<managed-property>
|
||||||
|
<property-name>dictionaryService</property-name>
|
||||||
|
<value>#{DictionaryService}</value>
|
||||||
|
</managed-property>
|
||||||
|
<managed-property>
|
||||||
|
<property-name>namespaceService</property-name>
|
||||||
|
<value>#{NamespaceService}</value>
|
||||||
|
</managed-property>
|
||||||
|
<managed-property>
|
||||||
|
<property-name>workflowService</property-name>
|
||||||
|
<value>#{WorkflowService}</value>
|
||||||
|
</managed-property>
|
||||||
|
</managed-bean>
|
||||||
|
|
||||||
<!-- ==================== COMPONENT GENERATOR BEANS ==================== -->
|
<!-- ==================== COMPONENT GENERATOR BEANS ==================== -->
|
||||||
<managed-bean>
|
<managed-bean>
|
||||||
<description>
|
<description>
|
||||||
|
@@ -0,0 +1,28 @@
|
|||||||
|
<%--
|
||||||
|
Copyright (C) 2005 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.
|
||||||
|
--%>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
|
||||||
|
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
|
||||||
|
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
|
||||||
|
|
||||||
|
<h:panelGrid columns="1" style="border: 1px solid #676767; background-color: #efefef; padding: 6px;">
|
||||||
|
<h:outputText value="#{msg.available_workflows}:"/>
|
||||||
|
<h:selectOneRadio id="selected-workflow" value="#{WizardManager.bean.selectedWorkflow}"
|
||||||
|
layout="pageDirection">
|
||||||
|
<f:selectItems value="#{WizardManager.bean.startableWorkflows}" />
|
||||||
|
</h:selectOneRadio>
|
||||||
|
</h:panelGrid>
|
@@ -0,0 +1,44 @@
|
|||||||
|
<%--
|
||||||
|
Copyright (C) 2005 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.
|
||||||
|
--%>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
|
||||||
|
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
|
||||||
|
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
|
||||||
|
|
||||||
|
<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
|
||||||
|
|
||||||
|
<h:panelGroup rendered="#{empty WizardManager.bean.taskMetadataNode}">
|
||||||
|
<f:verbatim>
|
||||||
|
<%PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc");%>
|
||||||
|
<table><tr><td>
|
||||||
|
</f:verbatim>
|
||||||
|
<h:graphicImage url="/images/icons/info_icon.gif" />
|
||||||
|
<f:verbatim>
|
||||||
|
</td><td>
|
||||||
|
</f:verbatim>
|
||||||
|
<h:outputText value="#{msg.start_workflow_no_metadata}" />
|
||||||
|
<f:verbatim>
|
||||||
|
</td></tr></table>
|
||||||
|
<%PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner");%>
|
||||||
|
</f:verbatim>
|
||||||
|
</h:panelGroup>
|
||||||
|
|
||||||
|
<h:panelGroup rendered="#{not empty WizardManager.bean.taskMetadataNode}">
|
||||||
|
<r:propertySheetGrid id="task-props" value="#{WizardManager.bean.taskMetadataNode}"
|
||||||
|
var="taskProps" columns="1" externalConfig="true" />
|
||||||
|
</h:panelGroup>
|
||||||
|
|
Reference in New Issue
Block a user