diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemContextBar.java.todo b/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemContextBar.java.todo index 690b6cf8a..3442ff5db 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemContextBar.java.todo +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/ContentItemContextBar.java.todo @@ -20,64 +20,59 @@ package com.arsdigita.cms.ui; import com.arsdigita.bebop.PageState; import com.arsdigita.cms.CMS; -import com.arsdigita.cms.ContentItem; -import com.arsdigita.cms.ContentSection; -import com.arsdigita.cms.ContentType; + +import org.librecms.contentsection.ContentItem; +import org.librecms.contentsection.ContentSection; +import org.librecms.contentsection.ContentType; + import com.arsdigita.cms.ItemSelectionModel; -import com.arsdigita.cms.Template; import com.arsdigita.cms.PageLocations; import com.arsdigita.web.ParameterMap; import com.arsdigita.web.URL; -import org.apache.log4j.Logger; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.List; /** - *
The context bar of the content section UI.
+ *+ * The context bar of the content section UI.
* - * @author Justin Ross <jross@redhat.com> - * @version $Id: ContentItemContextBar.java 287 2005-02-22 00:29:02Z sskracic $ + * @author Justin Ross + * @author Jens Pelzetter */ class ContentItemContextBar extends ContentSectionContextBar { - private static final Logger s_log = Logger.getLogger - (ContentItemContextBar.class); + private final ItemSelectionModel itemSelectionModel; - private final ItemSelectionModel m_item; - - ContentItemContextBar(final ItemSelectionModel item) { + ContentItemContextBar(final ItemSelectionModel itemSelectionModel) { super(); - m_item = item; + this.itemSelectionModel = itemSelectionModel; } @Override - protected final List entries(final PageState state) { - final List entries = super.entries(state); - final ContentItem item = (ContentItem) m_item.getSelectedObject(state); + protected final ListThe context bar of the content center UI.
+ *+ * The context bar of the content center UI.
* - * @author Justin Ross <jross@redhat.com> - * @version $Id$ + * @author Justin Ross + * @author Jens Pelzetter */ // Made public (instead of unspecified) in 6.6.8 public class WorkspaceContextBar extends ContextBar { - /** A logger instance, primarily to assist debugging . */ - private static final Logger s_log = Logger.getLogger - (WorkspaceContextBar.class); + /** + * A logger instance, primarily to assist debugging . + */ + private static final Logger LOGGER = LogManager.getLogger( + WorkspaceContextBar.class); /** - * + * * @param state - * @return + * + * @return */ @Override - protected List entries(final PageState state) { + protected List- * This panel displays basic details about a content item such as attributes and associations.
- * - *- * Container: {@link com.arsdigita.cms.ui.ContentItemPage} - * - *
- * This panel uses an {@link com.arsdigita.cms.dispatcher.XMLGenerator} to convert content items - * into XML.
- * - * @author Michael Pih (pihman@arsdigita.com) - * @version $Id: Summary.java 1940 2009-05-29 07:15:05Z terry $ - */ -public class Summary extends CMSContainer { - - private static final String SUMMARY = "itemAdminSummary"; - private static final String RESTART_WORKFLOW = "restartWorkflow"; - - private final ItemSelectionModel m_item; - - public Summary(ItemSelectionModel m) { - super(); - - m_item = m; - } - - /** - * Generate XML representation of an item summary. - * - * @param state The page state - * @param parent The parent DOM element - * - * @pre ( state != null ) - * @pre ( parent != null ) - */ - @Override - public void generateXML(PageState state, Element parent) { - if (isVisible(state)) { - - // Determine the item's environment - ContentItem item = getContentItem(state); - ContentSection section = getContentSection(state); - User user = Web.getWebContext().getUser(); - - // Setup xml element for item's properties - Element itemElement = new Element("cms:itemSummary", CMS.CMS_XML_NS); - - // Determine item's name / url stub - itemElement.addAttribute("name", item.getName()); - - // obviously getName() here gets the 'semantically meaningful name' - // from database using class DataType. It is not localizable! And - // it is not really 'semantically meaningful' - String objectType = item.getObjectType().getName(); - - // Quasimodo: ObjectType for summary - itemElement.addAttribute("objectType", objectType); - - // NOT USED - CUSTOMIZED SUMMARY - // Take advantage of caching in the CMS Dispatcher. - // XMLGenerator xmlGenerator = section.getXMLGenerator(); - // xmlGenerator.generateXML(state, parent, SUMMARY); - String descriptionAttribute = ""; - if (objectType.equals("NewsItem") || objectType.equals("Article")) { - descriptionAttribute = "lead"; - } else if (objectType.equals("FileStorageItem") || objectType.equals("Minutes")) { - descriptionAttribute = "description"; - } else if (objectType.equals("Job")) { - descriptionAttribute = "jobDescription"; - } else if (objectType.equals("MultiPartArticle") || objectType.equals("Agenda") - || objectType.equals("PressRelease") || objectType.equals("Service")) { - descriptionAttribute = "summary"; - } - - if (!descriptionAttribute.equals("")) { - itemElement.addAttribute("description", (String) DomainServiceInterfaceExposer.get( - item, descriptionAttribute)); - } - - try { - ContentPage page = new ContentPage(item.getID()); - itemElement.addAttribute("title", page.getTitle()); - } catch (DataObjectNotFoundException ex) { - // - } - - // subject category - Element subjectsElement = new Element("cms:subjectCategories", CMS.CMS_XML_NS); - itemElement.addContent(subjectsElement); - Category itemCategory = null; - Category subjectCategory = Category.getRootForObject(section, "subject"); - if (subjectCategory != null) { - CategoryCollection categories = item.getCategoryCollection(); - while (categories.next()) { - Category category = categories.getCategory(); - CategoryCollection parents = category.getDefaultAscendants(); - parents.addOrder(Category.DEFAULT_ANCESTORS); - if (parents.next()) { - Category parentCategory = parents.getCategory(); - if (parentCategory.equals(subjectCategory)) { - Element subjectElement = new Element("cms:subjectCategory", - CMS.CMS_XML_NS); - subjectElement.addAttribute("name", category.getName()); - subjectElement.setText(category.getPreferredQualifiedName(" -> ", - true)); - subjectsElement.addContent(subjectElement); - } - parents.close(); - } - } - } - - // URL - Element linkElement = new Element("cms:linkSummary", CMS.CMS_XML_NS); - try { - linkElement.addAttribute("url", - String.format("%s/redirect?oid=%s", - Web.getWebappContextPath(), - URLEncoder.encode(item.getDraftVersion() - .getOID() - .toString(), "utf-8"))); - } catch (UnsupportedEncodingException ex) { - throw new UncheckedWrapperException(ex); - } - - //"/redirect?oid=" + URLEncoder.encode(item.getDraftVersion().getOID().toString())); - // WORKFLOW - Element workflowElement = new Element("cms:workflowSummary", CMS.CMS_XML_NS); - Workflow workflow = Workflow.getObjectWorkflow(item); - - SecurityManager sm = CMS.getContext().getSecurityManager(); - if (canWorkflowBeExtended(user, item, workflow)) { - // control event for restarting workflow in edit mode - try { - state.setControlEvent(this, RESTART_WORKFLOW, item.getID().toString()); - workflowElement.addAttribute("restartWorkflowURL", state.stateAsURL()); - state.clearControlEvent(); - } catch (java.io.IOException ex) { - // - } - } - - if (workflow == null) { - workflowElement.addAttribute("noWorkflow", "1"); - } else { - workflowElement.addAttribute("name", workflow.getDisplayName()); - - TaskCollection tc = workflow.getTaskCollection(); - GraphSet g = new GraphSet(); - while (tc.next()) { - Task t = tc.getTask(); - final TaskCollection deps = t.getRequiredTasks(); - final StringBuffer buffer = new StringBuffer(); - while (deps.next()) { - Task dep = deps.getTask(); - g.addEdge(t, dep, null); - buffer.append(dep.getLabel() + ", "); - } - - final int len = buffer.length(); - if (len >= 2) { - buffer.setLength(len - 2); - } else { - g.addNode(t); - } - deps.close(); - } - - List taskList = new ArrayList(); - outer: - while (g.nodeCount() > 0) { - List l = Graphs.getSinkNodes(g); - for (Iterator it = l.iterator(); it.hasNext();) { - Task t = (Task) it.next(); - taskList.add(0, t); - g.removeNode(t); - continue outer; - } - // break loop if no nodes removed - break; - } - Iterator tasks = taskList.iterator(); - - while (tasks.hasNext()) { - Task task = (Task) tasks.next(); - Element taskElement = new Element("cms:task", CMS.CMS_XML_NS); - taskElement.addAttribute("name", task.getDisplayName()); - taskElement.addAttribute("state", task.getStateString()); - Iterator comments = task.getComments(); - while (comments.hasNext()) { - TaskComment comment = (TaskComment) comments.next(); - Element commentElement = new Element("cms:taskComment", CMS.CMS_XML_NS); - User author = comment.getUser(); - String authorName = "Anonymous"; - if (author != null) { - authorName = author.getDisplayName(); - } - - commentElement.addAttribute("author", authorName); - commentElement.addAttribute("comment", comment.getComment()); - commentElement.addAttribute("date", FormatStandards.formatDate(comment - .getDate())); - - taskElement.addContent(commentElement); - } - - workflowElement.addContent(taskElement); - } - } - - // REVISION HISTORY - Element transactionElement = new Element("cms:transactionSummary", CMS.CMS_XML_NS); - transactionElement.addAttribute("creationDate", FormatStandards.formatDate(item - .getCreationDate())); - transactionElement.addAttribute("lastModifiedDate", FormatStandards.formatDate(item - .getLastModifiedDate())); - - TransactionCollection transactions = Versions.getTaggedTransactions(item.getOID()); - while (transactions.next()) { - Transaction transaction = transactions.getTransaction(); - Element element = new Element("cms:transaction", CMS.CMS_XML_NS); - element.addAttribute("date", FormatStandards.formatDate(transaction.getTimestamp())); - String authorName = "Anonymous"; - User author = transaction.getUser(); - if (author != null) { - authorName = author.getDisplayName(); - } - element.addAttribute("author", authorName); - - String url = section.getItemResolver().generateItemURL(state, item, section, - CMSDispatcher.PREVIEW) - + "?transID=" + transaction.getID(); - element.addAttribute("url", url); - transactionElement.addContent(element); - } - - transactions.close(); - - // CATEGORY - Element categoryElement = new Element("cms:categorySummary", CMS.CMS_XML_NS); - - CategoryCollection categories = item.getCategoryCollection(); - while (categories.next()) { - Category category = categories.getCategory(); - Element element = new Element("cms:category", CMS.CMS_XML_NS); - element.setText(category.getPreferredQualifiedName(" -> ", true)); - categoryElement.addContent(element); - - } - categories.close(); - - // LIFECYCLE - Element lifecycleElement = new Element("cms:lifecycleSummary", CMS.CMS_XML_NS); - - Lifecycle lifecycle = item.getLifecycle(); - if (lifecycle == null) { - lifecycleElement.addAttribute("noLifecycle", "1"); - } else { - lifecycleElement.addAttribute("name", lifecycle.getLabel()); - lifecycleElement.addAttribute("startDate", FormatStandards.formatDate(lifecycle - .getStartDate())); - - java.util.Date endDate = lifecycle.getEndDate(); - if (endDate == null) { - lifecycleElement.addAttribute("endDateString", "last forever"); - } else { - lifecycleElement.addAttribute("endDateString", "expire on " + FormatStandards - .formatDate(endDate)); - lifecycleElement.addAttribute("endDate", FormatStandards.formatDate(endDate)); - } - - lifecycleElement.addAttribute("hasBegun", (new Boolean(lifecycle.hasBegun())) - .toString()); - lifecycleElement.addAttribute("hasEnded", (new Boolean(lifecycle.hasEnded())) - .toString()); - } - - parent.addContent(itemElement); - parent.addContent(categoryElement); - parent.addContent(linkElement); - parent.addContent(lifecycleElement); - parent.addContent(workflowElement); - parent.addContent(transactionElement); - } - } - - /** - * Fetch the selected content item. - * - * @param state The page state - * - * @return The selected item - * - * @pre ( state != null ) - */ - protected ContentItem getContentItem(PageState state) { - ContentItem item = (ContentItem) m_item.getSelectedObject(state); - Assert.exists(item); - return item; - } - - /** - * Fetch the current content section. - * - * @param state The page state - * - * @return The content section - * - * @pre ( state != null ) - */ - protected ContentSection getContentSection(PageState state) { - ContentSection section = CMS.getContext().getContentSection(); - return section; - } - - public void respond(PageState state) throws ServletException { - String key = state.getControlEventName(); - String value = state.getControlEventValue(); - if (RESTART_WORKFLOW.equals(key)) { - User user = Web.getWebContext().getUser(); - ContentItem item = getContentItem(state); - ContentSection section = item.getContentSection(); - Workflow w = Workflow.getObjectWorkflow(item); - - if (canWorkflowBeExtended(user, item, w)) { - WorkflowTemplate template = w.getWorkflowTemplate(); - if (template != null) { - template.extendWorkflow(w); - w.save(); - } - - // lock the next task - Engine engine = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE); - Iterator i = engine.getEnabledTasks(user, w.getID()).iterator(); - if (i.hasNext()) { - CMSTask task = (CMSTask) i.next(); - - if (!task.isLocked()) { - task.lock(user); - } - } - } - - String redirectURL = Web.getConfig().getDispatcherServletPath() + item - .getContentSection().getPath() + "/admin/item.jsp?item_id=" + item.getID() - + "&set_tab=1"; - throw new RedirectSignal(redirectURL, true); - } else { - throw new ServletException("Unknown control event: " + key); - } - } - - /* - * Checks if workflow can be extended - */ - protected boolean canWorkflowBeExtended(User user, ContentItem item, Workflow workflow) { - boolean canBeExtended = true; - - if (workflow == null) { - canBeExtended = false; - } else if (!workflow.isFinished()) { - canBeExtended = false; - } else if (workflow.getWorkflowTemplate() == null) { - canBeExtended = false; - } else { - TaskCollection templates = item.getContentSection().getWorkflowTemplates(); - Filter f = templates.addInSubqueryFilter("id", - "com.arsdigita.cms.getWorkflowTemplateUserFilter"); - f.set("userId", Web.getWebContext().getUser().getID()); - templates.addEqualsFilter(ACSObject.ID, workflow.getWorkflowTemplate().getID()); - - PrivilegeDescriptor pd = PrivilegeDescriptor.get(SecurityConstants.CMS_WORKFLOW_ADMIN); - PermissionDescriptor perm = new PermissionDescriptor(pd, item, user); - if (!(templates.next() || PermissionService.checkPermission(perm))) { - canBeExtended = false; - } - templates.close(); - - } - - return canBeExtended; - } - -} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/ItemLifecycleAdminPane.java.todo b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/ItemLifecycleAdminPane.java.todo index 1aacd1861..df604589c 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/ItemLifecycleAdminPane.java.todo +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/ItemLifecycleAdminPane.java.todo @@ -24,12 +24,10 @@ import com.arsdigita.bebop.Page; import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.event.ActionEvent; import com.arsdigita.bebop.event.ActionListener; -import com.arsdigita.categorization.Category; -import com.arsdigita.categorization.CategoryCollection; -import com.arsdigita.cms.CMS; -import com.arsdigita.cms.CMSConfig; -import com.arsdigita.cms.ContentItem; -import com.arsdigita.cms.lifecycle.Lifecycle; + +import org.librecms.contentsection.ContentItem; +import org.librecms.lifecycle.Lifecycle; + import com.arsdigita.cms.ui.BaseItemPane; import com.arsdigita.cms.ui.ContentItemPage; import com.arsdigita.cms.ui.item.ContentItemRequestLocal; @@ -37,101 +35,110 @@ import com.arsdigita.toolbox.ui.LayoutPanel; import com.arsdigita.web.RedirectSignal; import com.arsdigita.web.URL; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.PermissionChecker; +import org.librecms.contentsection.privileges.ItemPrivileges; + /** * @author Michael Pih * @author Jack Chung * @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 $ + * @author Jens Pelzetter */ public class ItemLifecycleAdminPane extends BaseItemPane { - private static final Logger s_log = Logger.getLogger( - ItemLifecycleAdminPane.class); - private final ContentItemRequestLocal m_item; - private final LifecycleRequestLocal m_lifecycle; - private final LayoutPanel m_introPane; - private final LayoutPanel m_detailPane; - private final LayoutPanel m_selectPane; - private final LayoutPanel m_lockedPane; - private final LayoutPanel m_errorPane; - private final LayoutPanel m_cantPublishPane; + private static final Logger LOGGER = LogManager.getLogger( + ItemLifecycleAdminPane.class); + private final ContentItemRequestLocal selectedItem; + private final LifecycleRequestLocal selectedLifecycle; + private final LayoutPanel introPane; + private final LayoutPanel detailPane; + private final LayoutPanel selectPane; + private final LayoutPanel lockedPane; + private final LayoutPanel errorPane; + private final LayoutPanel cantPublishPane; - public ItemLifecycleAdminPane(final ContentItemRequestLocal item) { - m_item = item; - m_lifecycle = new ItemLifecycleRequestLocal(); + public ItemLifecycleAdminPane(final ContentItemRequestLocal selectedItem) { + this.selectedItem = selectedItem; + selectedLifecycle = new ItemLifecycleRequestLocal(); - m_introPane = new LayoutPanel(); - add(m_introPane); + introPane = new LayoutPanel(); + add(introPane); final Label message = new Label(gz("cms.ui.item.lifecycle.intro")); - m_introPane.setBody(message); + introPane.setBody(message); - m_detailPane = new LayoutPanel(); - add(m_detailPane); + detailPane = new LayoutPanel(); + add(detailPane); - final ItemLifecycleItemPane itemPane = - new ItemLifecycleItemPane(m_item, - m_lifecycle); - m_detailPane.setBody(itemPane); + final ItemLifecycleItemPane itemPane = new ItemLifecycleItemPane( + selectedItem, selectedLifecycle); + detailPane.setBody(itemPane); - m_selectPane = new LayoutPanel(); - add(m_selectPane); + selectPane = new LayoutPanel(); + add(selectPane); - final ItemLifecycleSelectForm selectForm = - new ItemLifecycleSelectForm(m_item); - m_selectPane.setBody(selectForm); + final ItemLifecycleSelectForm selectForm = new ItemLifecycleSelectForm( + selectedItem); + selectPane.setBody(selectForm); - m_lockedPane = new LayoutPanel(); - add(m_lockedPane); + lockedPane = new LayoutPanel(); + add(lockedPane); final Label lockedMsg = new Label(gz( - "cms.ui.item.lifecycle.publish_locked")); - m_lockedPane.setBody(lockedMsg); + "cms.ui.item.lifecycle.publish_locked")); + lockedPane.setBody(lockedMsg); final ControlLink lockedUpdateLink = new ControlLink(new Label(gz( - "cms.ui.item.lifecycle.publish_locked.update"))); + "cms.ui.item.lifecycle.publish_locked.update"))); lockedUpdateLink.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { throw new RedirectSignal( - URL.getDispatcherPath() + URL.getDispatcherPath() + ContentItemPage.getItemURL( - item.getContentItem(event.getPageState()), + selectedItem.getContentItem(event.getPageState()), ContentItemPage.PUBLISHING_TAB), - true); + true); } - }); - m_lockedPane.setBottom(lockedUpdateLink); - m_errorPane = new LayoutPanel(); - add(m_errorPane); + }); + lockedPane.setBottom(lockedUpdateLink); + + errorPane = new LayoutPanel(); + add(errorPane); final Label errorMsg = new Label(gz("cms.ui.lifecycle.publish.error")); - m_errorPane.setBody(errorMsg); - - m_cantPublishPane = new LayoutPanel(); - add(m_cantPublishPane); - - final Label cantPublish = new Label(gz("cms.ui.lifecycle.publish.not_possible_abstract_category")); - m_cantPublishPane.setBody(cantPublish); + errorPane.setBody(errorMsg); - connect(selectForm, m_detailPane); + cantPublishPane = new LayoutPanel(); + add(cantPublishPane); + + final Label cantPublish = new Label(gz( + "cms.ui.lifecycle.publish.not_possible_abstract_category")); + cantPublishPane.setBody(cantPublish); + + connect(selectForm, detailPane); } private class ItemLifecycleRequestLocal extends LifecycleRequestLocal { + @Override protected final Object initialValue(final PageState state) { - final ContentItem item = m_item.getContentItem(state); + final ContentItem item = selectedItem.getContentItem(state); final Lifecycle lifecycle = item.getLifecycle(); - s_log.debug("Returning lifecycle " + lifecycle); + LOGGER.debug("Returning lifecycle " + lifecycle); return lifecycle; } + } + @Override public final void register(final Page page) { super.register(page); @@ -140,71 +147,71 @@ public class ItemLifecycleAdminPane extends BaseItemPane { private class VisibilityListener implements ActionListener { - public final void actionPerformed(final ActionEvent e) { - s_log.debug("Determining which pane to show"); + @Override + public final void actionPerformed(final ActionEvent event) { + LOGGER.debug("Determining which pane to show"); - final PageState state = e.getPageState(); + final PageState state = event.getPageState(); - if (CMSConfig.getInstanceOf().getThreadedPublishing() - && PublishLock.getInstance().isLocked(m_item.getContentItem( - state))) { - if (PublishLock.getInstance().hasError(m_item.getContentItem( - state))) { - push(state, m_errorPane); - } else { - push(state, m_lockedPane); - state.getResponse().addIntHeader("Refresh", 5); - } - } else if(isAssignedToAbstractCategory(m_item.getContentItem(state))) { - push(state, m_cantPublishPane); +// if (CMSConfig.getConfig().isThreadPublishing() +// && PublishLock.getInstance().isLocked(m_item.getContentItem( +// state))) { +// if (PublishLock.getInstance().hasError(m_item.getContentItem( +// state))) { +// push(state, m_errorPane); +// } else { +// push(state, m_lockedPane); +// state.getResponse().addIntHeader("Refresh", 5); +// } +// } else + if (isAssignedToAbstractCategory(selectedItem.getContentItem(state))) { + push(state, cantPublishPane); } else { if (state.isVisibleOnPage(ItemLifecycleAdminPane.this)) { - if (m_lifecycle.getLifecycle(state) == null) { + if (selectedLifecycle.getLifecycle(state) == null) { if (hasPermission(state)) { - push(state, m_selectPane); + push(state, selectPane); } else { - push(state, m_introPane); + push(state, introPane); } } else { - push(state, m_detailPane); + push(state, detailPane); } } } } + } private boolean hasPermission(final PageState state) { - final ContentItem item = m_item.getContentItem(state); + final ContentItem item = selectedItem.getContentItem(state); - return CMS.getContext().getSecurityManager().canAccess( - state.getRequest(), SCHEDULE_PUBLICATION, item); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final PermissionChecker permissionChecker = cdiUtil.findBean( + PermissionChecker.class); + + return permissionChecker.isPermitted(ItemPrivileges.PUBLISH, item); } - + /** * Checks if the item is assigned to an abstract category. - * + * * A category is abstract if not items can assigned to it. - * + * * @param item - * @return {@code true} if assigned to a abstract category, {@code false} if not. + * + * @return {@code true} if assigned to a abstract category, {@code false} if + * not. */ private boolean isAssignedToAbstractCategory(final ContentItem item) { + + final long count = item.getCategories().stream() + .filter(categorization -> { + return categorization.getCategory().isAbstractCategory(); + }) + .count(); - final CategoryCollection categories = item.getCategoryCollection(); - - boolean result = false; - Category category; - while(categories.next()) { - category = categories.getCategory(); - - if (category.isAbstract()) { - result = true; - break; - } - } - - categories.close(); - - return result; + return count > 0; } + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/ItemLifecycleItemPane.java.todo b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/ItemLifecycleItemPane.java.todo new file mode 100755 index 000000000..d138ecda6 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/ItemLifecycleItemPane.java.todo @@ -0,0 +1,1019 @@ +/* + * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.cms.ui.lifecycle; + +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; +import com.arsdigita.bebop.SimpleContainer; +import com.arsdigita.bebop.Table; +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; +import com.arsdigita.bebop.form.SingleSelect; +import com.arsdigita.bebop.form.Submit; +import com.arsdigita.cms.CMS; +import com.arsdigita.cms.ContentCenter; +import com.arsdigita.cms.dispatcher.Utilities; +import com.arsdigita.cms.ui.BaseItemPane; +import com.arsdigita.cms.ui.ContentItemPage; +import com.arsdigita.cms.ui.item.ContentItemRequestLocal; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.toolbox.ui.ActionGroup; +import com.arsdigita.toolbox.ui.Property; +import com.arsdigita.toolbox.ui.PropertyList; +import com.arsdigita.toolbox.ui.Section; +import com.arsdigita.util.UncheckedWrapperException; +import com.arsdigita.web.RedirectSignal; +import com.arsdigita.web.URL; +import com.arsdigita.web.Web; +import com.arsdigita.xml.Element; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.arsdigita.cms.CMSConfig; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.notification.Notification; +import org.libreccm.security.Party; +import org.libreccm.security.PermissionChecker; +import org.libreccm.security.User; +import org.libreccm.workflow.Workflow; +import org.libreccm.workflow.WorkflowManager; +import org.librecms.CmsConstants; +import org.librecms.contentsection.ContentItem; +import org.librecms.contentsection.ContentItemManager; +import org.librecms.contentsection.ContentItemRepository; +import org.librecms.contentsection.ContentSection; +import org.librecms.contentsection.ContentSectionConfig; +import org.librecms.contentsection.privileges.ItemPrivileges; +import org.librecms.lifecycle.Lifecycle; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.text.DateFormat; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Optional; + +/** + * 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 + * @author Xixi D'Moon + * @author Justin Ross + * @author Jens Pelzetter + */ +class ItemLifecycleItemPane extends BaseItemPane { + + private static final Logger LOGGER = LogManager.getLogger( + ItemLifecycleItemPane.class); + private final ContentItemRequestLocal selectedItem; + private final LifecycleRequestLocal selectedLifecycle; + private final SimpleContainer detailPane; + + public ItemLifecycleItemPane(final ContentItemRequestLocal selectedItem, + final LifecycleRequestLocal selectedLifecycle) { + this.selectedItem = selectedItem; + this.selectedLifecycle = selectedLifecycle; + + detailPane = new SimpleContainer(); + add(detailPane); + setDefault(detailPane); + + detailPane.add(new SummarySection()); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ContentItemRepository itemRepo = cdiUtil.findBean( + ContentItemRepository.class); + final ContentItemManager itemManager = cdiUtil.findBean( + ContentItemManager.class); + final GlobalizationHelper globalizationHelper = cdiUtil.findBean( + GlobalizationHelper.class); + + final Label lastPublishedLabel = new Label(); + lastPublishedLabel.addPrintListener(new PrintListener() { + + @Override + public void prepare(final PrintEvent event) { + final PageState state = event.getPageState(); + final Optional+ * A form to select and apply a lifecycle to a content item.
+ * + * @author Michael Pih + * @author Xixi D'moon <xdmoon@redhat.com> + * @author Justin Ross <jross@redhat.com> + * @author Jens Pelzetter jens@jp-digital.de + * @version $Id: ItemLifecycleSelectForm.java 2267 2012-01-09 16:50:14Z pboy $ + */ +class ItemLifecycleSelectForm extends BaseForm { + + private static final Logger s_log + = Logger.getLogger(ItemLifecycleSelectForm.class); + private final static String LIFECYCLE = "lifecycle"; + private final static String START_DATE = "start_date"; + private final static String END_DATE = "end_date"; + private final static String NOTIFICATION_DAYS = "notifyDays"; + private final static String NOTIFICATION_HOURS = "notifyHours"; + private final ContentItemRequestLocal m_item; + private final WorkflowRequestLocal m_workflow; + // Form widgets + private final SingleSelect m_cycleSelect; + private final Date m_startDate; + private final TextField m_startHour; + private final TextField m_startMinute; + private final SingleSelect m_startAmpm; + private final Date m_endDate; + private final TextField m_endHour; + private final TextField m_endMinute; + private final SingleSelect m_endAmpm; + private TextField m_notificationDays; + private TextField m_notificationHours; + + public ItemLifecycleSelectForm(final ContentItemRequestLocal item) { + super("PublishItem", gz("cms.ui.item.lifecycle.apply")); + + m_item = item; + m_workflow = new ItemWorkflowRequestLocal(); + + m_cycleSelect = new SingleSelect(new BigDecimalParameter(LIFECYCLE)); + try { + m_cycleSelect.addPrintListener(new OptionPrinter()); + } catch (TooManyListenersException tmle) { + throw new UncheckedWrapperException(tmle); + } + addField(gz("cms.ui.item.lifecycle"), m_cycleSelect); + + // Start date + m_startDate = new Date(new DateParameter(START_DATE) { + + @Override + protected final Calendar getCalendar(final HttpServletRequest sreq) { + final Calendar cal = super.getCalendar(sreq); + + cal.setLenient(false); + + return cal; + } + + }); + addField(gz("cms.ui.item.lifecycle.start_date"), m_startDate); + + // Start time + final BoxPanel startTime = new BoxPanel(BoxPanel.HORIZONTAL); + addField(gz("cms.ui.item.lifecycle.start_time"), startTime); + + // Hour + m_startHour = new TextField(new IntegerParameter("start_hour")); + startTime.add(m_startHour); + + m_startHour.setSize(3); + m_startHour.addValidationListener( + new NumberInRangeValidationListener(1, 12)); + + // Minute + m_startMinute = new TextField(new IntegerParameter("start_minute")); + startTime.add(m_startMinute); + + m_startMinute.setSize(3); + m_startMinute.addValidationListener(new NumberInRangeValidationListener( + 0, 59)); + + // AM/PM + m_startAmpm = new SingleSelect(new IntegerParameter("start_ampm")); + startTime.add(m_startAmpm); + + m_startAmpm.addOption(new Option("0", "am")); + m_startAmpm.addOption(new Option("1", "pm")); + + // Time zone + startTime.add(new Label(new TimeZonePrinter())); + + // Expiration date + m_endDate = new Date(new DateParameter(END_DATE) { + + @Override + protected final Calendar getCalendar(final HttpServletRequest sreq) { + final Calendar cal = super.getCalendar(sreq); + + cal.setLenient(false); + + return cal; + } + + }); + addField(gz("cms.ui.item.lifecycle.end_date"), m_endDate); + + // End time + final BoxPanel endTime = new BoxPanel(BoxPanel.HORIZONTAL); + addField(gz("cms.ui.item.lifecycle.end_time"), endTime); + + // Hour + m_endHour = new TextField(new IntegerParameter("end_hour")); + endTime.add(m_endHour); + + m_endHour.setSize(3); + m_endHour.addValidationListener(new NumberInRangeValidationListener(1, + 12)); + + // Minute + m_endMinute = new TextField(new IntegerParameter("end_minute")); + endTime.add(m_endMinute); + + m_endMinute.setSize(3); + m_endMinute.addValidationListener( + new NumberInRangeValidationListener(0, 59)); + + // AM/PM + m_endAmpm = new SingleSelect(new IntegerParameter("end_ampm")); + endTime.add(m_endAmpm); + + m_endAmpm.addOption(new Option("0", "am")); + m_endAmpm.addOption(new Option("1", "pm")); + + endTime.add(new Label(new TimeZonePrinter())); + + m_notificationDays = new TextField(new IntegerParameter(NOTIFICATION_DAYS)); + m_notificationDays.setSize(4); + m_notificationHours = new TextField(new IntegerParameter(NOTIFICATION_HOURS)); + m_notificationHours.setSize(4); + SimpleContainer cont = new SimpleContainer(); + cont.add(m_notificationDays); + cont.add(new Label(GlobalizationUtil.globalize("cms.ui.item.days"), + false)); + cont.add(m_notificationHours); + cont.add(new Label(GlobalizationUtil.globalize("cms.ui.item.hours"), + false)); + + addField(gz("cms.ui.item.notification_period"), cont); + + // A hidden field that checks to see if the user wants publish + // with a start time earlier than current time. + addAction(new Submit("finish", gz("cms.ui.item.lifecycle.publish"))); + + // Form listeners + addValidationListener(new ValidationListener()); + addSecurityListener(PUBLISH, m_item); + addInitListener(new InitListener()); + addProcessListener(new ProcessListener()); + } + + private class OptionPrinter implements PrintListener { + + @Override + public final void prepare(final PrintEvent e) { + final ContentSection section = CMS.getContext().getContentSection(); + + final LifecycleDefinitionCollection ldc = section.getLifecycleDefinitions(); + ldc.addOrder("label"); + + final SingleSelect target = (SingleSelect) e.getTarget(); + target.clearOptions(); + + while (ldc.next()) { + final LifecycleDefinition ld = ldc.getLifecycleDefinition(); + final PhaseDefinitionCollection pdc = ld.getPhaseDefinitions(); + + // XXX domlay this seems a little weak. perhaps + // there's a better way to determine if a lifecycle is + // ready to be applied to an item. + if (!pdc.isEmpty()) { + target.addOption(new Option(ld.getID().toString(), + ld.getLabel())); + } + + pdc.close(); + } + + ldc.close(); + } + + } + + private class InitListener implements FormInitListener { + + @Override + public final void init(final FormSectionEvent e) { + final PageState state = e.getPageState(); + + final ContentItem item = m_item.getContentItem(state); + + if (item.isPublished()) { + // If the item is published, select the currently + // associated lifecycle. + + final LifecycleDefinition ld = item.getLifecycle(). + getLifecycleDefinition(); + m_cycleSelect.setValue(state, ld.getID()); + } else { + // Set the default lifecycle (if it exists). + + final ContentSection section = CMS.getContext().getContentSection(); + final LifecycleDefinition ld = ContentTypeLifecycleDefinition. + getLifecycleDefinition(section, item.getContentType()); + + if (ld != null) { + m_cycleSelect.setValue(state, ld.getID()); + } + } + + // Set the default start date. + // XXX Isn't just new Date() sufficient? + final java.util.Date start = new java.util.Date(System. + currentTimeMillis()); + m_startDate.setValue(state, start); + + final Calendar calendar = Calendar.getInstance(); + calendar.setTime(start); + + // If the hour is 12, then Calendar.get(Calendar.HOUR) + // returns 0 (from the 24 hour time - 12). We want it to + // return 12. + if (calendar.get(Calendar.HOUR) == 0) { + m_startHour.setValue(state, new Integer(12)); + } else { + m_startHour.setValue(state, new Integer(calendar.get( + Calendar.HOUR))); + } + + final Integer min = new Integer(calendar.get(Calendar.MINUTE)); + + if (min.intValue() < 10) { + m_startMinute.setValue(state, "0" + min.toString()); + } else { + m_startMinute.setValue(state, min.toString()); + } + + m_startAmpm.setValue(state, + new Integer(calendar.get(Calendar.AM_PM))); + + BigInteger[] defaultTime = BigInteger.valueOf(ContentSection.getConfig(). + getDefaultNotificationTime()). + divideAndRemainder(BigInteger.valueOf(24)); + + m_notificationDays.setValue(state, new Integer(defaultTime[0]. + intValue())); + m_notificationHours.setValue(state, new Integer(defaultTime[1]. + 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 { + + @Override + public final void process(final FormSectionEvent e) + throws FormProcessException { + final PageState state = e.getPageState(); + final ContentItem item = m_item.getContentItem(state); + + final Publisher publisher = new Publisher(state); + if (CMSConfig.getInstanceOf().getThreadedPublishing()) { + final Runnable threadAction = new Runnable() { + + @Override + public void run() { + PublishLock.getInstance().lock(item); + publisher.publish(); + PublishLock.getInstance().unlock(item); + } + + }; + final Thread thread = new Thread(threadAction); + thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + + @Override + public void uncaughtException(final Thread thread, + final Throwable ex) { + final StringWriter strWriter = new StringWriter(); + final PrintWriter writer = new PrintWriter(strWriter); + ex.printStackTrace(writer); + + PublishLock.getInstance().setError(item, strWriter.toString()); + s_log.error(String.format( + "An error occurred while " + + "publishing the item '%s': ", + item.getOID().toString()), + ex); + + if ((CMSConfig.getInstanceOf().getPublicationFailureSender() + == null) + && (CMSConfig.getInstanceOf(). + getPublicationFailureReceiver() == null)) { + return; + } + + final PartyCollection receiverParties = Party. + retrieveAllParties(); + Party receiver = null; + receiverParties.addEqualsFilter("primaryEmail", + CMSConfig.getInstanceOf(). + getPublicationFailureReceiver()); + if (receiverParties.next()) { + receiver = receiverParties.getParty(); + } + receiverParties.close(); + + final PartyCollection senderParties = Party. + retrieveAllParties(); + Party sender = null; + senderParties.addEqualsFilter("primaryEmail", CMSConfig. + getInstanceOf().getPublicationFailureReceiver()); + if (senderParties.next()) { + sender = senderParties.getParty(); + } + senderParties.close(); + + if ((sender != null) && (receiver != null)) { + final Writer traceWriter = new StringWriter(); + final PrintWriter printWriter = new PrintWriter( + traceWriter); + ex.printStackTrace(printWriter); + + final Notification notification = new Notification( + sender, + receiver, + String.format("Failed to publish item '%s'", + item.getOID().toString()), + String.format("Publishing item '%s' failed " + + "with error message: %s.\n\n" + + "Stacktrace:\n%s", + item.getOID().toString(), + ex.getMessage(), + traceWriter.toString())); + notification.save(); + } + } + + }); + thread.start(); + } else { + publisher.publish(); + } + + if (CMSConfig.getInstanceOf().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(), + ContentCenter.getURL()), + true); + } + } + + /* + * 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.getInstanceOf(); + * 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.getInstanceOf(); + * + * 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.getWebContext().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); } + */ + } + + } + + /** + * 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.getWebContext().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(); + } + } + } + + // 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) && (user != null)) { + final Engine engine = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE); + // ; + + final Iterator iter = engine.getEnabledTasks(user, workflow.getID()). + iterator(); + + while (iter.hasNext()) { + final CMSTask task = (CMSTask) iter.next(); + if (s_log.isDebugEnabled()) { + s_log.debug("Task is " + task.getOID().toString()); + } + if (task.getTaskType().getID().equals(CMSTaskType.DEPLOY)) { + s_log.debug("Found DEPLOY task, ID=" + CMSTaskType.DEPLOY); + task.finish(user); + } + } + if (ContentSection.getConfig().getDeleteWorkflowAfterPublication()) { + workflow.delete(); + } else { + // restart the workflow by recreating it + // from the same workflow template + WorkflowTemplate t = workflow.getWorkflowTemplate(); + workflow.delete(); + workflow = t.instantiateNewWorkflow(); + workflow.setObject(item); + /* Startring the workflow will probably do the wrong thing, because most of the time + * the current user would be a publisher, not an author */ +// workflow.start(user); + workflow.save(); + } + } + } + + private class ValidationListener implements FormValidationListener { + + @Override + public void validate(FormSectionEvent e) throws FormProcessException { + final PageState state = e.getPageState(); + + final Integer startHour = (Integer) m_startHour.getValue(state); + if (startHour == null) { + throw new FormProcessException(GlobalizationUtil.globalize( + "cms.ui.item.start_time_incomplete")); + } + + Integer startMinute = (Integer) m_startMinute.getValue(state); + if (startMinute == null) { + startMinute = new Integer(0); + } + + Integer startAmpm = (Integer) m_startAmpm.getValue(state); + + java.util.Date startDate = (java.util.Date) m_startDate.getValue( + state); + if (startDate == null) { + throw new FormProcessException(GlobalizationUtil.globalize( + "cms.ui.item.lifecycle.start_date_invalid")); + } + + java.util.Date nowDate = new java.util.Date(System.currentTimeMillis()); + + Calendar cStart = Calendar.getInstance(); + Calendar cNow = Calendar.getInstance(); + cStart.setTime(startDate); + cNow.setTime(nowDate); + + if (startHour.intValue() != 12) { + cStart.set(Calendar.HOUR_OF_DAY, + 12 * startAmpm.intValue() + startHour.intValue()); + cStart.set(Calendar.HOUR, startHour.intValue()); + } else { + if (startAmpm.intValue() == 0) { + cStart.set(Calendar.HOUR_OF_DAY, 0); + cStart.set(Calendar.HOUR, 0); + } else { + cStart.set(Calendar.HOUR_OF_DAY, 12); + cStart.set(Calendar.HOUR, 0); + } + } + + // Give the user extra 5 minutes before form complains + // start time's in the past. + cStart.set(Calendar.MINUTE, startMinute.intValue() + 5); + cStart.set(Calendar.AM_PM, startAmpm.intValue()); + cStart.set(Calendar.SECOND, cNow.get(Calendar.SECOND)); + cStart.set(Calendar.MILLISECOND, cNow.get(Calendar.MILLISECOND)); + + if (cNow.after(cStart)) { + throw new FormProcessException(GlobalizationUtil.globalize( + "cms.ui.item.lifecycle.start_date_in_past")); + } + + Integer endHour = (Integer) m_endHour.getValue(state); + Integer endMinute = (Integer) m_endMinute.getValue(state); + java.util.Date endDate = (java.util.Date) m_endDate.getValue(state); + + if (endHour == null && (endMinute != null || endDate != null)) { + throw new FormProcessException(GlobalizationUtil.globalize( + "cms.ui.item.lifecycle.end_time_incomplete")); + } + + if (endMinute == null && endHour != null) { + endMinute = new Integer(0); + } + + boolean timeBlank = (endHour == null) && (endMinute == null); + + Integer endAmpm = (Integer) m_endAmpm.getValue(state); + + if (endDate == null && !timeBlank) { + throw new FormProcessException(GlobalizationUtil.globalize( + "cms.ui.item.lifecycle.end_date_invalid")); + } + + if (endDate != null) { + Calendar cEnd = Calendar.getInstance(); + cEnd.setTime(endDate); + + if (endHour.intValue() != 12) { + cEnd.set(Calendar.HOUR_OF_DAY, + 12 * endAmpm.intValue() + endHour.intValue()); + cEnd.set(Calendar.HOUR, endHour.intValue()); + } else { + if (endAmpm.intValue() == 0) { + cEnd.set(Calendar.HOUR_OF_DAY, 0); + cEnd.set(Calendar.HOUR, 0); + } else { + cEnd.set(Calendar.HOUR_OF_DAY, 12); + cEnd.set(Calendar.HOUR, 0); + } + } + + // Give the user extra 5 minutes before form complains + // end time's in the past. + cEnd.set(Calendar.MINUTE, endMinute.intValue() + 5); + cEnd.set(Calendar.AM_PM, endAmpm.intValue()); + cEnd.set(Calendar.SECOND, cNow.get(Calendar.SECOND)); + cEnd.set(Calendar.MILLISECOND, cNow.get(Calendar.MILLISECOND)); + + //check if the end date is prior to the start date + if (cStart.after(cEnd)) { + throw new FormProcessException(GlobalizationUtil.globalize( + "cms.ui.item.lifecycle.end_date_before_start_date")); + } + + Integer notificationDays = (Integer) m_notificationDays.getValue(state); + Integer notificationHours = (Integer) m_notificationHours.getValue(state); + + int notificationPeriod = 0; + if (notificationDays != null) { + notificationPeriod += notificationDays.intValue() * 24; + } + if (notificationHours != null) { + notificationPeriod += notificationHours.intValue(); + } + + if (notificationPeriod > 0) { + // point in time for notification == end date - notificationPeriod + java.util.Date notificationDate = computeNotificationDate(cEnd.getTime(), + notificationPeriod); + s_log.debug("cStart (Date): " + cStart.getTime()); + s_log.debug("notificationDate: " + notificationDate); + // complain if date for notification is before the start date + if (notificationDate.before(cStart.getTime())) { + s_log.debug("notification date is before start date!"); + + throw new FormProcessException(GlobalizationUtil.globalize("cms.ui.item.notification_period_before_start")); + } else { + s_log.debug("notification date is after start date, OK"); + } + } + } + } + + } + + public class TimeZonePrinter implements PrintListener { + + @Override + public void prepare(PrintEvent e) { + final Label target = (Label) e.getTarget(); + if (ContentSection.getConfig().getHideTimezone()) { + target.setLabel(""); + } else { + final PageState state = e.getPageState(); + final Calendar mStart = Calendar.getInstance(); + java.util.Date st = (java.util.Date) m_startDate.getValue(state); + + if (st != null) { + mStart.setTime((java.util.Date) m_startDate.getValue(state)); + } + + final String zone = mStart.getTimeZone().getDisplayName(true, + TimeZone.SHORT); + + target.setLabel(zone); + } + } + + } + + /** + * 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) { + if (endDate == null) { + return null; + } + + return new java.util.Date(endDate.getTime() - (long) notificationPeriod + * 3600000L); + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminPane.java.todo similarity index 100% rename from ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminPane.java rename to ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminPane.java.todo diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleItemPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleItemPane.java.todo similarity index 100% rename from ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleItemPane.java rename to ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleItemPane.java.todo diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleRequestLocal.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleRequestLocal.java new file mode 100755 index 000000000..3d3c9066d --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleRequestLocal.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.cms.ui.lifecycle; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.RequestLocal; + +import org.librecms.lifecycle.Lifecycle; + +public abstract class LifecycleRequestLocal extends RequestLocal { + + public final Lifecycle getLifecycle(final PageState state) { + return (Lifecycle) get(state); + } +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleItemPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleItemPane.java.todo similarity index 100% rename from ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleItemPane.java rename to ccm-cms/src/main/java/com/arsdigita/cms/ui/role/BaseRoleItemPane.java.todo diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPane.java.todo similarity index 100% rename from ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPane.java rename to ccm-cms/src/main/java/com/arsdigita/cms/ui/role/RoleAdminPane.java.todo diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/search/ItemQueryComponent.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/search/ItemQueryComponent.java.todo similarity index 100% rename from ccm-cms/src/main/java/com/arsdigita/cms/ui/search/ItemQueryComponent.java rename to ccm-cms/src/main/java/com/arsdigita/cms/ui/search/ItemQueryComponent.java.todo diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypePropertyList.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypePropertyList.java index fa02a1b54..7c2ebd20e 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypePropertyList.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/type/ContentTypePropertyList.java @@ -20,16 +20,23 @@ package com.arsdigita.cms.ui.type; import com.arsdigita.bebop.PageState; import com.arsdigita.cms.CMS; + import org.librecms.contentsection.ContentSection; import org.librecms.contentsection.ContentType; import org.librecms.lifecycle.LifecycleDefinition; + import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.kernel.KernelConfig; +import com.arsdigita.toolbox.ui.Property; import com.arsdigita.toolbox.ui.PropertyList; + import java.util.Locale; + import org.libreccm.workflow.WorkflowTemplate; import org.librecms.CmsConstants; +import java.util.List; + /** * This component displays basic attributes of a content type * including: @@ -50,8 +57,8 @@ class ContentTypePropertyList extends PropertyList { } @Override - protected final java.util.List properties(final PageState state) { - final java.util.List props = super.properties(state); + protected final ListA context bar.
* - * @author Justin Ross <jross@redhat.com> - * @version $Id$ + * @author Justin Ross + * @author Jens Pelzetter */ public abstract class ContextBar extends SimpleComponent { - private static final Logger s_log = Logger.getLogger(ContextBar.class); - - private static final RequestLocal s_entries = new RequestLocal() { + private static final RequestLocal ENTRIES = new RequestLocal() { + @Override protected final Object initialValue(final PageState state) { - return new ArrayList(); + return new ArrayList<>(); } }; @@ -49,17 +48,19 @@ public abstract class ContextBar extends SimpleComponent { super(); } - protected List entries(final PageState state) { - return (List) s_entries.get(state); + @SuppressWarnings("unchecked") + protected ListA context bar.
* - * @author Justin Ross <jross@redhat.com> + * @author Justin Ross + * @author Jens Pelzetter */ public abstract class PropertyList extends SimpleComponent { - private static final Logger s_log = Logger.getLogger(PropertyList.class); + private static final RequestLocal PROPERTIES = new RequestLocal() { - private static final RequestLocal s_props = new RequestLocal() { - protected final Object initialValue(final PageState state) { - return new ArrayList(); - } - }; + @Override + protected final Object initialValue(final PageState state) { + return new ArrayList<>(); + } + + }; public PropertyList() { super(); } - protected List properties(final PageState state) { - return (List) s_props.get(state); + @SuppressWarnings("unchecked") + protected List