UncaughtExceptionHandler für ThreadedPublishing

git-svn-id: https://svn.libreccm.org/ccm/trunk@1440 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2012-01-12 08:52:03 +00:00
parent 39ad6472b0
commit a61bb46566
8 changed files with 297 additions and 223 deletions

View File

@ -1089,3 +1089,4 @@ cms.ui.item.lifecycle.do=Execute
cms.ui.item.lifecycle.do.not_authorized=Your not authorized to publish this item.
cms.ui.item.lifecycle.publish_locked=This content item is being (re-)published
cms.ui.item.lifecycle.publish_locked.update=Update
cms.ui.lifecycle.publish.error=An error occured while publishing this item. Please inform your system administrator. This item will stay locked until the locked is removed by the system administrator manually.

View File

@ -1080,3 +1080,4 @@ cms.ui.item.lifecycle.do=Ausf\u00fchren
cms.ui.item.lifecycle.do.not_authorized=Sie sind nicht berechtigt, dieses Item zu publizieren.
cms.ui.item.lifecycle.publish_locked=Dieses Content-Item wird gerade (re-)publiziert
cms.ui.item.lifecycle.publish_locked.update=Aktualisieren
cms.ui.lifecycle.publish.error=W\u00e4hrend des Publizierens ist ein Fehler aufgetreten. Bitte informieren Sie Ihren System-Administrator. Dieses Item bleibt besperrt, bis der Administrator die Sperre manuell entfernt.

View File

@ -28,3 +28,4 @@ cms.ui.item.lifecycle.do=
cms.ui.item.lifecycle.do.not_authorized=
cms.ui.item.lifecycle.publish_locked=
cms.ui.item.lifecycle.publish_locked.update=
cms.ui.lifecycle.publish.error=

View File

@ -559,3 +559,4 @@ cms.ui.item.lifecycle.do=
cms.ui.item.lifecycle.do.not_authorized=
cms.ui.item.lifecycle.publish_locked=
cms.ui.item.lifecycle.publish_locked.update=
cms.ui.lifecycle.publish.error=

View File

@ -53,6 +53,7 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
private final LayoutPanel m_detailPane;
private final LayoutPanel m_selectPane;
private final LayoutPanel m_lockedPane;
private final LayoutPanel m_errorPane;
public ItemLifecycleAdminPane(final ContentItemRequestLocal item) {
m_item = item;
@ -100,6 +101,12 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
});
m_lockedPane.setBottom(lockedUpdateLink);
m_errorPane = new LayoutPanel();
add(m_errorPane);
final Label errorMsg = new Label(gz("cms.ui.lifecycle.publish.error"));
m_errorPane.setBody(errorMsg);
connect(selectForm, m_detailPane);
}
@ -131,7 +138,12 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
if (CMSConfig.getInstance().getThreadedPublishing()
&& PublishLock.getInstance().isLocked(m_item.getContentItem(
state))) {
push(state, m_lockedPane);
if (PublishLock.getInstance().hasError(m_item.getContentItem(
state))) {
push(state, m_errorPane);
} else {
push(state, m_lockedPane);
}
} else {
if (state.isVisibleOnPage(ItemLifecycleAdminPane.this)) {
if (m_lifecycle.getLifecycle(state) == null) {

View File

@ -65,10 +65,10 @@ import com.arsdigita.workflow.simple.Workflow;
import com.arsdigita.xml.Element;
/**
* This class contains the component which displays the information
* for a particular lifecycle, with the ability to edit and delete.
* This information also includes the associated phases for this
* lifecycle, also with the ability to add, edit, and delete.
* This class contains the component which displays the information for a
* particular lifecycle, with the ability to edit and delete. This information
* also includes the associated phases for this lifecycle, also with the ability
* to add, edit, and delete.
*
* @author Michael Pih
* @author Jack Chung
@ -246,6 +246,18 @@ class ItemLifecycleItemPane extends BaseItemPane {
if (CMSConfig.getInstance().getThreadedPublishing()) {
final Republisher republisher = new Republisher(item);
final Thread thread = new Thread(republisher);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(final Thread thread,
final Throwable ex) {
PublishLock.getInstance().setError(item);
s_log.error(String.format(
"An error occurred while "
+ "publishing the item '%s': ",
item.getOID().toString()),
ex);
}
});
thread.start();
@ -275,11 +287,10 @@ class ItemLifecycleItemPane extends BaseItemPane {
/**
* Saves OID of item as a string. This is necessary because it is
* not possible to access to same data object instance from
* multiple threads. So we have to create a new instance a the
* data object in the run method. To avoid any sort a problems,
* we store the OID as a string and convert it back to an OID in
* the run method.
* not possible to access to same data object instance from multiple
* threads. So we have to create a new instance a the data object in
* the run method. To avoid any sort a problems, we store the OID as
* a string and convert it back to an OID in the run method.
*/
private final String itemOid;
@ -316,12 +327,24 @@ class ItemLifecycleItemPane extends BaseItemPane {
final ContentItem item = m_item.getContentItem(state);
/**
* jensp 2011-12-14: Execute is a thread if
* threaded publishing is active.
* jensp 2011-12-14: Execute is a thread if threaded publishing
* is active.
*/
if (CMSConfig.getInstance().getThreadedPublishing()) {
final Republisher republisher = new Republisher(item);
final Thread thread = new Thread(republisher);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(final Thread thread,
final Throwable ex) {
PublishLock.getInstance().setError(item);
s_log.error(String.format(
"An error occurred while "
+ "publishing the item '%s': ",
item.getOID().toString()),
ex);
}
});
thread.start();
@ -351,11 +374,10 @@ class ItemLifecycleItemPane extends BaseItemPane {
/**
* Saves OID of item as a string. This is necessary because it is
* not possible to access to same data object instance from
* multiple threads. So we have to create a new instance a the
* data object in the run method. To avoid any sort a problems,
* we store the OID as a string and convert it back to an OID in
* the run method.
* not possible to access to same data object instance from multiple
* threads. So we have to create a new instance a the data object in
* the run method. To avoid any sort a problems, we store the OID as
* a string and convert it back to an OID in the run method.
*/
private final String itemOid;
@ -399,9 +421,9 @@ class ItemLifecycleItemPane extends BaseItemPane {
}
/**
* New style pane. Uses a select box for the action to avoid wrong clicks
* on unpublish.
*
* New style pane. Uses a select box for the action to avoid wrong clicks on
* unpublish.
*
* @author Jens Pelzetter
*/
private class ActionForm
@ -474,13 +496,25 @@ class ItemLifecycleItemPane extends BaseItemPane {
final ContentItem item = m_item.getContentItem(state);
/**
* Republish/Republish and Reset are executed in the thread
* if threaded publishing is active.
* Republish/Republish and Reset are executed in the thread if
* threaded publishing is active.
*/
if (REPUBLISH.equals(selected)) {
if (CMSConfig.getInstance().getThreadedPublishing()) {
final RepublishRunner runner = new RepublishRunner(item);
final Thread thread = new Thread(runner);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(final Thread thread,
final Throwable ex) {
PublishLock.getInstance().setError(item);
s_log.error(String.format(
"An error occurred while "
+ "publishing the item '%s': ",
item.getOID().toString()),
ex);
}
});
thread.start();
@ -504,6 +538,18 @@ class ItemLifecycleItemPane extends BaseItemPane {
new RepublishAndResetRunner(
item);
final Thread thread = new Thread(runner);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(final Thread thread,
final Throwable ex) {
PublishLock.getInstance().setError(item);
s_log.error(String.format(
"An error occurred while "
+ "publishing the item '%s': ",
item.getOID().toString()),
ex);
}
});
thread.start();
@ -532,11 +578,10 @@ class ItemLifecycleItemPane extends BaseItemPane {
/**
* Saves OID of item as a string. This is necessary because it is
* not possible to access to same data object instance from
* multiple threads. So we have to create a new instance a the
* data object in the run method. To avoid any sort a problems,
* we store the OID as a string and convert it back to an OID in
* the run method.
* not possible to access to same data object instance from multiple
* threads. So we have to create a new instance a the data object in
* the run method. To avoid any sort a problems, we store the OID as
* a string and convert it back to an OID in the run method.
*/
private final String itemOid;
@ -563,11 +608,10 @@ class ItemLifecycleItemPane extends BaseItemPane {
/**
* Saves OID of item as a string. This is necessary because it is
* not possible to access to same data object instance from
* multiple threads. So we have to create a new instance a the
* data object in the run method. To avoid any sort a problems,
* we store the OID as a string and convert it back to an OID in
* the run method.
* not possible to access to same data object instance from multiple
* threads. So we have to create a new instance a the data object in
* the run method. To avoid any sort a problems, we store the OID as
* a string and convert it back to an OID in the run method.
*/
private final String itemOid;

View File

@ -89,7 +89,8 @@ import com.arsdigita.workflow.simple.WorkflowTemplate;
* @author Xixi D'moon <xdmoon@redhat.com>
* @author Justin Ross <jross@redhat.com>
* @author Jens Pelzetter jens@jp-digital.de
* @version $Id: ItemLifecycleSelectForm.java 1643 2007-09-17 14:19:06Z chrisg23 $
* @version $Id: ItemLifecycleSelectForm.java 1643 2007-09-17 14:19:06Z chrisg23
* $
*/
class ItemLifecycleSelectForm extends BaseForm {
@ -365,12 +366,12 @@ class ItemLifecycleSelectForm extends BaseForm {
}
/**
* jensp 2011-12-14: Some larger changes to the behavior of the
* process listener. The real action has been moved to the
* @link{Publisher} class. If threaded publishing is active, the publish
* process runs in a separate thread (the item is locked before using
* {@link PublishLock}. If threaded publishing is not active, nothing
* has changed.
* jensp 2011-12-14: Some larger changes to the behavior of the process
* listener. The real action has been moved to the
* @link{Publisher} class. If threaded publishing is active, the publish
* process runs in a separate thread (the item is locked before using
* {@link PublishLock}. If threaded publishing is not active, nothing has
* changed.
*/
private class ProcessListener implements FormProcessListener {
@ -390,6 +391,18 @@ class ItemLifecycleSelectForm extends BaseForm {
}
};
final Thread thread = new Thread(threadAction);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(final Thread thread,
final Throwable ex) {
PublishLock.getInstance().setError(item);
s_log.error(String.format(
"An error occurred while "
+ "publishing the item '%s': ",
item.getOID().toString()),
ex);
}
});
thread.start();
} else {
publisher.publish();
@ -410,171 +423,129 @@ class ItemLifecycleSelectForm extends BaseForm {
}
}
/*final Integer startHour = (Integer) m_startHour.getValue(state);
Integer startMinute = (Integer) m_startMinute.getValue(state);
if (startMinute == null) {
startMinute = new Integer(0);
/*
* final Integer startHour = (Integer) m_startHour.getValue(state);
* Integer startMinute = (Integer) m_startMinute.getValue(state);
*
* if (startMinute == null) { startMinute = new Integer(0); }
*
* final Integer startAmpm = (Integer) m_startAmpm.getValue(state);
*
* final Integer endHour = (Integer) m_endHour.getValue(state);
* Integer endMinute = (Integer) m_endMinute.getValue(state);
*
* if (endMinute == null) { endMinute = new Integer(0); }
*
* final Integer endAmpm = (Integer) m_endAmpm.getValue(state);
*
* // Instantiate the instance of the content type. final
* ContentItem item = m_item.getContentItem(state);
*
* final BigDecimal defID = (BigDecimal)
* m_cycleSelect.getValue(state); Assert.exists(defID); final
* LifecycleDefinition cycleDef = new LifecycleDefinition(defID);
*
* java.util.Date startDate = (java.util.Date)
* m_startDate.getValue(state);
*
* final Calendar start = Calendar.getInstance();
* start.setTime(startDate); start.set(Calendar.AM_PM,
* startAmpm.intValue()); start.set(Calendar.MINUTE,
* startMinute.intValue()); start.set(Calendar.AM_PM,
* startAmpm.intValue()); if (startHour.intValue() != 12) {
* start.set(Calendar.HOUR_OF_DAY, 12 * startAmpm.intValue() +
* startHour.intValue()); start.set(Calendar.HOUR,
* startHour.intValue()); } else { if (startAmpm.intValue() == 0) {
* start.set(Calendar.HOUR_OF_DAY, 0); start.set(Calendar.HOUR, 0);
* } else { start.set(Calendar.HOUR_OF_DAY, 12);
* start.set(Calendar.HOUR, 0); } } startDate = start.getTime();
*
* java.util.Date endDate = (java.util.Date)
* m_endDate.getValue(state);
*
* if (endDate != null) { final Calendar end =
* Calendar.getInstance();
*
* end.setTime(endDate); end.set(Calendar.AM_PM,
* endAmpm.intValue()); end.set(Calendar.MINUTE,
* endMinute.intValue()); end.set(Calendar.AM_PM,
* endAmpm.intValue());
*
* if (endHour.intValue() != 12) { end.set(Calendar.HOUR_OF_DAY, 12
* * endAmpm.intValue() + endHour.intValue());
* end.set(Calendar.HOUR, endHour.intValue()); } else { if
* (endAmpm.intValue() == 0) { end.set(Calendar.HOUR_OF_DAY, 0);
* end.set(Calendar.HOUR, 0); } else { end.set(Calendar.HOUR_OF_DAY,
* 12); end.set(Calendar.HOUR, 0); } } endDate = end.getTime(); }
*
* // If the item is already published, remove the current
* lifecycle. // Do not touch the live version. if
* (item.isPublished()) { item.removeLifecycle(item); item.save(); }
*
* // Apply the new lifecycle. ContentItem pending =
* item.publish(cycleDef, startDate); final Lifecycle lifecycle =
* pending.getLifecycle();
*
* // XXX domlay Whoa. This must be broken for multiphase //
* lifecycles.
*
* if (endDate != null) {
*
* // update individual phases final PhaseCollection phases =
* lifecycle.getPhases();
*
* while (phases.next()) { final Phase phase = phases.getPhase();
* java.util.Date thisEnd = phase.getEndDate(); java.util.Date
* thisStart = phase.getStartDate(); if
* (thisStart.compareTo(endDate) > 0) { phase.setStartDate(endDate);
* phase.save(); }
*
* if (thisEnd == null || thisEnd.compareTo(endDate) > 0) {
* phase.setEndDate(endDate); phase.save(); } } }
*
* // endOfCycle may be the original date according to lifecycle
* phase definitions, or endDate if that was before // natural end
* of lifecycle java.util.Date endOfCycle = lifecycle.getEndDate();
* if (endOfCycle != null) {
*
* // if advance notification is requested (!= 0) // add another
* phase at the start of which the user is notified Integer
* notificationDays = (Integer) m_notificationDays.getValue(state);
* Integer notificationHours = (Integer)
* m_notificationHours.getValue(state); java.util.Date
* notificationDate = null;
*
* int notificationPeriod = 0; if (notificationDays != null) {
* notificationPeriod += notificationDays.intValue() * 24; } if
* (notificationHours != null) { notificationPeriod +=
* notificationHours.intValue(); }
*
* if (notificationPeriod > 0) { notificationDate =
* computeNotificationDate(endOfCycle, notificationPeriod);
* s_log.debug("adding custom phase"); Phase expirationImminentPhase
* = lifecycle.addCustomPhase("expirationImminent", new
* Long(notificationDate. getTime()), new
* Long(endOfCycle.getTime()));
* expirationImminentPhase.setListenerClassName(
* "com.arsdigita.cms.lifecycle.NotifyLifecycleListener");
* expirationImminentPhase.save(); } }
*
* // Force the lifecycle scheduler to run to avoid any // scheduler
* delay for items that should be published // immediately.
* pending.getLifecycle().start();
*
* item.save();
*
* final Workflow workflow = m_workflow.getWorkflow(state); try {
* finish(workflow, item, Web.getContext().getUser()); } catch
* (TaskException te) { throw new FormProcessException(te); } //
* redirect to /content-center if streamlined creation mode is
* active. if
* (ContentSection.getConfig().getUseStreamlinedCreation()) { throw
* new RedirectSignal(URL.there(state.getRequest(),
* Utilities.getWorkspaceURL()), true);
}
final Integer startAmpm = (Integer) m_startAmpm.getValue(state);
final Integer endHour = (Integer) m_endHour.getValue(state);
Integer endMinute = (Integer) m_endMinute.getValue(state);
if (endMinute == null) {
endMinute = new Integer(0);
}
final Integer endAmpm = (Integer) m_endAmpm.getValue(state);
// Instantiate the instance of the content type.
final ContentItem item = m_item.getContentItem(state);
final BigDecimal defID = (BigDecimal) m_cycleSelect.getValue(state);
Assert.exists(defID);
final LifecycleDefinition cycleDef = new LifecycleDefinition(defID);
java.util.Date startDate =
(java.util.Date) m_startDate.getValue(state);
final Calendar start = Calendar.getInstance();
start.setTime(startDate);
start.set(Calendar.AM_PM, startAmpm.intValue());
start.set(Calendar.MINUTE, startMinute.intValue());
start.set(Calendar.AM_PM, startAmpm.intValue());
if (startHour.intValue() != 12) {
start.set(Calendar.HOUR_OF_DAY,
12 * startAmpm.intValue() + startHour.intValue());
start.set(Calendar.HOUR, startHour.intValue());
} else {
if (startAmpm.intValue() == 0) {
start.set(Calendar.HOUR_OF_DAY, 0);
start.set(Calendar.HOUR, 0);
} else {
start.set(Calendar.HOUR_OF_DAY, 12);
start.set(Calendar.HOUR, 0);
}
}
startDate = start.getTime();
java.util.Date endDate =
(java.util.Date) m_endDate.getValue(state);
if (endDate != null) {
final Calendar end = Calendar.getInstance();
end.setTime(endDate);
end.set(Calendar.AM_PM, endAmpm.intValue());
end.set(Calendar.MINUTE, endMinute.intValue());
end.set(Calendar.AM_PM, endAmpm.intValue());
if (endHour.intValue() != 12) {
end.set(Calendar.HOUR_OF_DAY,
12 * endAmpm.intValue() + endHour.intValue());
end.set(Calendar.HOUR, endHour.intValue());
} else {
if (endAmpm.intValue() == 0) {
end.set(Calendar.HOUR_OF_DAY, 0);
end.set(Calendar.HOUR, 0);
} else {
end.set(Calendar.HOUR_OF_DAY, 12);
end.set(Calendar.HOUR, 0);
}
}
endDate = end.getTime();
}
// If the item is already published, remove the current lifecycle.
// Do not touch the live version.
if (item.isPublished()) {
item.removeLifecycle(item);
item.save();
}
// Apply the new lifecycle.
ContentItem pending = item.publish(cycleDef, startDate);
final Lifecycle lifecycle = pending.getLifecycle();
// XXX domlay Whoa. This must be broken for multiphase
// lifecycles.
if (endDate != null) {
// update individual phases
final PhaseCollection phases = lifecycle.getPhases();
while (phases.next()) {
final Phase phase = phases.getPhase();
java.util.Date thisEnd = phase.getEndDate();
java.util.Date thisStart = phase.getStartDate();
if (thisStart.compareTo(endDate) > 0) {
phase.setStartDate(endDate);
phase.save();
}
if (thisEnd == null || thisEnd.compareTo(endDate) > 0) {
phase.setEndDate(endDate);
phase.save();
}
}
}
// endOfCycle may be the original date according to lifecycle phase definitions, or endDate if that was before
// natural end of lifecycle
java.util.Date endOfCycle = lifecycle.getEndDate();
if (endOfCycle != null) {
// if advance notification is requested (!= 0)
// add another phase at the start of which the user is notified
Integer notificationDays =
(Integer) m_notificationDays.getValue(state);
Integer notificationHours =
(Integer) m_notificationHours.getValue(state);
java.util.Date notificationDate = null;
int notificationPeriod = 0;
if (notificationDays != null) {
notificationPeriod += notificationDays.intValue() * 24;
}
if (notificationHours != null) {
notificationPeriod += notificationHours.intValue();
}
if (notificationPeriod > 0) {
notificationDate =
computeNotificationDate(endOfCycle, notificationPeriod);
s_log.debug("adding custom phase");
Phase expirationImminentPhase =
lifecycle.addCustomPhase("expirationImminent",
new Long(notificationDate.
getTime()),
new Long(endOfCycle.getTime()));
expirationImminentPhase.setListenerClassName(
"com.arsdigita.cms.lifecycle.NotifyLifecycleListener");
expirationImminentPhase.save();
}
}
// Force the lifecycle scheduler to run to avoid any
// scheduler delay for items that should be published
// immediately.
pending.getLifecycle().start();
item.save();
final Workflow workflow = m_workflow.getWorkflow(state);
try {
finish(workflow, item, Web.getContext().getUser());
} catch (TaskException te) {
throw new FormProcessException(te);
}
// redirect to /content-center if streamlined creation mode is active.
if (ContentSection.getConfig().getUseStreamlinedCreation()) {
throw new RedirectSignal(URL.there(state.getRequest(),
Utilities.getWorkspaceURL()),
true);
}*/
*/
}
}
@ -600,8 +571,8 @@ class ItemLifecycleSelectForm extends BaseForm {
/**
* The constructor collects all necessary data and stores them.
*
* @param state
*
* @param state
*/
public Publisher(final PageState state) {
startHour = (Integer) m_startHour.getValue(state);
@ -689,8 +660,8 @@ class ItemLifecycleSelectForm extends BaseForm {
public void publish() {
/**
* We have to create a new instance here since it is not possible
* to access the same data object from multiple threads.
* We have to create a new instance here since it is not possible to
* access the same data object from multiple threads.
*/
final OID oid = OID.valueOf(oidStr);
final ContentItem item = (ContentItem) DomainObjectFactory.
@ -997,12 +968,14 @@ class ItemLifecycleSelectForm extends BaseForm {
}
/**
* Find out at which date a notification (about an item that is about
* to expire) should be sent, based on the endDate (== date at which the
* item is unpublished) and the notification period.
*@param endDate the endDate of the lifecycle, i.e. the date when the item
* is going to be unpublished
*@param notification how many hours the users shouls be notified in advance
* Find out at which date a notification (about an item that is about to
* expire) should be sent, based on the endDate (== date at which the item
* is unpublished) and the notification period.
*
* @param endDate the endDate of the lifecycle, i.e. the date when the item
* is going to be unpublished
* @param notification how many hours the users shouls be notified in
* advance
*/
private java.util.Date computeNotificationDate(java.util.Date endDate,
int notificationPeriod) {

View File

@ -7,10 +7,10 @@ import com.arsdigita.persistence.SessionManager;
import java.util.Calendar;
/**
* Used by {@link ItemLifecycleSelectForm} and {@link ItemLifecycleItemPane}
* to lock an item if threaded publishing is active.
*
* @author Jens Pelzetter
* Used by {@link ItemLifecycleSelectForm} and {@link ItemLifecycleItemPane} to
* lock an item if threaded publishing is active.
*
* @author Jens Pelzetter
* @version $Id$
*/
public class PublishLock {
@ -21,7 +21,8 @@ public class PublishLock {
public final static String LOCKED_OID = "lockedOid";
public final static String TIMESTAMP = "timestamp";
public final static String ACTION = "action";
private static PublishLock instance = new PublishLock();
public final static String ERROR = "error";
private static PublishLock instance = new PublishLock();
private PublishLock() {
}
@ -33,9 +34,9 @@ public class PublishLock {
protected synchronized void lock(final ContentItem item) {
lock(item, "publish");
}
protected synchronized void lock(final ContentItem item,
final String action) {
final String action) {
SessionManager.getSession().getTransactionContext().beginTxn();
final DataObject lock = SessionManager.getSession().create(
LOCK_OBJECT_TYPE);
@ -47,7 +48,7 @@ public class PublishLock {
SessionManager.getSession().getTransactionContext().commitTxn();
}
protected synchronized void unlock(final ContentItem item) {
protected synchronized void unlock(final ContentItem item) {
SessionManager.getSession().getTransactionContext().beginTxn();
final DataCollection collection = SessionManager.getSession().retrieve(
LOCK_OBJECT_TYPE);
@ -58,7 +59,7 @@ public class PublishLock {
final DataObject lock = collection.getDataObject();
lock.delete();
}
collection.close();
collection.close();
SessionManager.getSession().getTransactionContext().commitTxn();
}
@ -73,6 +74,46 @@ public class PublishLock {
} else {
collection.close();
return true;
}
}
}
protected synchronized void setError(final ContentItem item) {
SessionManager.getSession().getTransactionContext().beginTxn();
final DataCollection collection = SessionManager.getSession().retrieve(
LOCK_OBJECT_TYPE);
collection.addFilter(String.format("%s = '%s'", LOCKED_OID,
item.getOID().toString()));
if (!collection.isEmpty()) {
collection.next();
final DataObject lock = collection.getDataObject();
lock.set(ACTION, ERROR);
lock.save();
}
collection.close();
SessionManager.getSession().getTransactionContext().commitTxn();
}
protected synchronized boolean hasError(final ContentItem item) {
final DataCollection collection = SessionManager.getSession().retrieve(
LOCK_OBJECT_TYPE);
collection.addFilter(String.format("%s = '%s'", LOCKED_OID,
item.getOID().toString()));
if (collection.isEmpty()) {
collection.close();
return false;
} else {
collection.next();
final DataObject lock = collection.getDataObject();
if (ERROR.equals(lock.get(ACTION).toString())) {
collection.close();
return true;
} else {
collection.close();
return false;
}
}
}
}