Workflows werden nun auch bei einem Republish korrekt zurückgesetzt.

git-svn-id: https://svn.libreccm.org/ccm/trunk@2447 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2013-11-22 09:01:05 +00:00
parent a430009ed2
commit 818b0785cf
1 changed files with 808 additions and 799 deletions

View File

@ -18,17 +18,12 @@
*/
package com.arsdigita.cms.ui.lifecycle;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.event.FormSectionEvent;
import java.text.DateFormat;
import org.apache.log4j.Logger;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.RequestLocal;
@ -38,6 +33,7 @@ import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.bebop.form.Option;
@ -45,11 +41,10 @@ import com.arsdigita.bebop.form.SingleSelect;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.CMSConfig;
import com.arsdigita.cms.ContentCenter;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentPage;
import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.ContentCenter;
import com.arsdigita.cms.dispatcher.Utilities;
import com.arsdigita.cms.lifecycle.Lifecycle;
import com.arsdigita.cms.ui.BaseItemPane;
@ -60,6 +55,7 @@ import com.arsdigita.globalization.GlobalizationHelper;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.Party;
import com.arsdigita.kernel.PartyCollection;
import com.arsdigita.kernel.User;
import com.arsdigita.notification.Notification;
import com.arsdigita.persistence.OID;
import com.arsdigita.toolbox.ui.ActionGroup;
@ -75,12 +71,14 @@ import com.arsdigita.xml.Element;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Locale;
import java.text.DateFormat;
import org.apache.log4j.Logger;
/**
* 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
@ -109,7 +107,7 @@ class ItemLifecycleItemPane extends BaseItemPane {
m_detailPane.add(new SummarySection());
final Label lastPublishedLabel = new Label();
lastPublishedLabel.addPrintListener(new PrintListener() {
@Override
public void prepare(final PrintEvent event) {
final PageState state = event.getPageState();
final ContentItem item = m_item.getContentItem(state).
@ -133,7 +131,6 @@ class ItemLifecycleItemPane extends BaseItemPane {
dateStr);
label.setLabel(msg);
}
});
m_detailPane.add(lastPublishedLabel);
@ -164,6 +161,7 @@ class ItemLifecycleItemPane extends BaseItemPane {
private class Properties extends PropertyList {
@Override
protected final java.util.List properties(final PageState state) {
final java.util.List props = super.properties(state);
final Lifecycle cycle = m_lifecycle.getLifecycle(state);
@ -191,7 +189,6 @@ class ItemLifecycleItemPane extends BaseItemPane {
return props;
}
}
}
@ -203,6 +200,7 @@ class ItemLifecycleItemPane extends BaseItemPane {
super(c);
}
@Override
public void generateXML(PageState ps, Element parent) {
Boolean canPublish = (Boolean) m_canPublish.get(ps);
if (null == canPublish) {
@ -231,7 +229,6 @@ class ItemLifecycleItemPane extends BaseItemPane {
s_log.debug("User cannot publish " + item.getOID());
}
}
}
private class UnpublishLink extends PublishLink {
@ -244,6 +241,7 @@ class ItemLifecycleItemPane extends BaseItemPane {
private class Listener implements ActionListener {
@Override
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
final ContentItem item = m_item.getContentItem(state);
@ -256,16 +254,14 @@ class ItemLifecycleItemPane extends BaseItemPane {
throw new RedirectSignal(target, true);
}
}
}
private static void republish(ContentItem item, boolean reset) {
private static void republish(ContentItem item, boolean reset, User user) {
item.republish(reset);
Workflow workflow = Workflow.getObjectWorkflow(item);
try {
ItemLifecycleSelectForm.finish(workflow, item, Web.getContext().
getUser());
ItemLifecycleSelectForm.finish(workflow, item, user);
} catch (TaskException te) {
throw new UncheckedWrapperException(te);
}
@ -281,18 +277,20 @@ class ItemLifecycleItemPane extends BaseItemPane {
private class Listener implements ActionListener {
@Override
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
final ContentItem item = m_item.getContentItem(state);
final User user = Web.getContext().getUser();
/*
* jensp 2011-12-14: Check is threaded publishing is active. If yes, execute publishing in a thread.
*/
if (CMSConfig.getInstance().getThreadedPublishing()) {
final Republisher republisher = new Republisher(item);
final Republisher republisher = new Republisher(item, user);
final Thread thread = new Thread(republisher);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(final Thread thread,
final Throwable ex) {
PublishLock.getInstance().setError(item);
@ -352,7 +350,6 @@ class ItemLifecycleItemPane extends BaseItemPane {
notification.save();
}
}
});
thread.start();
@ -366,7 +363,7 @@ class ItemLifecycleItemPane extends BaseItemPane {
* jensp 2011-12-14 end
*/
} else {
republish(item, false);
republish(item, false, user);
if (ContentSection.getConfig().getUseStreamlinedCreation()) {
throw new RedirectSignal(
URL.there(state.getRequest(),
@ -374,7 +371,6 @@ class ItemLifecycleItemPane extends BaseItemPane {
}
}
}
}
/**
@ -383,24 +379,27 @@ class ItemLifecycleItemPane extends BaseItemPane {
private class Republisher implements Runnable {
/**
* 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.
* 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.
*/
private final String itemOid;
private final User user;
private Republisher(final ContentItem item) {
private Republisher(final ContentItem item, User user) {
itemOid = item.getOID().toString();
this.user = user;
}
@Override
public void run() {
final ContentItem item = (ContentItem) DomainObjectFactory.newInstance(OID.valueOf(itemOid));
PublishLock.getInstance().lock(item);
republish(item, false);
republish(item, false, user);
PublishLock.getInstance().unlock(item);
}
}
}
@ -418,18 +417,21 @@ class ItemLifecycleItemPane extends BaseItemPane {
private class Listener implements ActionListener {
@Override
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
final ContentItem item = m_item.getContentItem(state);
final User user = Web.getContext().getUser();
/**
* 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 Republisher republisher = new Republisher(item, user);
final Thread thread = new Thread(republisher);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(final Thread thread,
final Throwable ex) {
PublishLock.getInstance().setError(item);
@ -489,7 +491,6 @@ class ItemLifecycleItemPane extends BaseItemPane {
notification.save();
}
}
});
thread.start();
@ -503,7 +504,7 @@ class ItemLifecycleItemPane extends BaseItemPane {
/**
* jensp 2011-12-14 end
*/
republish(item, true);
republish(item, true, user);
if (ContentSection.getConfig().getUseStreamlinedCreation()) {
throw new RedirectSignal(
URL.there(state.getRequest(),
@ -511,7 +512,6 @@ class ItemLifecycleItemPane extends BaseItemPane {
}
}
}
}
/**
@ -520,24 +520,27 @@ class ItemLifecycleItemPane extends BaseItemPane {
private class Republisher implements Runnable {
/**
* 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.
* 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.
*/
private final String itemOid;
private final User user;
private Republisher(final ContentItem item) {
private Republisher(final ContentItem item, User user) {
itemOid = item.getOID().toString();
this.user = user;
}
@Override
public void run() {
final ContentItem item = (ContentItem) DomainObjectFactory.newInstance(OID.valueOf(itemOid));
PublishLock.getInstance().lock(item);
republish(item, true);
republish(item, true, user);
PublishLock.getInstance().unlock(item);
}
}
}
@ -551,7 +554,6 @@ class ItemLifecycleItemPane extends BaseItemPane {
group.setSubject(new PhaseTable());
}
}
private class PhaseTable extends Table {
@ -565,11 +567,11 @@ class ItemLifecycleItemPane extends BaseItemPane {
lz("cms.ui.item.lifecycle.end_date")
});
}
}
/**
* 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
*/
@ -617,6 +619,7 @@ class ItemLifecycleItemPane extends BaseItemPane {
addProcessListener(this);
}
@Override
public void init(FormSectionEvent fse) throws FormProcessException {
final PageState state = fse.getPageState();
final ContentItem item = m_item.getContentItem(state);
@ -634,23 +637,26 @@ class ItemLifecycleItemPane extends BaseItemPane {
}
}
@Override
public void process(final FormSectionEvent fse) throws
FormProcessException {
final PageState state = fse.getPageState();
final FormData data = fse.getFormData();
final User user = Web.getContext().getUser();
String selected = (String) data.get(LIFECYCLE_ACTION);
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 RepublishRunner runner = new RepublishRunner(item, user);
final Thread thread = new Thread(runner);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(final Thread thread,
final Throwable ex) {
PublishLock.getInstance().setError(item);
@ -710,7 +716,6 @@ class ItemLifecycleItemPane extends BaseItemPane {
notification.save();
}
}
});
thread.start();
@ -721,7 +726,7 @@ class ItemLifecycleItemPane extends BaseItemPane {
ContentItemPage.PUBLISHING_TAB),
true);
} else {
republish(item, false);
republish(item, false, user);
if (ContentSection.getConfig().getUseStreamlinedCreation()) {
throw new RedirectSignal(
@ -732,11 +737,10 @@ class ItemLifecycleItemPane extends BaseItemPane {
} else if (REPUBLISH_AND_RESET.equals(selected)) {
if (CMSConfig.getInstance().getThreadedPublishing()) {
final RepublishAndResetRunner runner =
new RepublishAndResetRunner(
item);
new RepublishAndResetRunner(item, user);
final Thread thread = new Thread(runner);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(final Thread thread,
final Throwable ex) {
PublishLock.getInstance().setError(item);
@ -796,7 +800,6 @@ class ItemLifecycleItemPane extends BaseItemPane {
notification.save();
}
}
});
thread.start();
@ -807,7 +810,7 @@ class ItemLifecycleItemPane extends BaseItemPane {
ContentItemPage.PUBLISHING_TAB),
true);
} else {
republish(item, true);
republish(item, true, user);
if (ContentSection.getConfig().getUseStreamlinedCreation()) {
throw new RedirectSignal(
@ -825,57 +828,63 @@ class ItemLifecycleItemPane extends BaseItemPane {
private class RepublishRunner implements Runnable {
/**
* 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.
* 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.
*/
private final String itemOid;
private final User user;
private RepublishRunner(final ContentItem item) {
private RepublishRunner(final ContentItem item, User user) {
itemOid = item.getOID().toString();
this.user = user;
}
private void doRepublish() {
final ContentItem item = (ContentItem) DomainObjectFactory.newInstance(OID.valueOf(itemOid));
republish(item, false);
republish(item, false, user);
}
@Override
public void run() {
final ContentItem item = (ContentItem) DomainObjectFactory.newInstance(OID.valueOf(itemOid));
PublishLock.getInstance().lock(item);
doRepublish();
PublishLock.getInstance().unlock(item);
}
}
private class RepublishAndResetRunner implements Runnable {
/**
* 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.
* 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.
*/
private final String itemOid;
private final User user;
private RepublishAndResetRunner(final ContentItem item) {
private RepublishAndResetRunner(final ContentItem item, User user) {
itemOid = item.getOID().toString();
this.user = user;
}
private void doRepublishAndReset() {
final ContentItem item = (ContentItem) DomainObjectFactory.newInstance(OID.valueOf(itemOid));
republish(item, true);
republish(item, true, user);
}
@Override
public void run() {
final ContentItem item = (ContentItem) DomainObjectFactory.newInstance(OID.valueOf(itemOid));
PublishLock.getInstance().lock(item);
doRepublishAndReset();
PublishLock.getInstance().unlock(item);
}
}
}
}