diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index bf1000a700..578aff3195 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -976,14 +976,17 @@ submit_submission_info=Submission Info submit_comment=Comment submit_snapshotlabel=Snapshot Label submit_workflow_selection=Use the following workflow to submit all modified items -submit_not_submit_warning=The following items will not be submitted +submit_not_submit_warning=The following items cannot be submitted as they are already part of a workflow. submit_no_workflow_warning=No suitable workflows could be found for the modified items below submit_submit_info=The following items will be submitted submit_items_title=Submit Items submit_items_desc=This page helps you to submit modified items for publishing on the website. +submit_configure_workflow=Configure Workflow +submit_configure_workflow_desc=Configure the workflow settings and parameters create_webapp=Create Webapp Folder create_webapp_title=Create Webapp Folder create_webapp_desc=Create a new root Webapp folder for this web project +submit_workflow_config_error=Workflow parameters have not been fully configured, cannot submit items. # New User Wizard messages new_user_title=New User Wizard diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml index 6e06e8a857..c6047e0a93 100644 --- a/config/alfresco/web-client-config-dialogs.xml +++ b/config/alfresco/web-client-config-dialogs.xml @@ -182,6 +182,10 @@ icon="/images/icons/submit_large.gif" title-id="submit_items_title" description-id="submit_items_desc" /> + + diff --git a/source/java/org/alfresco/web/bean/repository/Node.java b/source/java/org/alfresco/web/bean/repository/Node.java index f5e3388f19..036537666f 100644 --- a/source/java/org/alfresco/web/bean/repository/Node.java +++ b/source/java/org/alfresco/web/bean/repository/Node.java @@ -123,7 +123,7 @@ public class Node implements Serializable { String assocName = assocRef.getTypeQName().toString(); - List list = (List)this.associations.get(assocName); + List list = (List)this.associations.get(assocName); // create the list if this is first association with 'assocName' if (list == null) { diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java index 3fa1185a08..ff3890cbd2 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java @@ -113,7 +113,7 @@ public class CreateWebsiteWizard extends BaseWizardBean protected List workflows = null; /** Current workflow for dialog context */ - protected WorkflowWrapper actionWorkflow = null; + protected WorkflowConfiguration actionWorkflow = null; // ------------------------------------------------------------------------------ @@ -578,13 +578,13 @@ public class CreateWebsiteWizard extends BaseWizardBean */ public void setupWorkflowAction(ActionEvent event) { - setActionWorkflow( (WorkflowWrapper)this.workflowsDataModel.getRowData() ); + setActionWorkflow( (WorkflowConfiguration)this.workflowsDataModel.getRowData() ); } /** * @return Returns the action Workflow for dialog context */ - public WorkflowWrapper getActionWorkflow() + public WorkflowConfiguration getActionWorkflow() { return this.actionWorkflow; } @@ -592,7 +592,7 @@ public class CreateWebsiteWizard extends BaseWizardBean /** * @param actionWorkflow The action Workflow to set for dialog context */ - public void setActionWorkflow(WorkflowWrapper actionWorkflow) + public void setActionWorkflow(WorkflowConfiguration actionWorkflow) { this.actionWorkflow = actionWorkflow; } @@ -736,7 +736,7 @@ public class CreateWebsiteWizard extends BaseWizardBean /** * Wrapper class for a configurable template Form instance */ - public class FormWrapper + public static class FormWrapper { private Form form; private String title; @@ -940,7 +940,7 @@ public class CreateWebsiteWizard extends BaseWizardBean /** * Class to represent a single configured Workflow instance */ - public static class WorkflowWrapper + public static class WorkflowWrapper implements WorkflowConfiguration { private String name; private String title; @@ -956,7 +956,7 @@ public class CreateWebsiteWizard extends BaseWizardBean this.description = description; } - public WorkflowWrapper(String name, String title, String description, String filenamePattern) + public WorkflowWrapper(String name, String title, String description, String filenamePattern) { this.name = name; this.title = title; diff --git a/source/java/org/alfresco/web/bean/wcm/FormWorkflowDialog.java b/source/java/org/alfresco/web/bean/wcm/FormWorkflowDialog.java index a27e7d9666..fc011382eb 100644 --- a/source/java/org/alfresco/web/bean/wcm/FormWorkflowDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/FormWorkflowDialog.java @@ -16,7 +16,9 @@ */ package org.alfresco.web.bean.wcm; +import java.io.Serializable; import java.text.MessageFormat; +import java.util.List; import java.util.Map; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -27,11 +29,11 @@ import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition; +import org.alfresco.service.namespace.QName; import org.alfresco.web.app.Application; import org.alfresco.web.bean.dialog.BaseDialogBean; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.TransientNode; -import org.alfresco.web.bean.wcm.CreateWebsiteWizard.WorkflowWrapper; import org.alfresco.web.bean.workflow.WorkflowUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -104,13 +106,35 @@ public class FormWorkflowDialog extends BaseDialogBean this.filenamePattern = null; this.workflowNode = null; - WorkflowWrapper workflow = getActionWorkflow(); - if (workflow != null && workflow.getParams() != null) + + WorkflowConfiguration workflow = getActionWorkflow(); + if (workflow == null) { - // get params from action Workflow and populate the TransientNode properties and assocs + throw new IllegalArgumentException("Workflow action context is mandatory."); + } + + // populate the workflow if exists and already has a task type assigned + if (workflow.getType() != null) + { + // bind against current params from action Workflow this.workflowNode = new TransientNode(workflow.getType(), "task_" + System.currentTimeMillis(), workflow.getParams()); } + else + { + // no type found - init workflow node type based on workflow definition + WorkflowDefinition flowDef = this.workflowService.getDefinitionByName(workflow.getName()); + if (flowDef != null) + { + WorkflowTaskDefinition taskDef = flowDef.startTaskDefinition; + if (taskDef != null) + { + // create an instance of a task from the data dictionary + this.workflowNode = new TransientNode(taskDef.metadata.getName(), + "task_" + System.currentTimeMillis(), workflow.getParams()); + } + } + } } /** @@ -122,8 +146,31 @@ public class FormWorkflowDialog extends BaseDialogBean if (this.workflowNode != null) { // push serialized params back into workflow object - WorkflowWrapper wf = getActionWorkflow(); - wf.setParams(WorkflowUtil.prepareTaskParams(this.workflowNode)); + WorkflowConfiguration wf = getActionWorkflow(); + Map taskParams = WorkflowUtil.prepareTaskParams(this.workflowNode); + if (wf.getParams() == null) + { + wf.setParams(taskParams); + } + else + { + // merge existing with params - as only new items are returned from the editor + Map params = wf.getParams(); + for (QName qname : taskParams.keySet()) + { + Serializable value = taskParams.get(qname); + if (params.get(qname) == null || (value instanceof List == false)) + { + params.put(qname, value); + } + else + { + List current = (List)params.get(qname); + current.addAll((List)value); + } + } + wf.setParams(params); + } wf.setType(this.workflowNode.getType()); if (this.filenamePattern != null && this.filenamePattern.length() != 0) @@ -158,7 +205,7 @@ public class FormWorkflowDialog extends BaseDialogBean /** * @return an object representing the workflow for the current action */ - public WorkflowWrapper getActionWorkflow() + public WorkflowConfiguration getActionWorkflow() { return this.websiteWizard.getActionWorkflow(); } @@ -170,27 +217,6 @@ public class FormWorkflowDialog extends BaseDialogBean */ public Node getWorkflowMetadataNode() { - if (this.workflowNode == null) - { - WorkflowDefinition flowDef = this.workflowService.getDefinitionByName(getActionWorkflow().getName()); - - if (logger.isDebugEnabled()) - logger.debug("Selected workflow: "+ flowDef); - - if (flowDef != null) - { - 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.workflowNode = new TransientNode(taskDef.metadata.getName(), - "task_" + System.currentTimeMillis(), null); - } - } - } return this.workflowNode; } } diff --git a/source/java/org/alfresco/web/bean/wcm/SubmitConfigureWorkflowDialog.java b/source/java/org/alfresco/web/bean/wcm/SubmitConfigureWorkflowDialog.java new file mode 100644 index 0000000000..7f6834160e --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/SubmitConfigureWorkflowDialog.java @@ -0,0 +1,47 @@ +/* + * 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. + */ +package org.alfresco.web.bean.wcm; + + +/** + * Configure Workflow sub-dialog for the Submit Dialog. + * + * @author Kevin Roast + */ +public class SubmitConfigureWorkflowDialog extends FormWorkflowDialog +{ + protected SubmitDialog submitDialog; + + + /** + * @param submitDialog The SubmitDialog to set. + */ + public void setSubmitDialog(SubmitDialog submitDialog) + { + this.submitDialog = submitDialog; + } + + + /** + * @return an object representing the workflow for the current action + */ + @Override + public WorkflowConfiguration getActionWorkflow() + { + return this.submitDialog.getActionWorkflow(); + } +} diff --git a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java index ec9532d430..09463b2d91 100644 --- a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java @@ -28,8 +28,8 @@ import java.util.Set; import java.util.regex.Pattern; import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; -import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; import org.alfresco.repo.avm.AVMDAOs; @@ -63,12 +63,15 @@ import org.alfresco.web.ui.common.component.UIListItem; import org.alfresco.web.ui.wcm.WebResources; /** + * Submit items for WCM workflow dialog. + * * @author Kevin Roast */ public class SubmitDialog extends BaseDialogBean { private static final String SPACE_ICON = "/images/icons/" + BrowseBean.SPACE_SMALL_DEFAULT + ".gif"; private static final String MSG_DELETED_ITEM = "avm_node_deleted"; + private static final String MSG_ERR_WORKFLOW_CONFIG = "submit_workflow_config_error"; private String comment; private String label; @@ -87,6 +90,9 @@ public class SubmitDialog extends BaseDialogBean protected AVMSyncService avmSyncService; protected NameMatcher nameMatcher; + /** Current workflow for dialog context */ + protected WorkflowConfiguration actionWorkflow = null; + /** * @param avmService The AVM Service to set. */ @@ -191,9 +197,9 @@ public class SubmitDialog extends BaseDialogBean String workflowName = this.workflowSelectedValue[0]; for (FormWorkflowWrapper wrapper : this.workflows) { - if (wrapper.Name.equals(workflowName)) + if (wrapper.name.equals(workflowName)) { - params = wrapper.Params; + params = wrapper.params; } } @@ -232,8 +238,9 @@ public class SubmitDialog extends BaseDialogBean } else { - // TODO: jump to dialog and allow user to finish wf properties config! - throw new AlfrescoRuntimeException("Workflow parameters have not been configured, cannot submit items."); + // create error msg for display in dialog - the user must configure the workflow params + Utils.addErrorMessage(Application.getMessage(context, MSG_ERR_WORKFLOW_CONFIG)); + outcome = null; } } else @@ -262,6 +269,15 @@ public class SubmitDialog extends BaseDialogBean return outcome; } + /** + * @see org.alfresco.web.bean.dialog.BaseDialogBean#getFinishButtonDisabled() + */ + @Override + public boolean getFinishButtonDisabled() + { + return (getSubmitItemsSize() == 0); + } + /** * @return Returns the workflow comment. */ @@ -362,7 +378,7 @@ public class SubmitDialog extends BaseDialogBean List items = new ArrayList(this.workflows.size()); for (FormWorkflowWrapper wrapper : this.workflows) { - WorkflowDefinition workflowDef = this.workflowService.getDefinitionByName(wrapper.Name); + WorkflowDefinition workflowDef = this.workflowService.getDefinitionByName(wrapper.name); UIListItem item = new UIListItem(); item.setValue(workflowDef.getName()); item.setLabel(workflowDef.getTitle()); @@ -522,9 +538,9 @@ public class SubmitDialog extends BaseDialogBean String formName = (String)this.nodeService.getProperty( formInstanceDataRef, WCMAppModel.PROP_PARENT_FORM_NAME); FormWorkflowWrapper wrapper = this.formWorkflowMap.get(formName); - if (wrapper != null && wrapper.Params != null) + if (wrapper != null) { - // found a workflow with params attached to the form + // found a workflow attached to the form this.workflows.add(wrapper); } } @@ -595,32 +611,104 @@ public class SubmitDialog extends BaseDialogBean return packageNodeRef; } + /** + * Action method to setup a workflow for dialog context for the current row + */ + public void setupConfigureWorkflow(ActionEvent event) + { + if (this.workflowSelectedValue != null) + { + String workflowName = this.workflowSelectedValue[0]; + for (WorkflowConfiguration wrapper : this.workflows) + { + if (wrapper.getName().equals(workflowName)) + { + setActionWorkflow(wrapper); + } + } + } + } + + /** + * @return Returns the action Workflow for dialog context + */ + public WorkflowConfiguration getActionWorkflow() + { + return this.actionWorkflow; + } + + /** + * @param actionWorkflow The action Workflow to set for dialog context + */ + public void setActionWorkflow(WorkflowConfiguration actionWorkflow) + { + this.actionWorkflow = actionWorkflow; + } + /** * Simple structure class to wrap form workflow name and default parameter values */ - private static class FormWorkflowWrapper + private static class FormWorkflowWrapper implements WorkflowConfiguration { - public String Name; - public Map Params; + private String name; + private Map params; + private QName type; + private String strFilenamePattern; private Pattern filenamePattern; FormWorkflowWrapper(String name, Map params) { - this.Name = name; - this.Params = params; + this.name = name; + this.params = params; } FormWorkflowWrapper(String name, Map params, String filenamePattern) { - this.Name = name; - this.Params = params; - if (filenamePattern != null) + this.name = name; + this.params = params; + setFilenamePattern(filenamePattern); + } + + public String getName() + { + return this.name; + } + + public String getFilenamePattern() + { + return this.strFilenamePattern; + } + + public void setFilenamePattern(String pattern) + { + if (pattern != null) { - this.filenamePattern = Pattern.compile(filenamePattern); + this.strFilenamePattern = pattern; + this.filenamePattern = Pattern.compile(pattern); } } + public Map getParams() + { + return this.params; + } + + public void setParams(Map params) + { + this.params = params; + } + + public QName getType() + { + return this.type; + } + + public void setType(QName type) + { + this.type = type; + } + boolean matchesPath(String path) { if (filenamePattern != null) @@ -632,11 +720,11 @@ public class SubmitDialog extends BaseDialogBean return false; } } - + @Override public int hashCode() { - return this.Name.hashCode(); + return this.name.hashCode(); } @Override @@ -644,7 +732,7 @@ public class SubmitDialog extends BaseDialogBean { if (obj instanceof FormWorkflowWrapper) { - return this.Name.equals( ((FormWorkflowWrapper)obj).Name ); + return this.name.equals( ((FormWorkflowWrapper)obj).name ); } else { diff --git a/source/java/org/alfresco/web/bean/wcm/WorkflowConfiguration.java b/source/java/org/alfresco/web/bean/wcm/WorkflowConfiguration.java new file mode 100644 index 0000000000..d68cc03bb1 --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/WorkflowConfiguration.java @@ -0,0 +1,65 @@ +/* + * 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. + */ +package org.alfresco.web.bean.wcm; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.service.namespace.QName; + +/** + * Interface contract for wrapper classes that encapsulate workflow configuration data. + * + * @author Kevin Roast + */ +public interface WorkflowConfiguration +{ + /** + * @return definition name of the workflow + */ + public String getName(); + + /** + * @return the param map for the workflow + */ + public Map getParams(); + + /** + * @param params The param map for the workflow + */ + public void setParams(Map params); + + /** + * @return the filename pattern match regex for the workflow + */ + public String getFilenamePattern(); + + /** + * @param pattern The filename pattern match regex for the workflow + */ + public void setFilenamePattern(String pattern); + + /** + * @return the QName type of the underlying node representing the workflow + */ + public QName getType(); + + /** + * @param type QName type of the underlying node representing the workflow + */ + public void setType(QName type); +} diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index 14685b93a7..c93aba5431 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -2862,6 +2862,23 @@ + + + The bean that backs up the Submit Configure Workflow dialog + + SubmitConfigureWorkflowDialog + org.alfresco.web.bean.wcm.SubmitConfigureWorkflowDialog + session + + submitDialog + #{SubmitDialog} + + + workflowService + #{WorkflowService} + + + diff --git a/source/web/jsp/wcm/submit-config-workflow.jsp b/source/web/jsp/wcm/submit-config-workflow.jsp new file mode 100644 index 0000000000..3d06be32b5 --- /dev/null +++ b/source/web/jsp/wcm/submit-config-workflow.jsp @@ -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" %> + +<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> +<%@ page isELIgnored="false" %> + + + + diff --git a/source/web/jsp/wcm/submit-dialog.jsp b/source/web/jsp/wcm/submit-dialog.jsp index 98ffbb647e..4d69aeff2c 100644 --- a/source/web/jsp/wcm/submit-dialog.jsp +++ b/source/web/jsp/wcm/submit-dialog.jsp @@ -26,23 +26,28 @@