mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.1 to HEAD
13033: Back end support for ETHREEOH-1179 13038: JAWS-436 - refactor WCM submit dialog to use WCM sandbox service + update unit tests 13046: Merged V3.0 to V3.1 13043: Merged V2.2 to V3.0 13016: Fix for ETWOTWO-1088 (reset layer using flatten rather than delete & add, users can flatten in stores they own but not delete) 13049: Build/test fix (WCM AssetTest) 13057: Merged V2.1-A to V3.1 8770: Added Flex SDK module 8771: Added Flex SDK binary (swc) DH: I'm not sure about the svn:eol-style property appearing here. SVN Clients? 13059: Added 'AIX' as a platform type, from Adobe V2.1A, missed checkin. 13060: [no comments] 13061: [no comments] 13063: [no comments] 13064: [no comments] 13066: [no comments] 13067: Add NodeService.getChildrenByName 13072: Added new NodeService.getChildrenByName() method to public-services-security-context. ___________________________________________________________________ Modified: svn:mergeinfo Merged /alfresco/BRANCHES/V3.0:r13043 Merged /alfresco/BRANCHES/V2.2:r13016 Merged /alfresco/BRANCHES/V3.1:r13033,13038,13046,13049,13057,13059-13061,13063-13064,13066-13067,13072 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13552 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -32,7 +32,6 @@ import java.io.ObjectOutputStream;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
@@ -41,24 +40,16 @@ import javax.faces.context.FacesContext;
|
|||||||
import org.alfresco.config.ConfigElement;
|
import org.alfresco.config.ConfigElement;
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.model.WCMAppModel;
|
import org.alfresco.model.WCMAppModel;
|
||||||
import org.alfresco.repo.avm.AVMNodeConverter;
|
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.domain.PropertyValue;
|
|
||||||
import org.alfresco.repo.workflow.WorkflowModel;
|
|
||||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||||
import org.alfresco.service.cmr.avm.AVMService;
|
import org.alfresco.service.cmr.avm.AVMService;
|
||||||
import org.alfresco.service.cmr.avmsync.AVMDifference;
|
|
||||||
import org.alfresco.service.cmr.avmsync.AVMSyncService;
|
|
||||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
|
||||||
import org.alfresco.service.cmr.repository.ContentReader;
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
import org.alfresco.service.cmr.repository.ContentService;
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
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.WorkflowService;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||||
import org.alfresco.wcm.sandbox.SandboxInfo;
|
|
||||||
import org.alfresco.wcm.util.WCMWorkflowUtil;
|
import org.alfresco.wcm.util.WCMWorkflowUtil;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
import org.alfresco.web.bean.repository.Repository;
|
import org.alfresco.web.bean.repository.Repository;
|
||||||
@@ -78,34 +69,6 @@ public class AVMWorkflowUtil extends WorkflowUtil
|
|||||||
|
|
||||||
// cached configured lists
|
// cached configured lists
|
||||||
private static List<WorkflowDefinition> configuredWorkflowDefs = null;
|
private static List<WorkflowDefinition> configuredWorkflowDefs = null;
|
||||||
|
|
||||||
public static NodeRef createWorkflowPackage(final List<String> srcPaths,
|
|
||||||
final SandboxInfo sandboxInfo,
|
|
||||||
final WorkflowPath path)
|
|
||||||
{
|
|
||||||
final FacesContext fc = FacesContext.getCurrentInstance();
|
|
||||||
final WorkflowService workflowService = Repository.getServiceRegistry(fc).getWorkflowService();
|
|
||||||
final AVMService avmService = Repository.getServiceRegistry(fc).getAVMLockingAwareService();
|
|
||||||
|
|
||||||
// create package paths (layered to user sandbox area as target)
|
|
||||||
final String workflowMainStoreName = sandboxInfo.getMainStoreName();
|
|
||||||
final String packagesPath = AVMUtil.buildStoreRootPath(workflowMainStoreName);
|
|
||||||
|
|
||||||
// convert package to workflow package
|
|
||||||
final AVMNodeDescriptor packageDesc = avmService.lookup(-1, packagesPath);
|
|
||||||
final NodeRef packageNodeRef = workflowService.createPackage(AVMNodeConverter.ToNodeRef(-1, packageDesc.getPath()));
|
|
||||||
|
|
||||||
avmService.setNodeProperty(packagesPath, WorkflowModel.PROP_IS_SYSTEM_PACKAGE, new PropertyValue(DataTypeDefinition.BOOLEAN, true));
|
|
||||||
|
|
||||||
// NOTE: WCM-1019: As permissions are now implemented for AVM nodes we no longer need to set permisssions here
|
|
||||||
// as they will be inherited from the store the workflow store is layered over.
|
|
||||||
|
|
||||||
//final ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance());
|
|
||||||
//final PermissionService permissionService = services.getPermissionService();
|
|
||||||
//permissionService.setPermission(packageNodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.ALL_PERMISSIONS, true);
|
|
||||||
|
|
||||||
return packageNodeRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize the workflow params to a content stream
|
* Serialize the workflow params to a content stream
|
||||||
@@ -227,10 +190,4 @@ public class AVMWorkflowUtil extends WorkflowUtil
|
|||||||
AVMService avmService = Repository.getServiceRegistry(fc).getAVMService();
|
AVMService avmService = Repository.getServiceRegistry(fc).getAVMService();
|
||||||
return WCMWorkflowUtil.getAssociatedTasksForNode(avmService, node, tasks);
|
return WCMWorkflowUtil.getAssociatedTasksForNode(avmService, node, tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<WorkflowTask> getAssociatedTasksForNode(AVMNodeDescriptor node)
|
|
||||||
{
|
|
||||||
final List<WorkflowTask> tasks = AVMWorkflowUtil.getAssociatedTasksForSandbox(AVMUtil.getStoreName(node.getPath()));
|
|
||||||
return AVMWorkflowUtil.getAssociatedTasksForNode(node, tasks);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -42,31 +42,22 @@ import javax.transaction.UserTransaction;
|
|||||||
import org.alfresco.config.JNDIConstants;
|
import org.alfresco.config.JNDIConstants;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.model.WCMAppModel;
|
import org.alfresco.model.WCMAppModel;
|
||||||
import org.alfresco.model.WCMWorkflowModel;
|
|
||||||
import org.alfresco.repo.avm.AVMNodeConverter;
|
import org.alfresco.repo.avm.AVMNodeConverter;
|
||||||
import org.alfresco.repo.domain.PropertyValue;
|
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
|
||||||
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
||||||
import org.alfresco.repo.workflow.WorkflowModel;
|
|
||||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||||
import org.alfresco.service.cmr.avm.AVMService;
|
import org.alfresco.service.cmr.avm.AVMService;
|
||||||
import org.alfresco.service.cmr.avmsync.AVMDifference;
|
import org.alfresco.service.cmr.avmsync.AVMDifference;
|
||||||
import org.alfresco.service.cmr.avmsync.AVMSyncService;
|
import org.alfresco.service.cmr.avmsync.AVMSyncService;
|
||||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
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.WorkflowService;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
|
||||||
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.util.ISO8601DateFormat;
|
import org.alfresco.util.ISO8601DateFormat;
|
||||||
import org.alfresco.util.NameMatcher;
|
import org.alfresco.util.NameMatcher;
|
||||||
import org.alfresco.wcm.sandbox.SandboxFactory;
|
import org.alfresco.wcm.sandbox.SandboxFactory;
|
||||||
import org.alfresco.wcm.sandbox.SandboxInfo;
|
|
||||||
import org.alfresco.wcm.sandbox.SandboxService;
|
import org.alfresco.wcm.sandbox.SandboxService;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
import org.alfresco.web.app.servlet.DownloadContentServlet;
|
import org.alfresco.web.app.servlet.DownloadContentServlet;
|
||||||
@@ -97,8 +88,6 @@ public class SubmitDialog extends BaseDialogBean
|
|||||||
private static final String MSG_DELETED_ITEM = "avm_node_deleted";
|
private static final String MSG_DELETED_ITEM = "avm_node_deleted";
|
||||||
private static final String MSG_ERR_WORKFLOW_CONFIG = "submit_workflow_config_error";
|
private static final String MSG_ERR_WORKFLOW_CONFIG = "submit_workflow_config_error";
|
||||||
|
|
||||||
private static final String WORKFLOW_SUBMITDIRECT = "jbpm$wcmwf:submitdirect";
|
|
||||||
|
|
||||||
private String comment;
|
private String comment;
|
||||||
private String label;
|
private String label;
|
||||||
private String[] workflowSelectedValue;
|
private String[] workflowSelectedValue;
|
||||||
@@ -115,19 +104,6 @@ public class SubmitDialog extends BaseDialogBean
|
|||||||
private Map<String, Date> expirationDates;
|
private Map<String, Date> expirationDates;
|
||||||
private List<UIListItem> workflowItems;
|
private List<UIListItem> workflowItems;
|
||||||
private Map<QName, Serializable> workflowParams;
|
private Map<QName, Serializable> workflowParams;
|
||||||
private SandboxInfo sandboxInfo;
|
|
||||||
private List<String> srcPaths;
|
|
||||||
|
|
||||||
// The virtualization server might need to be notified
|
|
||||||
// because one or more of the files submitted could alter
|
|
||||||
// the behavior the virtual webapp in the target of the submit.
|
|
||||||
// For example, the user might be submitting a new jar or web.xml file.
|
|
||||||
//
|
|
||||||
// This must take place after the transaction has been completed;
|
|
||||||
// therefore, a variable is needed to store the path to the
|
|
||||||
// updated webapp so it can happen in doPostCommitProcessing.
|
|
||||||
private String virtUpdatePath;
|
|
||||||
|
|
||||||
|
|
||||||
protected AVMBrowseBean avmBrowseBean;
|
protected AVMBrowseBean avmBrowseBean;
|
||||||
|
|
||||||
@@ -294,8 +270,6 @@ public class SubmitDialog extends BaseDialogBean
|
|||||||
this.validateLinks = this.avmBrowseBean.getLinkValidationEnabled();
|
this.validateLinks = this.avmBrowseBean.getLinkValidationEnabled();
|
||||||
this.autoDeploy = false;
|
this.autoDeploy = false;
|
||||||
this.workflowParams = null;
|
this.workflowParams = null;
|
||||||
this.sandboxInfo = null;
|
|
||||||
this.virtUpdatePath = null;
|
|
||||||
|
|
||||||
// determine if the dialog has been started from a workflow
|
// determine if the dialog has been started from a workflow
|
||||||
this.loadSelectedNodesFromBrowseBean = Boolean.valueOf(this.parameters.get(PARAM_LOAD_SELECTED_NODES_FROM_BROWSE_BEAN));
|
this.loadSelectedNodesFromBrowseBean = Boolean.valueOf(this.parameters.get(PARAM_LOAD_SELECTED_NODES_FROM_BROWSE_BEAN));
|
||||||
@@ -339,7 +313,51 @@ public class SubmitDialog extends BaseDialogBean
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// note: always submit via workflow (always defaults to direct submit workflow)
|
// note: always submit via workflow (always defaults to direct submit workflow)
|
||||||
outcome = submitViaWorkflow(context);
|
//outcome = submitViaWorkflow(context);
|
||||||
|
|
||||||
|
String workflowName = null;
|
||||||
|
if ((this.workflowSelectedValue != null) && (this.workflowSelectedValue.length > 0))
|
||||||
|
{
|
||||||
|
// get the defaults from the workflow configuration attached to the selected workflow
|
||||||
|
workflowName = this.workflowSelectedValue[0];
|
||||||
|
for (FormWorkflowWrapper wrapper : this.workflows)
|
||||||
|
{
|
||||||
|
if (wrapper.name.equals(workflowName))
|
||||||
|
{
|
||||||
|
this.workflowParams = wrapper.params;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.workflowParams == null)
|
||||||
|
{
|
||||||
|
// create error msg for display in dialog - the user must configure the workflow params
|
||||||
|
Utils.addErrorMessage(Application.getMessage(context, MSG_ERR_WORKFLOW_CONFIG));
|
||||||
|
return outcome;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ItemWrapper> items = getSubmitItems();
|
||||||
|
|
||||||
|
List<String> relativePaths = new ArrayList<String>(items.size());
|
||||||
|
|
||||||
|
for (ItemWrapper wrapper : items)
|
||||||
|
{
|
||||||
|
relativePaths.add(AVMUtil.getStoreRelativePath(wrapper.getDescriptor().getPath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
String sbStoreId = this.avmBrowseBean.getSandbox();
|
||||||
|
|
||||||
|
String submitLabel = this.label;
|
||||||
|
String submitComment = this.comment;
|
||||||
|
|
||||||
|
// note: always submit via workflow (if no workflow selected, then defaults to direct submit workflow)
|
||||||
|
getSandboxService().submitListAssets(sbStoreId, relativePaths,
|
||||||
|
workflowName, workflowParams,
|
||||||
|
submitLabel, submitComment,
|
||||||
|
expirationDates, launchDate, validateLinks, autoDeploy);
|
||||||
|
|
||||||
|
// if we get this far return the default outcome
|
||||||
|
outcome = this.getDefaultFinishOutcome();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -350,286 +368,6 @@ public class SubmitDialog extends BaseDialogBean
|
|||||||
|
|
||||||
return outcome;
|
return outcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Submits the selected items via the configured workflow.
|
|
||||||
* <p>
|
|
||||||
* This method uses 2 separate transactions to perform the submit.
|
|
||||||
* The first one creates the workflow sandbox. The virtualisation
|
|
||||||
* server is then informed of the new stores. The second
|
|
||||||
* transaction then starts the appropriate workflow. This approach
|
|
||||||
* is needed to allow link validation to be performed on the
|
|
||||||
* workflow sandbox.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param context Faces context
|
|
||||||
* @return The outcome to use
|
|
||||||
*/
|
|
||||||
protected String submitViaWorkflow(final FacesContext context)
|
|
||||||
{
|
|
||||||
String outcome = null;
|
|
||||||
|
|
||||||
RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(context);
|
|
||||||
RetryingTransactionCallback<String> sandboxCallback = new RetryingTransactionCallback<String>()
|
|
||||||
{
|
|
||||||
public String execute() throws Throwable
|
|
||||||
{
|
|
||||||
// call the actual implementation
|
|
||||||
createWorkflowSandbox(context);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
RetryingTransactionCallback<String> workflowCallback = new RetryingTransactionCallback<String>()
|
|
||||||
{
|
|
||||||
public String execute() throws Throwable
|
|
||||||
{
|
|
||||||
// call the actual implementation
|
|
||||||
startWorkflow();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// create the workflow sandbox firstly
|
|
||||||
txnHelper.doInTransaction(sandboxCallback, false, true);
|
|
||||||
|
|
||||||
if (this.sandboxInfo != null)
|
|
||||||
{
|
|
||||||
// inform the virtualisation server if the workflow sandbox was created
|
|
||||||
if (this.virtUpdatePath != null)
|
|
||||||
{
|
|
||||||
AVMUtil.updateVServerWebapp(this.virtUpdatePath, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// start the workflow
|
|
||||||
txnHelper.doInTransaction(workflowCallback, false, true);
|
|
||||||
}
|
|
||||||
catch (Throwable err)
|
|
||||||
{
|
|
||||||
cleanupWorkflowSandbox(context);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we get this far return the default outcome
|
|
||||||
outcome = this.getDefaultFinishOutcome();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Throwable e)
|
|
||||||
{
|
|
||||||
Utils.addErrorMessage(formatErrorMessage(e), e);
|
|
||||||
outcome = getErrorOutcome(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return outcome;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a workflow sandbox for all the submitted items
|
|
||||||
*
|
|
||||||
* @param context Faces context
|
|
||||||
*/
|
|
||||||
protected void createWorkflowSandbox(FacesContext context)
|
|
||||||
{
|
|
||||||
if (this.workflowSelectedValue != null && this.workflowSelectedValue.length > 0)
|
|
||||||
{
|
|
||||||
// get the defaults from the workflow configuration attached to the selected workflow
|
|
||||||
String workflowName = this.workflowSelectedValue[0];
|
|
||||||
for (FormWorkflowWrapper wrapper : this.workflows)
|
|
||||||
{
|
|
||||||
if (wrapper.name.equals(workflowName))
|
|
||||||
{
|
|
||||||
this.workflowParams = wrapper.params;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.workflowParams == null)
|
|
||||||
{
|
|
||||||
// create error msg for display in dialog - the user must configure the workflow params
|
|
||||||
Utils.addErrorMessage(Application.getMessage(context, MSG_ERR_WORKFLOW_CONFIG));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create workflow sandbox for workflow package
|
|
||||||
this.sandboxInfo = sandboxFactory.createWorkflowSandbox(this.avmBrowseBean.getStagingStore());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// default to direct submit workflow
|
|
||||||
this.workflowSelectedValue = new String[] { WORKFLOW_SUBMITDIRECT };
|
|
||||||
this.workflowParams = new HashMap<QName, Serializable>();
|
|
||||||
|
|
||||||
// NOTE: read only workflow sandbox is lighter to construct than full workflow sandbox
|
|
||||||
this.sandboxInfo = sandboxFactory.createReadOnlyWorkflowSandbox(this.avmBrowseBean.getStagingStore());
|
|
||||||
}
|
|
||||||
|
|
||||||
// create container for our avm workflow package
|
|
||||||
final List<ItemWrapper> items = this.getSubmitItems();
|
|
||||||
this.srcPaths = new ArrayList<String>(items.size());
|
|
||||||
|
|
||||||
for (ItemWrapper wrapper : items)
|
|
||||||
{
|
|
||||||
// Example srcPath:
|
|
||||||
// mysite--alice:/www/avm_webapps/ROOT/foo.txt
|
|
||||||
String srcPath = wrapper.getDescriptor().getPath();
|
|
||||||
|
|
||||||
// We *always* want to update virtualization server
|
|
||||||
// when a workflow sandbox is given data in the
|
|
||||||
// context of a submit workflow. Without this,
|
|
||||||
// it would be impossible to see workflow data
|
|
||||||
// in context. The raw operation to create a
|
|
||||||
// workflow sandbox does not notify the virtualization
|
|
||||||
// server that it exists because it's useful to
|
|
||||||
// defer this operation until everything is already
|
|
||||||
// in place; this allows pointlessly fine-grained
|
|
||||||
// notifications to be suppressed (they're expensive).
|
|
||||||
//
|
|
||||||
// Therefore, just derive the name of the webapp
|
|
||||||
// in the workflow sandbox from the 1st item in
|
|
||||||
// the submit list (even if it's not in WEB-INF),
|
|
||||||
// and force the virt server notification after the
|
|
||||||
// transaction has completed via doPostCommitProcessing.
|
|
||||||
if (this.virtUpdatePath == null)
|
|
||||||
{
|
|
||||||
// Example workflow main store name:
|
|
||||||
// mysite--workflow-9161f640-b020-11db-8015-130bf9b5b652
|
|
||||||
String workflowMainStoreName = sandboxInfo.getMainStoreName();
|
|
||||||
|
|
||||||
// The virtUpdatePath looks just like the srcPath
|
|
||||||
// except that it belongs to a the main store of
|
|
||||||
// the workflow sandbox instead of the sandbox
|
|
||||||
// that originated the submit.
|
|
||||||
this.virtUpdatePath =
|
|
||||||
workflowMainStoreName +
|
|
||||||
srcPath.substring(srcPath.indexOf(':'),srcPath.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
// process the expiration date (if any)
|
|
||||||
processExpirationDate(srcPath);
|
|
||||||
|
|
||||||
this.srcPaths.add(srcPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
String workflowMainStoreName = sandboxInfo.getMainStoreName();
|
|
||||||
List<AVMDifference> diffs = new ArrayList<AVMDifference>(srcPaths.size());
|
|
||||||
for (final String srcPath : srcPaths)
|
|
||||||
{
|
|
||||||
diffs.add(new AVMDifference(-1, srcPath, -1,
|
|
||||||
AVMUtil.getCorrespondingPath(srcPath, workflowMainStoreName),
|
|
||||||
AVMDifference.NEWER));
|
|
||||||
}
|
|
||||||
|
|
||||||
// write changes to layer so files are marked as modified
|
|
||||||
getAvmSyncService().update(diffs, null, false, false, false, false, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the configured workflow to allow the submitted items to be link
|
|
||||||
* checked and reviewed.
|
|
||||||
*/
|
|
||||||
protected void startWorkflow()
|
|
||||||
{
|
|
||||||
if (this.workflowParams != null)
|
|
||||||
{
|
|
||||||
// start the workflow to get access to the start task
|
|
||||||
String workflowName = this.workflowSelectedValue[0];
|
|
||||||
WorkflowDefinition wfDef = getWorkflowService().getDefinitionByName(workflowName);
|
|
||||||
WorkflowPath path = getWorkflowService().startWorkflow(wfDef.id, null);
|
|
||||||
if (path != null)
|
|
||||||
{
|
|
||||||
// extract the start task
|
|
||||||
List<WorkflowTask> tasks = getWorkflowService().getTasksForWorkflowPath(path.id);
|
|
||||||
if (tasks.size() == 1)
|
|
||||||
{
|
|
||||||
WorkflowTask startTask = tasks.get(0);
|
|
||||||
|
|
||||||
if (startTask.state == WorkflowTaskState.IN_PROGRESS)
|
|
||||||
{
|
|
||||||
final NodeRef workflowPackage =
|
|
||||||
AVMWorkflowUtil.createWorkflowPackage(this.srcPaths, sandboxInfo, path);
|
|
||||||
|
|
||||||
this.workflowParams.put(WorkflowModel.ASSOC_PACKAGE, workflowPackage);
|
|
||||||
|
|
||||||
// add submission parameters
|
|
||||||
this.workflowParams.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, getComment());
|
|
||||||
this.workflowParams.put(WCMWorkflowModel.PROP_LABEL, getLabel());
|
|
||||||
this.workflowParams.put(WCMWorkflowModel.PROP_FROM_PATH,
|
|
||||||
AVMUtil.buildStoreRootPath(this.avmBrowseBean.getSandbox()));
|
|
||||||
this.workflowParams.put(WCMWorkflowModel.PROP_LAUNCH_DATE, this.launchDate);
|
|
||||||
this.workflowParams.put(WCMWorkflowModel.PROP_VALIDATE_LINKS,
|
|
||||||
new Boolean(this.validateLinks));
|
|
||||||
this.workflowParams.put(WCMWorkflowModel.PROP_AUTO_DEPLOY,
|
|
||||||
new Boolean(this.autoDeploy));
|
|
||||||
this.workflowParams.put(WCMWorkflowModel.PROP_WEBAPP,
|
|
||||||
this.avmBrowseBean.getWebapp());
|
|
||||||
this.workflowParams.put(WCMWorkflowModel.ASSOC_WEBPROJECT,
|
|
||||||
this.avmBrowseBean.getWebsite().getNodeRef());
|
|
||||||
|
|
||||||
// update start task with submit parameters
|
|
||||||
getWorkflowService().updateTask(startTask.id, this.workflowParams, null, null);
|
|
||||||
|
|
||||||
// end the start task to trigger the first 'proper' task in the workflow
|
|
||||||
getWorkflowService().endTask(startTask.id, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleans up the workflow sandbox created by the first transaction. This
|
|
||||||
* action is itself preformed in a separate transaction.
|
|
||||||
*
|
|
||||||
* @param context Faces context
|
|
||||||
*/
|
|
||||||
protected void cleanupWorkflowSandbox(FacesContext context)
|
|
||||||
{
|
|
||||||
RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(context);
|
|
||||||
RetryingTransactionCallback<String> callback = new RetryingTransactionCallback<String>()
|
|
||||||
{
|
|
||||||
public String execute() throws Throwable
|
|
||||||
{
|
|
||||||
// call the actual implementation
|
|
||||||
cleanupWorkflowSandboxImpl();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Execute the cleanup handler
|
|
||||||
txnHelper.doInTransaction(callback);
|
|
||||||
}
|
|
||||||
catch (Throwable e)
|
|
||||||
{
|
|
||||||
// not much we can do now, just log the error to inform admins
|
|
||||||
logger.error("Failed to cleanup workflow sandbox after workflow failure", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the actual deletion of stores in the workflow sandbox.
|
|
||||||
*/
|
|
||||||
protected void cleanupWorkflowSandboxImpl()
|
|
||||||
{
|
|
||||||
if (this.sandboxInfo != null)
|
|
||||||
{
|
|
||||||
String mainWorkflowStore = this.sandboxInfo.getMainStoreName();
|
|
||||||
Map<QName, PropertyValue> matches = getAvmService().queryStorePropertyKey(mainWorkflowStore,
|
|
||||||
QName.createQName(null, ".sandbox-id%"));
|
|
||||||
QName sandboxID = matches.keySet().iterator().next();
|
|
||||||
// Get all the stores in the sandbox.
|
|
||||||
Map<String, Map<QName, PropertyValue>> stores = getAvmService().queryStoresPropertyKeys(sandboxID);
|
|
||||||
for (String storeName : stores.keySet())
|
|
||||||
{
|
|
||||||
getAvmService().purgeStore(storeName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.alfresco.web.bean.dialog.BaseDialogBean#getFinishButtonDisabled()
|
* @see org.alfresco.web.bean.dialog.BaseDialogBean#getFinishButtonDisabled()
|
||||||
*/
|
*/
|
||||||
@@ -1057,36 +795,7 @@ public class SubmitDialog extends BaseDialogBean
|
|||||||
throw (RuntimeException)e;
|
throw (RuntimeException)e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up the expiration date for the given source path
|
|
||||||
*
|
|
||||||
* @param srcPath The path to set the expiration date for
|
|
||||||
*/
|
|
||||||
private void processExpirationDate(String srcPath)
|
|
||||||
{
|
|
||||||
// if an expiration date has been set for this item we need to
|
|
||||||
// add the expires aspect and the date supplied
|
|
||||||
Date expirationDate = this.expirationDates.get(srcPath);
|
|
||||||
if (expirationDate == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// make sure the aspect is present
|
|
||||||
if (getAvmService().hasAspect(-1, srcPath, WCMAppModel.ASPECT_EXPIRES) == false)
|
|
||||||
{
|
|
||||||
getAvmService().addAspect(srcPath, WCMAppModel.ASPECT_EXPIRES);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the expiration date
|
|
||||||
getAvmService().setNodeProperty(srcPath, WCMAppModel.PROP_EXPIRATIONDATE,
|
|
||||||
new PropertyValue(DataTypeDefinition.DATETIME, expirationDate));
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Set expiration date of " + expirationDate +
|
|
||||||
" for " + srcPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action method to setup a workflow for dialog context for the current row
|
* Action method to setup a workflow for dialog context for the current row
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user