Verbesserung der Publizieren-Formulars:

- Der eigentliche Vorgang wird jetzt nebenläufig durchgeführt
	- Solange der Vorgang noch läuft wird eine entsprechende Meldung angezeigt


git-svn-id: https://svn.libreccm.org/ccm/trunk@1352 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2011-12-14 15:18:43 +00:00
parent 248b26555d
commit b7f54a9921
11 changed files with 728 additions and 220 deletions

View File

@ -26,23 +26,3 @@ ALTER TABLE cms_persons
ALTER TABLE cms_persons ALTER TABLE cms_persons
ADD COLUMN dabin_id INTEGER; ADD COLUMN dabin_id INTEGER;
CREATE TABLE cms_organizationalunits_hierarchy_map (
superior_orgaunit_id integer NOT NULL,
subordinate_orgaunit_id integer NOT NULL,
assoc_type character varying(128),
superior_orgaunit_order integer,
subordinate_orgaunit_order integer
);
-- No sure how to get db owner here
ALTER TABLE public.cms_organizationalunits_hierarchy_map OWNER TO iaw;
ALTER TABLE ONLY cms_organizationalunits_hierarchy_map
ADD CONSTRAINT cms_org_hie_map_sub_or_p_nykpq PRIMARY KEY (subordinate_orgaunit_id, superior_orgaunit_id);
ALTER TABLE ONLY cms_organizationalunits_hierarchy_map
ADD CONSTRAINT cms_org_hie_map_sub_or_f_xq5is FOREIGN KEY (subordinate_orgaunit_id) REFERENCES cms_organizationalunits(organizationalunit_id);
ALTER TABLE ONLY cms_organizationalunits_hierarchy_map
ADD CONSTRAINT cms_org_hie_map_sup_or_f_qchkn FOREIGN KEY (superior_orgaunit_id) REFERENCES cms_organizationalunits(organizationalunit_id);

View File

@ -27,5 +27,6 @@ begin;
\i ../default/upgrade/6.6.2-6.6.3/upd_table_persons.sql \i ../default/upgrade/6.6.2-6.6.3/upd_table_persons.sql
\i ../default/upgrade/6.6.2-6.6.3/create_orgaunit_hierarchy_table.sql \i ../default/upgrade/6.6.2-6.6.3/create_orgaunit_hierarchy_table.sql
\i ../default/upgrade/6.6.2-6.6.3/create_publish_lock_table.sql
commit; commit;

View File

@ -588,6 +588,19 @@ public final class CMSConfig extends AbstractConfig {
Parameter.REQUIRED, Parameter.REQUIRED,
false); false);
////////////////////////////////////////////////
//Actives threaded publishing. If active, the publish process for
//content items will run in a separate thread. May useful if you have
//large objects.
//
//WARNING: Not tested very much. Use at your own risk.
//
////////////////////////////////////////////////////
private final Parameter m_threadPublishing = new BooleanParameter(
"com.arsdigita.cms.lifecycle.threaded_publishing",
Parameter.REQUIRED,
false);
// /////////////////////////////////////////// // ///////////////////////////////////////////
// publishToFile package related parameter // publishToFile package related parameter
// /////////////////////////////////////////// // ///////////////////////////////////////////
@ -669,6 +682,7 @@ public final class CMSConfig extends AbstractConfig {
register(m_folderAtoZShowLimit); register(m_folderAtoZShowLimit);
register(m_useOldStyleItemLifecycleItemPane); register(m_useOldStyleItemLifecycleItemPane);
register(m_threadPublishing);
// publishToFile package related parameter // publishToFile package related parameter
// Moved to publishToFile.PublishToFileConfig as of version 6.0.2 // Moved to publishToFile.PublishToFileConfig as of version 6.0.2
@ -1071,4 +1085,8 @@ public final class CMSConfig extends AbstractConfig {
public Boolean getUseOldStyleItemLifecycleItemPane() { public Boolean getUseOldStyleItemLifecycleItemPane() {
return (Boolean) get(m_useOldStyleItemLifecycleItemPane); return (Boolean) get(m_useOldStyleItemLifecycleItemPane);
} }
public Boolean getThreadedPublishing() {
return (Boolean) get(m_threadPublishing);
}
} }

View File

@ -254,6 +254,11 @@ com.arsdigita.cms.lifecycle.use_old_style_item_lifecycle_item_pane.purpose = If
com.arsdigita.cms.lifecycle.use_old_style_item_lifecycle_item_pane.example = false com.arsdigita.cms.lifecycle.use_old_style_item_lifecycle_item_pane.example = false
com.arsdigita.cms.lifecycle.use_old_style_item_lifecycle_item_pane.format = [Boolean] com.arsdigita.cms.lifecycle.use_old_style_item_lifecycle_item_pane.format = [Boolean]
com.arsdigita.cms.lifecycle.threaded_publishing.title = Threaded publishing
com.arsdigita.cms.lifecycle.threaded_publishing.purpose = Decides if publishing is done in a thread (new behaviour) or directly (old, well tested behaviour).
com.arsdigita.cms.lifecycle.threaded_publishing.example = false
com.arsdigita.cms.lifecycle.threaded_com.arsdigita.cms.lifecycle.threaded_publishingpublishing.format = [Boolean]
com.arsdigita.cms.xx.title= com.arsdigita.cms.xx.title=
com.arsdigita.cms.xx.purpose= com.arsdigita.cms.xx.purpose=
com.arsdigita.cms.xx.example= com.arsdigita.cms.xx.example=

View File

@ -1087,3 +1087,5 @@ cms.contenttypes.person.alias.select.same_as_person=Selected person is the same
cms.contenttypes.person.alias.select.no_suitable_language_variant=The selected item has no suitable language variant. cms.contenttypes.person.alias.select.no_suitable_language_variant=The selected item has no suitable language variant.
cms.ui.item.lifecycle.do=Execute 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.update=Update

View File

@ -1078,3 +1078,5 @@ cms.contenttypes.person.alias.select.same_as_person=Der ausgew\u00e4hlte Datensa
cms.contenttypes.person.alias.select.no_suitable_language_variant=Das ausgew\u00e4hlte Item hat keine passende Sprachvariante. cms.contenttypes.person.alias.select.no_suitable_language_variant=Das ausgew\u00e4hlte Item hat keine passende Sprachvariante.
cms.ui.item.lifecycle.do=Ausf\u00fchren 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.update=Aktualisieren

View File

@ -26,3 +26,5 @@ cms.contenttypes.person.alias.select.same_as_person=
cms.contenttypes.person.alias.select.no_suitable_language_variant= cms.contenttypes.person.alias.select.no_suitable_language_variant=
cms.ui.item.lifecycle.do= 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.update=

View File

@ -557,3 +557,5 @@ cms.contenttypes.person.alias.select.same_as_person=
cms.contenttypes.person.alias.select.no_suitable_language_variant= cms.contenttypes.person.alias.select.no_suitable_language_variant=
cms.ui.item.lifecycle.do= 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.update=

View File

@ -18,36 +18,41 @@
*/ */
package com.arsdigita.cms.ui.lifecycle; package com.arsdigita.cms.ui.lifecycle;
import com.arsdigita.bebop.ControlLink;
import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page; import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.ActionEvent; import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener; import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.cms.CMS; import com.arsdigita.cms.CMS;
import com.arsdigita.cms.CMSConfig;
import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.lifecycle.Lifecycle; import com.arsdigita.cms.lifecycle.Lifecycle;
import com.arsdigita.cms.ui.BaseItemPane; import com.arsdigita.cms.ui.BaseItemPane;
import com.arsdigita.cms.ui.ContentItemPage;
import com.arsdigita.cms.ui.item.ContentItemRequestLocal; import com.arsdigita.cms.ui.item.ContentItemRequestLocal;
import com.arsdigita.toolbox.ui.LayoutPanel; import com.arsdigita.toolbox.ui.LayoutPanel;
import com.arsdigita.web.RedirectSignal;
import com.arsdigita.web.URL;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* @author Michael Pih * @author Michael Pih
* @author Jack Chung * @author Jack Chung
* @author Justin Ross <jross@redhat.com> * @author Justin Ross <jross@redhat.com>
* @author Jens Pelzetter jens@jp-digital.de
* @version $Id: ItemLifecycleAdminPane.java 1942 2009-05-29 07:53:23Z terry $ * @version $Id: ItemLifecycleAdminPane.java 1942 2009-05-29 07:53:23Z terry $
*/ */
public class ItemLifecycleAdminPane extends BaseItemPane { public class ItemLifecycleAdminPane extends BaseItemPane {
private static final Logger s_log = Logger.getLogger private static final Logger s_log = Logger.getLogger(
(ItemLifecycleAdminPane.class); ItemLifecycleAdminPane.class);
private final ContentItemRequestLocal m_item; private final ContentItemRequestLocal m_item;
private final LifecycleRequestLocal m_lifecycle; private final LifecycleRequestLocal m_lifecycle;
private final LayoutPanel m_introPane; private final LayoutPanel m_introPane;
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;
public ItemLifecycleAdminPane(final ContentItemRequestLocal item) { public ItemLifecycleAdminPane(final ContentItemRequestLocal item) {
m_item = item; m_item = item;
@ -63,7 +68,8 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
add(m_detailPane); add(m_detailPane);
final ItemLifecycleItemPane itemPane = final ItemLifecycleItemPane itemPane =
new ItemLifecycleItemPane(m_item, m_lifecycle); new ItemLifecycleItemPane(m_item,
m_lifecycle);
m_detailPane.setBody(itemPane); m_detailPane.setBody(itemPane);
m_selectPane = new LayoutPanel(); m_selectPane = new LayoutPanel();
@ -73,10 +79,32 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
new ItemLifecycleSelectForm(m_item); new ItemLifecycleSelectForm(m_item);
m_selectPane.setBody(selectForm); m_selectPane.setBody(selectForm);
m_lockedPane = new LayoutPanel();
add(m_lockedPane);
final Label lockedMsg = new Label(gz(
"cms.ui.item.lifecycle.publish_locked"));
m_lockedPane.setBody(lockedMsg);
final ControlLink lockedUpdateLink = new ControlLink(new Label(gz(
"cms.ui.item.lifecycle.publish_locked.update")));
lockedUpdateLink.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent event) {
throw new RedirectSignal(
URL.getDispatcherPath()
+ ContentItemPage.getItemURL(
item.getContentItem(event.getPageState()),
ContentItemPage.PUBLISHING_TAB),
true);
}
});
m_lockedPane.setBottom(lockedUpdateLink);
connect(selectForm, m_detailPane); connect(selectForm, m_detailPane);
} }
private class ItemLifecycleRequestLocal extends LifecycleRequestLocal { private class ItemLifecycleRequestLocal extends LifecycleRequestLocal {
protected final Object initialValue(final PageState state) { protected final Object initialValue(final PageState state) {
final ContentItem item = m_item.getContentItem(state); final ContentItem item = m_item.getContentItem(state);
final Lifecycle lifecycle = item.getLifecycle(); final Lifecycle lifecycle = item.getLifecycle();
@ -94,11 +122,17 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
} }
private class VisibilityListener implements ActionListener { private class VisibilityListener implements ActionListener {
public final void actionPerformed(final ActionEvent e) { public final void actionPerformed(final ActionEvent e) {
s_log.debug("Determining which pane to show"); s_log.debug("Determining which pane to show");
final PageState state = e.getPageState(); final PageState state = e.getPageState();
if (CMSConfig.getInstance().getThreadedPublishing()
&& PublishLock.getInstance().isLocked(m_item.getContentItem(
state))) {
push(state, m_lockedPane);
} else {
if (state.isVisibleOnPage(ItemLifecycleAdminPane.this)) { if (state.isVisibleOnPage(ItemLifecycleAdminPane.this)) {
if (m_lifecycle.getLifecycle(state) == null) { if (m_lifecycle.getLifecycle(state) == null) {
if (hasPermission(state)) { if (hasPermission(state)) {
@ -112,11 +146,12 @@ public class ItemLifecycleAdminPane extends BaseItemPane {
} }
} }
} }
}
private boolean hasPermission(final PageState state) { private boolean hasPermission(final PageState state) {
final ContentItem item = m_item.getContentItem(state); final ContentItem item = m_item.getContentItem(state);
return CMS.getContext().getSecurityManager().canAccess return CMS.getContext().getSecurityManager().canAccess(
(state.getRequest(), SCHEDULE_PUBLICATION, item); state.getRequest(), SCHEDULE_PUBLICATION, item);
} }
} }

View File

@ -42,6 +42,7 @@ import com.arsdigita.bebop.form.Option;
import com.arsdigita.bebop.form.SingleSelect; import com.arsdigita.bebop.form.SingleSelect;
import com.arsdigita.bebop.form.Submit; import com.arsdigita.bebop.form.Submit;
import com.arsdigita.cms.CMS; import com.arsdigita.cms.CMS;
import com.arsdigita.cms.CMSConfig;
import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.SecurityManager; import com.arsdigita.cms.SecurityManager;
@ -50,6 +51,8 @@ import com.arsdigita.cms.lifecycle.Lifecycle;
import com.arsdigita.cms.ui.BaseItemPane; import com.arsdigita.cms.ui.BaseItemPane;
import com.arsdigita.cms.ui.ContentItemPage; import com.arsdigita.cms.ui.ContentItemPage;
import com.arsdigita.cms.ui.item.ContentItemRequestLocal; import com.arsdigita.cms.ui.item.ContentItemRequestLocal;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.persistence.OID;
import com.arsdigita.toolbox.ui.ActionGroup; import com.arsdigita.toolbox.ui.ActionGroup;
import com.arsdigita.toolbox.ui.PropertyList; import com.arsdigita.toolbox.ui.PropertyList;
import com.arsdigita.toolbox.ui.Section; import com.arsdigita.toolbox.ui.Section;
@ -71,6 +74,7 @@ import com.arsdigita.xml.Element;
* @author Jack Chung * @author Jack Chung
* @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
* @version $Id: ItemLifecycleItemPane.java 1942 2009-05-29 07:53:23Z terry $ * @version $Id: ItemLifecycleItemPane.java 1942 2009-05-29 07:53:23Z terry $
*/ */
class ItemLifecycleItemPane extends BaseItemPane { class ItemLifecycleItemPane extends BaseItemPane {
@ -235,6 +239,25 @@ class ItemLifecycleItemPane extends BaseItemPane {
final PageState state = e.getPageState(); final PageState state = e.getPageState();
final ContentItem item = m_item.getContentItem(state); final ContentItem item = m_item.getContentItem(state);
/*
* 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 Thread thread = new Thread(republisher);
thread.start();
throw new RedirectSignal(
URL.getDispatcherPath()
+ ContentItemPage.getItemURL(item,
ContentItemPage.PUBLISHING_TAB),
true);
/*
* jensp 2011-12-14 end
*/
} else {
republish(item, false); republish(item, false);
if (ContentSection.getConfig().getUseStreamlinedCreation()) { if (ContentSection.getConfig().getUseStreamlinedCreation()) {
throw new RedirectSignal( throw new RedirectSignal(
@ -245,6 +268,35 @@ class ItemLifecycleItemPane extends BaseItemPane {
} }
} }
/**
* @author Jens Pelzetter
*/
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.
*/
private final String itemOid;
private Republisher(final ContentItem item) {
itemOid = item.getOID().toString();
}
public void run() {
final ContentItem item = (ContentItem) DomainObjectFactory.
newInstance(OID.valueOf(itemOid));
PublishLock.getInstance().lock(item);
republish(item, false);
PublishLock.getInstance().unlock(item);
}
}
}
private class RepublishAndResetLink extends PublishLink { private class RepublishAndResetLink extends PublishLink {
RepublishAndResetLink() { RepublishAndResetLink() {
@ -263,6 +315,25 @@ class ItemLifecycleItemPane extends BaseItemPane {
final PageState state = e.getPageState(); final PageState state = e.getPageState();
final ContentItem item = m_item.getContentItem(state); final ContentItem item = m_item.getContentItem(state);
/**
* 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.start();
throw new RedirectSignal(
URL.getDispatcherPath()
+ ContentItemPage.getItemURL(item,
ContentItemPage.PUBLISHING_TAB),
true);
} else {
/**
* jensp 2011-12-14 end
*/
republish(item, true); republish(item, true);
if (ContentSection.getConfig().getUseStreamlinedCreation()) { if (ContentSection.getConfig().getUseStreamlinedCreation()) {
throw new RedirectSignal( throw new RedirectSignal(
@ -273,6 +344,35 @@ class ItemLifecycleItemPane extends BaseItemPane {
} }
} }
/**
* @author Jens Pelzetter
*/
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.
*/
private final String itemOid;
private Republisher(final ContentItem item) {
itemOid = item.getOID().toString();
}
public void run() {
final ContentItem item = (ContentItem) DomainObjectFactory.
newInstance(OID.valueOf(itemOid));
PublishLock.getInstance().lock(item);
republish(item, true);
PublishLock.getInstance().unlock(item);
}
}
}
private class PhaseSection extends Section { private class PhaseSection extends Section {
PhaseSection() { PhaseSection() {
@ -298,6 +398,12 @@ class ItemLifecycleItemPane extends BaseItemPane {
} }
} }
/**
* New style pane. Uses a select box for the action to avoid wrong clicks
* on unpublish.
*
* @author Jens Pelzetter
*/
private class ActionForm private class ActionForm
extends Form extends Form
implements FormProcessListener, implements FormProcessListener,
@ -367,7 +473,23 @@ class ItemLifecycleItemPane extends BaseItemPane {
String selected = (String) data.get(LIFECYCLE_ACTION); String selected = (String) data.get(LIFECYCLE_ACTION);
final ContentItem item = m_item.getContentItem(state); final ContentItem item = m_item.getContentItem(state);
/**
* Republish/Republish and Reset are executed in the thread
* if threaded publishing is active.
*/
if (REPUBLISH.equals(selected)) { if (REPUBLISH.equals(selected)) {
if (CMSConfig.getInstance().getThreadedPublishing()) {
final RepublishRunner runner = new RepublishRunner(item);
final Thread thread = new Thread(runner);
thread.start();
throw new RedirectSignal(
URL.getDispatcherPath()
+ ContentItemPage.getItemURL(item,
ContentItemPage.PUBLISHING_TAB),
true);
} else {
republish(item, false); republish(item, false);
if (ContentSection.getConfig().getUseStreamlinedCreation()) { if (ContentSection.getConfig().getUseStreamlinedCreation()) {
@ -375,7 +497,22 @@ class ItemLifecycleItemPane extends BaseItemPane {
URL.there(state.getRequest(), URL.there(state.getRequest(),
Utilities.getWorkspaceURL()), true); Utilities.getWorkspaceURL()), true);
} }
}
} else if (REPUBLISH_AND_RESET.equals(selected)) { } else if (REPUBLISH_AND_RESET.equals(selected)) {
if (CMSConfig.getInstance().getThreadedPublishing()) {
final RepublishAndResetRunner runner =
new RepublishAndResetRunner(
item);
final Thread thread = new Thread(runner);
thread.start();
throw new RedirectSignal(
URL.getDispatcherPath()
+ ContentItemPage.getItemURL(item,
ContentItemPage.PUBLISHING_TAB),
true);
} else {
republish(item, true); republish(item, true);
if (ContentSection.getConfig().getUseStreamlinedCreation()) { if (ContentSection.getConfig().getUseStreamlinedCreation()) {
@ -383,11 +520,74 @@ class ItemLifecycleItemPane extends BaseItemPane {
URL.there(state.getRequest(), URL.there(state.getRequest(),
Utilities.getWorkspaceURL()), true); Utilities.getWorkspaceURL()), true);
} }
}
} else if (UNPUBLISH.equals(selected)) { } else if (UNPUBLISH.equals(selected)) {
item.unpublish(); item.unpublish();
} else { } else {
throw new IllegalArgumentException("Illegal selection"); throw new IllegalArgumentException("Illegal selection");
} }
} }
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.
*/
private final String itemOid;
private RepublishRunner(final ContentItem item) {
itemOid = item.getOID().toString();
}
private void doRepublish() {
final ContentItem item = (ContentItem) DomainObjectFactory.
newInstance(OID.valueOf(itemOid));
republish(item, false);
}
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.
*/
private final String itemOid;
private RepublishAndResetRunner(final ContentItem item) {
itemOid = item.getOID().toString();
}
private void doRepublishAndReset() {
final ContentItem item = (ContentItem) DomainObjectFactory.
newInstance(OID.valueOf(itemOid));
republish(item, true);
}
public void run() {
final ContentItem item = (ContentItem) DomainObjectFactory.
newInstance(OID.valueOf(itemOid));
PublishLock.getInstance().lock(item);
doRepublishAndReset();
PublishLock.getInstance().unlock(item);
}
}
} }
} }

View File

@ -50,6 +50,7 @@ import com.arsdigita.bebop.parameters.DateParameter;
import com.arsdigita.bebop.parameters.IntegerParameter; import com.arsdigita.bebop.parameters.IntegerParameter;
import com.arsdigita.bebop.parameters.NumberInRangeValidationListener; import com.arsdigita.bebop.parameters.NumberInRangeValidationListener;
import com.arsdigita.cms.CMS; import com.arsdigita.cms.CMS;
import com.arsdigita.cms.CMSConfig;
import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.ContentTypeLifecycleDefinition; import com.arsdigita.cms.ContentTypeLifecycleDefinition;
@ -61,6 +62,7 @@ import com.arsdigita.cms.lifecycle.Phase;
import com.arsdigita.cms.lifecycle.PhaseCollection; import com.arsdigita.cms.lifecycle.PhaseCollection;
import com.arsdigita.cms.lifecycle.PhaseDefinitionCollection; import com.arsdigita.cms.lifecycle.PhaseDefinitionCollection;
import com.arsdigita.cms.ui.BaseForm; import com.arsdigita.cms.ui.BaseForm;
import com.arsdigita.cms.ui.ContentItemPage;
import com.arsdigita.cms.ui.item.ContentItemRequestLocal; import com.arsdigita.cms.ui.item.ContentItemRequestLocal;
import com.arsdigita.cms.ui.item.ItemWorkflowRequestLocal; import com.arsdigita.cms.ui.item.ItemWorkflowRequestLocal;
import com.arsdigita.cms.ui.workflow.WorkflowRequestLocal; import com.arsdigita.cms.ui.workflow.WorkflowRequestLocal;
@ -68,8 +70,9 @@ import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.cms.workflow.CMSEngine; import com.arsdigita.cms.workflow.CMSEngine;
import com.arsdigita.cms.workflow.CMSTask; import com.arsdigita.cms.workflow.CMSTask;
import com.arsdigita.cms.workflow.CMSTaskType; import com.arsdigita.cms.workflow.CMSTaskType;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.kernel.User; import com.arsdigita.kernel.User;
import com.arsdigita.util.Assert; import com.arsdigita.persistence.OID;
import com.arsdigita.util.UncheckedWrapperException; import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.web.RedirectSignal; import com.arsdigita.web.RedirectSignal;
import com.arsdigita.web.URL; import com.arsdigita.web.URL;
@ -85,22 +88,20 @@ import com.arsdigita.workflow.simple.WorkflowTemplate;
* @author Michael Pih * @author Michael Pih
* @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
* @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 {
private static final Logger s_log = Logger.getLogger private static final Logger s_log =
(ItemLifecycleSelectForm.class); Logger.getLogger(ItemLifecycleSelectForm.class);
private final static String LIFECYCLE = "lifecycle"; private final static String LIFECYCLE = "lifecycle";
private final static String START_DATE = "start_date"; private final static String START_DATE = "start_date";
private final static String END_DATE = "end_date"; private final static String END_DATE = "end_date";
private final static String NOTIFICATION_DAYS = "notifyDays"; private final static String NOTIFICATION_DAYS = "notifyDays";
private final static String NOTIFICATION_HOURS = "notifyHours"; private final static String NOTIFICATION_HOURS = "notifyHours";
private final ContentItemRequestLocal m_item; private final ContentItemRequestLocal m_item;
private final WorkflowRequestLocal m_workflow; private final WorkflowRequestLocal m_workflow;
// Form widgets // Form widgets
private final SingleSelect m_cycleSelect; private final SingleSelect m_cycleSelect;
private final Date m_startDate; private final Date m_startDate;
@ -130,9 +131,10 @@ class ItemLifecycleSelectForm extends BaseForm {
// Start date // Start date
m_startDate = new Date(new DateParameter(START_DATE) { m_startDate =
protected final Calendar getCalendar new Date(new DateParameter(START_DATE) {
(final HttpServletRequest sreq) {
protected final Calendar getCalendar(final HttpServletRequest sreq) {
final Calendar cal = super.getCalendar(sreq); final Calendar cal = super.getCalendar(sreq);
cal.setLenient(false); cal.setLenient(false);
@ -153,8 +155,8 @@ class ItemLifecycleSelectForm extends BaseForm {
startTime.add(m_startHour); startTime.add(m_startHour);
m_startHour.setSize(3); m_startHour.setSize(3);
m_startHour.addValidationListener m_startHour.addValidationListener(
(new NumberInRangeValidationListener(1, 12)); new NumberInRangeValidationListener(1, 12));
// Minute // Minute
@ -162,8 +164,8 @@ class ItemLifecycleSelectForm extends BaseForm {
startTime.add(m_startMinute); startTime.add(m_startMinute);
m_startMinute.setSize(3); m_startMinute.setSize(3);
m_startMinute.addValidationListener m_startMinute.addValidationListener(new NumberInRangeValidationListener(
(new NumberInRangeValidationListener(0, 59)); 0, 59));
// AM/PM // AM/PM
@ -179,9 +181,10 @@ class ItemLifecycleSelectForm extends BaseForm {
// Expiration date // Expiration date
m_endDate = new Date(new DateParameter(END_DATE) { m_endDate =
protected final Calendar getCalendar new Date(new DateParameter(END_DATE) {
(final HttpServletRequest sreq) {
protected final Calendar getCalendar(final HttpServletRequest sreq) {
final Calendar cal = super.getCalendar(sreq); final Calendar cal = super.getCalendar(sreq);
cal.setLenient(false); cal.setLenient(false);
@ -202,8 +205,8 @@ class ItemLifecycleSelectForm extends BaseForm {
endTime.add(m_endHour); endTime.add(m_endHour);
m_endHour.setSize(3); m_endHour.setSize(3);
m_endHour.addValidationListener m_endHour.addValidationListener(new NumberInRangeValidationListener(1,
(new NumberInRangeValidationListener(1, 12)); 12));
// Minute // Minute
@ -211,8 +214,8 @@ class ItemLifecycleSelectForm extends BaseForm {
endTime.add(m_endMinute); endTime.add(m_endMinute);
m_endMinute.setSize(3); m_endMinute.setSize(3);
m_endMinute.addValidationListener m_endMinute.addValidationListener(
(new NumberInRangeValidationListener(0, 59)); new NumberInRangeValidationListener(0, 59));
// AM/PM // AM/PM
@ -233,9 +236,11 @@ class ItemLifecycleSelectForm extends BaseForm {
m_notificationHours.setSize(4); m_notificationHours.setSize(4);
SimpleContainer cont = new SimpleContainer(); SimpleContainer cont = new SimpleContainer();
cont.add(m_notificationDays); cont.add(m_notificationDays);
cont.add(new Label(GlobalizationUtil.globalize("cms.ui.item.days"), false)); cont.add(new Label(GlobalizationUtil.globalize("cms.ui.item.days"),
false));
cont.add(m_notificationHours); cont.add(m_notificationHours);
cont.add(new Label(GlobalizationUtil.globalize("cms.ui.item.hours"), false)); cont.add(new Label(GlobalizationUtil.globalize("cms.ui.item.hours"),
false));
addField(gz("cms.ui.item.notification_period"), cont); addField(gz("cms.ui.item.notification_period"), cont);
@ -254,6 +259,7 @@ class ItemLifecycleSelectForm extends BaseForm {
} }
private class OptionPrinter implements PrintListener { private class OptionPrinter implements PrintListener {
public final void prepare(final PrintEvent e) { public final void prepare(final PrintEvent e) {
final ContentSection section = final ContentSection section =
CMS.getContext().getContentSection(); CMS.getContext().getContentSection();
@ -273,8 +279,7 @@ class ItemLifecycleSelectForm extends BaseForm {
// ready to be applied to an item. // ready to be applied to an item.
if (!pdc.isEmpty()) { if (!pdc.isEmpty()) {
target.addOption target.addOption(new Option(ld.getID().toString(),
(new Option(ld.getID().toString(),
ld.getLabel())); ld.getLabel()));
} }
@ -286,6 +291,7 @@ class ItemLifecycleSelectForm extends BaseForm {
} }
private class InitListener implements FormInitListener { private class InitListener implements FormInitListener {
public final void init(final FormSectionEvent e) { public final void init(final FormSectionEvent e) {
final PageState state = e.getPageState(); final PageState state = e.getPageState();
@ -296,7 +302,8 @@ class ItemLifecycleSelectForm extends BaseForm {
// associated lifecycle. // associated lifecycle.
final LifecycleDefinition ld = final LifecycleDefinition ld =
item.getLifecycle().getLifecycleDefinition(); item.getLifecycle().
getLifecycleDefinition();
m_cycleSelect.setValue(state, ld.getID()); m_cycleSelect.setValue(state, ld.getID());
} else { } else {
// Set the default lifecycle (if it exists). // Set the default lifecycle (if it exists).
@ -304,8 +311,8 @@ class ItemLifecycleSelectForm extends BaseForm {
final ContentSection section = final ContentSection section =
CMS.getContext().getContentSection(); CMS.getContext().getContentSection();
final LifecycleDefinition ld = final LifecycleDefinition ld =
ContentTypeLifecycleDefinition.getLifecycleDefinition ContentTypeLifecycleDefinition.
(section, item.getContentType()); getLifecycleDefinition(section, item.getContentType());
if (ld != null) { if (ld != null) {
m_cycleSelect.setValue(state, ld.getID()); m_cycleSelect.setValue(state, ld.getID());
@ -315,8 +322,8 @@ class ItemLifecycleSelectForm extends BaseForm {
// Set the default start date. // Set the default start date.
// XXX Isn't just new Date() sufficient? // XXX Isn't just new Date() sufficient?
final java.util.Date start = new java.util.Date final java.util.Date start = new java.util.Date(System.
(System.currentTimeMillis()); currentTimeMillis());
m_startDate.setValue(state, start); m_startDate.setValue(state, start);
final Calendar calendar = Calendar.getInstance(); final Calendar calendar = Calendar.getInstance();
@ -329,8 +336,8 @@ class ItemLifecycleSelectForm extends BaseForm {
if (calendar.get(Calendar.HOUR) == 0) { if (calendar.get(Calendar.HOUR) == 0) {
m_startHour.setValue(state, new Integer(12)); m_startHour.setValue(state, new Integer(12));
} else { } else {
m_startHour.setValue m_startHour.setValue(state, new Integer(calendar.get(
(state, new Integer(calendar.get(Calendar.HOUR))); Calendar.HOUR)));
} }
final Integer min = new Integer(calendar.get(Calendar.MINUTE)); final Integer min = new Integer(calendar.get(Calendar.MINUTE));
@ -341,28 +348,69 @@ class ItemLifecycleSelectForm extends BaseForm {
m_startMinute.setValue(state, min.toString()); m_startMinute.setValue(state, min.toString());
} }
m_startAmpm.setValue m_startAmpm.setValue(state,
(state, new Integer(calendar.get(Calendar.AM_PM))); new Integer(calendar.get(Calendar.AM_PM)));
BigInteger [] defaultTime = BigInteger[] defaultTime =
BigInteger.valueOf(ContentSection. BigInteger.valueOf(ContentSection.getConfig().
getConfig().getDefaultNotificationTime()). getDefaultNotificationTime()).
divideAndRemainder(BigInteger.valueOf(24)); divideAndRemainder(BigInteger.valueOf(24));
m_notificationDays. m_notificationDays.setValue(state, new Integer(defaultTime[0].
setValue(state, new Integer(defaultTime[0].intValue())); intValue()));
m_notificationHours. m_notificationHours.setValue(state, new Integer(defaultTime[1].
setValue(state, new Integer(defaultTime[1].intValue())); intValue()));
} }
} }
/**
* 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 { private class ProcessListener implements FormProcessListener {
public final void process(final FormSectionEvent e) public final void process(final FormSectionEvent e)
throws FormProcessException { throws FormProcessException {
final PageState state = e.getPageState(); final PageState state = e.getPageState();
final ContentItem item = m_item.getContentItem(state);
final Integer startHour = (Integer) m_startHour.getValue(state); final Publisher publisher = new Publisher(state);
if (CMSConfig.getInstance().getThreadedPublishing()) {
final Runnable threadAction = new Runnable() {
public void run() {
PublishLock.getInstance().lock(item);
publisher.publish();
PublishLock.getInstance().unlock(item);
}
};
final Thread thread = new Thread(threadAction);
thread.start();
} else {
publisher.publish();
}
if (CMSConfig.getInstance().getThreadedPublishing()) {
throw new RedirectSignal(
URL.getDispatcherPath()
+ ContentItemPage.getItemURL(item,
ContentItemPage.PUBLISHING_TAB),
true);
} else {
if (ContentSection.getConfig().getUseStreamlinedCreation()) {
throw new RedirectSignal(
URL.there(state.getRequest(),
Utilities.getWorkspaceURL()),
true);
}
}
/*final Integer startHour = (Integer) m_startHour.getValue(state);
Integer startMinute = (Integer) m_startMinute.getValue(state); Integer startMinute = (Integer) m_startMinute.getValue(state);
if (startMinute == null) { if (startMinute == null) {
@ -383,11 +431,9 @@ class ItemLifecycleSelectForm extends BaseForm {
// Instantiate the instance of the content type. // Instantiate the instance of the content type.
final ContentItem item = m_item.getContentItem(state); final ContentItem item = m_item.getContentItem(state);
final BigDecimal defID = (BigDecimal) m_cycleSelect.getValue final BigDecimal defID = (BigDecimal) m_cycleSelect.getValue(state);
(state);
Assert.exists(defID); Assert.exists(defID);
final LifecycleDefinition cycleDef = new LifecycleDefinition final LifecycleDefinition cycleDef = new LifecycleDefinition(defID);
(defID);
java.util.Date startDate = java.util.Date startDate =
(java.util.Date) m_startDate.getValue(state); (java.util.Date) m_startDate.getValue(state);
@ -482,14 +528,14 @@ class ItemLifecycleSelectForm extends BaseForm {
// if advance notification is requested (!= 0) // if advance notification is requested (!= 0)
// add another phase at the start of which the user is notified // add another phase at the start of which the user is notified
Integer notificationDays = Integer notificationDays =
(Integer)m_notificationDays.getValue(state); (Integer) m_notificationDays.getValue(state);
Integer notificationHours = Integer notificationHours =
(Integer)m_notificationHours.getValue(state); (Integer) m_notificationHours.getValue(state);
java.util.Date notificationDate = null; java.util.Date notificationDate = null;
int notificationPeriod = 0; int notificationPeriod = 0;
if (notificationDays != null) { if (notificationDays != null) {
notificationPeriod += notificationDays.intValue()*24; notificationPeriod += notificationDays.intValue() * 24;
} }
if (notificationHours != null) { if (notificationHours != null) {
notificationPeriod += notificationHours.intValue(); notificationPeriod += notificationHours.intValue();
@ -501,10 +547,11 @@ class ItemLifecycleSelectForm extends BaseForm {
s_log.debug("adding custom phase"); s_log.debug("adding custom phase");
Phase expirationImminentPhase = Phase expirationImminentPhase =
lifecycle.addCustomPhase("expirationImminent", lifecycle.addCustomPhase("expirationImminent",
new Long(notificationDate.getTime()), new Long(notificationDate.
getTime()),
new Long(endOfCycle.getTime())); new Long(endOfCycle.getTime()));
expirationImminentPhase. expirationImminentPhase.setListenerClassName(
setListenerClassName("com.arsdigita.cms.lifecycle.NotifyLifecycleListener"); "com.arsdigita.cms.lifecycle.NotifyLifecycleListener");
expirationImminentPhase.save(); expirationImminentPhase.save();
} }
} }
@ -524,26 +571,236 @@ class ItemLifecycleSelectForm extends BaseForm {
} }
// redirect to /content-center if streamlined creation mode is active. // redirect to /content-center if streamlined creation mode is active.
if (ContentSection.getConfig().getUseStreamlinedCreation()) { if (ContentSection.getConfig().getUseStreamlinedCreation()) {
throw new RedirectSignal throw new RedirectSignal(URL.there(state.getRequest(),
(URL.there(state.getRequest(),
Utilities.getWorkspaceURL()), Utilities.getWorkspaceURL()),
true); true);
}*/
}
}
/**
* This class contains the real publish action.
*/
private class Publisher {
private final Integer startHour;
private final Integer startMinute;
private final Integer startAmpm;
private final Integer endHour;
private final Integer endMinute;
private final Integer endAmpm;
private final String oidStr;
private final BigDecimal defID;
private final java.util.Date startDate;
private final java.util.Date endDate;
private final Integer notificationDays;
private final Integer notificationHours;
private final String workflowOid;
private final User user;
/**
* The constructor collects all necessary data and stores them.
*
* @param state
*/
public Publisher(final PageState state) {
startHour = (Integer) m_startHour.getValue(state);
if (m_startMinute.getValue(state) == null) {
startMinute = new Integer(0);
} else {
startMinute = (Integer) m_startMinute.getValue(state);
}
startAmpm = (Integer) m_startAmpm.getValue(state);
endHour = (Integer) m_endHour.getValue(state);
if (m_endMinute.getValue(state) == null) {
endMinute = new Integer(0);
} else {
endMinute = (Integer) m_endMinute.getValue(state);
}
endAmpm = (Integer) m_endAmpm.getValue(state);
//item = m_item.getContentItem(state);
oidStr = m_item.getContentItem(state).getOID().toString();
defID = (BigDecimal) m_cycleSelect.getValue(state);
final Calendar start = Calendar.getInstance();
start.setTime((java.util.Date) m_startDate.getValue(state));
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();
if (m_endDate.getValue(state) == null) {
endDate = null;
} else {
final Calendar end = Calendar.getInstance();
end.setTime((java.util.Date) m_endDate.getValue(state));
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();
}
notificationDays = (Integer) m_notificationDays.getValue(state);
notificationHours = (Integer) m_notificationHours.getValue(state);
if (m_workflow.getWorkflow(state) != null) {
workflowOid = m_workflow.getWorkflow(state).getOID().toString();
} else {
workflowOid = null;
}
user = Web.getContext().getUser();
}
/**
* Published the item
*/
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.
*/
final OID oid = OID.valueOf(oidStr);
final ContentItem item = (ContentItem) DomainObjectFactory.
newInstance(oid);
// If the item is already published, remove the current lifecycle.
// Do not touch the live version.
if (item.isPublished()) {
item.removeLifecycle(item);
item.save();
}
ContentItem pending;
final LifecycleDefinition cycleDef;
final Lifecycle lifecycle;
// Apply the new lifecycle.
cycleDef = new LifecycleDefinition(defID);
pending = item.publish(cycleDef, startDate);
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();
} }
} }
} }
static void finish(Workflow workflow, ContentItem item, User user) throws TaskException { // 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
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();
if (workflowOid != null) {
final Workflow workflow =
(Workflow) DomainObjectFactory.newInstance(OID.
valueOf(workflowOid));
try {
finish(workflow, item, user);
} catch (TaskException ex) {
throw new UncheckedWrapperException(ex);
}
}
}
}
static void finish(Workflow workflow, ContentItem item, User user) throws
TaskException {
if (workflow != null) { if (workflow != null) {
final Engine engine = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE); final Engine engine = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE);
// ; // ;
final Iterator iter = engine.getEnabledTasks final Iterator iter = engine.getEnabledTasks(user, workflow.getID()).
(user, workflow.getID()).iterator(); iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
final CMSTask task = (CMSTask) iter.next(); final CMSTask task = (CMSTask) iter.next();
if( s_log.isDebugEnabled() ) if (s_log.isDebugEnabled()) {
s_log.debug( "Task is " + task.getOID().toString() ); s_log.debug("Task is " + task.getOID().toString());
}
if (task.getTaskType().getID().equals(CMSTaskType.DEPLOY)) { if (task.getTaskType().getID().equals(CMSTaskType.DEPLOY)) {
s_log.debug("Found DEPLOY task, ID=" + CMSTaskType.DEPLOY); s_log.debug("Found DEPLOY task, ID=" + CMSTaskType.DEPLOY);
task.finish(user); task.finish(user);
@ -565,13 +822,14 @@ class ItemLifecycleSelectForm extends BaseForm {
} }
private class ValidationListener implements FormValidationListener { private class ValidationListener implements FormValidationListener {
public void validate(FormSectionEvent e) throws FormProcessException { public void validate(FormSectionEvent e) throws FormProcessException {
final PageState state = e.getPageState(); final PageState state = e.getPageState();
final Integer startHour = (Integer) m_startHour.getValue(state); final Integer startHour = (Integer) m_startHour.getValue(state);
if (startHour == null) { if (startHour == null) {
throw new FormProcessException throw new FormProcessException(lz(
(lz("cms.ui.item.start_time_incomplete")); "cms.ui.item.start_time_incomplete"));
} }
Integer startMinute = (Integer) m_startMinute.getValue(state); Integer startMinute = (Integer) m_startMinute.getValue(state);
@ -581,13 +839,15 @@ class ItemLifecycleSelectForm extends BaseForm {
Integer startAmpm = (Integer) m_startAmpm.getValue(state); Integer startAmpm = (Integer) m_startAmpm.getValue(state);
java.util.Date startDate = (java.util.Date) m_startDate.getValue(state); java.util.Date startDate = (java.util.Date) m_startDate.getValue(
state);
if (startDate == null) { if (startDate == null) {
throw new FormProcessException throw new FormProcessException(lz(
(lz("cms.ui.item.lifecycle.start_date_invalid")); "cms.ui.item.lifecycle.start_date_invalid"));
} }
java.util.Date nowDate = new java.util.Date(System.currentTimeMillis()); java.util.Date nowDate =
new java.util.Date(System.currentTimeMillis());
Calendar cStart = Calendar.getInstance(); Calendar cStart = Calendar.getInstance();
Calendar cNow = Calendar.getInstance(); Calendar cNow = Calendar.getInstance();
@ -617,8 +877,8 @@ class ItemLifecycleSelectForm extends BaseForm {
cStart.set(Calendar.MILLISECOND, cNow.get(Calendar.MILLISECOND)); cStart.set(Calendar.MILLISECOND, cNow.get(Calendar.MILLISECOND));
if (cNow.after(cStart)) { if (cNow.after(cStart)) {
throw new FormProcessException throw new FormProcessException(lz(
(lz("cms.ui.item.lifecycle.start_date_in_past")); "cms.ui.item.lifecycle.start_date_in_past"));
} }
Integer endHour = (Integer) m_endHour.getValue(state); Integer endHour = (Integer) m_endHour.getValue(state);
@ -627,8 +887,8 @@ class ItemLifecycleSelectForm extends BaseForm {
(java.util.Date) m_endDate.getValue(state); (java.util.Date) m_endDate.getValue(state);
if (endHour == null && (endMinute != null || endDate != null)) { if (endHour == null && (endMinute != null || endDate != null)) {
throw new FormProcessException throw new FormProcessException(lz(
(lz("cms.ui.item.lifecycle.end_time_incomplete")); "cms.ui.item.lifecycle.end_time_incomplete"));
} }
if (endMinute == null && endHour != null) { if (endMinute == null && endHour != null) {
@ -640,8 +900,8 @@ class ItemLifecycleSelectForm extends BaseForm {
Integer endAmpm = (Integer) m_endAmpm.getValue(state); Integer endAmpm = (Integer) m_endAmpm.getValue(state);
if (endDate == null && !timeBlank) { if (endDate == null && !timeBlank) {
throw new FormProcessException throw new FormProcessException(lz(
(lz("cms.ui.item.lifecycle.end_date_invalid")); "cms.ui.item.lifecycle.end_date_invalid"));
} }
if (endDate != null) { if (endDate != null) {
@ -665,25 +925,25 @@ class ItemLifecycleSelectForm extends BaseForm {
// Give the user extra 5 minutes before form complains // Give the user extra 5 minutes before form complains
// end time's in the past. // end time's in the past.
cEnd.set(Calendar.MINUTE, endMinute.intValue()+5); cEnd.set(Calendar.MINUTE, endMinute.intValue() + 5);
cEnd.set(Calendar.AM_PM, endAmpm.intValue()); cEnd.set(Calendar.AM_PM, endAmpm.intValue());
cEnd.set(Calendar.SECOND, cNow.get(Calendar.SECOND)); cEnd.set(Calendar.SECOND, cNow.get(Calendar.SECOND));
cEnd.set(Calendar.MILLISECOND, cNow.get(Calendar.MILLISECOND)); cEnd.set(Calendar.MILLISECOND, cNow.get(Calendar.MILLISECOND));
//check if the end date is prior to the start date //check if the end date is prior to the start date
if(cStart.after(cEnd)) { if (cStart.after(cEnd)) {
throw new FormProcessException throw new FormProcessException(lz(
(lz("cms.ui.item.lifecycle.end_date_before_start_date")); "cms.ui.item.lifecycle.end_date_before_start_date"));
} }
Integer notificationDays = Integer notificationDays =
(Integer)m_notificationDays.getValue(state); (Integer) m_notificationDays.getValue(state);
Integer notificationHours = Integer notificationHours =
(Integer)m_notificationHours.getValue(state); (Integer) m_notificationHours.getValue(state);
int notificationPeriod = 0; int notificationPeriod = 0;
if (notificationDays != null) { if (notificationDays != null) {
notificationPeriod += notificationDays.intValue()*24; notificationPeriod += notificationDays.intValue() * 24;
} }
if (notificationHours != null) { if (notificationHours != null) {
notificationPeriod += notificationHours.intValue(); notificationPeriod += notificationHours.intValue();
@ -697,15 +957,14 @@ class ItemLifecycleSelectForm extends BaseForm {
s_log.debug("cStart (Date): " + cStart.getTime()); s_log.debug("cStart (Date): " + cStart.getTime());
s_log.debug("notificationDate: " + notificationDate); s_log.debug("notificationDate: " + notificationDate);
// complain if date for notification is before the start date // complain if date for notification is before the start date
if (notificationDate.before( cStart.getTime() )) { if (notificationDate.before(cStart.getTime())) {
s_log.debug("notification date is before start date!"); s_log.debug("notification date is before start date!");
String errorMessage = (String) String errorMessage = (String) GlobalizationUtil.
GlobalizationUtil globalize(
.globalize("cms.ui.item.notification_period_before_start") "cms.ui.item.notification_period_before_start").
.localize(); localize();
throw new FormProcessException(errorMessage); throw new FormProcessException(errorMessage);
} } else {
else {
s_log.debug("notification date is after start date, OK"); s_log.debug("notification date is after start date, OK");
} }
} }
@ -714,6 +973,7 @@ class ItemLifecycleSelectForm extends BaseForm {
} }
public class TimeZonePrinter implements PrintListener { public class TimeZonePrinter implements PrintListener {
public void prepare(PrintEvent e) { public void prepare(PrintEvent e) {
final Label target = (Label) e.getTarget(); final Label target = (Label) e.getTarget();
if (ContentSection.getConfig().getHideTimezone()) { if (ContentSection.getConfig().getHideTimezone()) {
@ -727,8 +987,9 @@ class ItemLifecycleSelectForm extends BaseForm {
mStart.setTime((java.util.Date) m_startDate.getValue(state)); mStart.setTime((java.util.Date) m_startDate.getValue(state));
} }
final String zone = mStart.getTimeZone().getDisplayName final String zone =
(true, TimeZone.SHORT); mStart.getTimeZone().getDisplayName(true,
TimeZone.SHORT);
target.setLabel(zone); target.setLabel(zone);
} }
@ -749,7 +1010,7 @@ class ItemLifecycleSelectForm extends BaseForm {
return null; return null;
} }
return new return new java.util.Date(endDate.getTime() - (long) notificationPeriod
java.util.Date(endDate.getTime() - (long)notificationPeriod * 3600000L); * 3600000L);
} }
} }