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.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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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=
|
||||
|
|
|
|||
|
|
@ -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=
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue