From 6f715f4fe3a5de10b1bf0c00ceef6d0c71fe426c Mon Sep 17 00:00:00 2001 From: jensp Date: Wed, 19 Jul 2017 15:06:13 +0000 Subject: [PATCH] CCM NG/ccm-cms: Infrastructure for adding common authoring steps git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4881 8810af33-2d31-482b-a856-94f89814c4df Former-commit-id: cbbcbbb2b31d1090bf737461dffed731b9af5d3d --- .../cms/ui/authoring/AuthoringKitWizard.java | 293 +++++------------- .../ui/authoring/AuthoringStepComponent.java | 1 - .../cms/ui/authoring/assets/ImageStep.java | 50 +++ .../ui/authoring/assets/RelatedInfoStep.java | 50 +++ .../contentsection/ContentSectionConfig.java | 33 +- .../contenttypes/AuthoringStepInfo.java | 2 +- .../authoring/ContentItemAuthoringStep.java | 74 +++++ .../ContentItemAuthoringStepInfo.java | 161 ++++++++++ .../ContentItemAuthoringStepManager.java | 142 +++++++++ .../org/librecms/CmsResources.properties | 4 + .../org/librecms/CmsResources_de.properties | 4 + .../org/librecms/CmsResources_fr.properties | 4 + 12 files changed, 593 insertions(+), 225 deletions(-) create mode 100644 ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/assets/ImageStep.java create mode 100644 ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/assets/RelatedInfoStep.java create mode 100644 ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStep.java create mode 100644 ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStepInfo.java create mode 100644 ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStepManager.java diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitWizard.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitWizard.java index cc61c4a46..723781edb 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitWizard.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringKitWizard.java @@ -20,7 +20,6 @@ package com.arsdigita.cms.ui.authoring; import com.arsdigita.bebop.Component; import com.arsdigita.bebop.ControlLink; -import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.GridPanel; import com.arsdigita.bebop.List; import com.arsdigita.bebop.Page; @@ -32,8 +31,6 @@ import com.arsdigita.bebop.event.ActionEvent; import com.arsdigita.bebop.event.ActionListener; import com.arsdigita.bebop.event.ChangeEvent; import com.arsdigita.bebop.event.ChangeListener; -import com.arsdigita.bebop.event.FormProcessListener; -import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.list.ListCellRenderer; import com.arsdigita.bebop.parameters.StringParameter; @@ -61,8 +58,6 @@ import org.apache.logging.log4j.Logger; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Iterator; -import java.util.ArrayList; -import java.util.Collections; import java.util.Objects; import java.util.ResourceBundle; @@ -77,6 +72,8 @@ import org.librecms.contenttypes.AuthoringKit; import org.librecms.contenttypes.AuthoringKitInfo; import org.librecms.contenttypes.AuthoringStepInfo; import org.librecms.contenttypes.ContentTypeInfo; +import org.librecms.ui.authoring.ContentItemAuthoringStepInfo; +import org.librecms.ui.authoring.ContentItemAuthoringStepManager; import org.librecms.workflow.CmsTaskType; /** @@ -104,19 +101,17 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { private static final Logger LOGGER = LogManager .getLogger(AuthoringKitWizard.class); -// public final String SELECTED_LANGUAGE = "selectedLanguage"; - private static Class[] arguments = new Class[]{ + private final static Class[] ARGUMENTS = new Class[]{ ItemSelectionModel.class, AuthoringKitWizard.class, StringParameter.class }; - private static Class[] userDefinedArgs = new Class[]{ + private static final Class[] USER_DEFINED_ARGS = new Class[]{ ItemSelectionModel.class, AuthoringKitWizard.class, ContentType.class }; - private static final java.util.List ASSETS - = new ArrayList(); + private final Object[] values; private final ContentTypeInfo typeInfo; private final AuthoringKitInfo kitInfo; @@ -129,7 +124,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { private final GridPanel leftPanel; private final ModalPanel bodyPanel; private final SimpleContainer stepsContainer; - private final TaskFinishForm m_taskFinishForm; + private final TaskFinishForm taskFinishForm; private final StringParameter selectedLanguageParam; @@ -188,7 +183,9 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { leftPanel.add(new AssignedTaskSection(workflowRequestLocal, assignedTaskTable)); - final Section stepSection = new Section(gz("cms.ui.authoring.steps")); + final Section stepSection = new Section( + new GlobalizedMessage("cms.ui.authoring.steps", + CmsConstants.CMS_BUNDLE)); leftPanel.add(stepSection); list = new List(); @@ -198,12 +195,12 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { list.setCellRenderer(new ListCellRenderer() { @Override - public Component getComponent(List list, - PageState state, - Object value, - String key, - int index, - boolean isSelected) { + public Component getComponent(final List list, + final PageState state, + final Object value, + final String key, + final int index, + final boolean isSelected) { final Label label; if (value instanceof GlobalizedMessage) { label = new Label((GlobalizedMessage) value); @@ -251,14 +248,13 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { * The "label" and "description" are only here for backwards * compatibility */ - final ResourceBundle labelBundle = ResourceBundle.getBundle(step. - getLabelBundle()); - final ResourceBundle descBundle = ResourceBundle.getBundle(step. - getDescriptionBundle()); + final ResourceBundle labelBundle = ResourceBundle + .getBundle(step.getLabelBundle()); + final ResourceBundle descBundle = ResourceBundle + .getBundle(step.getDescriptionBundle()); final String labelKey = step.getLabelKey(); final String label = labelBundle.getString(labelKey); final String descriptionKey = step.getDescriptionKey(); - final String description = descBundle.getString(descriptionKey); final Class componentClass = step. getComponent(); @@ -269,25 +265,25 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { } panel = new StepComponent(compClassName); stepsContainer.add(panel); - final Component comp; + final Component component; if (compClassName.equals(SEC_PAGE_EDIT_DYN) || compClassName.equals(PAGE_EDIT_DYN)) { - comp = instantiateUserDefinedStep(compClassName, typeInfo); + component = instantiateUserDefinedStep(compClassName, typeInfo); } else { - comp = instantiateStep(compClassName); + component = instantiateStep(compClassName); } - panel.add(comp); - // XXX should be optional - if (comp instanceof AuthoringStepComponent) { - ((AuthoringStepComponent) comp).addCompletionListener( + panel.add(component); + if (component instanceof AuthoringStepComponent) { + ((AuthoringStepComponent) component).addCompletionListener( new StepCompletionListener()); } final GlobalizedMessage gzLabel; if (labelKey != null) { if (step.getLabelBundle() == null) { - gzLabel = gz(labelKey); + gzLabel = new GlobalizedMessage(labelKey, + CmsConstants.CMS_BUNDLE); } else { gzLabel = new GlobalizedMessage(labelKey, step.getLabelBundle()); @@ -302,9 +298,6 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { } } - final Class typeClass = typeInfo - .getContentItemClass(); - final java.util.List skipSteps = cmsConfig.getSkipAssetSteps(); if (LOGGER.isDebugEnabled()) { for (final String step : skipSteps) { @@ -312,60 +305,43 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { } } - for (final AssetStepEntry data : ASSETS) { + for (final ContentItemAuthoringStepInfo stepInfo + : getContentItemAuthoringSteps()) { - final Class baseObjectType; - try { - baseObjectType = Class.forName(data.getBaseDataObjectType()); - } catch (ClassNotFoundException ex) { - throw new UncheckedWrapperException(ex); + if (panel != null) { + panel.setNextStepKey(stepInfo.getStep()); } - //Class step = (Class) data[1]; - Class step = data.getStep(); - LOGGER.debug("possibly adding asset step " + step.getName()); - if (!skipSteps.contains(step.getName())) { - GlobalizedMessage label = data.getLabel(); - if (!typeClass.isAssignableFrom(baseObjectType)) { - continue; - } + panel = new StepComponent(stepInfo.getStep()); + stepsContainer.add(panel); - if (panel != null) { - panel.setNextStepKey(step); - } - panel = new StepComponent(step); - stepsContainer.add(panel); - - Component comp = instantiateStep(step.getName()); - if (comp instanceof AuthoringStepComponent) { - ((AuthoringStepComponent) comp).addCompletionListener( - new StepCompletionListener()); - } - panel.add(comp); - - labels.put(step, label); + final Component component = instantiateStep(stepInfo + .getStep().getName()); + if (component instanceof AuthoringStepComponent) { + ((AuthoringStepComponent) component) + .addCompletionListener(new StepCompletionListener()); } + panel.add(component); + + labels.put(stepInfo.getStep(), + new GlobalizedMessage(stepInfo.getLabelKey(), + stepInfo.getLabelBundle())); } list.addChangeListener(new StepListener()); - m_taskFinishForm = new TaskFinishForm(new TaskSelectionRequestLocal()); - bodyPanel.add(m_taskFinishForm); + taskFinishForm = new TaskFinishForm(new TaskSelectionRequestLocal()); + bodyPanel.add(taskFinishForm); - bodyPanel.connect(assignedTaskTable, 2, m_taskFinishForm); - bodyPanel.connect(m_taskFinishForm); + bodyPanel.connect(assignedTaskTable, 2, taskFinishForm); + bodyPanel.connect(taskFinishForm); - m_taskFinishForm.addProcessListener(new FormProcessListener() { - - @Override - public final void process(final FormSectionEvent event) - throws FormProcessException { - final PageState state = event.getPageState(); - - assignedTaskTable.getRowSelectionModel().clearSelection(state); - } - - }); + taskFinishForm + .addProcessListener( + event -> assignedTaskTable + .getRowSelectionModel() + .clearSelection(event.getPageState()) + ); } private final class StepListener implements ChangeListener { @@ -375,7 +351,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { final PageState state = event.getPageState(); final String key = list.getSelectedKey(state).toString(); - final Iterator iter = stepsContainer.children(); + final Iterator iter = stepsContainer.children(); while (iter.hasNext()) { final StepComponent step = (StepComponent) iter.next(); @@ -396,20 +372,22 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { private final class StepCompletionListener implements ActionListener { @Override + @SuppressWarnings("unchecked") public final void actionPerformed(final ActionEvent event) { final PageState state = event.getPageState(); if (ContentItemPage.isStreamlinedCreationActive(state)) { final String key = list.getSelectedKey(state).toString(); - final Iterator iter = stepsContainer.children(); + final Iterator iter = stepsContainer.children(); while (iter.hasNext()) { final StepComponent step = (StepComponent) iter.next(); if (step.getStepKey().toString().equals(key)) { Object nextStep = step.getNextStepKey(); if (nextStep != null) { - list.getSelectionModel().setSelectedKey( - state, nextStep.toString()); + list + .getSelectionModel() + .setSelectedKey(state, nextStep.toString()); } } } @@ -422,7 +400,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { public final void register(final Page page) { super.register(page); - final Iterator iter = stepsContainer.children(); + final Iterator iter = stepsContainer.children(); while (iter.hasNext()) { final StepComponent child = (StepComponent) iter.next(); @@ -439,8 +417,9 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { final PageState state = event.getPageState(); if (state.isVisibleOnPage(AuthoringKitWizard.this)) { - final SingleSelectionModel model = list. - getSelectionModel(); + @SuppressWarnings("unchecked") + final SingleSelectionModel model = list + .getSelectionModel(); if (!model.isSelected(state)) { model.setSelectedKey(state, defaultKey); @@ -451,122 +430,13 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { }); } - public static void registerAssetStep(final String baseObjectType, - final Class step, - final GlobalizedMessage label, - final GlobalizedMessage description, - final int sortKey) { - // cg - allow registered steps to be overridden by registering a step with the same label - // this is a bit of a hack used specifically for creating a specialised version of image - // step. There is no straightforward way of preventing the original image step from being - // registered, but I needed the image step to use a different step class if the specialised - // image step application was loaded. Solution is to ensure initialiser in new project - // runs after original ccm-ldn-image-step initializer and override the registered step here - LOGGER.debug("registering asset step - label: \"{}\"; " - + "step class: \"%s\"", - label.localize(), - step.getName()); + private java.util.List getContentItemAuthoringSteps() { - for (final AssetStepEntry data : ASSETS) { - - final String thisObjectType = data.getBaseDataObjectType(); - final GlobalizedMessage thisLabel = data.getLabel(); - - /** - * jensp 2011-11-14: The code above was only testing for the same - * label, but not for the same object type. I don't think that this - * was indented since this made it impossible to attach the same - * step to different object types. The orginal line was if - * (thisLabel.localize().equals(label.localize())) { - * - */ - if ((thisObjectType.equals(baseObjectType)) - && (thisLabel.localize().equals(label.localize()))) { - LOGGER.debug( - "registering authoring step with same label as previously registered step"); - ASSETS.remove(data); - break; - } - } - ASSETS.add( - new AssetStepEntry(baseObjectType, step, label, description, - sortKey)); - Collections.sort(ASSETS); - } - - private static class AssetStepEntry implements Comparable { - - private String baseDataObjectType; - private Class step; - private GlobalizedMessage label; - private GlobalizedMessage description; - private Integer sortKey; - - public AssetStepEntry() { - super(); - } - - public AssetStepEntry(final String baseDataObjectType, - final Class step, - final GlobalizedMessage label, - final GlobalizedMessage description, - final Integer sortKey) { - this.baseDataObjectType = baseDataObjectType; - this.step = step; - this.label = label; - this.description = description; - this.sortKey = sortKey; - } - - public String getBaseDataObjectType() { - return baseDataObjectType; - } - - public void setBaseDataObjectType(final String baseDataObjectType) { - this.baseDataObjectType = baseDataObjectType; - } - - public Class getStep() { - return step; - } - - public void setStep(final Class step) { - this.step = step; - } - - public GlobalizedMessage getLabel() { - return label; - } - - public void setLabel(final GlobalizedMessage label) { - this.label = label; - } - - public GlobalizedMessage getDescription() { - return description; - } - - public void setDescription(final GlobalizedMessage description) { - this.description = description; - } - - public Integer getSortKey() { - return sortKey; - } - - public void setSortKey(final Integer sortKey) { - this.sortKey = sortKey; - } - - @Override - public int compareTo(final AssetStepEntry other) { - if ((int) sortKey == (int) other.getSortKey()) { - return step.getName().compareTo(other.getStep().getName()); - } else { - return sortKey.compareTo(other.getSortKey()); - } - } + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ContentItemAuthoringStepManager manager = cdiUtil + .findBean(ContentItemAuthoringStepManager.class); + return manager.getContentItemAuthoringStepInfos(); } /** @@ -606,12 +476,12 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { LOGGER.debug("Instantiating kit wizard \"{}\" with arguments {}...", className, - arguments); + ARGUMENTS); try { // Get the creation component - final Class createClass = Class.forName(className); - final Constructor constr = createClass.getConstructor(arguments); + final Class createClass = Class.forName(className); + final Constructor constr = createClass.getConstructor(ARGUMENTS); final Component component = (Component) constr.newInstance(values); return component; @@ -645,12 +515,11 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { protected Component instantiateUserDefinedStep( final String className, final ContentTypeInfo originatingType) { - Object[] vals; try { // Get the creation component - final Class createClass = Class.forName(className); - final Constructor constr = createClass.getConstructor( - userDefinedArgs); + final Class createClass = Class.forName(className); + final Constructor constr = createClass.getConstructor( + USER_DEFINED_ARGS); final Object[] userDefinedVals = new Object[]{selectionModel, this, originatingType}; @@ -658,8 +527,10 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { userDefinedVals); return component; - } catch (ClassNotFoundException | NoSuchMethodException - | InstantiationException | IllegalAccessException + } catch (ClassNotFoundException + | NoSuchMethodException + | InstantiationException + | IllegalAccessException | InvocationTargetException ex) { throw new UncheckedWrapperException(ex); } @@ -710,12 +581,4 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable { } - 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/authoring/AuthoringStepComponent.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringStepComponent.java index bb75d953a..12e4ed642 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringStepComponent.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/AuthoringStepComponent.java @@ -25,7 +25,6 @@ import com.arsdigita.bebop.event.ActionListener; * currently an optional interface. * * @author Scott Seago (sseago@redhat.com) - * @version $Revision: #4 $ $DateTime: 2004/08/17 23:15:09 $ */ public interface AuthoringStepComponent { diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/assets/ImageStep.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/assets/ImageStep.java new file mode 100644 index 000000000..87479f3e6 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/assets/ImageStep.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.cms.ui.authoring.assets; + +import com.arsdigita.bebop.Text; +import com.arsdigita.bebop.parameters.StringParameter; +import com.arsdigita.cms.ItemSelectionModel; +import com.arsdigita.cms.ui.authoring.AuthoringKitWizard; +import com.arsdigita.cms.ui.authoring.ResettableContainer; + +import org.librecms.CmsConstants; +import org.librecms.ui.authoring.ContentItemAuthoringStep; + +/** + * + * @author Jens Pelzetter + */ +@ContentItemAuthoringStep( + labelBundle = CmsConstants.CMS_BUNDLE, + labelKey = "image_step.label", + descriptionBundle = CmsConstants.CMS_BUNDLE, + descriptionKey = "image_step.description") +public class ImageStep extends ResettableContainer { + + public ImageStep(final ItemSelectionModel itemSelectionModel, + final AuthoringKitWizard authoringKitWizard, + final StringParameter selectedLanguage) { + + super(); + + super.add(new Text("Image Step placeholder")); + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/assets/RelatedInfoStep.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/assets/RelatedInfoStep.java new file mode 100644 index 000000000..ec452c0fc --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/authoring/assets/RelatedInfoStep.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.cms.ui.authoring.assets; + +import com.arsdigita.bebop.Text; +import com.arsdigita.bebop.parameters.StringParameter; +import com.arsdigita.cms.ItemSelectionModel; +import com.arsdigita.cms.ui.authoring.AuthoringKitWizard; +import com.arsdigita.cms.ui.authoring.ResettableContainer; + +import org.librecms.CmsConstants; +import org.librecms.ui.authoring.ContentItemAuthoringStep; + +/** + * + * @author Jens Pelzetter + */ +@ContentItemAuthoringStep( + labelBundle = CmsConstants.CMS_BUNDLE, + labelKey = "related_info_step.label", + descriptionBundle = CmsConstants.CMS_BUNDLE, + descriptionKey = "related_info_step.description") +public class RelatedInfoStep extends ResettableContainer { + + public RelatedInfoStep(final ItemSelectionModel itemSelectionModel, + final AuthoringKitWizard authoringKitWizard, + final StringParameter selectedLanguage) { + + super(); + + super.add(new Text("Related Info Step placeholder")); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionConfig.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionConfig.java index dc3a22318..6666a6c76 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionConfig.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentSectionConfig.java @@ -38,12 +38,12 @@ public class ContentSectionConfig { /** * A list of workflow tasks, and the associated events for which alerts have - * to be sent. Parameter name TASK_ALERTS in the old initializer system / + * to be sent. Parameter name TASK_ALERTS in the old initialiser system / * enterprise.init Specifies when to generate email alerts: by default, * generate email alerts on enable, finish, and rollback (happens on * rejection) changes. There are four action types for each task type: * enable, disable, finish, and rollback. Example: (Note that the values - * below are based on the task labels, and as such are not globalized.) + * below are based on the task labels, and as such are not globalised.) *
      * taskAlerts = {
      *      { "Authoring",
@@ -58,12 +58,12 @@ public class ContentSectionConfig {
      *  };
      * 
* - * In the new Initializer system we use a specifically formatted String + * In the new Initialiser system we use a specifically formatted String * Array because we have no List parameter. Format: - A string for each task * to handle, possible values: Authoring, Approval, Deploy - Each Task * String: [taskName]:[alert_1]:...:[alert_n] The specially formatted string * is not handled by StringArray parameter, but forwarded untouched to the - * initializer which has the duty to process it! + * initialiser which has the duty to process it! * * Currently there is no way to persist taskAlerts section specific. So all * sections have to treated equally. Default values are provided here. @@ -78,7 +78,7 @@ public class ContentSectionConfig { /** * Should we send alerts about overdue tasks at all? Send alerts when a task * is overdue (has remained in the \"enabled\" state for a long time) - * Parameter SEND_OVERDUE_ALERTS in the old initializer system, default + * Parameter SEND_OVERDUE_ALERTS in the old initialiser system, default * false */ @Setting @@ -99,7 +99,7 @@ public class ContentSectionConfig { /** * The time to wait between sending successive alerts on the same overdue - * task (in HOURS). Parameter name OVERDUE_ALERT_INTERVAL in old initializer + * task (in HOURS). Parameter name OVERDUE_ALERT_INTERVAL in old initialiser * system Description: Time to wait between sending overdue notifications on * the same task (in hours) */ @@ -108,15 +108,24 @@ public class ContentSectionConfig { /** * The maximum number of alerts to send about any one overdue task. - * Parameter name MAX_ALERTS in old initializer system. Description: The + * Parameter name MAX_ALERTS in old initialiser system. Description: The * maximum number of alerts to send that a single task is overdue */ @Setting private int maxAlerts = 5; + /** + * Assets steps which are added which are present on all content items. + */ + @Setting + private List defaultAuthoringSteps = Arrays + .asList(new String[]{ + "com.arsdigita.cms.ui.authoring.assets.ImageStep", + "com.arsdigita.cms.ui.authoring.assets.RelatedInfoStep"}); + public static ContentSectionConfig getConfig() { final ConfigurationManager confManager = CdiUtil.createCdiUtil() - .findBean(ConfigurationManager.class); + .findBean(ConfigurationManager.class); return confManager.findConfiguration(ContentSectionConfig.class); } @@ -163,5 +172,13 @@ public class ContentSectionConfig { public void setMaxAlerts(final int maxAlerts) { this.maxAlerts = maxAlerts; } + + public List getDefaultAuthoringSteps() { + return new ArrayList<>(defaultAuthoringSteps); + } + + public void setDefaultAuthoringSteps(final List defaultAuthoringSteps) { + this.defaultAuthoringSteps = new ArrayList<>(defaultAuthoringSteps); + } } diff --git a/ccm-cms/src/main/java/org/librecms/contenttypes/AuthoringStepInfo.java b/ccm-cms/src/main/java/org/librecms/contenttypes/AuthoringStepInfo.java index 97bdbc850..6787c23fd 100644 --- a/ccm-cms/src/main/java/org/librecms/contenttypes/AuthoringStepInfo.java +++ b/ccm-cms/src/main/java/org/librecms/contenttypes/AuthoringStepInfo.java @@ -163,7 +163,7 @@ public class AuthoringStepInfo { public String toString(final String data) { return String.format("%s{ " - + "labelBundle = \"%s\"," + + "labelBundle = \"%s\", " + "labelKey = \"%s\", " + "descriptionBundle = \"%s\"," + "descriptionKey = \"%s\"," diff --git a/ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStep.java b/ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStep.java new file mode 100644 index 000000000..474209fec --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStep.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.ui.authoring; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Provides meta information about an authoring step which is independent from + * the type of the content item. + * + * @author Jens Pelzetter + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ContentItemAuthoringStep { + + /** + * Key of the label in the {@link #labelBundle()}. If blank (default) the + * simple name of the annotated class with the suffix {@code .label} is + * used. + * + * @return The label key of the authoring step. + */ + String labelKey() default ""; + + /** + * Bundle providing the localised label for the authoring step. If omitted + * the default bundle will be used. The default bundle is the fully + * qualified name of the authoring step class with the suffix + * {@code Bundle}. + * + * @return The bundle providing the label for the authoring step. + */ + String labelBundle() default ""; + + /** + * Key of the description in the {@link #descriptionBundle()}. If blank + * (default) the simple name of the annotated class with the suffix + * {@code .description} is used. + * + * @return The description key of the authoring step. + */ + String descriptionKey() default ""; + + /** + * Bundle providing the localised description for the authoring step. If + * omitted the default bundle will be used. The default bundle is the fully + * qualified name of the authoring step class with the suffix + * {@code Bundle}. + * + * @return The bundle providing the description for the authoring step. + */ + String descriptionBundle() default ""; + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStepInfo.java b/ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStepInfo.java new file mode 100644 index 000000000..1c090ed54 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStepInfo.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.ui.authoring; + +import com.arsdigita.bebop.Component; + +import java.util.Objects; + +/** + * Information about a authoring step which is independent from the type of the + * content item. + * + * @author Jens Pelzetter + */ +public class ContentItemAuthoringStepInfo { + + private Class step; + + /** + * The bundle which provides the label for the authoring step. + */ + private String labelBundle; + /** + * The key of label for the authoring step in the {@link #labelBundle} + */ + private String labelKey; + /** + * The bundle which provides the description for the authoring step. + */ + private String descriptionBundle; + /** + * The key of the description for the authoring step in the + * {@link #descriptionBundle}. + */ + private String descriptionKey; + + public Class getStep() { + return step; + } + + public void setStep(Class step) { + this.step = step; + } + + public String getLabelBundle() { + return labelBundle; + } + + public void setLabelBundle(String labelBundle) { + this.labelBundle = labelBundle; + } + + public String getLabelKey() { + return labelKey; + } + + public void setLabelKey(String labelKey) { + this.labelKey = labelKey; + } + + public String getDescriptionBundle() { + return descriptionBundle; + } + + public void setDescriptionBundle(String descriptionBundle) { + this.descriptionBundle = descriptionBundle; + } + + public String getDescriptionKey() { + return descriptionKey; + } + + public void setDescriptionKey(String descriptionKey) { + this.descriptionKey = descriptionKey; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 53 * hash + Objects.hashCode(step); + hash = 53 * hash + Objects.hashCode(labelBundle); + hash = 53 * hash + Objects.hashCode(labelKey); + hash = 53 * hash + Objects.hashCode(descriptionBundle); + hash = 53 * hash + Objects.hashCode(descriptionKey); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof ContentItemAuthoringStepInfo)) { + return false; + } + final ContentItemAuthoringStepInfo other + = (ContentItemAuthoringStepInfo) obj; + if (!other.canEqual(this)) { + return false; + } + + if (!Objects.equals(labelBundle, other.getLabelBundle())) { + return false; + } + if (!Objects.equals(labelKey, other.getLabelKey())) { + return false; + } + if (!Objects.equals(descriptionBundle, other.getDescriptionBundle())) { + return false; + } + if (!Objects.equals(descriptionKey, other.getDescriptionKey())) { + return false; + } + return Objects.equals(step, other.getStep()); + } + + public boolean canEqual(final Object obj) { + return obj instanceof ContentItemAuthoringStep; + } + + @Override + public final String toString() { + return toString(""); + } + + public String toString(final String data) { + return String.format("%s{ " + + "labelBundle = \"%s\", " + + "labelKey = \"%s\", " + + "descriptionBundle = \"%s\", " + + "descriptionKey = \"%s\"," + + "step = \"%s\"%s }", + super.toString(), + labelBundle, + labelKey, + descriptionBundle, + descriptionKey, + Objects.toString(step), + data); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStepManager.java b/ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStepManager.java new file mode 100644 index 000000000..d92a4e109 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/authoring/ContentItemAuthoringStepManager.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.librecms.ui.authoring; + +import com.arsdigita.bebop.Component; + +import org.libreccm.configuration.ConfigurationManager; +import org.libreccm.core.UnexpectedErrorException; +import org.librecms.contentsection.ContentSectionConfig; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; + +/** + * Provides easy access to information about the default authoring step which + * are available for every content type. + * + * @author Jens Pelzetter + */ +@RequestScoped +public class ContentItemAuthoringStepManager { + + @Inject + private ConfigurationManager confManager; + + private List stepInfos; + + @PostConstruct + protected void initialize() { + + final ContentSectionConfig config = confManager + .findConfiguration(ContentSectionConfig.class); + final List classNames = config.getDefaultAuthoringSteps(); + + stepInfos = classNames + .stream() + .map(className -> createStepInfo(className)) + .collect(Collectors.toList()); + } + + public List getContentItemAuthoringStepInfos() { + + return Collections.unmodifiableList(stepInfos); + } + + @SuppressWarnings("unchecked") + private ContentItemAuthoringStepInfo createStepInfo(final String className) { + + Objects.requireNonNull(className); + + if (className.isEmpty()) { + throw new IllegalArgumentException("The name of the authoring step " + + "class can't be empty."); + } + + final Class clazz; + try { + clazz = (Class) Class.forName(className); + } catch (ClassNotFoundException ex) { + throw new UnexpectedErrorException(String + .format("No class for class name \"%s\" available.", + className), + ex); + } + + return createStepInfo(clazz); + } + + private ContentItemAuthoringStepInfo createStepInfo( + final Class clazz) { + + final ContentItemAuthoringStepInfo stepInfo + = new ContentItemAuthoringStepInfo(); + + final ContentItemAuthoringStep step = clazz + .getAnnotation(ContentItemAuthoringStep.class); + + final String defaultBundleName = String + .join("", clazz.getName(), "Bundle"); + final String defaultLabelKey = String.join(".", + clazz.getSimpleName(), + "label"); + final String defaultDescKey = String.join(".", + clazz.getSimpleName(), + "description"); + + if (step == null) { + stepInfo.setLabelBundle(defaultBundleName); + stepInfo.setDescriptionBundle(defaultBundleName); + stepInfo.setLabelKey(defaultLabelKey); + stepInfo.setDescriptionKey(defaultDescKey); + } else { + if (step.labelBundle() == null || step.labelBundle().isEmpty()) { + stepInfo.setLabelBundle(defaultBundleName); + } else { + stepInfo.setLabelBundle(step.labelBundle()); + } + if (step.labelKey() == null || step.labelKey().isEmpty()) { + stepInfo.setLabelKey(defaultLabelKey); + } else { + stepInfo.setLabelKey(step.labelKey()); + } + if (step.descriptionBundle() == null + || step.descriptionBundle().isEmpty()) { + stepInfo.setDescriptionBundle(defaultBundleName); + } else { + stepInfo.setDescriptionBundle(step.descriptionBundle()); + } + if (step.descriptionKey() == null + || step.descriptionKey().isEmpty()) { + stepInfo.setDescriptionKey(defaultDescKey); + } + } + + stepInfo.setStep(clazz); + + return stepInfo; + } + +} diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties index 39495f1ba..90b30178c 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties @@ -379,3 +379,7 @@ cms.contenttypes.ui.mparticle.no_launch_date=Launch date is required cms.contenttypes.ui.mparticle.an_item_with_name_already_exists=An item with this name already exists cms.contenttypes.ui.mparticle.section_table.header_page_break=Page break audio_asset.label=Audio +image_step.label=Images +related_info_step.label=Related information +image_step.description=Attach images +related_info_step_description=Add related information diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties index 62b3b799a..50ba2452e 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties @@ -376,3 +376,7 @@ cms.contenttypes.ui.mparticle.no_launch_date=Es wurde kein Ver\u00f6ffentlichung cms.contenttypes.ui.mparticle.an_item_with_name_already_exists=Ein Dokument mit diesem Namen existiert bereits. cms.contenttypes.ui.mparticle.section_table.header_page_break=Seitenumbruch audio_asset.label=Audio +image_step.label=Bilder +related_info_step.label=Weiterf\u00fchrende Informationen +image_step.description=Bilder hinzuf\u00fcgen +related_info_step_description=Weiterf\u00fchrende Informationen hinzuf\u00fcgen diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties index 508be5c3f..027202cc4 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties @@ -335,3 +335,7 @@ cms.contenttypes.ui.mparticle.no_launch_date=Launch date is required cms.contenttypes.ui.mparticle.an_item_with_name_already_exists=An item with this name already exists cms.contenttypes.ui.mparticle.section_table.header_page_break=Page break audio_asset.label=Audio +image_step.label=Images +related_info_step.label=Related information +image_step.description=Attach images +related_info_step_description=Add related information