diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/lifecycle/Duration.java b/ccm-cms/src/main/java/com/arsdigita/cms/lifecycle/Duration.java new file mode 100755 index 000000000..a29421061 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/lifecycle/Duration.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2001-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.lifecycle; + +import com.arsdigita.util.Assert; + +/** + * Utility methods for lifecycle durations. + * + * @author Michael Pih + */ +public class Duration { + + /** + * A convenience wrapper around {@link #formatDuration(long)}. + * + * @param minutes + * + * @return + * + * @see #formatDuration(long) + * @pre minutes != null + */ + public static String formatDuration(final Long minutes) { + Assert.exists(minutes, "minutes"); + return formatDuration(minutes.longValue()); + } + + /** + * Formats a duration longo a user friendly format of the form "x days, h + * hours, m minutes". + * + * @param minutes the duration in minutes + * @return + */ + public static String formatDuration(final long minutes) { + long[] dhm = formatDHM(minutes); + final StringBuilder buffer = new StringBuilder(); + + if (dhm[0] > 0) { + buffer.append(dhm[0]).append(" days"); + } + + if (dhm[1] > 0) { + if (dhm[0] > 0) { + buffer.append(", "); + } + buffer.append(dhm[1]).append(" hours"); + } + + if (dhm[0] > 0 || dhm[1] > 0) { + buffer.append(", "); + } + buffer.append(dhm[2]).append(" minutes"); + + return buffer.toString(); + } + + /** + * Formats time in minutes longo a days/hours/minutes format. + * + * @param minutes + * @return + */ + public static long[] formatDHM(final long minutes) { + long[] dhm = new long[3]; + + long days = minutes / (60 * 24); + long hours = minutes / 60; // no pun longended + long mins = minutes; + + if (days > 0) { + hours -= (days * 24); + mins -= (days * 24 * 60); + } + if (hours > 0) { + mins -= (hours * 60); + } + + dhm[0] = days; + dhm[1] = hours; + dhm[2] = mins; + return dhm; + } + + /** + * Formats time in minutes longo a days/hours/minutes format. + * + * @return + * @see #formatDHM(long) + * @param minutes timespan in minutes + */ + public static Long[] formatDHM(final Long minutes) { + long dhm[] = formatDHM(minutes.longValue()); + return copyArray(dhm); + } + + private static Long[] copyArray(long[] from) { + Assert.exists(from, "from"); + Long[] to = new Long[from.length]; + for (int ii = 0; ii < from.length; ii++) { + to[ii] = from[ii]; + } + return to; + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseItemPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseItemPane.java new file mode 100755 index 000000000..72ae3900f --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseItemPane.java @@ -0,0 +1,48 @@ +/* + * 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; + +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.toolbox.ui.ModalPanel; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.librecms.CmsConstants; + +/** + * @author Jens Pelzetter + * @author Justin Ross + */ +public abstract class BaseItemPane extends ModalPanel { + + private static final Logger LOGGER = LogManager.getLogger + (BaseItemPane.class); + + protected BaseItemPane() { + super(); + } + + protected final static GlobalizedMessage gz(final String key) { + return new GlobalizedMessage(key, CmsConstants.CMS_BUNDLE); + } + + protected final static String lz(final String key) { + return (String) gz(key).localize(); + } +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/AddPhaseForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/AddPhaseForm.java new file mode 100755 index 000000000..d9d89a256 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/AddPhaseForm.java @@ -0,0 +1,400 @@ +/* + * 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.ColumnPanel; +import com.arsdigita.bebop.FormProcessException; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.SimpleContainer; +import com.arsdigita.bebop.event.FormInitListener; +import com.arsdigita.bebop.event.FormProcessListener; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.bebop.event.FormValidationListener; +import com.arsdigita.bebop.form.FormErrorDisplay; +import com.arsdigita.bebop.form.Hidden; +import com.arsdigita.bebop.form.Submit; +import com.arsdigita.bebop.form.TextArea; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.parameters.BigDecimalParameter; +import com.arsdigita.bebop.parameters.IntegerParameter; +import com.arsdigita.bebop.parameters.NotEmptyValidationListener; +import com.arsdigita.bebop.parameters.NotNullValidationListener; +import com.arsdigita.bebop.parameters.NumberInRangeValidationListener; +import com.arsdigita.bebop.parameters.StringLengthValidationListener; +import com.arsdigita.bebop.parameters.TrimmedStringParameter; + +import org.librecms.lifecycle.LifecycleDefinition; +import org.librecms.lifecycle.PhaseDefinition; + +import com.arsdigita.cms.ui.CMSForm; +import com.arsdigita.cms.ui.FormSecurityListener; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.kernel.KernelConfig; +import com.arsdigita.util.UncheckedWrapperException; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.configuration.ConfigurationManager; +import org.librecms.CmsConstants; +import org.librecms.lifecycle.LifecycleDefinitionRepository; +import org.librecms.lifecycle.PhaseDefinititionRepository; + +import java.math.BigDecimal; +import java.sql.SQLException; +import java.util.List; +import java.util.Locale; + +/** + * This class contains a form component to add a lifecycle phase definition. + * + * @author Jens Pelzetter + * @author Jack Chung + * @author Xixi D'Moon + * @author Michael Pih + */ +class AddPhaseForm extends CMSForm { + + private final static String PHASE_ID = "id"; + private final static String LABEL = "label"; + private final static String DESCRIPTION = "description"; + private final static String DELAY_DAYS = "delay_days"; + private final static String DELAY_HOURS = "delay_hours"; + private final static String DELAY_MINUTES = "delay_minutes"; + private final static String DURATION_DAYS = "duration_days"; + private final static String DURATION_HOURS = "duration_hours"; + private final static String DURATION_MINUTES = "duration_minutes"; + private final static String SUBMIT = "submit"; + private final static String CANCEL = "cancel"; + + private final LifecycleDefinitionRequestLocal m_cycle; + + private final Hidden m_id; + private final TextField m_label; + private final TextArea m_description; + private final TextField m_delay_days; + private final TextField m_delay_hours; + private final TextField m_delay_minutes; + private final TextField m_duration_days; + private final TextField m_duration_hours; + private final TextField m_duration_minutes; + private final Submit m_submit; + private final Submit m_cancel; + + /** + * Constructor. + * + * @param cycles The cycle selection model. This is to tell the form which + * cycle definition is selected since phase definitions are + * associated to cycle definitions + */ + public AddPhaseForm(final LifecycleDefinitionRequestLocal cycle) { + super("LifecyclePhaseDefinition"); + + m_cycle = cycle; + + m_id = new Hidden(new BigDecimalParameter(PHASE_ID)); + add(m_id); + m_id.addValidationListener(new NotNullValidationListener()); + + Label heading = new Label(gz("cms.ui.lifecycle.phase_add")); + heading.setFontWeight(Label.BOLD); + add(heading, ColumnPanel.FULL_WIDTH); + add(new FormErrorDisplay(this), ColumnPanel.FULL_WIDTH); + + add(new Label(gz("cms.ui.name"))); + m_label = new TextField(new TrimmedStringParameter(LABEL)); + m_label.addValidationListener(new NotEmptyValidationListener()); + m_label.setSize(40); + m_label.setMaxLength(1000); + add(m_label); + + add(new Label(gz("cms.ui.description"))); + m_description = new TextArea(new TrimmedStringParameter(DESCRIPTION)); + m_description.addValidationListener(new StringLengthValidationListener( + 4000)); + m_description.setCols(40); + m_description.setRows(5); + m_description.setWrap(TextArea.SOFT); + add(m_description); + + // phase delay + add(new Label(gz("cms.ui.lifecycle.phase_start_delay"))); + m_delay_days = new TextField(new IntegerParameter(DELAY_DAYS)); + m_delay_hours = new TextField(new IntegerParameter(DELAY_HOURS)); + m_delay_minutes = new TextField(new IntegerParameter(DELAY_MINUTES)); + + //max value: days: 60 years, hours: 7 days, minutes: 1 day + m_delay_days.addValidationListener( + new NumberInRangeValidationListener(0, 21900)); + m_delay_hours.addValidationListener(new NumberInRangeValidationListener( + 0, 168)); + m_delay_minutes.addValidationListener( + new NumberInRangeValidationListener(0, 1440)); + m_delay_days.setSize(7); + m_delay_hours.setSize(7); + m_delay_minutes.setSize(7); + m_delay_days.setClassAttr("DaysField"); + m_delay_hours.setClassAttr("HoursField"); + m_delay_minutes.setClassAttr("MinutesField"); + + SimpleContainer de = new SimpleContainer(); + de.add(new Label(gz("cms.ui.lifecycle.phase_days"))); + de.add(m_delay_days); + de.add(new Label(gz("cms.ui.lifecycle.phase_hours"))); + de.add(m_delay_hours); + de.add(new Label(gz("cms.ui.lifecycle.phase_mins"))); + de.add(m_delay_minutes); + add(de); + + // phase duration + add(new Label(gz("cms.ui.lifecycle.phase_duration"))); + m_duration_days = new TextField(new IntegerParameter(DURATION_DAYS)); + m_duration_hours = new TextField(new IntegerParameter(DURATION_HOURS)); + m_duration_minutes = new TextField( + new IntegerParameter(DURATION_MINUTES)); + + //max value: days: 60 years, hours: 7 days, minutes: 1 day + m_duration_days.addValidationListener( + new NumberInRangeValidationListener(0, 21900)); + m_duration_hours.addValidationListener( + new NumberInRangeValidationListener(0, 168)); + m_duration_minutes.addValidationListener( + new NumberInRangeValidationListener(0, 1440)); + m_duration_days.setSize(7); + m_duration_hours.setSize(7); + m_duration_minutes.setSize(7); + m_duration_days.setClassAttr("DaysField"); + m_duration_hours.setClassAttr("HoursField"); + m_duration_minutes.setClassAttr("MinutesField"); + + SimpleContainer du = new SimpleContainer(); + du.add(new Label(gz("cms.ui.lifecycle.phase_days"))); + du.add(m_duration_days); + du.add(new Label(gz("cms.ui.lifecycle.phase_hours"))); + du.add(m_duration_hours); + du.add(new Label(gz("cms.ui.lifecycle.phase_mins"))); + du.add(m_duration_minutes); + add(du); + + SimpleContainer s = new SimpleContainer(); + m_submit = new Submit(SUBMIT); + m_submit.setButtonLabel("Add Phase"); + s.add(m_submit); + m_cancel = new Submit(CANCEL); + m_cancel.setButtonLabel("Cancel"); + s.add(m_cancel); + add(s, ColumnPanel.FULL_WIDTH | ColumnPanel.CENTER); + + addInitListener(new FormInitListener() { + + public final void init(final FormSectionEvent event) + throws FormProcessException { + initializePhase(event.getPageState()); + } + + }); + + addSubmissionListener(new FormSecurityListener( + CmsConstants.PRIVILEGE_ADMINISTER_LIFECYLES)); + + addValidationListener(new FormValidationListener() { + + @Override + public final void validate(final FormSectionEvent event) + throws FormProcessException { + final PageState state = event.getPageState(); + validateDuration(state); + validateUniqueName(state); + } + + }); + + addProcessListener(new FormProcessListener() { + + public final void process(final FormSectionEvent event) + throws FormProcessException { + addPhase(event.getPageState()); + } + + }); + } + + /** + * Returns true if this form was cancelled. + * + * @param state The page state + * + * @return True if the form was cancelled, false otherwise + * + * @pre state != null + */ + @Override + public boolean isCancelled(final PageState state) { + return m_cancel.isSelected(state); + } + + /** + * Generate a unique ID for the new phase. + * + * @param state The page state + * + * @pre state != null + */ + protected void initializePhase(final PageState state) + throws FormProcessException { + // Not neccessary with JPA +// if (m_id.getValue(state) == null) { +// try { +// m_id.setValue(state, Sequences.getNextValue()); +// } catch (SQLException e) { +// throw new UncheckedWrapperException(e); +// } +// } + } + + /** + * Add a new phase using data from the form. + * + * @param state The page state + * + * @pre state != null + */ + protected void addPhase(final PageState state) throws FormProcessException { + final String label = (String) m_label.getValue(state); + final String description = (String) m_description.getValue(state); + final Integer delDays = (Integer) m_delay_days.getValue(state); + final Integer delHours = (Integer) m_delay_hours.getValue(state); + final Integer delMinutes = (Integer) m_delay_minutes.getValue(state); + final Integer durDays = (Integer) m_duration_days.getValue(state); + final Integer durHours = (Integer) m_duration_hours.getValue(state); + final Integer durMinutes = (Integer) m_duration_minutes.getValue(state); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final LifecycleDefinitionRepository lifecycleDefRepo = cdiUtil.findBean( + LifecycleDefinitionRepository.class); + final PhaseDefinititionRepository phaseDefRepo = cdiUtil.findBean( + PhaseDefinititionRepository.class); + final ConfigurationManager confManager = cdiUtil.findBean( + ConfigurationManager.class); + final KernelConfig kernelConfig = confManager.findConfiguration( + KernelConfig.class); + final Locale defaultLocale = new Locale(kernelConfig + .getDefaultLanguage()); + + // Check if the object already exists for double click protection. + final PhaseDefinition phaseDef = new PhaseDefinition(); + final LifecycleDefinition cycleDef = m_cycle.getLifecycleDefinition( + state); + cycleDef.addPhaseDefinition(phaseDef); + + phaseDef.getLabel().addValue(defaultLocale, label); + phaseDef.getDescription().addValue(defaultLocale, description); + phaseDef.setDefaultDelay(delDays * delHours * delMinutes * 60); + phaseDef.setDefaultDuration(durDays * durHours * durMinutes * 60); + + phaseDefRepo.save(phaseDef); + lifecycleDefRepo.save(cycleDef); + } + + /** + * Validate name uniqueness. + * + * @param state The page state + * + * @pre state != null + */ + protected void validateUniqueName(PageState state) + throws FormProcessException { + String label = (String) m_label.getValue(state); + + final LifecycleDefinition cycleDef = m_cycle.getLifecycleDefinition( + state); + final List phaseDefs = cycleDef.getPhaseDefinitions(); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ConfigurationManager confManager = cdiUtil.findBean( + ConfigurationManager.class); + final KernelConfig kernelConfig = confManager.findConfiguration( + KernelConfig.class); + final Locale defaultLocale = new Locale(kernelConfig + .getDefaultLanguage()); + + for (final PhaseDefinition phaseDef : phaseDefs) { + if (phaseDef.getLabel().getValue(defaultLocale).equalsIgnoreCase( + label)) { + throw new FormProcessException(new GlobalizedMessage( + "cms.ui.lifecycle.phase_name_not_unique", + CmsConstants.CMS_BUNDLE)); + } + } + } + + /** + * Validate the phase duration. The duration cannot be 0. + * + * @param state The page state + * + * @pre state != null + */ + protected void validateDuration(PageState state) + throws FormProcessException { + Integer durDays = (Integer) m_duration_days.getValue(state); + Integer durHours = (Integer) m_duration_hours.getValue(state); + Integer durMinutes = (Integer) m_duration_minutes.getValue(state); + + // Phase duration is infinite, so the duration is valid. + if (durDays == null && durHours == null && durMinutes == null) { + return; + } + + int days, hours, minutes; + if (durDays != null) { + days = durDays.intValue(); + } else { + days = 0; + } + + if (durHours != null) { + hours = durHours.intValue(); + } else { + hours = 0; + } + + if (durMinutes != null) { + minutes = durMinutes.intValue(); + } else { + minutes = 0; + } + + if ((days + hours + minutes) == 0) { + throw new FormProcessException(new GlobalizedMessage( + "cms.ui.lifecycle.phase_duration_negative", + CmsConstants.CMS_BUNDLE)); + } + } + + private static GlobalizedMessage gz(final String key) { + return new GlobalizedMessage(key, + CmsConstants.CMS_BUNDLE); + } + + private static String lz(final String key) { + return (String) gz(key).localize(); + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/BaseLifecycleForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/BaseLifecycleForm.java new file mode 100755 index 000000000..f0da704e2 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/BaseLifecycleForm.java @@ -0,0 +1,123 @@ +/* + * 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.FormProcessException; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.event.ParameterEvent; +import com.arsdigita.bebop.event.ParameterListener; +import com.arsdigita.bebop.form.TextArea; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.parameters.NotEmptyValidationListener; +import com.arsdigita.bebop.parameters.StringLengthValidationListener; +import com.arsdigita.bebop.parameters.TrimmedStringParameter; +import com.arsdigita.cms.CMS; + +import com.arsdigita.cms.ui.BaseForm; +import com.arsdigita.cms.ui.FormSecurityListener; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.kernel.KernelConfig; + +import org.apache.log4j.Logger; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.configuration.ConfigurationManager; +import org.librecms.CmsConstants; +import org.librecms.lifecycle.LifecycleDefinition; + +import java.util.Locale; + +/** + * @author Jens Pelzetter + * @author Justin Ross + */ +class BaseLifecycleForm extends BaseForm { + + private static final Logger s_log = Logger + .getLogger(BaseLifecycleForm.class); + + final TextField m_name; + final TextArea m_description; + + BaseLifecycleForm(final String key, final GlobalizedMessage message) { + super(key, message); + + m_name = new TextField(new TrimmedStringParameter("label")); + addField(gz("cms.ui.name"), m_name); + + m_name.addValidationListener(new NotEmptyValidationListener()); + m_name.setSize(40); + m_name.setMaxLength(1000); + + m_description = new TextArea(new TrimmedStringParameter("description")); + addField(gz("cms.ui.description"), m_description); + + m_description.addValidationListener(new StringLengthValidationListener( + 4000)); + m_description.setCols(40); + m_description.setRows(5); + m_description.setWrap(TextArea.SOFT); + + addAction(new Finish()); + addAction(new Cancel()); + + addSubmissionListener(new FormSecurityListener( + CmsConstants.PRIVILEGE_ADMINISTER_LIFECYLES)); + } + + class NameUniqueListener implements ParameterListener { + + private final LifecycleDefinitionRequestLocal m_definition; + + NameUniqueListener(final LifecycleDefinitionRequestLocal definition) { + m_definition = definition; + } + + @Override + public final void validate(final ParameterEvent e) + throws FormProcessException { + + final PageState state = e.getPageState(); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ConfigurationManager confManager = cdiUtil.findBean( + ConfigurationManager.class); + final KernelConfig kernelConfig = confManager.findConfiguration( + KernelConfig.class); + final Locale defaultLocale = new Locale(kernelConfig + .getDefaultLanguage()); + final String label = (String) m_name.getValue(state); + + final java.util.List definitions = CMS + .getContext().getContentSection().getLifecycleDefinitions(); + + for (final LifecycleDefinition definition : definitions) { + if (definition.getLabel().getValue(defaultLocale) + .equalsIgnoreCase(label) + && (m_definition == null + || !m_definition.getLifecycleDefinition(state) + .equals(definition))) { + throw new FormProcessException(new GlobalizedMessage( + "cms.ui.lifecycle.name_not_unique", + CmsConstants.CMS_BUNDLE)); + } + } + } + + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/DeletePhaseForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/DeletePhaseForm.java new file mode 100755 index 000000000..b11081595 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/DeletePhaseForm.java @@ -0,0 +1,148 @@ +/* + * 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.BoxPanel; +import com.arsdigita.bebop.ColumnPanel; +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.FormData; +import com.arsdigita.bebop.FormProcessException; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.event.FormInitListener; +import com.arsdigita.bebop.event.FormProcessListener; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.bebop.form.Hidden; +import com.arsdigita.bebop.form.Submit; +import com.arsdigita.bebop.parameters.BigDecimalParameter; +import com.arsdigita.bebop.parameters.NotNullValidationListener; + +import org.librecms.lifecycle.PhaseDefinition; + +import com.arsdigita.cms.ui.CMSForm; +import com.arsdigita.cms.ui.FormSecurityListener; + +import org.libreccm.cdi.utils.CdiUtil; +import org.librecms.CmsConstants; +import org.librecms.lifecycle.PhaseDefinititionRepository; + +import java.math.BigDecimal; + +/** + * This class handles the deleting of a phase definition. + * + * @author Jens Pelzetter + * @author Jack Chung + */ +class DeletePhaseForm extends CMSForm + implements FormProcessListener, FormInitListener { + + private final PhaseRequestLocal m_phase; + + private final Hidden m_id; + private final Submit m_deleteWidget; + private final Submit m_cancelWidget; + + /** + * @param m The phase selection model. This tells the form which phase + * definition is selected. + */ + public DeletePhaseForm(final PhaseRequestLocal phase) { + super("PhaseDefinitionDelete"); + + m_phase = phase; + + m_id = new Hidden(new BigDecimalParameter("id")); + add(m_id); + m_id.addValidationListener(new NotNullValidationListener()); + + final BoxPanel buttons = new BoxPanel(BoxPanel.HORIZONTAL); + m_deleteWidget = new Submit("delete"); + m_deleteWidget.setButtonLabel("Delete"); + m_deleteWidget.setClassAttr("deletePhase"); + buttons.add(m_deleteWidget); + + m_cancelWidget = new Submit("cancel"); + m_cancelWidget.setButtonLabel("Cancel"); + m_cancelWidget.setClassAttr("canceldeletePhase"); + buttons.add(m_cancelWidget); + + add(buttons, ColumnPanel.CENTER | ColumnPanel.FULL_WIDTH); + + addInitListener(this); + + addSubmissionListener(new FormSecurityListener( + CmsConstants.PRIVILEGE_ADMINISTER_LIFECYLES)); + + addProcessListener(this); + } + + /** + * Returns true if this form was cancelled. + * + * @param state The page state + * + * @return true if the form was cancelled, false otherwise + */ + @Override + public boolean isCancelled(final PageState state) { + return m_cancelWidget.isSelected(state); + } + + /** + * Form process listener. Deletes a phase definition + * + * @param event The form process event + * + * @exception FormProcessException + */ + @Override + public final void process(final FormSectionEvent event) + throws FormProcessException { + final FormData data = event.getFormData(); + final Long key = (Long) data.get(m_id.getName()); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final PhaseDefinititionRepository phaseDefRepo = cdiUtil.findBean( + PhaseDefinititionRepository.class); + + // Check if the object is already deleted for double click + // protection. + final PhaseDefinition phaseDef = phaseDefRepo.findById(key); + if (phaseDef != null) { + phaseDefRepo.delete(phaseDef); + } + + } + + /** + * Init listener. gets the id of the selected phase definition + * + * @param event The form init event + */ + @Override + public final void init(final FormSectionEvent event) { + final FormData data = event.getFormData(); + final PageState state = event.getPageState(); + + final Long id = m_phase.getPhase(state).getDefinitionId(); + + data.put(m_id.getName(), id); + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/EditPhaseForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/EditPhaseForm.java new file mode 100755 index 000000000..a81805e57 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/EditPhaseForm.java @@ -0,0 +1,390 @@ +/* + * 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.ColumnPanel; +import com.arsdigita.bebop.FormProcessException; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.SimpleContainer; +import com.arsdigita.bebop.event.FormInitListener; +import com.arsdigita.bebop.event.FormProcessListener; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.bebop.event.FormValidationListener; +import com.arsdigita.bebop.form.FormErrorDisplay; +import com.arsdigita.bebop.form.Submit; +import com.arsdigita.bebop.form.TextArea; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.parameters.IntegerParameter; +import com.arsdigita.bebop.parameters.NotEmptyValidationListener; +import com.arsdigita.bebop.parameters.NumberInRangeValidationListener; +import com.arsdigita.bebop.parameters.StringLengthValidationListener; +import com.arsdigita.bebop.parameters.TrimmedStringParameter; +import com.arsdigita.cms.lifecycle.Duration; + +import org.librecms.lifecycle.PhaseDefinition; + +import com.arsdigita.cms.ui.CMSForm; +import com.arsdigita.cms.ui.FormSecurityListener; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.kernel.KernelConfig; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.configuration.ConfigurationManager; +import org.librecms.CmsConstants; +import org.librecms.lifecycle.PhaseDefinititionRepository; + +import java.util.Locale; + +/** + * This class contains a form component to edit a lifecycle phase definition. + * + * @author Jens Pelzetter + * @author Jack Chung + * @author Xixi D'Moon + * @author Michael Pih + */ +class EditPhaseForm extends CMSForm { + + private final static String PHASE_ID = "id"; + private final static String LABEL = "label"; + private final static String DESCRIPTION = "description"; + private final static String DELAY_DAYS = "delay_days"; + private final static String DELAY_HOURS = "delay_hours"; + private final static String DELAY_MINUTES = "delay_minutes"; + private final static String DURATION_DAYS = "duration_days"; + private final static String DURATION_HOURS = "duration_hours"; + private final static String DURATION_MINUTES = "duration_minutes"; + private final static String SUBMIT = "submit"; + private final static String CANCEL = "cancel"; + + private final PhaseRequestLocal m_phase; + + private final TextField m_label; + private final TextArea m_description; + private final TextField m_delayDays; + private final TextField m_delayHours; + private final TextField m_delayMinutes; + private final TextField m_durDays; + private final TextField m_durHours; + private final TextField m_durMinutes; + private final Submit m_submit; + private final Submit m_cancel; + + /** + * Constructor. + * + * @param m A single selection model for phase definitions. This is to tell + * the form which phase definition is selected for editing. + * + * @pre phases != null + */ + public EditPhaseForm(final PhaseRequestLocal phase) { + super("EditPhaseDefinition"); + + m_phase = phase; + + add(new Label()); + add(new FormErrorDisplay(this)); + + add(new Label(gz("cms.ui.name"))); + m_label = new TextField(new TrimmedStringParameter(LABEL)); + m_label.addValidationListener(new NotEmptyValidationListener()); + m_label.setSize(40); + m_label.setMaxLength(1000); + add(m_label); + + add(new Label(gz("cms.ui.description"))); + m_description = new TextArea(new TrimmedStringParameter(DESCRIPTION)); + m_description.addValidationListener(new StringLengthValidationListener( + 4000)); + m_description.setCols(40); + m_description.setRows(5); + m_description.setWrap(TextArea.SOFT); + add(m_description); + + // Phase duration + // Max value: days: 60 years, hours: 7 days, minutes: 1 day + m_delayDays = new TextField(new IntegerParameter(DELAY_DAYS)); + m_delayDays.addValidationListener(new NumberInRangeValidationListener(0, + 21900)); + m_delayDays.setSize(7); + m_delayDays.setClassAttr("DaysField"); + + m_delayHours = new TextField(new IntegerParameter(DELAY_HOURS)); + m_delayHours.addValidationListener( + new NumberInRangeValidationListener(0, 168)); + m_delayHours.setClassAttr("HoursField"); + m_delayHours.setSize(7); + + m_delayMinutes = new TextField(new IntegerParameter(DELAY_MINUTES)); + m_delayMinutes.addValidationListener( + new NumberInRangeValidationListener(0, 1440)); + m_delayMinutes.setSize(7); + m_delayMinutes.setClassAttr("MinutesField"); + + add(new Label(new GlobalizedMessage("cms.ui.lifecycle.start_delay", + CmsConstants.CMS_BUNDLE))); + SimpleContainer de = new SimpleContainer(); + de.add(new Label(gz("cms.ui.lifecycle.phase_days"))); + de.add(m_delayDays); + de.add(new Label(gz("cms.ui.lifecycle.phase_hours"))); + de.add(m_delayHours); + de.add(new Label(gz("cms.ui.lifecycle.phase_mins"))); + de.add(m_delayMinutes); + add(de); + + // Phase duration + // Max value: days: 60 years, hours: 7 days, minutes: 1 day + m_durDays = new TextField(new IntegerParameter(DURATION_DAYS)); + m_durDays.addValidationListener(new NumberInRangeValidationListener(0, + 21900)); + m_durDays.setSize(7); + m_durDays.setClassAttr("DaysField"); + + m_durHours = new TextField(new IntegerParameter(DURATION_HOURS)); + m_durHours.addValidationListener(new NumberInRangeValidationListener(0, + 168)); + m_durHours.setSize(7); + m_durHours.setClassAttr("HoursField"); + + m_durMinutes = new TextField(new IntegerParameter(DURATION_MINUTES)); + m_durMinutes.addValidationListener( + new NumberInRangeValidationListener(0, 1440)); + m_durMinutes.setSize(7); + m_durMinutes.setClassAttr("MinutesField"); + + add(new Label(gz("cms.ui.lifecycle.duration"))); + SimpleContainer du = new SimpleContainer(); + du.add(new Label(gz("cms.ui.lifecycle.phase_days"))); + du.add(m_durDays); + du.add(new Label(gz("cms.ui.lifecycle.phase_hours"))); + du.add(m_durHours); + du.add(new Label(gz("cms.ui.lifecycle.phase_mins"))); + du.add(m_durMinutes); + add(du); + + // Submit and cancel buttons + SimpleContainer s = new SimpleContainer(); + m_submit = new Submit(SUBMIT); + m_submit.setButtonLabel("Edit Phase"); + s.add(m_submit); + m_cancel = new Submit(CANCEL); + m_cancel.setButtonLabel("Cancel"); + s.add(m_cancel); + add(s, ColumnPanel.FULL_WIDTH | ColumnPanel.CENTER); + + // Add form listeners. + addInitListener(new FormInitListener() { + + @Override + public final void init(final FormSectionEvent event) + throws FormProcessException { + initializePhaseDefinition(event.getPageState()); + } + + }); + + addSubmissionListener(new FormSecurityListener( + CmsConstants.PRIVILEGE_ADMINISTER_LIFECYLES)); + + addValidationListener(new FormValidationListener() { + + @Override + public final void validate(final FormSectionEvent event) + throws FormProcessException { + final PageState state = event.getPageState(); + + validateDuration(state); + validateUniqueName(state); + } + + }); + + addProcessListener(new FormProcessListener() { + + @Override + public void process(final FormSectionEvent event) + throws FormProcessException { + updatePhaseDefinition(event.getPageState()); + } + + }); + } + + /** + * Returns true if this form was cancelled. + * + * @param state The page state + * + * @return True if the form was cancelled, false otherwise + * + * @pre state != null + */ + @Override + public boolean isCancelled(final PageState state) { + return m_cancel.isSelected(state); + } + + /** + * Populate the form fields with the current phase definition attribute + * values. + * + * @param state The page state + * + * @pre state != null + */ + private void initializePhaseDefinition(final PageState state) + throws FormProcessException { + PhaseDefinition pd = m_phase.getPhase(state); + m_label.setValue(state, pd.getLabel()); + m_description.setValue(state, pd.getDescription()); + + long[] delay = Duration.formatDHM(pd.getDefaultDelay()); + m_delayDays.setValue(state, delay[0]); + m_delayHours.setValue(state, delay[1]); + m_delayMinutes.setValue(state, delay[2]); + + Long duration = pd.getDefaultDuration(); + if (duration != null) { + Long[] dhm = Duration.formatDHM(duration); + m_durDays.setValue(state, dhm[0]); + m_durHours.setValue(state, dhm[1]); + m_durMinutes.setValue(state, dhm[2]); + } + } + + /** + * Update the phase definition with values from the form. + * + * @param state The page state + * + * @pre state != null + */ + private void updatePhaseDefinition(final PageState state) + throws FormProcessException { + + final String label = (String) m_label.getValue(state); + final String description = (String) m_description.getValue(state); + final Integer delayDays = (Integer) m_delayDays.getValue(state); + final Integer delayHours = (Integer) m_delayHours.getValue(state); + final Integer delayMinutes = (Integer) m_delayMinutes.getValue(state); + final Integer durDays = (Integer) m_durDays.getValue(state); + final Integer durHours = (Integer) m_durHours.getValue(state); + final Integer durMinutes = (Integer) m_durMinutes.getValue(state); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ConfigurationManager confManager = cdiUtil.findBean(ConfigurationManager.class); + final PhaseDefinititionRepository phaseDefRepo = cdiUtil.findBean( + PhaseDefinititionRepository.class); + final KernelConfig kernelConfig = confManager.findConfiguration( + KernelConfig.class); + final Locale defaultLocale = new Locale(kernelConfig.getDefaultLanguage()); + + final PhaseDefinition phaseDefinition = m_phase.getPhase(state); + phaseDefinition.getLabel().addValue(defaultLocale, label); + phaseDefinition.getDescription().addValue(defaultLocale, description); + phaseDefinition.setDefaultDelay(delayDays * delayHours * delayMinutes * 60); + phaseDefinition.setDefaultDuration(durDays * durHours * durMinutes * 60); + phaseDefRepo.save(phaseDefinition); + } + + /** + * Ensures that the new name (if it has changed) is unique within the + * lifecycle definition. + * + * @param state The page state + * + * @pre state != null + */ + private void validateUniqueName(final PageState state) + throws FormProcessException { + final String newLabel = (String) m_label.getValue(state); + +// PhaseDefinition pd = m_phase.getPhase(state); +// PhaseDefinitionCollection phaseDefs = pd.getLifecycleDefinition() +// .getPhaseDefinitions(); +// +// // If the name has changed, check for uniqueness. +// if (!pd.getLabel().equalsIgnoreCase(newLabel)) { +// while (phaseDefs.next()) { +// PhaseDefinition phaseDef = phaseDefs.getPhaseDefinition(); +// +// if (phaseDef.getLabel().equalsIgnoreCase(newLabel)) { +// phaseDefs.close(); +// throw new FormProcessException(GlobalizationUtil.globalize( +// "cms.ui.lifecycle.phase_name_not_unique")); +// } +// } +// } + } + + /** + * Validate the phase duration. The duration cannot be 0. + * + * @param state The page state + * + * @pre state != null + */ + private void validateDuration(final PageState state) + throws FormProcessException { + final Integer durDays = (Integer) m_durDays.getValue(state); + final Integer durHours = (Integer) m_durHours.getValue(state); + final Integer durMinutes = (Integer) m_durMinutes.getValue(state); + + // Phase duration is infinite, so the duration is valid. + if (durDays == null && durHours == null && durMinutes == null) { + return; + } + + int days, hours, minutes; + if (durDays != null) { + days = durDays.intValue(); + } else { + days = 0; + } + + if (durHours != null) { + hours = durHours.intValue(); + } else { + hours = 0; + } + + if (durMinutes != null) { + minutes = durMinutes.intValue(); + } else { + minutes = 0; + } + + if ((days + hours + minutes) == 0) { + throw new FormProcessException(new GlobalizedMessage( + "cms.ui.phase.duration_negative", + CmsConstants.CMS_BUNDLE)); + } + } + + private static GlobalizedMessage gz(final String key) { + return new GlobalizedMessage(key, CmsConstants.CMS_BUNDLE); + } + + private static String lz(final String key) { + return (String) gz(key).localize(); + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAddForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAddForm.java new file mode 100755 index 000000000..664665be0 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAddForm.java @@ -0,0 +1,100 @@ +/* + * 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.FormProcessException; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.SingleSelectionModel; +import com.arsdigita.bebop.event.FormProcessListener; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.cms.CMS; +import com.arsdigita.kernel.KernelConfig; + +import org.apache.logging.log4j.LogManager; +import org.librecms.contentsection.ContentSection; +import org.librecms.lifecycle.LifecycleDefinition; +import org.apache.logging.log4j.Logger; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.configuration.ConfigurationManager; +import org.librecms.contentsection.ContentSectionManager; +import org.librecms.lifecycle.LifecycleDefinitionRepository; + +import java.util.Locale; + +/** + * @author Jens Pelzetter + * @author Michael Pih + * @author Jack Chung + * @author Xixi D'Moon + * @author Justin Ross + */ +class LifecycleAddForm extends BaseLifecycleForm { + + private static final Logger LOGGER = LogManager.getLogger(LifecycleAddForm.class); + + private final SingleSelectionModel m_model; + + LifecycleAddForm(final SingleSelectionModel model) { + super("LifecycleDefinition", gz("cms.ui.lifecycle.add")); + + m_model = model; + + m_name.addValidationListener(new NameUniqueListener(null)); + + addProcessListener(new ProcessListener()); + } + + private class ProcessListener implements FormProcessListener { + + @Override + public final void process(final FormSectionEvent e) + throws FormProcessException { + final PageState state = e.getPageState(); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ConfigurationManager confManager = cdiUtil.findBean( + ConfigurationManager.class); + final LifecycleDefinitionRepository lifecycleDefRepo = cdiUtil.findBean( + LifecycleDefinitionRepository.class); + final ContentSectionManager sectionManager = cdiUtil.findBean( + ContentSectionManager.class); + final KernelConfig kernelConfig = confManager.findConfiguration( + KernelConfig.class); + final Locale defaultLocale = new Locale(kernelConfig + .getDefaultLanguage()); + + final LifecycleDefinition definition = new LifecycleDefinition(); + + definition.getLabel().addValue(defaultLocale, + (String) m_name.getValue(state)); + definition.getDescription().addValue( + defaultLocale, + (String) m_description.getValue(state)); + lifecycleDefRepo.save(definition); + + final ContentSection section = CMS.getContext().getContentSection(); + sectionManager.addLifecycleDefinitionToContentSection(definition, + section); + + m_model.setSelectedKey(state, + definition.getDefinitionId()); + } + + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminContainer.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminContainer.java new file mode 100755 index 000000000..d1066227a --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminContainer.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2001-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.Component; +import com.arsdigita.bebop.PageState; +import com.arsdigita.cms.dispatcher.Utilities; + +import org.libreccm.security.Party; + +import com.arsdigita.toolbox.ui.SecurityContainer; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.PermissionChecker; +import org.librecms.CmsConstants; + + +/** + * Security container that wraps the canAdministerLifecycles access check + * around its components. + * + * @author Jens Pelzetter + * @author Michael Pih + */ +public class LifecycleAdminContainer extends SecurityContainer { + + + /** + * This default constructor should be followed by calls to + * add. + */ + public LifecycleAdminContainer() { + super(); + } + + /** + * Create a SecurityContainer around a child component. + * + * @param component The child component + */ + public LifecycleAdminContainer(final Component component) { + super(component); + } + + /** + * Returns true if the current user can access the child component. + * + * @param state The page state + * @return true if the access checks pass, false otherwise + */ + @Override + protected boolean canAccess(final Party party, final PageState state) { + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final PermissionChecker permissionChecker = cdiUtil.findBean(PermissionChecker.class); + + return permissionChecker.isPermitted(CmsConstants.PRIVILEGE_ADMINISTER_LIFECYLES); + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminPane.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminPane.java similarity index 71% rename from ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminPane.java.off rename to ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminPane.java index 55ab2b208..f8baa3483 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminPane.java.off +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleAdminPane.java @@ -24,12 +24,20 @@ import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.SingleSelectionModel; import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.cms.CMS; + import org.librecms.contentsection.ContentSection; import org.librecms.lifecycle.LifecycleDefinition; + import com.arsdigita.cms.ui.BaseAdminPane; import com.arsdigita.cms.ui.BaseDeleteForm; import com.arsdigita.cms.ui.FormSecurityListener; + import org.apache.log4j.Logger; +import org.libreccm.cdi.utils.CdiUtil; +import org.librecms.CmsConstants; +import org.librecms.contentsection.ContentSectionManager; +import org.librecms.lifecycle.Lifecycle; +import org.librecms.lifecycle.LifecycleDefinitionRepository; import java.math.BigDecimal; @@ -37,10 +45,10 @@ import java.math.BigDecimal; *

This class contains the split pane for the lifecycle administration * interface.

* + * @author Jens Pelzetter * @author Michael Pih * @author Jack Chung - * @author Justin Ross <jross@redhat.com> - * @version $Id: LifecycleAdminPane.java 1942 2009-05-29 07:53:23Z terry $ + * @author Justin Ross */ public class LifecycleAdminPane extends BaseAdminPane { @@ -75,10 +83,14 @@ public class LifecycleAdminPane extends BaseAdminPane { private class SelectionRequestLocal extends LifecycleDefinitionRequestLocal { + @Override protected final Object initialValue(final PageState state) { final String id = m_model.getSelectedKey(state).toString(); - return new LifecycleDefinition(new BigDecimal(id)); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final LifecycleDefinitionRepository lifecycleDefRepo = cdiUtil.findBean(LifecycleDefinitionRepository.class); + + return lifecycleDefRepo.findById(Long.parseLong(id)); } } @@ -87,22 +99,26 @@ public class LifecycleAdminPane extends BaseAdminPane { super(new Label(gz("cms.ui.lifecycle.delete_prompt"))); addSubmissionListener - (new FormSecurityListener(SecurityManager.LIFECYCLE_ADMIN)); + (new FormSecurityListener(CmsConstants.PRIVILEGE_ADMINISTER_LIFECYLES)); } - public final void process(final FormSectionEvent e) + public final void process(final FormSectionEvent event) throws FormProcessException { - final PageState state = e.getPageState(); + final PageState state = event.getPageState(); final ContentSection section = CMS.getContext().getContentSection(); final LifecycleDefinition definition = m_definition.getLifecycleDefinition(state); - section.removeLifecycleDefinition(definition); - section.save(); - - definition.delete(); - + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ContentSectionManager sectionManager = cdiUtil.findBean( + ContentSectionManager.class); + final LifecycleDefinitionRepository lifecycleDefRepo = cdiUtil.findBean(LifecycleDefinitionRepository.class); + + sectionManager.removeLifecycleDefinitionFromContentSection( + definition, section); + lifecycleDefRepo.delete(definition); + m_model.clearSelection(state); } } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleEditForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleEditForm.java new file mode 100755 index 000000000..6361585cc --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleEditForm.java @@ -0,0 +1,104 @@ +/* + * 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.FormProcessException; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.event.FormInitListener; +import com.arsdigita.bebop.event.FormProcessListener; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.kernel.KernelConfig; + +import org.apache.logging.log4j.LogManager; +import org.librecms.lifecycle.LifecycleDefinition; +import org.apache.logging.log4j.Logger; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.configuration.ConfigurationManager; +import org.librecms.lifecycle.LifecycleDefinitionRepository; + +import java.util.Locale; + +/** + * This class contains a form component to edit a lifecycle definition. + * + * @author Jack Chung + * @author Xixi D'Moon <xdmoon@redhat.com> + * @author Justin Ross <jross@redhat.com> + * @version $Id$ + */ +class LifecycleEditForm extends BaseLifecycleForm { + + private static final Logger LOGGER = LogManager.getLogger( + LifecycleEditForm.class); + + private final LifecycleDefinitionRequestLocal m_definition; + + LifecycleEditForm(final LifecycleDefinitionRequestLocal definition) { + super("LifecycleEdit", gz("cms.ui.lifecycle.edit")); + + m_definition = definition; + + m_name.addValidationListener(new NameUniqueListener(m_definition)); + + addInitListener(new InitListener()); + addProcessListener(new ProcessListener()); + } + + private class InitListener implements FormInitListener { + + public final void init(final FormSectionEvent e) { + final PageState state = e.getPageState(); + final LifecycleDefinition cycle = m_definition + .getLifecycleDefinition(state); + + m_name.setValue(state, cycle.getLabel()); + m_description.setValue(state, cycle.getDescription()); + } + + } + + private class ProcessListener implements FormProcessListener { + + public final void process(final FormSectionEvent e) + throws FormProcessException { + final PageState state = e.getPageState(); + final LifecycleDefinition definition = m_definition + .getLifecycleDefinition(state); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ConfigurationManager confManager = cdiUtil.findBean( + ConfigurationManager.class); + final LifecycleDefinitionRepository lifecycleDefRepo = cdiUtil + .findBean(LifecycleDefinitionRepository.class); + final KernelConfig kernelConfig = confManager.findConfiguration( + KernelConfig.class); + final Locale defaultLocale = new Locale(kernelConfig + .getDefaultLanguage()); + + definition.getLabel().addValue(defaultLocale, + (String) m_name.getValue(state)); + definition.getDescription().addValue( + defaultLocale, + (String) m_description.getValue(state)); + lifecycleDefRepo.save(definition); + } + + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleListModelBuilder.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleListModelBuilder.java similarity index 86% rename from ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleListModelBuilder.java.off rename to ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleListModelBuilder.java index 17a2ecdcf..05f44522e 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleListModelBuilder.java.off +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/LifecycleListModelBuilder.java @@ -24,7 +24,6 @@ import com.arsdigita.bebop.list.ListModelBuilder; import com.arsdigita.cms.CMS; import org.librecms.contentsection.ContentSection; import com.arsdigita.util.LockableImpl; -import com.arsdigita.util.UncheckedWrapperException; import java.util.List; import java.util.NoSuchElementException; @@ -49,7 +48,8 @@ public final class LifecycleListModelBuilder extends LockableImpl private class Model implements ListModel { - private List m_cycles; + private final List m_cycles; + private int index = -1; public Model(final PageState state) { m_cycles = getCollection(state); @@ -58,24 +58,25 @@ public final class LifecycleListModelBuilder extends LockableImpl private List getCollection(final PageState state) { final ContentSection section = CMS.getContext().getContentSection(); - final List cycles = section.get - getLifecycleDefinitions(); - - cycles.addOrder("upper(label)"); + final List cycles = section.getLifecycleDefinitions(); return cycles; } + @Override public boolean next() throws NoSuchElementException { - return m_cycles.next(); + index++; + return index < m_cycles.size(); } + @Override public Object getElement() { - return m_cycles.getLifecycleDefinition().getLabel(); + return m_cycles.get(index).getLabel(); } + @Override public String getKey() { - return m_cycles.getLifecycleDefinition().getID().toString(); + return Long.toString(m_cycles.get(index).getDefinitionId()); } } } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/PhaseRequestLocal.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/PhaseRequestLocal.java new file mode 100755 index 000000000..cb315acfa --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/PhaseRequestLocal.java @@ -0,0 +1,34 @@ +/* + * 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.PhaseDefinition; +import org.apache.log4j.Logger; + +public abstract class PhaseRequestLocal extends RequestLocal { + + private static final Logger s_log = Logger.getLogger + (PhaseRequestLocal.class); + + public final PhaseDefinition getPhase(final PageState state) { + return (PhaseDefinition) get(state); + } +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/PhaseTableModelBuilder.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/PhaseTableModelBuilder.java new file mode 100755 index 000000000..a745fc3d3 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/lifecycle/PhaseTableModelBuilder.java @@ -0,0 +1,124 @@ +/* + * 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.Table; +import com.arsdigita.bebop.table.TableModel; +import com.arsdigita.bebop.table.TableModelBuilder; +import com.arsdigita.cms.lifecycle.Duration; + +import org.librecms.lifecycle.LifecycleDefinition; +import org.librecms.lifecycle.PhaseDefinition; + +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.util.Assert; +import com.arsdigita.util.LockableImpl; + +import org.arsdigita.cms.CMSConfig; +import org.librecms.CmsConstants; + +import java.util.List; + +class PhaseTableModelBuilder extends LockableImpl + implements TableModelBuilder { + private final LifecycleDefinitionRequestLocal m_cycle; + + public PhaseTableModelBuilder + (final LifecycleDefinitionRequestLocal cycle) { + m_cycle = cycle; + } + + public final TableModel makeModel(final Table table, + final PageState state) { + return new PhaseTableModel(m_cycle.getLifecycleDefinition(state)); + } + + private static class PhaseTableModel implements TableModel { + private PhaseDefinition m_phase; + private final List m_phases; + private int index = -1; + + public PhaseTableModel(final LifecycleDefinition cycle) { + m_phases = cycle.getPhaseDefinitions(); + m_phase = null; + } + + @Override + public final int getColumnCount() { + return 6; + } + + @Override + public final boolean nextRow() { + index++; + if (index < m_phases.size()) { + m_phase = m_phases.get(index); + + return true; + } else { + return false; + } + } + + @Override + public final Object getElementAt(final int column) { + Assert.exists(m_phase, "PhaseDefinition m_phase"); + + switch (column) { + case 0: + return m_phase.getLabel(); + case 1: + return m_phase.getDescription(); + case 2: + return Duration.formatDuration(m_phase.getDefaultDelay()); + case 3: + final Long duration = m_phase.getDefaultDuration(); + + if (duration == null) { + return lz("cms.ui.lifecycle.forever"); + } else { + return Duration.formatDuration(duration); + } + case 4: + return lz("cms.ui.lifecycle.phase_edit"); + case 5: + return lz("cms.ui.lifecycle.phase_delete"); + default: + throw new IllegalStateException(); + } + } + + public Object getKeyAt(int columnIndex) { + if (m_phase == null) { + throw new IllegalStateException(); + } else { + return m_phase.getDefinitionId(); + } + } + } + + private static GlobalizedMessage gz(final String key) { + return new GlobalizedMessage(key, CmsConstants.CMS_BUNDLE); + } + + private static String lz(final String key) { + return (String) gz(key).localize(); + } +}