UncaughtExceptionHandler für ThreadedPublishing
git-svn-id: https://svn.libreccm.org/ccm/trunk@1440 8810af33-2d31-482b-a856-94f89814c4dfmaster
parent
39ad6472b0
commit
a61bb46566
|
|
@ -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.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=This content item is being (re-)published
|
||||||
cms.ui.item.lifecycle.publish_locked.update=Update
|
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.
|
||||||
|
|
|
||||||
|
|
@ -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.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=Dieses Content-Item wird gerade (re-)publiziert
|
||||||
cms.ui.item.lifecycle.publish_locked.update=Aktualisieren
|
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.
|
||||||
|
|
|
||||||
|
|
@ -28,3 +28,4 @@ cms.ui.item.lifecycle.do=
|
||||||
cms.ui.item.lifecycle.do.not_authorized=
|
cms.ui.item.lifecycle.do.not_authorized=
|
||||||
cms.ui.item.lifecycle.publish_locked=
|
cms.ui.item.lifecycle.publish_locked=
|
||||||
cms.ui.item.lifecycle.publish_locked.update=
|
cms.ui.item.lifecycle.publish_locked.update=
|
||||||
|
cms.ui.lifecycle.publish.error=
|
||||||
|
|
|
||||||
|
|
@ -559,3 +559,4 @@ cms.ui.item.lifecycle.do=
|
||||||
cms.ui.item.lifecycle.do.not_authorized=
|
cms.ui.item.lifecycle.do.not_authorized=
|
||||||
cms.ui.item.lifecycle.publish_locked=
|
cms.ui.item.lifecycle.publish_locked=
|
||||||
cms.ui.item.lifecycle.publish_locked.update=
|
cms.ui.item.lifecycle.publish_locked.update=
|
||||||
|
cms.ui.lifecycle.publish.error=
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
|
||||||
private final LayoutPanel m_detailPane;
|
private final LayoutPanel m_detailPane;
|
||||||
private final LayoutPanel m_selectPane;
|
private final LayoutPanel m_selectPane;
|
||||||
private final LayoutPanel m_lockedPane;
|
private final LayoutPanel m_lockedPane;
|
||||||
|
private final LayoutPanel m_errorPane;
|
||||||
|
|
||||||
public ItemLifecycleAdminPane(final ContentItemRequestLocal item) {
|
public ItemLifecycleAdminPane(final ContentItemRequestLocal item) {
|
||||||
m_item = item;
|
m_item = item;
|
||||||
|
|
@ -100,6 +101,12 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
|
||||||
});
|
});
|
||||||
m_lockedPane.setBottom(lockedUpdateLink);
|
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);
|
connect(selectForm, m_detailPane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,7 +138,12 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
|
||||||
if (CMSConfig.getInstance().getThreadedPublishing()
|
if (CMSConfig.getInstance().getThreadedPublishing()
|
||||||
&& PublishLock.getInstance().isLocked(m_item.getContentItem(
|
&& PublishLock.getInstance().isLocked(m_item.getContentItem(
|
||||||
state))) {
|
state))) {
|
||||||
|
if (PublishLock.getInstance().hasError(m_item.getContentItem(
|
||||||
|
state))) {
|
||||||
|
push(state, m_errorPane);
|
||||||
|
} else {
|
||||||
push(state, m_lockedPane);
|
push(state, m_lockedPane);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (state.isVisibleOnPage(ItemLifecycleAdminPane.this)) {
|
if (state.isVisibleOnPage(ItemLifecycleAdminPane.this)) {
|
||||||
if (m_lifecycle.getLifecycle(state) == null) {
|
if (m_lifecycle.getLifecycle(state) == null) {
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,10 @@ import com.arsdigita.workflow.simple.Workflow;
|
||||||
import com.arsdigita.xml.Element;
|
import com.arsdigita.xml.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains the component which displays the information
|
* This class contains the component which displays the information for a
|
||||||
* for a particular lifecycle, with the ability to edit and delete.
|
* particular lifecycle, with the ability to edit and delete. This information
|
||||||
* This information also includes the associated phases for this
|
* also includes the associated phases for this lifecycle, also with the ability
|
||||||
* lifecycle, also with the ability to add, edit, and delete.
|
* to add, edit, and delete.
|
||||||
*
|
*
|
||||||
* @author Michael Pih
|
* @author Michael Pih
|
||||||
* @author Jack Chung
|
* @author Jack Chung
|
||||||
|
|
@ -246,6 +246,18 @@ class ItemLifecycleItemPane extends BaseItemPane {
|
||||||
if (CMSConfig.getInstance().getThreadedPublishing()) {
|
if (CMSConfig.getInstance().getThreadedPublishing()) {
|
||||||
final Republisher republisher = new Republisher(item);
|
final Republisher republisher = new Republisher(item);
|
||||||
final Thread thread = new Thread(republisher);
|
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();
|
thread.start();
|
||||||
|
|
||||||
|
|
@ -275,11 +287,10 @@ class ItemLifecycleItemPane extends BaseItemPane {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves OID of item as a string. This is necessary because it is
|
* Saves OID of item as a string. This is necessary because it is
|
||||||
* not possible to access to same data object instance from
|
* not possible to access to same data object instance from multiple
|
||||||
* multiple threads. So we have to create a new instance a the
|
* threads. So we have to create a new instance a the data object in
|
||||||
* data object in the run method. To avoid any sort a problems,
|
* the run method. To avoid any sort a problems, we store the OID as
|
||||||
* we store the OID as a string and convert it back to an OID in
|
* a string and convert it back to an OID in the run method.
|
||||||
* the run method.
|
|
||||||
*/
|
*/
|
||||||
private final String itemOid;
|
private final String itemOid;
|
||||||
|
|
||||||
|
|
@ -316,12 +327,24 @@ class ItemLifecycleItemPane extends BaseItemPane {
|
||||||
final ContentItem item = m_item.getContentItem(state);
|
final ContentItem item = m_item.getContentItem(state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* jensp 2011-12-14: Execute is a thread if
|
* jensp 2011-12-14: Execute is a thread if threaded publishing
|
||||||
* threaded publishing is active.
|
* is active.
|
||||||
*/
|
*/
|
||||||
if (CMSConfig.getInstance().getThreadedPublishing()) {
|
if (CMSConfig.getInstance().getThreadedPublishing()) {
|
||||||
final Republisher republisher = new Republisher(item);
|
final Republisher republisher = new Republisher(item);
|
||||||
final Thread thread = new Thread(republisher);
|
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();
|
thread.start();
|
||||||
|
|
||||||
|
|
@ -351,11 +374,10 @@ class ItemLifecycleItemPane extends BaseItemPane {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves OID of item as a string. This is necessary because it is
|
* Saves OID of item as a string. This is necessary because it is
|
||||||
* not possible to access to same data object instance from
|
* not possible to access to same data object instance from multiple
|
||||||
* multiple threads. So we have to create a new instance a the
|
* threads. So we have to create a new instance a the data object in
|
||||||
* data object in the run method. To avoid any sort a problems,
|
* the run method. To avoid any sort a problems, we store the OID as
|
||||||
* we store the OID as a string and convert it back to an OID in
|
* a string and convert it back to an OID in the run method.
|
||||||
* the run method.
|
|
||||||
*/
|
*/
|
||||||
private final String itemOid;
|
private final String itemOid;
|
||||||
|
|
||||||
|
|
@ -399,8 +421,8 @@ class ItemLifecycleItemPane extends BaseItemPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New style pane. Uses a select box for the action to avoid wrong clicks
|
* New style pane. Uses a select box for the action to avoid wrong clicks on
|
||||||
* on unpublish.
|
* unpublish.
|
||||||
*
|
*
|
||||||
* @author Jens Pelzetter
|
* @author Jens Pelzetter
|
||||||
*/
|
*/
|
||||||
|
|
@ -474,13 +496,25 @@ class ItemLifecycleItemPane extends BaseItemPane {
|
||||||
final ContentItem item = m_item.getContentItem(state);
|
final ContentItem item = m_item.getContentItem(state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Republish/Republish and Reset are executed in the thread
|
* Republish/Republish and Reset are executed in the thread if
|
||||||
* if threaded publishing is active.
|
* threaded publishing is active.
|
||||||
*/
|
*/
|
||||||
if (REPUBLISH.equals(selected)) {
|
if (REPUBLISH.equals(selected)) {
|
||||||
if (CMSConfig.getInstance().getThreadedPublishing()) {
|
if (CMSConfig.getInstance().getThreadedPublishing()) {
|
||||||
final RepublishRunner runner = new RepublishRunner(item);
|
final RepublishRunner runner = new RepublishRunner(item);
|
||||||
final Thread thread = new Thread(runner);
|
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();
|
thread.start();
|
||||||
|
|
||||||
|
|
@ -504,6 +538,18 @@ class ItemLifecycleItemPane extends BaseItemPane {
|
||||||
new RepublishAndResetRunner(
|
new RepublishAndResetRunner(
|
||||||
item);
|
item);
|
||||||
final Thread thread = new Thread(runner);
|
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();
|
thread.start();
|
||||||
|
|
||||||
|
|
@ -532,11 +578,10 @@ class ItemLifecycleItemPane extends BaseItemPane {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves OID of item as a string. This is necessary because it is
|
* Saves OID of item as a string. This is necessary because it is
|
||||||
* not possible to access to same data object instance from
|
* not possible to access to same data object instance from multiple
|
||||||
* multiple threads. So we have to create a new instance a the
|
* threads. So we have to create a new instance a the data object in
|
||||||
* data object in the run method. To avoid any sort a problems,
|
* the run method. To avoid any sort a problems, we store the OID as
|
||||||
* we store the OID as a string and convert it back to an OID in
|
* a string and convert it back to an OID in the run method.
|
||||||
* the run method.
|
|
||||||
*/
|
*/
|
||||||
private final String itemOid;
|
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
|
* Saves OID of item as a string. This is necessary because it is
|
||||||
* not possible to access to same data object instance from
|
* not possible to access to same data object instance from multiple
|
||||||
* multiple threads. So we have to create a new instance a the
|
* threads. So we have to create a new instance a the data object in
|
||||||
* data object in the run method. To avoid any sort a problems,
|
* the run method. To avoid any sort a problems, we store the OID as
|
||||||
* we store the OID as a string and convert it back to an OID in
|
* a string and convert it back to an OID in the run method.
|
||||||
* the run method.
|
|
||||||
*/
|
*/
|
||||||
private final String itemOid;
|
private final String itemOid;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,8 @@ import com.arsdigita.workflow.simple.WorkflowTemplate;
|
||||||
* @author Xixi D'moon <xdmoon@redhat.com>
|
* @author Xixi D'moon <xdmoon@redhat.com>
|
||||||
* @author Justin Ross <jross@redhat.com>
|
* @author Justin Ross <jross@redhat.com>
|
||||||
* @author Jens Pelzetter jens@jp-digital.de
|
* @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 {
|
class ItemLifecycleSelectForm extends BaseForm {
|
||||||
|
|
||||||
|
|
@ -365,12 +366,12 @@ class ItemLifecycleSelectForm extends BaseForm {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* jensp 2011-12-14: Some larger changes to the behavior of the
|
* jensp 2011-12-14: Some larger changes to the behavior of the process
|
||||||
* process listener. The real action has been moved to the
|
* listener. The real action has been moved to the
|
||||||
* @link{Publisher} class. If threaded publishing is active, the publish
|
* @link{Publisher} class. If threaded publishing is active, the publish
|
||||||
* process runs in a separate thread (the item is locked before using
|
* process runs in a separate thread (the item is locked before using
|
||||||
* {@link PublishLock}. If threaded publishing is not active, nothing
|
* {@link PublishLock}. If threaded publishing is not active, nothing has
|
||||||
* has changed.
|
* changed.
|
||||||
*/
|
*/
|
||||||
private class ProcessListener implements FormProcessListener {
|
private class ProcessListener implements FormProcessListener {
|
||||||
|
|
||||||
|
|
@ -390,6 +391,18 @@ class ItemLifecycleSelectForm extends BaseForm {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
final Thread thread = new Thread(threadAction);
|
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();
|
thread.start();
|
||||||
} else {
|
} else {
|
||||||
publisher.publish();
|
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);
|
* final Integer startHour = (Integer) m_startHour.getValue(state);
|
||||||
|
* Integer startMinute = (Integer) m_startMinute.getValue(state);
|
||||||
if (startMinute == null) {
|
*
|
||||||
startMinute = new Integer(0);
|
* 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);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -689,8 +660,8 @@ class ItemLifecycleSelectForm extends BaseForm {
|
||||||
public void publish() {
|
public void publish() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We have to create a new instance here since it is not possible
|
* We have to create a new instance here since it is not possible to
|
||||||
* to access the same data object from multiple threads.
|
* access the same data object from multiple threads.
|
||||||
*/
|
*/
|
||||||
final OID oid = OID.valueOf(oidStr);
|
final OID oid = OID.valueOf(oidStr);
|
||||||
final ContentItem item = (ContentItem) DomainObjectFactory.
|
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
|
* Find out at which date a notification (about an item that is about to
|
||||||
* to expire) should be sent, based on the endDate (== date at which the
|
* expire) should be sent, based on the endDate (== date at which the item
|
||||||
* item is unpublished) and the notification period.
|
* is unpublished) and the notification period.
|
||||||
|
*
|
||||||
* @param endDate the endDate of the lifecycle, i.e. the date when the item
|
* @param endDate the endDate of the lifecycle, i.e. the date when the item
|
||||||
* is going to be unpublished
|
* is going to be unpublished
|
||||||
*@param notification how many hours the users shouls be notified in advance
|
* @param notification how many hours the users shouls be notified in
|
||||||
|
* advance
|
||||||
*/
|
*/
|
||||||
private java.util.Date computeNotificationDate(java.util.Date endDate,
|
private java.util.Date computeNotificationDate(java.util.Date endDate,
|
||||||
int notificationPeriod) {
|
int notificationPeriod) {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ import com.arsdigita.persistence.SessionManager;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by {@link ItemLifecycleSelectForm} and {@link ItemLifecycleItemPane}
|
* Used by {@link ItemLifecycleSelectForm} and {@link ItemLifecycleItemPane} to
|
||||||
* to lock an item if threaded publishing is active.
|
* lock an item if threaded publishing is active.
|
||||||
*
|
*
|
||||||
* @author Jens Pelzetter
|
* @author Jens Pelzetter
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
|
|
@ -21,6 +21,7 @@ public class PublishLock {
|
||||||
public final static String LOCKED_OID = "lockedOid";
|
public final static String LOCKED_OID = "lockedOid";
|
||||||
public final static String TIMESTAMP = "timestamp";
|
public final static String TIMESTAMP = "timestamp";
|
||||||
public final static String ACTION = "action";
|
public final static String ACTION = "action";
|
||||||
|
public final static String ERROR = "error";
|
||||||
private static PublishLock instance = new PublishLock();
|
private static PublishLock instance = new PublishLock();
|
||||||
|
|
||||||
private PublishLock() {
|
private PublishLock() {
|
||||||
|
|
@ -75,4 +76,44 @@ public class PublishLock {
|
||||||
return true;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue