()
{
@@ -100,7 +110,7 @@ public class NotifyOfRecordsDueForReviewJob implements Job
public Boolean execute() throws Throwable
{
// Send notification
- notificationHelper.recordsDueForReviewEmailNotification(resultNodes);
+ recordsManagementNotificationHelper.recordsDueForReviewEmailNotification(resultNodes);
return null;
}
@@ -122,10 +132,10 @@ public class NotifyOfRecordsDueForReviewJob implements Job
/**
* Now do the work, one action in each transaction
*/
- trn.setMaxRetries(0); // don't retry the send email
- trn.doInTransaction(txCallbackSendEmail);
- trn.setMaxRetries(10);
- trn.doInTransaction(txUpdateNodesCallback);
+ retryingTransactionHelper.setMaxRetries(0); // don't retry the send email
+ retryingTransactionHelper.doInTransaction(txCallbackSendEmail);
+ retryingTransactionHelper.setMaxRetries(10);
+ retryingTransactionHelper.doInTransaction(txUpdateNodesCallback);
}
return null;
}
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/PublishUpdatesJob.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/PublishUpdatesJobExecuter.java
similarity index 84%
rename from rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/PublishUpdatesJob.java
rename to rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/PublishUpdatesJobExecuter.java
index 0d998729e2..1d9d428438 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/PublishUpdatesJob.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/PublishUpdatesJobExecuter.java
@@ -24,7 +24,6 @@ import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.job.publish.PublishExecutor;
import org.alfresco.module.org_alfresco_module_rm.job.publish.PublishExecutorRegistry;
-import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
@@ -37,47 +36,51 @@ import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.quartz.Job;
-import org.quartz.JobDataMap;
-import org.quartz.JobExecutionContext;
-import org.quartz.JobExecutionException;
/**
* Job to publish any pending updates on marked node references.
*
* @author Roy Wetherall
*/
-public class PublishUpdatesJob implements Job, RecordsManagementModel
+public class PublishUpdatesJobExecuter extends RecordsManagementJobExecuter
{
/** Logger */
- private static Log logger = LogFactory.getLog(PublishUpdatesJob.class);
+ private static Log logger = LogFactory.getLog(PublishUpdatesJobExecuter.class);
/** Node service */
private NodeService nodeService;
/** Search service */
- private SearchService searchService;
-
- /** Retrying transaction helper */
- private RetryingTransactionHelper retryingTransactionHelper;
+ private SearchService searchService;
/** Publish executor register */
- private PublishExecutorRegistry register;
+ private PublishExecutorRegistry publishExecutorRegistry;
/** Behaviour filter */
private BehaviourFilter behaviourFilter;
- /** Indicates whether the job bean has been initialised or not */
- private boolean initialised = false;
-
- /**
- * @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
- */
- public void execute(JobExecutionContext context) throws JobExecutionException
+ public void setNodeService(NodeService nodeService)
{
- // Initialise the service references
- initServices(context);
-
+ this.nodeService = nodeService;
+ }
+
+ public void setSearchService(SearchService searchService)
+ {
+ this.searchService = searchService;
+ }
+
+ public void setPublishExecutorRegistry(PublishExecutorRegistry publishExecutorRegistry)
+ {
+ this.publishExecutorRegistry = publishExecutorRegistry;
+ }
+
+ public void setBehaviourFilter(BehaviourFilter behaviourFilter)
+ {
+ this.behaviourFilter = behaviourFilter;
+ }
+
+ public void execute()
+ {
if (logger.isDebugEnabled() == true)
{
logger.debug("Job Starting");
@@ -156,25 +159,6 @@ public class PublishUpdatesJob implements Job, RecordsManagementModel
return retryingTransactionHelper.doInTransaction(execution, true);
}
- /**
- * Initialise service based on the job execution context
- * @param context job execution context
- */
- private void initServices(JobExecutionContext context)
- {
- if (initialised == false)
- {
- // Get references to the required services
- JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
- nodeService = (NodeService)jobDataMap.get("nodeService");
- searchService = (SearchService)jobDataMap.get("searchService");
- retryingTransactionHelper = (RetryingTransactionHelper)jobDataMap.get("retryingTransactionHelper");
- register = (PublishExecutorRegistry)jobDataMap.get("publishExecutorRegistry");
- behaviourFilter = (BehaviourFilter)jobDataMap.get("behaviourFilter");
- initialised = true;
- }
- }
-
/**
* Mark the node as publish in progress. This is often used as a marker to prevent any further updates
* to a node.
@@ -235,7 +219,7 @@ public class PublishUpdatesJob implements Job, RecordsManagementModel
}
// Get the publish executor
- PublishExecutor executor = register.get(updateTo);
+ PublishExecutor executor = publishExecutorRegistry.get(updateTo);
if (executor == null)
{
if (logger.isDebugEnabled() == true)
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJob.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJob.java
new file mode 100644
index 0000000000..1def909851
--- /dev/null
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJob.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2009-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.module.org_alfresco_module_rm.job;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+import org.alfresco.repo.lock.JobLockService;
+import org.alfresco.repo.lock.LockAcquisitionException;
+import org.alfresco.repo.lock.JobLockService.JobLockRefreshCallback;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+
+/**
+ * Base records management job implementation.
+ *
+ * Delegates job execution and ensures locking
+ * is enforced.
+ *
+ * @author Roy Wetherall
+ */
+public class RecordsManagementJob implements Job
+{
+ private static long DEFAULT_TIME = 2000L;
+
+ private JobLockService jobLockService;
+
+ private RecordsManagementJobExecuter jobExecuter;
+
+ private String jobName;
+
+ private QName getLockQName()
+ {
+ return QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, jobName);
+ }
+
+ /**
+ * Attempts to get the lock. If the lock couldn't be taken, then null is returned.
+ *
+ * @return Returns the lock token or null
+ */
+ private String getLock()
+ {
+ try
+ {
+ return jobLockService.getLock(getLockQName(), DEFAULT_TIME);
+ }
+ catch (LockAcquisitionException e)
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public void execute(JobExecutionContext context) throws JobExecutionException
+ {
+ // get the job lock service
+ jobLockService = (JobLockService)context.getJobDetail().getJobDataMap().get("jobLockService");
+ if (jobLockService == null)
+ {
+ throw new AlfrescoRuntimeException("Job lock service has not been specified.");
+ }
+
+ // get the job executer
+ jobExecuter = (RecordsManagementJobExecuter)context.getJobDetail().getJobDataMap().get("jobExecuter");
+ if (jobExecuter == null)
+ {
+ throw new AlfrescoRuntimeException("Job executer has not been specified.");
+ }
+
+ // get the job name
+ jobName = (String)context.getJobDetail().getJobDataMap().get("jobName");
+ if (jobName == null)
+ {
+ throw new AlfrescoRuntimeException("Job name has not been specified.");
+ }
+
+ AuthenticationUtil.runAs(new RunAsWork()
+ {
+ public Void doWork() throws Exception
+ {
+ // try and get the lock
+ String lockToken = getLock();
+ if (lockToken == null)
+ {
+ // exit
+ return null;
+ }
+
+ // use a flag to keep track of the running job
+ final AtomicBoolean running = new AtomicBoolean(true);
+ jobLockService.refreshLock(lockToken, getLockQName(), DEFAULT_TIME, new JobLockRefreshCallback()
+ {
+ @Override
+ public boolean isActive()
+ {
+ return running.get();
+ }
+ @Override
+ public void lockReleased()
+ {
+ running.set(false);
+ }
+ });
+
+ try
+ {
+ // do work
+ jobExecuter.execute();
+ }
+ finally
+ {
+ // The lock will self-release if answer isActive in the negative
+ running.set(false);
+ }
+
+ // return
+ return null;
+ }
+ }, AuthenticationUtil.getSystemUserName());
+ }
+}
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJobExecuter.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJobExecuter.java
new file mode 100644
index 0000000000..871a65bb28
--- /dev/null
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/RecordsManagementJobExecuter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.module.org_alfresco_module_rm.job;
+
+import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
+import org.alfresco.repo.transaction.RetryingTransactionHelper;
+
+/**
+ * @author Roy Wetherall
+ */
+public abstract class RecordsManagementJobExecuter implements RecordsManagementModel
+{
+ protected RetryingTransactionHelper retryingTransactionHelper;
+
+ public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
+ {
+ this.retryingTransactionHelper = retryingTransactionHelper;
+ }
+
+ public abstract void execute();
+}