mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.1 to HEAD
12982: Merged V3.0 to V3.1 12921: Merged V2.2 to V3.0 12524: Fix ETWOTWO-974: Submit Action Queue (...) 12687: Add missing workflow to bootstrap (follow on from 12524) ___________________________________________________________________ Modified: svn:mergeinfo Merged /alfresco/BRANCHES/V3.0:r12921 Merged /alfresco/BRANCHES/V2.2:r12524,12687 Merged /alfresco/BRANCHES/V3.1:r12982 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13545 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -86,46 +86,11 @@ public class AVMWorkflowUtil extends WorkflowUtil
|
|||||||
final FacesContext fc = FacesContext.getCurrentInstance();
|
final FacesContext fc = FacesContext.getCurrentInstance();
|
||||||
final WorkflowService workflowService = Repository.getServiceRegistry(fc).getWorkflowService();
|
final WorkflowService workflowService = Repository.getServiceRegistry(fc).getWorkflowService();
|
||||||
final AVMService avmService = Repository.getServiceRegistry(fc).getAVMLockingAwareService();
|
final AVMService avmService = Repository.getServiceRegistry(fc).getAVMLockingAwareService();
|
||||||
final AVMSyncService avmSyncService = Repository.getServiceRegistry(fc).getAVMSyncService();
|
|
||||||
|
|
||||||
// create package paths (layered to user sandbox area as target)
|
// create package paths (layered to user sandbox area as target)
|
||||||
final String workflowMainStoreName = sandboxInfo.getMainStoreName();
|
final String workflowMainStoreName = sandboxInfo.getMainStoreName();
|
||||||
final String packagesPath = AVMUtil.buildStoreRootPath(workflowMainStoreName);
|
final String packagesPath = AVMUtil.buildStoreRootPath(workflowMainStoreName);
|
||||||
|
|
||||||
final String stagingStoreName = AVMUtil.getStoreId(workflowMainStoreName);
|
|
||||||
final List<AVMDifference> diffs = new ArrayList<AVMDifference>(srcPaths.size());
|
|
||||||
for (final String srcPath : srcPaths)
|
|
||||||
{
|
|
||||||
final AVMNodeDescriptor node = avmService.lookup(-1, srcPath, true);
|
|
||||||
if (node.isDirectory())
|
|
||||||
{
|
|
||||||
diffs.add(new AVMDifference(-1, srcPath,
|
|
||||||
-1, AVMUtil.getCorrespondingPath(srcPath, workflowMainStoreName),
|
|
||||||
AVMDifference.NEWER));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final HashSet<String> directoriesAdded = new HashSet<String>();
|
|
||||||
// add all newly created directories
|
|
||||||
String parentPath = AVMNodeConverter.SplitBase(srcPath)[0];
|
|
||||||
while (!directoriesAdded.contains(parentPath) &&
|
|
||||||
avmService.lookup(-1, AVMUtil.getCorrespondingPath(parentPath, stagingStoreName), true) == null)
|
|
||||||
{
|
|
||||||
diffs.add(new AVMDifference(-1, parentPath,
|
|
||||||
-1, AVMUtil.getCorrespondingPath(parentPath, workflowMainStoreName),
|
|
||||||
AVMDifference.NEWER));
|
|
||||||
directoriesAdded.add(parentPath);
|
|
||||||
parentPath = AVMNodeConverter.SplitBase(parentPath)[0];
|
|
||||||
}
|
|
||||||
diffs.add(new AVMDifference(-1, srcPath,
|
|
||||||
-1, AVMUtil.getCorrespondingPath(srcPath, workflowMainStoreName),
|
|
||||||
AVMDifference.NEWER));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// write changes to layer so files are marked as modified
|
|
||||||
avmSyncService.update(diffs, null, true, true, false, false, null, null);
|
|
||||||
|
|
||||||
// convert package to workflow package
|
// convert package to workflow package
|
||||||
final AVMNodeDescriptor packageDesc = avmService.lookup(-1, packagesPath);
|
final AVMNodeDescriptor packageDesc = avmService.lookup(-1, packagesPath);
|
||||||
final NodeRef packageNodeRef = workflowService.createPackage(AVMNodeConverter.ToNodeRef(-1, packageDesc.getPath()));
|
final NodeRef packageNodeRef = workflowService.createPackage(AVMNodeConverter.ToNodeRef(-1, packageDesc.getPath()));
|
||||||
|
@@ -97,6 +97,8 @@ 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;
|
||||||
@@ -336,16 +338,8 @@ public class SubmitDialog extends BaseDialogBean
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (this.workflowSelectedValue != null)
|
// note: always submit via workflow (always defaults to direct submit workflow)
|
||||||
{
|
outcome = submitViaWorkflow(context);
|
||||||
// if there is a workflow set submit via that
|
|
||||||
outcome = submitViaWorkflow(context);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if there's no workflow submit changes directly to staging
|
|
||||||
outcome = submitDirectToStaging(context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -357,41 +351,6 @@ public class SubmitDialog extends BaseDialogBean
|
|||||||
return outcome;
|
return outcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Submits the selected items straight to the staging area i.e. when
|
|
||||||
* there is no workflow configured for the web project.
|
|
||||||
*
|
|
||||||
* @param context Faces context
|
|
||||||
* @return The outcome to use
|
|
||||||
*/
|
|
||||||
protected String submitDirectToStaging(final FacesContext context)
|
|
||||||
{
|
|
||||||
String outcome = null;
|
|
||||||
|
|
||||||
RetryingTransactionHelper txnHelper = Repository.getRetryingTransactionHelper(context);
|
|
||||||
RetryingTransactionCallback<String> callback = new RetryingTransactionCallback<String>()
|
|
||||||
{
|
|
||||||
public String execute() throws Throwable
|
|
||||||
{
|
|
||||||
// call the actual implementation
|
|
||||||
return submitDirectToStagingImpl();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Execute
|
|
||||||
outcome = txnHelper.doInTransaction(callback);
|
|
||||||
}
|
|
||||||
catch (Throwable e)
|
|
||||||
{
|
|
||||||
Utils.addErrorMessage(formatErrorMessage(e), e);
|
|
||||||
outcome = getErrorOutcome(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return outcome;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submits the selected items via the configured workflow.
|
* Submits the selected items via the configured workflow.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -468,34 +427,6 @@ public class SubmitDialog extends BaseDialogBean
|
|||||||
return outcome;
|
return outcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the actual submisson to staging
|
|
||||||
*
|
|
||||||
* @return The outcome to use
|
|
||||||
*/
|
|
||||||
protected String submitDirectToStagingImpl()
|
|
||||||
{
|
|
||||||
// direct submit to the staging area without workflow
|
|
||||||
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;
|
|
||||||
|
|
||||||
getSandboxService().submitList(sbStoreId, relativePaths, this.expirationDates, submitLabel, submitComment);
|
|
||||||
|
|
||||||
// if we get this far return the default outcome
|
|
||||||
return this.getDefaultFinishOutcome();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a workflow sandbox for all the submitted items
|
* Creates a workflow sandbox for all the submitted items
|
||||||
*
|
*
|
||||||
@@ -503,86 +434,96 @@ public class SubmitDialog extends BaseDialogBean
|
|||||||
*/
|
*/
|
||||||
protected void createWorkflowSandbox(FacesContext context)
|
protected void createWorkflowSandbox(FacesContext context)
|
||||||
{
|
{
|
||||||
// get the defaults from the workflow configuration attached to the selected workflow
|
if (this.workflowSelectedValue != null && this.workflowSelectedValue.length > 0)
|
||||||
String workflowName = this.workflowSelectedValue[0];
|
|
||||||
for (FormWorkflowWrapper wrapper : this.workflows)
|
|
||||||
{
|
{
|
||||||
if (wrapper.name.equals(workflowName))
|
// get the defaults from the workflow configuration attached to the selected workflow
|
||||||
|
String workflowName = this.workflowSelectedValue[0];
|
||||||
|
for (FormWorkflowWrapper wrapper : this.workflows)
|
||||||
{
|
{
|
||||||
this.workflowParams = wrapper.params;
|
if (wrapper.name.equals(workflowName))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.workflowParams != null)
|
|
||||||
{
|
|
||||||
// Create workflow sandbox for workflow package
|
|
||||||
this.sandboxInfo = sandboxFactory.createWorkflowSandbox(
|
|
||||||
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:
|
this.workflowParams = wrapper.params;
|
||||||
// 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();
|
if (this.workflowParams == null)
|
||||||
List<AVMDifference> diffs = new ArrayList<AVMDifference>(srcPaths.size());
|
|
||||||
for (final String srcPath : srcPaths)
|
|
||||||
{
|
{
|
||||||
diffs.add(new AVMDifference(-1, srcPath, -1,
|
// create error msg for display in dialog - the user must configure the workflow params
|
||||||
AVMUtil.getCorrespondingPath(srcPath, workflowMainStoreName),
|
Utils.addErrorMessage(Application.getMessage(context, MSG_ERR_WORKFLOW_CONFIG));
|
||||||
AVMDifference.NEWER));
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write changes to layer so files are marked as modified
|
// Create workflow sandbox for workflow package
|
||||||
getAvmSyncService().update(diffs, null, true, true, false, false, null, null);
|
this.sandboxInfo = sandboxFactory.createWorkflowSandbox(this.avmBrowseBean.getStagingStore());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// create error msg for display in dialog - the user must configure the workflow params
|
// default to direct submit workflow
|
||||||
Utils.addErrorMessage(Application.getMessage(context, MSG_ERR_WORKFLOW_CONFIG));
|
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, true, true, false, false, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -182,7 +182,6 @@ public class WebProject implements Serializable
|
|||||||
|
|
||||||
private final NodeRef nodeRef;
|
private final NodeRef nodeRef;
|
||||||
private String storeId = null;
|
private String storeId = null;
|
||||||
private Boolean hasWorkflow = null;
|
|
||||||
|
|
||||||
public WebProject(final NodeRef nodeRef)
|
public WebProject(final NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
@@ -339,27 +338,9 @@ public class WebProject implements Serializable
|
|||||||
*/
|
*/
|
||||||
public boolean hasWorkflow()
|
public boolean hasWorkflow()
|
||||||
{
|
{
|
||||||
if (this.hasWorkflow == null)
|
// note: there's always a submit workflow, as direct to staging is now
|
||||||
{
|
// also routed via workflow
|
||||||
final NodeService nodeService = this.getServiceRegistry().getNodeService();
|
return true;
|
||||||
List<ChildAssociationRef> webWorkflowRefs = nodeService.getChildAssocs(
|
|
||||||
this.nodeRef, WCMAppModel.ASSOC_WEBWORKFLOWDEFAULTS, RegexQNamePattern.MATCH_ALL);
|
|
||||||
this.hasWorkflow = (webWorkflowRefs.size() != 0);
|
|
||||||
if (!this.hasWorkflow)
|
|
||||||
{
|
|
||||||
// might have a workflow assigned to one of the forms used in the website
|
|
||||||
Map<String, Form> forms = getFormsImpl();
|
|
||||||
for (Form form : forms.values())
|
|
||||||
{
|
|
||||||
if (form.getDefaultWorkflow() != null)
|
|
||||||
{
|
|
||||||
this.hasWorkflow = Boolean.TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.hasWorkflow.booleanValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Form> getFormsImpl()
|
private Map<String, Form> getFormsImpl()
|
||||||
|
Reference in New Issue
Block a user