bpapez 2005/12/06 13:13:50 CET
Modified files:
core/src/java/org/jahia/engines/workflow
AdvancedWorkflowEngine.java
Log:
- refactored applyModifications and made a new method processWorkflow, which
just calls the workflowService.activate or workflowService.changeStagingStatus
in a transaction
- put the sending of mail in a finally, so that in exception cases, a mail is
at least sent for all successfully activated objects
Revision Changes Path
1.26 +327 -117
jahia/core/src/java/org/jahia/engines/workflow/AdvancedWorkflowEngine.java
http://jahia.mine.nu:8080/cgi-bin/cvsweb.cgi/jahia/core/src/java/org/jahia/engines/workflow/AdvancedWorkflowEngine.java.diff?r1=1.25&r2=1.26&f=h
Index: AdvancedWorkflowEngine.java
===================================================================
RCS file:
/home/cvs/repository/jahia/core/src/java/org/jahia/engines/workflow/AdvancedWorkflowEngine.java,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- AdvancedWorkflowEngine.java 1 Dec 2005 10:25:17 -0000 1.25
+++ AdvancedWorkflowEngine.java 6 Dec 2005 12:13:50 -0000 1.26
@@ -10,6 +10,7 @@
import org.jahia.engines.JahiaEngine;
import org.jahia.engines.validation.EngineValidationHelper;
import org.jahia.exceptions.JahiaException;
+import org.jahia.hibernate.manager.SpringContextSingleton;
import org.jahia.params.ProcessingContext;
import org.jahia.registries.ServicesRegistry;
import org.jahia.resourcebundle.JahiaResourceBundle;
@@ -18,8 +19,6 @@
import org.jahia.services.lock.LockService;
import org.jahia.services.pages.ContentPage;
import org.jahia.services.pages.JahiaPageService;
-import org.jahia.services.scheduler.BackgroundJob;
-import org.jahia.services.scheduler.SchedulerService;
import org.jahia.services.sitemap.JahiaSiteMapService;
import org.jahia.services.sites.SiteLanguageSettings;
import org.jahia.services.usermanager.JahiaUser;
@@ -27,9 +26,17 @@
import org.jahia.services.version.EntryLoadRequest;
import org.jahia.services.version.JahiaSaveVersion;
import org.jahia.services.version.StateModificationContext;
-import org.jahia.services.workflow.ActivationJob;
import org.jahia.services.workflow.ExternalWorkflow;
import org.jahia.services.workflow.WorkflowService;
+import org.jahia.services.workflow.ActivationJob;
+import org.jahia.services.scheduler.BackgroundJob;
+import org.jahia.services.scheduler.SchedulerService;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.support.TransactionCallback;
+import
org.springframework.transaction.support.TransactionCallbackWithoutResult;
+import org.springframework.transaction.support.TransactionTemplate;
+import org.springframework.util.StopWatch;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
@@ -53,6 +60,8 @@
private EngineToolBox toolBox;
private WorkflowService service;
+
+ private TransactionTemplate transactionTemplate = null;
private static final org.apache.log4j.Logger logger =
org.apache.log4j.Logger.getLogger(AdvancedWorkflowEngine.class);
@@ -461,7 +470,7 @@
*
* @param jParams ;)
*/
- private void applyModifications(final ProcessingContext jParams,
+ private void applyModifications(ProcessingContext jParams,
final WorkflowHelper workflowHelper)
throws JahiaException {
// Get the cache instance BEFORE applying any modification in case
the cache cannot
@@ -474,12 +483,22 @@
JahiaPageService.PAGE_CHILD_CACHE +"] instance.",
JahiaException.CACHE_ERROR,
JahiaException.CRITICAL_SEVERITY);
- final JahiaSaveVersion saveVersion = ServicesRegistry.getInstance
().getJahiaVersionService ().
+ if (transactionTemplate == null) {
+ SpringContextSingleton instance = SpringContextSingleton
+ .getInstance();
+ if (instance.isInitialized()) {
+ PlatformTransactionManager manager =
(PlatformTransactionManager) instance
+ .getContext().getBean("transactionManager");
+ transactionTemplate = new TransactionTemplate(manager);
+ }
+ }
+
+ JahiaSaveVersion saveVersion = ServicesRegistry.getInstance
().getJahiaVersionService ().
getSiteSaveVersion (jParams.getSiteID ());
final Map selectedEntries = new HashMap();
- final String action = (String)
_lastAction.get(jParams.getSessionID());
+ String action = (String) _lastAction.get(jParams.getSessionID());
final Iterator paramNames = jParams.getParameterNames();
while (paramNames.hasNext()) {
@@ -526,132 +545,323 @@
}
}
final Map userNotifData = new HashMap();
- ArrayList recipients = null;
- final List ordered = workflowHelper.getOrderedKeys();
- for (int j=ordered.size()-1; j>=0; j--) {
- final ObjectKey key = (ObjectKey) ordered.get(j);
- if (!selectedEntries.containsKey(key)) {
- continue;
- }
- final Map options = (Map) selectedEntries.get(key);
- final Iterator additionalIt = options.keySet().iterator();
- while ( additionalIt.hasNext() ) {
- final String additionalKey = (String) additionalIt.next();
- final Set languageCodes = (Set) options.get(additionalKey);
-
-// for (Iterator iterator = selectedEntries.keySet().iterator();
iterator.hasNext();) {
-// ObjectKey key = (ObjectKey) iterator.next();
-// Set languageCodes = (Set) selectedEntries.get(key);
-
- final StateModificationContext stateModifContext = new
StateModificationContext(key, languageCodes);
- stateModifContext.setDescendingInSubPages(false);
- ContentObject object = null;
-
- try {
- object = (ContentObject) JahiaObject.getInstance(key);
- } catch (ClassNotFoundException e) {
+ try {
+ final List ordered = workflowHelper.getOrderedKeys();
+ for (int j = ordered.size() - 1; j >= 0; j--) {
+ ObjectKey key = (ObjectKey) ordered.get(j);
+ if (!selectedEntries.containsKey(key)) {
+ continue;
+ }
+ final Map options = (Map) selectedEntries.get(key);
+ final Iterator additionalIt = options.keySet().iterator();
+ while (additionalIt.hasNext()) {
+ String additionalKey = (String) additionalIt.next();
+ Set languageCodes = (Set) options.get(additionalKey);
+
+// for (Iterator iterator =
selectedEntries.keySet().iterator(); iterator.hasNext();) {
+// ObjectKey key = (ObjectKey) iterator.next();
+// Set languageCodes = (Set) selectedEntries.get(key);
+
+ processWorkflow(jParams, workflowHelper, key,
+ additionalKey, action, languageCodes,
saveVersion,
+ userNotifData);
}
+ }
+ } finally {
+ sendMail(jParams, userNotifData);
+ }
+ }
+
- final int mode = service.getInheritedMode(object);
+ private void processWorkflow(final ProcessingContext jParams,
+ final WorkflowHelper workflowHelper, final ObjectKey key,
+ final String additionalKey, final String action,
+ final Set languageCodes, final JahiaSaveVersion saveVersion,
+ Map userNotifData) throws JahiaException {
+ ArrayList recipients = null;
+ final StateModificationContext stateModifContext = new
StateModificationContext(
+ key, languageCodes);
+ stateModifContext.setDescendingInSubPages(false);
- try {
- final ContentObject contentObject = (ContentObject)
ContentObject.getInstance(key);
- if (mode == WorkflowService.INACTIVE) {
- if (action.equals(approvePendingPages) &&
additionalKey.equals(ACCEPT)) {
-
ServicesRegistry.getInstance().getWorkflowService().activate(contentObject,
languageCodes, saveVersion, jParams, stateModifContext);
- }
- } else if (mode == WorkflowService.JAHIA_INTERNAL) {
- final String comment =
jParams.getParameter("commentsInput");
- PageNotifData pageNotifData = null;
- if (action.equals(notifyCompletedPages)) {
-
ServicesRegistry.getInstance().getWorkflowService().changeStagingStatus(contentObject,
languageCodes,
-
EntryLoadRequest.WAITING_WORKFLOW_STATE,
stateModifContext, jParams);
- if (contentObject instanceof ContentPage) {
- pageNotifData = new
PageNotifData(jParams.getSiteURL(contentObject.getID(), false, false), comment,
(ContentPage) contentObject, languageCodes, true, null, null);
- }
- } else if (action.equals(approvePendingPages) &&
additionalKey.equals(ACCEPT)) {
- final ActivationTestResults
activationTestResults =
ServicesRegistry.getInstance().getWorkflowService().activate(contentObject,
languageCodes, saveVersion, jParams, stateModifContext);
- final boolean workflowSuccessful =
(activationTestResults.getStatus() !=
ActivationTestResults.FAILED_OPERATION_STATUS);
- if (contentObject instanceof ContentPage) {
- pageNotifData = new PageNotifData (
- jParams.getSiteURL
(contentObject.getID(), false, false),
- comment, (ContentPage)
contentObject, languageCodes, workflowSuccessful,
activationTestResults.getErrors(), activationTestResults.getWarnings());
- }
- } else if (action.equals(approvePendingPages) &&
additionalKey.equals(REFUSE)) {
-// String accept =
jParams.getParameter("acceptRefuse");
-// if ("accept".equals(accept)) {
-//
ServicesRegistry.getInstance().getWorkflowService().activate(contentObject,
languageCodes, saveVersion, jParams, stateModifContext);
-// } else if ("refuse".equals(accept)) {
-
ServicesRegistry.getInstance().getWorkflowService().changeStagingStatus(contentObject,
languageCodes,
-
EntryLoadRequest.STAGING_WORKFLOW_STATE,
stateModifContext, jParams);
- if (contentObject instanceof ContentPage) {
- pageNotifData = new
PageNotifData(jParams.getSiteURL(contentObject.getID(), false, false), comment,
(ContentPage) contentObject, languageCodes, true, null, null);
- }
-// }
- }
- if (pageNotifData != null) {
- // new system, per user messaging
- recipients = getRecipients(contentObject,
jParams.getSiteID(), 0x3);
- for (int i=0; i < recipients.size(); i++) {
- final String curEmail = (String)
recipients.get(i);
- Map operationMap = (Map)
userNotifData.get(curEmail);
- if (operationMap == null) {
- operationMap = new HashMap();
- }
- String opname = null;
- if (action.equals(notifyCompletedPages)) {
- opname = WAITINGFORAPPROVAL_OPNAME;
- } else if
(action.equals(approvePendingPages) && additionalKey.equals(REFUSE)) {
- opname = REFUSAL_OPNAME;
- } else if
(action.equals(approvePendingPages) && additionalKey.equals(ACCEPT)) {
- opname = APPROVAL_OPNAME;
- }
+ ContentObject object = null;
- Set pageList = (Set)
operationMap.get(opname);
- if (pageList == null) {
- pageList = new HashSet();
- }
- pageList.add(pageNotifData);
- operationMap.put(opname, pageList);
- userNotifData.put(curEmail, operationMap);
- }
- }
- } else if (mode == WorkflowService.EXTERNAL) {
- final ExternalWorkflow workflow =
workflowHelper.getEntry(key).getExternalWorkflow();
- final String processId =
service.getInheritedExternalWorkflowProcessId(object);
+ try {
+ object = (ContentObject) JahiaObject.getInstance(key);
+ } catch (ClassNotFoundException e) {
+ }
- final Iterator iterator2 = languageCodes.iterator();
- while ( iterator2.hasNext() ) {
- final String language = (String)
iterator2.next();
- if
(jParams.getPage().checkAdminAccess(jParams.getUser())) {
- if (approvePendingPages.equals(action) &&
additionalKey.equals(ACCEPT)) {
- final ActivationTestResults res =
ServicesRegistry.getInstance().getWorkflowService().activate(contentObject,
languageCodes, saveVersion, jParams, stateModifContext);
- if (res.getStatus() ==
ActivationTestResults.COMPLETED_OPERATION_STATUS) {
-
workflow.abortProcess(processId,key.toString(), language, jParams);
+ final int mode = service.getInheritedMode(object);
+
+ try {
+ if (mode == WorkflowService.INACTIVE) {
+ if (action.equals(approvePendingPages)
+ && additionalKey.equals(ACCEPT)) {
+ transactionTemplate
+ .execute(new TransactionCallbackWithoutResult() {
+ protected void doInTransactionWithoutResult(
+ TransactionStatus status) {
+ try {
+ ContentObject contentObject =
(ContentObject) ContentObject
+ .getInstance(key, true);
+ ServicesRegistry.getInstance()
+
.getWorkflowService().activate(
+ contentObject,
+ languageCodes,
+ saveVersion, jParams,
+ stateModifContext);
+ } catch (JahiaException je) {
+ logger
+ .error(
+ "Cannot change Jahia
Page staging status",
+ je);
+ throw new RuntimeException(je);
+ } catch (ClassNotFoundException cnfe) {
+ logger.error("Cannot find class",
cnfe);
+ throw new RuntimeException(cnfe);
}
}
- if (approvePendingPages.equals(action) &&
additionalKey.equals(REFUSE)) {
-
ServicesRegistry.getInstance().getWorkflowService().changeStagingStatus(contentObject,
languageCodes,
-
EntryLoadRequest.STAGING_WORKFLOW_STATE,
stateModifContext, jParams);
-
workflow.abortProcess(processId,key.toString(), language, jParams);
-
workflow.initProcess(processId,key.toString(), language, jParams);
+ });
+ }
+ } else if (mode == WorkflowService.JAHIA_INTERNAL) {
+ PageNotifData pageNotifData = (PageNotifData)
transactionTemplate
+ .execute(new TransactionCallback() {
+ public Object doInTransaction(
+ TransactionStatus status) {
+ PageNotifData pageNotifData = null;
+ try {
+ ContentObject contentObject =
(ContentObject) ContentObject
+ .getInstance(key, true);
+ final String comment = jParams
+ .getParameter("commentsInput");
+ if (action.equals(notifyCompletedPages))
{
+ ServicesRegistry
+ .getInstance()
+ .getWorkflowService()
+ .changeStagingStatus(
+ contentObject,
+ languageCodes,
+
EntryLoadRequest.WAITING_WORKFLOW_STATE,
+ stateModifContext,
+ jParams);
+ if (contentObject instanceof
ContentPage) {
+ pageNotifData = new
PageNotifData(
+ jParams.getSiteURL(
+ contentObject
+ .getID(),
+ false, false),
+ comment,
+ (ContentPage)
contentObject,
+ languageCodes, true,
null,
+ null);
+ }
+ } else if (action
+ .equals(approvePendingPages)
+ && additionalKey.equals(ACCEPT))
{
+ final ActivationTestResults
activationTestResults = ServicesRegistry
+ .getInstance()
+
.getWorkflowService().activate(
+ contentObject,
+ languageCodes,
+ saveVersion, jParams,
+ stateModifContext);
+ final boolean workflowSuccessful =
(activationTestResults
+ .getStatus() !=
ActivationTestResults.FAILED_OPERATION_STATUS);
+ if (contentObject instanceof
ContentPage) {
+ pageNotifData = new
PageNotifData(
+ jParams.getSiteURL(
+ contentObject
+ .getID(),
+ false, false),
+ comment,
+ (ContentPage)
contentObject,
+ languageCodes,
+ workflowSuccessful,
+ activationTestResults
+ .getErrors(),
+ activationTestResults
+ .getWarnings());
+ }
+ } else if (action
+ .equals(approvePendingPages)
+ && additionalKey.equals(REFUSE))
{
+ // String accept =
+ //
jParams.getParameter("acceptRefuse");
+ // if ("accept".equals(accept)) {
+ //
ServicesRegistry.getInstance().getWorkflowService().activate(contentObject,
+ // languageCodes, saveVersion,
jParams,
+ // stateModifContext);
+ // } else if
("refuse".equals(accept)) {
+ ServicesRegistry
+ .getInstance()
+ .getWorkflowService()
+ .changeStagingStatus(
+ contentObject,
+ languageCodes,
+
EntryLoadRequest.STAGING_WORKFLOW_STATE,
+ stateModifContext,
+ jParams);
+ if (contentObject instanceof
ContentPage) {
+ pageNotifData = new
PageNotifData(
+ jParams.getSiteURL(
+ contentObject
+ .getID(),
+ false, false),
+ comment,
+ (ContentPage)
contentObject,
+ languageCodes, true,
null,
+ null);
+ }
+ // }
+ }
+ } catch (JahiaException je) {
+ logger
+ .error(
+ "Cannot change Jahia
Page staging status",
+ je);
+ throw new RuntimeException(je);
+ } catch (ClassNotFoundException cnfe) {
+ logger.error("Cannot find class", cnfe);
+ throw new RuntimeException(cnfe);
}
+ return pageNotifData;
}
- if (action.indexOf('.') > -1) {
- final String actionName =
action.substring(action.lastIndexOf('.')+1);
- boolean result =
workflow.sendAction(processId,key.toString(), language, actionName, jParams);
- if (!result) break;
- }
+ });
+
+ if (pageNotifData != null) {
+ // new system, per user messaging
+ recipients = getRecipients(object, jParams.getSiteID(),
0x3);
+ for (int i = 0; i < recipients.size(); i++) {
+ final String curEmail = (String) recipients.get(i);
+ Map operationMap = (Map) userNotifData.get(curEmail);
+ if (operationMap == null) {
+ operationMap = new HashMap();
}
+ String opname = null;
+ if (action.equals(notifyCompletedPages)) {
+ opname = WAITINGFORAPPROVAL_OPNAME;
+ } else if (action.equals(approvePendingPages)
+ && additionalKey.equals(REFUSE)) {
+ opname = REFUSAL_OPNAME;
+ } else if (action.equals(approvePendingPages)
+ && additionalKey.equals(ACCEPT)) {
+ opname = APPROVAL_OPNAME;
+ }
+
+ Set pageList = (Set) operationMap.get(opname);
+ if (pageList == null) {
+ pageList = new HashSet();
+ }
+ pageList.add(pageNotifData);
+ operationMap.put(opname, pageList);
+ userNotifData.put(curEmail, operationMap);
+ }
+ }
+ } else if (mode == WorkflowService.EXTERNAL) {
+ final ExternalWorkflow workflow =
workflowHelper.getEntry(key)
+ .getExternalWorkflow();
+ final String processId = service
+ .getInheritedExternalWorkflowProcessId(object);
+
+ final Iterator iterator2 = languageCodes.iterator();
+ while (iterator2.hasNext()) {
+ final String language = (String) iterator2.next();
+ if
(jParams.getPage().checkAdminAccess(jParams.getUser())) {
+ if (approvePendingPages.equals(action)
+ && additionalKey.equals(ACCEPT)) {
+ final ActivationTestResults res =
(ActivationTestResults) transactionTemplate
+ .execute(new TransactionCallback() {
+ public Object doInTransaction(
+ TransactionStatus status) {
+ ActivationTestResults res = null;
+ try {
+ ContentObject contentObject
= (ContentObject) ContentObject
+ .getInstance(key,
true);
+ res = ServicesRegistry
+ .getInstance()
+ .getWorkflowService()
+ .activate(
+
contentObject,
+
languageCodes,
+ saveVersion,
+ jParams,
+
stateModifContext);
+ } catch (JahiaException je) {
+ logger
+ .error(
+ "Cannot
change Jahia Page staging status",
+ je);
+ throw new
RuntimeException(je);
+ } catch (ClassNotFoundException
cnfe) {
+ logger.error(
+ "Cannot find class",
+ cnfe);
+ throw new
RuntimeException(cnfe);
+ }
+ return res;
+ }
+ });
+ if (res.getStatus() ==
ActivationTestResults.COMPLETED_OPERATION_STATUS) {
+ workflow.abortProcess(processId,
+ key.toString(), language, jParams);
+ }
+ }
+ if (approvePendingPages.equals(action)
+ && additionalKey.equals(REFUSE)) {
+ transactionTemplate
+ .execute(new
TransactionCallbackWithoutResult() {
+ protected void
doInTransactionWithoutResult(
+ TransactionStatus status) {
+ try {
+ ContentObject contentObject
= (ContentObject) ContentObject
+ .getInstance(key,
true);
+ ServicesRegistry
+ .getInstance()
+ .getWorkflowService()
+ .changeStagingStatus(
+
contentObject,
+
languageCodes,
+
EntryLoadRequest.STAGING_WORKFLOW_STATE,
+
stateModifContext,
+ jParams);
+ } catch (JahiaException je) {
+ logger
+ .error(
+ "Cannot
change Jahia Page staging status",
+ je);
+ throw new
RuntimeException(je);
+ } catch (ClassNotFoundException
cnfe) {
+ logger.error(
+ "Cannot find class",
+ cnfe);
+ throw new
RuntimeException(cnfe);
+ }
+ }
+ });
+ workflow.abortProcess(processId, key.toString(),
+ language, jParams);
+ workflow.initProcess(processId, key.toString(),
+ language, jParams);
+ }
+ }
+ if (action.indexOf('.') > -1) {
+ final String actionName = action.substring(action
+ .lastIndexOf('.') + 1);
+ boolean result = workflow.sendAction(processId, key
+ .toString(), language, actionName, jParams);
+ if (!result)
+ break;
}
- } catch (ClassNotFoundException e) {
- throw new JahiaException("Cannot get object", "Cannot
get object", JahiaException.PERSISTENCE_ERROR,
JahiaException.CRITICAL_SEVERITY, e);
}
}
+ } catch (Throwable e) {
+ logger
+ .error("Error during workflow operation! We must flush
all caches to ensure integrity between database and viewing");
+
ServicesRegistry.getInstance().getCacheService().flushAllCaches();
+ throw new JahiaException(e.getMessage(), e.getMessage(),
+ JahiaException.DATABASE_ERROR,
+ JahiaException.CRITICAL_SEVERITY, e);
}
-
- sendMail(jParams, userNotifData);
}
private void backgroundActivation(ContentObject contentObject, Set
languageCodes, ProcessingContext jParams) throws JahiaException {