CCM NG/ccm-cms: Next part of porting the editing step for managing the sections of a MulitPartArticle

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4866 8810af33-2d31-482b-a856-94f89814c4df
jensp 2017-07-12 16:00:09 +00:00
parent 713a2e82ce
commit 671c6dab9d
8 changed files with 726 additions and 335 deletions

View File

@ -24,8 +24,11 @@ import org.librecms.contenttypes.MultiPartArticleSection;
import org.librecms.contenttypes.MultiPartArticleSectionManager; import org.librecms.contenttypes.MultiPartArticleSectionManager;
import org.librecms.contenttypes.MultiPartArticleSectionRepository; import org.librecms.contenttypes.MultiPartArticleSectionRepository;
import java.util.List;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.inject.Inject; import javax.inject.Inject;
import javax.transaction.Transactional;
/** /**
* *
@ -43,6 +46,21 @@ public class MultiPartArticleSectionStepController {
@Inject @Inject
private MultiPartArticleSectionManager sectionManager; private MultiPartArticleSectionManager sectionManager;
@Transactional(Transactional.TxType.REQUIRED)
public List<MultiPartArticleSection> retrieveSections(
final MultiPartArticle forArticle) {
final MultiPartArticle article = itemRepo
.findById(forArticle.getObjectId(),
MultiPartArticle.class)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No MultiPartArticle with ID %d in the database.",
forArticle.getObjectId())));
return article.getSections();
}
@Transactional(Transactional.TxType.REQUIRED)
public void moveToFirst(final MultiPartArticle article, public void moveToFirst(final MultiPartArticle article,
final MultiPartArticleSection section) { final MultiPartArticleSection section) {

View File

@ -21,23 +21,35 @@ package com.arsdigita.cms.contenttypes.ui.mparticle;
import com.arsdigita.bebop.ActionLink; import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.ColumnPanel; import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Container; import com.arsdigita.bebop.Container;
import com.arsdigita.bebop.DefaultSingleSelectionModel;
import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SingleSelectionModel; import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.parameters.LongParameter; import com.arsdigita.bebop.parameters.LongParameter;
import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.cms.contenttypes.ui.ResettableContainer; import com.arsdigita.cms.contenttypes.ui.ResettableContainer;
import com.arsdigita.cms.ui.GlobalNavigation; import com.arsdigita.cms.dispatcher.Utilities;
import com.arsdigita.cms.ui.authoring.AuthoringKitWizard; import com.arsdigita.cms.ui.authoring.AuthoringKitWizard;
import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.security.PermissionChecker;
import org.librecms.CmsConstants; import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.privileges.ItemPrivileges;
import org.librecms.contenttypes.MultiPartArticle; import org.librecms.contenttypes.MultiPartArticle;
import org.librecms.contenttypes.MultiPartArticleSection; import org.librecms.contenttypes.MultiPartArticleSection;
import org.librecms.contenttypes.MultiPartArticleSectionManager;
import java.util.Locale;
/** /**
* Authoring kit step to manage the sections of a MultiPartArticle. Process is * Authoring kit step to manage the sections of a MultiPartArticle. Process is
@ -126,8 +138,11 @@ public class MultiPartArticleSectionsStep extends ResettableContainer {
sectionTable.setClassAttr(DATA_TABLE); sectionTable.setClassAttr(DATA_TABLE);
// selected section is based on the selection in the SectionTable // selected section is based on the selection in the SectionTable
selectedSectionModel = new SectionSelectionModel<>(sectionTable @SuppressWarnings("unchecked")
.getRowSelectionModel()); final SingleSelectionModel<Long> rowSelectionModel = sectionTable
.getRowSelectionModel();
selectedSectionModel = new SectionSelectionModel<>(
MultiPartArticleSection.class, rowSelectionModel);
sectionTable.setSectionModel(selectedSectionModel); sectionTable.setSectionModel(selectedSectionModel);
@ -161,5 +176,208 @@ public class MultiPartArticleSectionsStep extends ResettableContainer {
controller.moveToFirst(article, section); controller.moveToFirst(article, section);
}); });
moveSectionModel.addChangeListener(event -> {
final PageState state = event.getPageState();
if (moveSectionModel.getSelectedKey(state) == null) {
beginLink.setVisible(state, false);
moveSectionLabel.setVisible(state, false);
} else {
beginLink.setVisible(state, true);
moveSectionLabel.setVisible(state, true);
final String selectedLanguage = (String) state
.getValue(selectedLanguageParam);
final Locale selectedLocale;
if (selectedLanguage == null) {
selectedLocale = KernelConfig.getConfig().getDefaultLocale();
} else {
selectedLocale = new Locale(selectedLanguage);
}
final Object[] parameterObj = {
moveSectionModel
.getSelectedSection(state)
.getTitle()
.getValue(selectedLocale)
};
moveSectionLabel
.setLabel(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.move_section_name",
CmsConstants.CMS_BUNDLE,
parameterObj));
}
});
// handle clicks to preview or delete a Section
sectionTable.addTableActionListener(new TableActionListener() {
@Override
public void cellSelected(final TableActionEvent event) {
final PageState state = event.getPageState();
final TableColumn column = sectionTable
.getColumnModel()
.get(event.getColumn()
.intValue());
if (column.getModelIndex() == SectionTable.COL_INDEX_DELETE) {
onlyShowComponent(state, SECTION_DELETE + typeIdStr);
} else if (column.getModelIndex() == SectionTable.COL_INDEX_EDIT) {
onlyShowComponent(state, SECTION_EDIT + typeIdStr);
}
}
@Override
public void headSelected(final TableActionEvent event) {
//Nothing
}
});
panel.add(sectionTable);
panel.add(buildAddLink());
return panel;
}
/**
* Builds a container to hold a SectionEditForm and a link to return to the
* section list.
*
* @return
*/
protected Container buildSectionEdit() {
final ColumnPanel panel = new ColumnPanel(1);
panel.setKey(SECTION_EDIT + typeIdStr);
panel.setBorderColor("#FFFFFF");
panel.setPadColor("#FFFFFF");
// display an appropriate title
panel.add(new Label(event -> {
final PageState state = event.getPageState();
final Label target = (Label) event.getTarget();
if (selectedSectionModel.getSelectedKey(state) == null) {
target.setLabel(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.add_section",
CmsConstants.CMS_BUNDLE));
} else {
target.setLabel(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.edit_section",
CmsConstants.CMS_BUNDLE));
}
}));
sectionEditForm = new SectionEditForm(selectedArticleModel,
selectedSectionModel,
this,
selectedLanguageParam);
panel.add(sectionEditForm);
panel.add(buildViewAllLink());
panel.add(buildAddLink());
return panel;
}
/**
* Builds a container to hold the component to confirm deletion of a
* section.
*
* @return
*/
protected Container buildSectionDelete() {
final ColumnPanel panel = new ColumnPanel(1);
panel.setKey(SECTION_DELETE + typeIdStr);
panel.setBorderColor("#FFFFFF");
panel.setPadColor("#FFFFFF");
panel.add(new Label(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.delete_section",
CmsConstants.CMS_BUNDLE)));
sectionDeleteForm = new SectionDeleteForm(selectedArticleModel,
selectedSectionModel);
sectionDeleteForm.addSubmissionListener(event -> {
final PageState state = event.getPageState();
onlyShowComponent(state, SECTION_TABLE + typeIdStr);
});
panel.add(sectionDeleteForm);
panel.add(buildViewAllLink());
return panel;
}
/**
* Utility method to create a link to display the section list.
*
* @return
*/
protected ActionLink buildViewAllLink() {
final ActionLink viewAllLink = new ActionLink(
new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.view_all_sections",
CmsConstants.CMS_BUNDLE));
viewAllLink.setClassAttr(ACTION_LINK);
viewAllLink.addActionListener(event -> {
onlyShowComponent(event.getPageState(),
SECTION_TABLE + typeIdStr);
});
return viewAllLink;
}
/**
* Utility method to create a link to display the section list.
*
* @return
*/
protected ActionLink buildAddLink() {
final ActionLink addLink = new ActionLink(
new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.add_new_section",
CmsConstants.CMS_BUNDLE)) {
@Override
public boolean isVisible(final PageState state) {
final PermissionChecker permissionChecker = CdiUtil
.createCdiUtil()
.findBean(PermissionChecker.class);
final ContentItem item = selectedArticleModel
.getSelectedItem(state);
return super.isVisible(state)
&& permissionChecker.isPermitted(ItemPrivileges.EDIT,
item);
}
};
addLink.setClassAttr(ACTION_LINK);
addLink.addActionListener(event -> {
final PageState state = event.getPageState();
selectedSectionModel.clearSelection(state);
onlyShowComponent(state, SECTION_EDIT + typeIdStr);
});
return addLink;
}
@Override
public void register(final Page page) {
super.register(page);
page.addGlobalStateParam(moveSectionParam);
page.setVisibleDefault(beginLink, false);
page.setVisibleDefault(moveSectionLabel, false);
}
public String getTypeIDStr() {
return typeIdStr;
}
} }

View File

@ -18,7 +18,6 @@
*/ */
package com.arsdigita.cms.contenttypes.ui.mparticle; package com.arsdigita.cms.contenttypes.ui.mparticle;
import com.arsdigita.bebop.ColumnPanel; import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Form; import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.FormProcessException;
@ -35,7 +34,9 @@ import com.arsdigita.cms.contenttypes.MultiPartArticle;
import com.arsdigita.cms.contenttypes.util.MPArticleGlobalizationUtil; import com.arsdigita.cms.contenttypes.util.MPArticleGlobalizationUtil;
import com.arsdigita.cms.util.GlobalizationUtil; import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.util.Assert; import com.arsdigita.util.Assert;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.librecms.contenttypes.MultiPartArticleSection;
/** /**
* A form to confirm deletion of a single section of a MultiPartArticle. * A form to confirm deletion of a single section of a MultiPartArticle.
@ -44,24 +45,24 @@ import org.apache.log4j.Logger;
* @version $Id: SectionDeleteForm.java 287 2005-02-22 00:29:02Z sskracic $ * @version $Id: SectionDeleteForm.java 287 2005-02-22 00:29:02Z sskracic $
*/ */
public class SectionDeleteForm extends Form public class SectionDeleteForm extends Form
implements FormInitListener, FormSubmissionListener, FormProcessListener implements FormInitListener, FormSubmissionListener, FormProcessListener {
{
private final static Logger log = Logger.getLogger(SectionDeleteForm.class.getName()); private final static Logger log = Logger.getLogger(SectionDeleteForm.class
.getName());
protected ItemSelectionModel m_selArticle; protected ItemSelectionModel m_selArticle;
protected ItemSelectionModel m_selSection; protected ItemSelectionModel m_selSection;
protected SaveCancelSection m_saveCancelSection; protected SaveCancelSection m_saveCancelSection;
private Label m_sectionNameLabel; private Label m_sectionNameLabel;
/** /**
* *
* @param selArticle * @param selArticle
* @param selSection * @param selSection
*/ */
public SectionDeleteForm public SectionDeleteForm(
( ItemSelectionModel selArticle, final ItemSelectionModel selArticle,
ItemSelectionModel selSection) { final SectionSelectionModel<? extends MultiPartArticleSection> selSection) {
super("SectionDeleteForm", new ColumnPanel(2)); super("SectionDeleteForm", new ColumnPanel(2));
m_selArticle = selArticle; m_selArticle = selArticle;
m_selSection = selSection; m_selSection = selSection;
@ -98,7 +99,8 @@ public class SectionDeleteForm extends Form
public void init(FormSectionEvent event) throws FormProcessException { public void init(FormSectionEvent event) throws FormProcessException {
PageState state = event.getPageState(); PageState state = event.getPageState();
ArticleSection section = (ArticleSection)m_selSection.getSelectedObject(state); ArticleSection section = (ArticleSection) m_selSection
.getSelectedObject(state);
if (section == null) { if (section == null) {
log.error("No section selected"); log.error("No section selected");
@ -124,8 +126,10 @@ public class SectionDeleteForm extends Form
public void process(FormSectionEvent event) throws FormProcessException { public void process(FormSectionEvent event) throws FormProcessException {
PageState state = event.getPageState(); PageState state = event.getPageState();
MultiPartArticle article = (MultiPartArticle)m_selArticle.getSelectedObject(state); MultiPartArticle article = (MultiPartArticle) m_selArticle
ArticleSection section = (ArticleSection)m_selSection.getSelectedObject(state); .getSelectedObject(state);
ArticleSection section = (ArticleSection) m_selSection
.getSelectedObject(state);
Assert.exists(article, MultiPartArticle.class); Assert.exists(article, MultiPartArticle.class);
Assert.exists(section, ArticleSection.class); Assert.exists(section, ArticleSection.class);
@ -134,4 +138,5 @@ public class SectionDeleteForm extends Form
log.info("section " + m_selSection.getSelectedKey(state) + " delete"); log.info("section " + m_selSection.getSelectedKey(state) + " delete");
} }
} }

View File

@ -18,7 +18,6 @@
*/ */
package com.arsdigita.cms.contenttypes.ui.mparticle; package com.arsdigita.cms.contenttypes.ui.mparticle;
import com.arsdigita.bebop.ColumnPanel; import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Form; import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData; import com.arsdigita.bebop.FormData;
@ -36,6 +35,7 @@ import com.arsdigita.bebop.form.CheckboxGroup;
import com.arsdigita.bebop.form.Option; import com.arsdigita.bebop.form.Option;
import com.arsdigita.bebop.parameters.BigDecimalParameter; import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.parameters.NotNullValidationListener; import com.arsdigita.bebop.parameters.NotNullValidationListener;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.parameters.TrimmedStringParameter; import com.arsdigita.bebop.parameters.TrimmedStringParameter;
import com.arsdigita.cms.ReusableImageAsset; import com.arsdigita.cms.ReusableImageAsset;
import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.cms.ItemSelectionModel;
@ -46,11 +46,12 @@ import com.arsdigita.cms.ui.CMSDHTMLEditor;
import com.arsdigita.cms.contenttypes.util.MPArticleGlobalizationUtil; import com.arsdigita.cms.contenttypes.util.MPArticleGlobalizationUtil;
import com.arsdigita.domain.DataObjectNotFoundException; import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.util.UncheckedWrapperException; import com.arsdigita.util.UncheckedWrapperException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.librecms.contenttypes.MultiPartArticleSection;
import java.math.BigDecimal; import java.math.BigDecimal;
/** /**
* Form to edit an ArticleSection for a MultiPartArticle. * Form to edit an ArticleSection for a MultiPartArticle.
* *
@ -74,7 +75,6 @@ public class SectionEditForm extends Form {
private SaveCancelSection m_saveCancelSection; private SaveCancelSection m_saveCancelSection;
private ImageUploadSection m_imageUpload; private ImageUploadSection m_imageUpload;
public static final String TITLE = "title"; public static final String TITLE = "title";
public static final String TEXT = "text"; public static final String TEXT = "text";
public static final String IMAGE = "image"; public static final String IMAGE = "image";
@ -93,20 +93,24 @@ public class SectionEditForm extends Form {
ItemSelectionModel selSection) { ItemSelectionModel selSection) {
this(selArticle, selSection, null); this(selArticle, selSection, null);
} }
/** /**
* Constructor. * Constructor.
* *
* @param selArticle the current article * @param selArticle the current article
* @param selSection the current section * @param selSection the current section
* @param container container which this form is added to * @param sectionsStep container which this form is added to
*/ */
public SectionEditForm(ItemSelectionModel selArticle, public SectionEditForm(
ItemSelectionModel selSection, final ItemSelectionModel selArticle,
MultiPartArticleViewSections container) { final SectionSelectionModel<? extends MultiPartArticleSection> selSection,
final MultiPartArticleSectionsStep sectionsStep,
final StringParameter selectedLanguageParam) {
super("SectionEditForm", new ColumnPanel(2)); super("SectionEditForm", new ColumnPanel(2));
m_selArticle = selArticle; m_selArticle = selArticle;
m_selSection = selSection; m_selSection = selSection;
m_container = container; m_container = sectionsStep;
m_imageParam = new BigDecimalParameter(IMAGE_PARAM); m_imageParam = new BigDecimalParameter(IMAGE_PARAM);
m_selImage = new ItemSelectionModel(ReusableImageAsset.class.getName(), m_selImage = new ItemSelectionModel(ReusableImageAsset.class.getName(),
@ -171,8 +175,8 @@ public class SectionEditForm extends Form {
//add(new Label(MPArticleGlobalizationUtil //add(new Label(MPArticleGlobalizationUtil
// .globalize("cms.contenttypes.ui.mparticle.section.text")), // .globalize("cms.contenttypes.ui.mparticle.section.text")),
// ColumnPanel.LEFT | ColumnPanel.FULL_WIDTH); // ColumnPanel.LEFT | ColumnPanel.FULL_WIDTH);
CMSDHTMLEditor textWidget = CMSDHTMLEditor textWidget = new CMSDHTMLEditor(
new CMSDHTMLEditor(new TrimmedStringParameter(TEXT)); new TrimmedStringParameter(TEXT));
textWidget.setLabel(MPArticleGlobalizationUtil textWidget.setLabel(MPArticleGlobalizationUtil
.globalize("cms.contenttypes.ui.mparticle.section.text")); .globalize("cms.contenttypes.ui.mparticle.section.text"));
textWidget.setRows(40); textWidget.setRows(40);
@ -193,7 +197,8 @@ public class SectionEditForm extends Form {
CheckboxGroup pageBreak = new CheckboxGroup(PAGE_BREAK); CheckboxGroup pageBreak = new CheckboxGroup(PAGE_BREAK);
pageBreak.addOption(new Option("true", pageBreak.addOption(new Option("true",
new Label(MPArticleGlobalizationUtil new Label(MPArticleGlobalizationUtil
.globalize("cms.contenttypes.ui.mparticle.section.create_break")) )); .globalize(
"cms.contenttypes.ui.mparticle.section.create_break"))));
add(pageBreak); add(pageBreak);
} }
@ -202,6 +207,7 @@ public class SectionEditForm extends Form {
* *
* @param event * @param event
* @param article * @param article
*
* @return * @return
*/ */
protected ArticleSection createSection(FormSectionEvent event, protected ArticleSection createSection(FormSectionEvent event,
@ -230,11 +236,10 @@ public class SectionEditForm extends Form {
p.addGlobalStateParam(m_textParam); p.addGlobalStateParam(m_textParam);
} }
/** /**
* Initialize the form. If there is a selected section, ie. this * Initialize the form. If there is a selected section, ie. this is an
* is an 'edit' step rather than a 'create new' step, load the data * 'edit' step rather than a 'create new' step, load the data into the form
* into the form fields. * fields.
*/ */
private class SectionInitListener implements FormInitListener { private class SectionInitListener implements FormInitListener {
@ -246,7 +251,6 @@ public class SectionEditForm extends Form {
m_selImage.setSelectedObject(state, null); m_selImage.setSelectedObject(state, null);
m_selText.setSelectedObject(state, null); m_selText.setSelectedObject(state, null);
if (m_selSection.getSelectedKey(state) != null) { if (m_selSection.getSelectedKey(state) != null) {
BigDecimal id = new BigDecimal(m_selSection BigDecimal id = new BigDecimal(m_selSection
.getSelectedKey(state).toString()); .getSelectedKey(state).toString());
@ -280,12 +284,12 @@ public class SectionEditForm extends Form {
// initializing the image section // initializing the image section
m_imageUpload.initImageUpload(event); m_imageUpload.initImageUpload(event);
} }
} }
/** /**
* Called on form submission. Check to see if the user clicked the * Called on form submission. Check to see if the user clicked the cancel
* cancel button. If they did, don't continue with the form. * button. If they did, don't continue with the form.
*/ */
private class SectionSubmissionListener implements FormSubmissionListener { private class SectionSubmissionListener implements FormSubmissionListener {
@ -297,8 +301,8 @@ public class SectionEditForm extends Form {
if (m_saveCancelSection.getCancelButton() if (m_saveCancelSection.getCancelButton()
.isSelected(state) && m_container != null) { .isSelected(state) && m_container != null) {
m_container.onlyShowComponent( m_container.onlyShowComponent(
state, MultiPartArticleViewSections.SECTION_TABLE+ state, MultiPartArticleViewSections.SECTION_TABLE
m_container.getTypeIDStr()); + m_container.getTypeIDStr());
throw new FormProcessException( throw new FormProcessException(
"Submission cancelled", "Submission cancelled",
MPArticleGlobalizationUtil.globalize( MPArticleGlobalizationUtil.globalize(
@ -317,6 +321,7 @@ public class SectionEditForm extends Form {
} }
} }
} }
/** /**
@ -343,8 +348,8 @@ public class SectionEditForm extends Form {
} }
// get the selected section to update or create a new one // get the selected section to update or create a new one
ArticleSection section = (ArticleSection) ArticleSection section = (ArticleSection) m_selSection
m_selSection.getSelectedObject(state); .getSelectedObject(state);
if (section == null) { if (section == null) {
section = createSection(event, article); section = createSection(event, article);
article.addSection(section); article.addSection(section);
@ -354,9 +359,8 @@ public class SectionEditForm extends Form {
Object[] pageBreakVal = (Object[]) data.get(PAGE_BREAK); Object[] pageBreakVal = (Object[]) data.get(PAGE_BREAK);
boolean pageBreak; boolean pageBreak;
if (pageBreakVal == null || if (pageBreakVal == null || pageBreakVal.length == 0 || !"true"
pageBreakVal.length == 0 || .equals(pageBreakVal[0])) {
!"true".equals(pageBreakVal[0])) {
pageBreak = false; pageBreak = false;
} else { } else {
pageBreak = true; pageBreak = true;
@ -364,14 +368,13 @@ public class SectionEditForm extends Form {
section.setPageBreak(pageBreak); section.setPageBreak(pageBreak);
// get the image asset // get the image asset
ReusableImageAsset reusableImageAsset = ReusableImageAsset reusableImageAsset = m_imageUpload
m_imageUpload.processImageUpload(event); .processImageUpload(event);
if (reusableImageAsset != null) { if (reusableImageAsset != null) {
section.setImage(reusableImageAsset); section.setImage(reusableImageAsset);
m_selImage.setSelectedObject(state, reusableImageAsset); m_selImage.setSelectedObject(state, reusableImageAsset);
} }
// get the text asset // get the text asset
TextAsset textAsset = (TextAsset) m_selText.getSelectedObject(state); TextAsset textAsset = (TextAsset) m_selText.getSelectedObject(state);
if (textAsset == null) { if (textAsset == null) {
@ -390,10 +393,11 @@ public class SectionEditForm extends Form {
if (m_container != null) { if (m_container != null) {
m_container.onlyShowComponent( m_container.onlyShowComponent(
state, state,
MultiPartArticleViewSections.SECTION_TABLE+ MultiPartArticleViewSections.SECTION_TABLE + m_container
m_container.getTypeIDStr()); .getTypeIDStr());
}
} }
} }
} }
}

View File

@ -38,7 +38,7 @@ import org.librecms.contenttypes.MultiPartArticleSectionRepository;
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
class SectionSelectionModel<T extends MultiPartArticleSection> public class SectionSelectionModel<T extends MultiPartArticleSection>
implements SingleSelectionModel<Long> { implements SingleSelectionModel<Long> {
private final Class<T> clazz; private final Class<T> clazz;

View File

@ -31,268 +31,189 @@ import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableModel; import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder; import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.cms.CMS; import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ContentItem;
import org.librecms.contentsection.ContentItem;
import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.cms.SecurityManager; import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.cms.contenttypes.ArticleSection;
import com.arsdigita.cms.contenttypes.ArticleSectionCollection; import org.librecms.contenttypes.MultiPartArticleSection;
import com.arsdigita.cms.contenttypes.MultiPartArticle; import org.librecms.contenttypes.MultiPartArticle;
import com.arsdigita.cms.contenttypes.util.MPArticleGlobalizationUtil;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.persistence.OID;
import com.arsdigita.util.LockableImpl; import com.arsdigita.util.LockableImpl;
import org.apache.log4j.Logger; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.CmsConstants;
import org.librecms.contenttypes.MultiPartArticleSection;
import org.librecms.contenttypes.MultiPartArticleSectionRepository;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Objects;
/** /**
* A table that displays the sections for the currently * A table that displays the sections for the currently selected
* selected MultiPartArticle. * MultiPartArticle.
* *
* @author <a href="mailto:dturner@arsdigita.com">Dave Turner</a> * @author <a href="mailto:dturner@arsdigita.com">Dave Turner</a>
* @version $Id: SectionTable.java 2099 2010-04-17 15:35:14Z pboy $ * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
public class SectionTable extends Table { public class SectionTable extends Table {
private static final Logger s_log = Logger.getLogger(SectionTable.class); private static final Logger LOGGER = LogManager
// match columns by (symbolic) index, makes for easier reordering .getLogger(SectionTable.class);
public static final int COL_INDEX_TITLE = 0; // "Section";
public static final int COL_INDEX_EDIT = 1; // "Edit"; /**
public static final int COL_INDEX_MOVE = 2; // "Move"; * Index of the title column
public static final int COL_INDEX_DELETE = 3; // "Delete"; */
private ItemSelectionModel m_selArticle; public static final int COL_INDEX_TITLE = 0;
private ItemSelectionModel m_selSection; /**
private ItemSelectionModel m_moveSection; * Index of the edit column.
*/
public static final int COL_INDEX_EDIT = 1;
/**
* Index of the move column
*/
public static final int COL_INDEX_MOVE = 2;
/**
* Index of the delete column
*/
public static final int COL_INDEX_DELETE = 3;
private ItemSelectionModel selectedArticleModel;
private SectionSelectionModel<? extends MultiPartArticleSection> selectedSectionModel;
private SectionSelectionModel<? extends MultiPartArticleSection> moveSectionModel;
/** /**
* Constructor. Create an instance of this class. * Constructor. Create an instance of this class.
* *
* @param selArticle a selection model that returns the MultiPartArticle * @param selectedArticleModel a selection model that returns the
* which holds the sections to display. * MultiPartArticle which holds the sections to
* @param moveSection * display.
* @param moveSectionModel
*/ */
public SectionTable(ItemSelectionModel selArticle, public SectionTable(
ItemSelectionModel moveSection) { final ItemSelectionModel selectedArticleModel,
final SectionSelectionModel<? extends MultiPartArticleSection> moveSectionModel) {
super(); super();
m_selArticle = selArticle; this.selectedArticleModel = selectedArticleModel;
m_moveSection = moveSection; this.moveSectionModel = moveSectionModel;
TableColumnModel model = getColumnModel(); final TableColumnModel model = getColumnModel();
model.add(new TableColumn( model.add(new TableColumn(
COL_INDEX_TITLE, COL_INDEX_TITLE,
new Label(MPArticleGlobalizationUtil.globalize( new Label(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.section_table.header_section")))); "cms.contenttypes.ui.mparticle.section_table.header_section",
CmsConstants.CMS_BUNDLE))));
model.add(new TableColumn( model.add(new TableColumn(
COL_INDEX_EDIT, COL_INDEX_EDIT,
new Label(MPArticleGlobalizationUtil.globalize( new Label(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.section_table.header_edit")))); "cms.contenttypes.ui.mparticle.section_table.header_edit",
CmsConstants.CMS_BUNDLE))));
model.add(new TableColumn( model.add(new TableColumn(
COL_INDEX_MOVE, COL_INDEX_MOVE,
new Label(MPArticleGlobalizationUtil.globalize( new Label(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.section_table.header_move")))); "cms.contenttypes.ui.mparticle.section_table.header_move",
CmsConstants.CMS_BUNDLE))));
model.add(new TableColumn( model.add(new TableColumn(
COL_INDEX_DELETE, COL_INDEX_DELETE,
new Label(MPArticleGlobalizationUtil.globalize( new Label(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.section_table.header_delete")))); "cms.contenttypes.ui.mparticle.section_table.header_delete",
CmsConstants.CMS_BUNDLE))));
model.get(1).setCellRenderer(new SectionTableCellRenderer(true)); model.get(1).setCellRenderer(new SectionTableCellRenderer(true));
model.get(2).setCellRenderer(new SectionTableCellRenderer(true)); model.get(2).setCellRenderer(new SectionTableCellRenderer(true));
model.get(3).setCellRenderer(new SectionTableCellRenderer(true)); model.get(3).setCellRenderer(new SectionTableCellRenderer(true));
setModelBuilder(
setModelBuilder(new SectionTableModelBuilder(m_selArticle, m_moveSection)); new SectionTableModelBuilder(selectedArticleModel, moveSectionModel));
addTableActionListener(new TableActionListener() { addTableActionListener(new TableActionListener() {
@Override @Override
public void cellSelected(TableActionEvent event) { public void cellSelected(final TableActionEvent event) {
PageState state = event.getPageState();
TableColumn col = getColumnModel().get(event.getColumn() final PageState state = event.getPageState();
.intValue());
if (col.getModelIndex() == COL_INDEX_MOVE) { final TableColumn column = getColumnModel()
if (m_moveSection.getSelectedKey(state) == null) { .get(event.getColumn());
m_moveSection.setSelectedKey(state,
m_selSection if (column.getModelIndex() == COL_INDEX_MOVE) {
.getSelectedKey(state));
if (moveSectionModel.getSelectedKey(state) == null) {
moveSectionModel.setSelectedKey(
state,
selectedSectionModel.getSelectedKey(state));
} else { } else {
MultiPartArticle article = (MultiPartArticle) m_selArticle. final MultiPartArticle article
getSelectedObject(state); = (MultiPartArticle) selectedArticleModel
.getSelectedObject(state);
BigDecimal id = (BigDecimal) m_moveSection.getSelectedKey(state); final Long sectionId = moveSectionModel
ArticleSection sect = (ArticleSection) DomainObjectFactory.newInstance( .getSelectedKey(state);
new OID(ArticleSection.BASE_DATA_OBJECT_TYPE, id));
BigDecimal dest = final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
new BigDecimal((String) event.getRowKey()); final MultiPartArticleSectionRepository sectionRepo
ArticleSection destSect = (ArticleSection) DomainObjectFactory.newInstance( = cdiUtil
new OID(ArticleSection.BASE_DATA_OBJECT_TYPE, dest)); .findBean(
MultiPartArticleSectionRepository.class);
final MultiPartArticleSectionStepController controller
= cdiUtil
.findBean(
MultiPartArticleSectionStepController.class);
final MultiPartArticleSection section = sectionRepo
.findById(sectionId)
.orElseThrow(() -> new IllegalArgumentException(
String
.format(
"No MultiPartArticleSection with ID %d in "
+ "the database.",
sectionId)));
final Long destId = Long
.parseLong((String) event.getRowKey());
final MultiPartArticleSection destSection = sectionRepo
.findById(destId)
.orElseThrow(() -> new IllegalArgumentException(
String.format(
"No MultiPartArticleSection with ID %d in "
+ "the database.",
destId)));
// if sect is lower in rank than the dest // if sect is lower in rank than the dest
// then move below is default behavior // then move below is default behavior
int rank = destSect.getRank().intValue(); int rank = destSection.getRank();
if (sect.getRank().intValue() > rank) { if (section.getRank() > rank) {
// otherwise, add one to get "move below" // otherwise, add one to get "move below"
rank++; rank++;
} }
article.changeSectionRank(sect, rank); section.setRank(rank);
m_moveSection.setSelectedKey(state, null); sectionRepo.save(section);
moveSectionModel.setSelectedKey(state, null);
} }
} }
} }
@Override @Override
public void headSelected(TableActionEvent event) { public void headSelected(final TableActionEvent event) {
// do nothing // do nothing
} }
}); });
} }
public void setSectionModel(ItemSelectionModel selSection) { public void setSectionModel(
if (selSection == null) { final SectionSelectionModel<? extends MultiPartArticleSection> selectedSectionModel) {
s_log.warn("null item model");
} Objects.requireNonNull(selectedSectionModel);
m_selSection = selSection;
this.selectedSectionModel = selectedSectionModel;
} }
/**
* The model builder to generate a suitable model for the SectionTable
*/
protected class SectionTableModelBuilder extends LockableImpl
implements TableModelBuilder {
protected ItemSelectionModel m_selArticle;
protected ItemSelectionModel m_moveSection;
/**
* Private class constructor.
* @param selArticle
* @param moveSection
*/
public SectionTableModelBuilder(ItemSelectionModel selArticle,
ItemSelectionModel moveSection) {
m_selArticle = selArticle;
m_moveSection = moveSection;
}
/**
*
* @param table
* @param state
* @return
*/
@Override
public TableModel makeModel(Table table, PageState state) {
table.getRowSelectionModel().clearSelection(state);
MultiPartArticle article = (MultiPartArticle) m_selArticle
.getSelectedObject(state);
return new SectionTableModel(table, state, article, m_moveSection);
}
}
/**
* Internal class
*/
protected class SectionTableModel implements TableModel {
private TableColumnModel m_colModel;
private SectionTable m_table;
private PageState m_state;
private ArticleSectionCollection m_sections;
private ItemSelectionModel m_moveSection;
private ArticleSection m_section;
/** Constructor.
* @param table
* @param state
* @param article
* @param moveSection
*/
public SectionTableModel(Table table, PageState state,
MultiPartArticle article,
ItemSelectionModel moveSection) {
m_colModel = table.getColumnModel();
m_state = state;
m_sections = article.getSections();
m_table = (SectionTable) table;
m_moveSection = moveSection;
}
/** Return the number of columsn this TableModel has. */
@Override
public int getColumnCount() {
return m_colModel.size();
}
/** Move to the next row and return true if the model is now positioned
* on a valid row.
*/
@Override
public boolean nextRow() {
if (m_sections.next()) {
m_section = (ArticleSection) m_sections.getArticleSection();
return true;
}
return false;
}
/**
* Return the data element for the given column and the current row.
*/
@Override
public Object getElementAt(int columnIndex) {
if (m_colModel == null) {
return null;
}
// match columns by (symbolic) index, makes for easier reordering
if (columnIndex == COL_INDEX_TITLE) {
return m_section.getTitle();
} else if (columnIndex == COL_INDEX_EDIT) {
//return "edit";
return new Label(
MPArticleGlobalizationUtil.globalize(
"cms.contenttypes.ui.mparticle.section_table.link_edit"));
} else if (columnIndex == COL_INDEX_DELETE) {
// return "delete";
return new Label(
MPArticleGlobalizationUtil.globalize(
"cms.contenttypes.ui.mparticle.section_table.link_delete"));
} else if (columnIndex == COL_INDEX_MOVE) {
if (m_moveSection.getSelectedKey(m_state) == null) {
// return "move";
return new Label(
MPArticleGlobalizationUtil.globalize(
"cms.contenttypes.ui.mparticle.section_table.link_move"));
} else {
// return "move below here";
return new Label(
MPArticleGlobalizationUtil.globalize(
"cms.contenttypes.ui.mparticle.section_table.link_move_below"));
}
}
return null;
}
/**
* Return the key for the given column and the current row.
*/
@Override
public Object getKeyAt(int columnIndex) {
return m_section.getID();
}
}
/** /**
* *
@ -317,7 +238,9 @@ public class SectionTable extends Table {
Component ret; Component ret;
SecurityManager sm = CMS.getSecurityManager(state); SecurityManager sm = CMS.getSecurityManager(state);
ContentItem item = (ContentItem) m_selArticle.getSelectedObject(state); ContentItem item = (ContentItem) selectedArticleModel
.getSelectedObject(
state);
boolean active = m_active && sm.canAccess(state.getRequest(), boolean active = m_active && sm.canAccess(state.getRequest(),
SecurityManager.EDIT_ITEM, SecurityManager.EDIT_ITEM,
@ -347,4 +270,5 @@ public class SectionTable extends Table {
} }
} }
} }

View File

@ -0,0 +1,148 @@
/*
* 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.contenttypes.ui.mparticle;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.globalization.GlobalizedMessage;
import org.arsdigita.cms.CMSConfig;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.CmsConstants;
import org.librecms.contenttypes.MultiPartArticle;
import org.librecms.contenttypes.MultiPartArticleSection;
import java.util.Iterator;
import java.util.List;
class SectionTableModel implements TableModel {
private final TableColumnModel columnModel;
private final SectionTable sectionTable;
private final PageState pageState;
private final SectionSelectionModel<? extends MultiPartArticleSection> moveSectionModel;
private final Iterator<MultiPartArticleSection> iterator;
private MultiPartArticleSection currentSection;
/**
* Constructor.
*
* @param sectionTable
* @param pageState
* @param article
* @param moveSectionModel
*/
public SectionTableModel(
final Table sectionTable,
final PageState pageState,
final MultiPartArticle article,
final SectionSelectionModel<? extends MultiPartArticleSection> moveSectionModel) {
this.pageState = pageState;
this.sectionTable = (SectionTable) sectionTable;
this.moveSectionModel = moveSectionModel;
columnModel = sectionTable.getColumnModel();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final MultiPartArticleSectionStepController controller = cdiUtil
.findBean(MultiPartArticleSectionStepController.class);
final List<MultiPartArticleSection> sections = controller
.retrieveSections(article);
iterator = sections.iterator();
}
/**
* Return the number of columns this TableModel has.
*/
@Override
public int getColumnCount() {
return columnModel.size();
}
/**
* Move to the next row and return true if the model is now positioned on a
* valid row.
*/
@Override
public boolean nextRow() {
if (iterator.hasNext()) {
currentSection = iterator.next();
return true;
} else {
return false;
}
}
/**
* Return the data element for the given column and the current row.
*/
@Override
public Object getElementAt(final int columnIndex) {
if (columnModel == null) {
return null;
}
// match columns by (symbolic) index, makes for easier reordering
switch (columnIndex) {
case SectionTable.COL_INDEX_TITLE:
return currentSection.getTitle();
case SectionTable.COL_INDEX_EDIT:
//return "edit";
return new Label(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.section_table.link_edit",
CmsConstants.CMS_BUNDLE));
case SectionTable.COL_INDEX_DELETE:
// return "delete";
return new Label(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.section_table.link_delete",
CmsConstants.CMS_BUNDLE));
case SectionTable.COL_INDEX_MOVE:
if (moveSectionModel.getSelectedKey(pageState) == null) {
// return "move";
return new Label(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.section_table.link_move",
CmsConstants.CMS_BUNDLE));
} else {
// return "move below here";
return new Label(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.section_table.link_move_below",
CmsConstants.CMS_BUNDLE));
}
default:
return null;
}
}
/**
* Return the key for the given column and the current row.
*/
@Override
public Object getKeyAt(final int columnIndex) {
return currentSection.getSectionId();
}
}

View File

@ -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 com.arsdigita.cms.contenttypes.ui.mparticle;
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.ItemSelectionModel;
import com.arsdigita.util.LockableImpl;
import org.librecms.contenttypes.MultiPartArticle;
import org.librecms.contenttypes.MultiPartArticleSection;
/**
* The model builder to generate a suitable model for the SectionTable
*/
class SectionTableModelBuilder extends LockableImpl implements TableModelBuilder {
private final ItemSelectionModel selectedArticleModel;
private final SectionSelectionModel<? extends MultiPartArticleSection> moveSectionModel;
/**
* Private class constructor.
*
* @param selectedArticleModel
* @param moveSectionModel
*/
public SectionTableModelBuilder(
final ItemSelectionModel selectedArticleModel,
final SectionSelectionModel<? extends MultiPartArticleSection> moveSectionModel) {
this.selectedArticleModel = selectedArticleModel;
this.moveSectionModel = moveSectionModel;
}
/**
*
* @param table
* @param state
*
* @return
*/
@Override
public TableModel makeModel(final Table table,
final PageState state) {
table.getRowSelectionModel().clearSelection(state);
MultiPartArticle article
= (MultiPartArticle) selectedArticleModel
.getSelectedObject(state);
return new SectionTableModel(table,
state,
article,
moveSectionModel);
}
}