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:
Derek Hulley
2009-03-11 01:17:39 +00:00
parent 5c7525fc4a
commit 8c01eb0ffe
3 changed files with 85 additions and 198 deletions

View File

@@ -86,45 +86,10 @@ 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);

View File

@@ -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);
} }
/** /**

View File

@@ -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()