CCM NG/ccm-cms: First part of authoring step for managing the sections of a multi part article

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4863 8810af33-2d31-482b-a856-94f89814c4df
jensp 2017-07-11 15:18:33 +00:00
parent 128c92fca2
commit 6a4c44305c
14 changed files with 1709 additions and 8 deletions

View File

@ -0,0 +1,209 @@
/*
* Copyright (C) 2002-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.contenttypes.ui;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Resettable;
import com.arsdigita.bebop.SimpleContainer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* A container which implements the {@link Resettable} interface and provides
* other useful methods.
*
* @author <a href="mailto:phong@arsdigita.com">Phong Nguyen</a>
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ResettableContainer extends SimpleContainer implements Resettable {
/**
* A list of all resettable components in this container
*/
private final List<Component> resettableComponents = new ArrayList<>();
/**
* A list of all components that are not visible by default
*/
private final List<Component> componentsNotVisibleByDefault
= new ArrayList<>();
/**
* Constructs a new, empty {@code RessetableContainer}.
*
*/
public ResettableContainer() {
super();
}
/**
* Constructs a new, empty {@code ResettableContainer}.
*
* @param key The key for this container.
*
*/
public ResettableContainer(final String key) {
super();
setKey(key);
}
/**
* Constructs a new, empty {@code RessetableContainer}. The container will
* wrap its children in the specified tag.
*
* @param tag The name of the XML element that will be used to wrap
* the children of this container.
* @param namespace The namespace for the tag.
*
*/
public ResettableContainer(final String tag, final String namespace) {
super(tag, namespace);
}
/**
* Adds a component to container.
*
* @param component The component to be added.
*
*/
@Override
public void add(final Component component) {
add(component, true);
}
/**
* Add a component to this container
*
* @param component The component to be added.
* @param constraints This parameter is ignored. Child classes should
* override the add method if they wish to provide
* special handling of constraints.
*
*/
@Override
public void add(final Component component, final int constraints) {
add(component);
}
/**
* Adds the component to this pane with the specified default visibility.
*
* @param component
* @param defaultVisibility The default visibility of this component
*
*
*/
public void add(final Component component,
final boolean defaultVisibility) {
super.add(component);
if (component instanceof Resettable) {
resettableComponents.add(component);
}
if (!defaultVisibility) {
componentsNotVisibleByDefault.add(component);
}
}
/**
* Sets the visibility of all child components to false, except for the
* component with the specified key.
*
* @param state The state of the current request.
* @param key The key of the component. There will be no visibility
* changes if key is null.
*
*/
public void onlyShowComponent(final PageState state,
final String key) {
if (key == null) {
return;
}
@SuppressWarnings("unchecked")
final Iterator<Component> iter = children();
Component child;
while (iter.hasNext()) {
child = iter.next();
child.setVisible(state, key.equals(child.getKey()));
}
}
/**
* Sets the visibility of all child components to false, except for the
* specified component.
*
* @param state The state of the current request.
* @param component The key of the component. There will be no visibility
* changes if {@code component} is null.
*
*/
public void onlyShowComponent(final PageState state,
final Component component) {
if (component == null) {
return;
}
@SuppressWarnings("unchecked")
final Iterator<Component> iter = children();
Component child;
while (iter.hasNext()) {
child = iter.next();
child.setVisible(state, child.equals(component));
}
}
/**
* Resets all resettable components added to this container.
*
* @param state The state of the current request.
*
*/
@Override
public void reset(final PageState state) {
// Reset all resettable components automatically
final Iterator<Component> iter = resettableComponents.iterator();
while (iter.hasNext()) {
((Resettable) iter.next()).reset(state);
}
}
/**
* Registers with page that this container belongs to and sets the default
* visibility of child components.
*
* @param page The page this container belongs to.
*
*/
@Override
public void register(final Page page) {
final Iterator<Component> iter = componentsNotVisibleByDefault
.iterator();
while (iter.hasNext()) {
page.setVisibleDefault(iter.next(), false);
}
}
}

View File

@ -0,0 +1,65 @@
/*
* 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 org.librecms.contentsection.ContentItemRepository;
import org.librecms.contenttypes.MultiPartArticle;
import org.librecms.contenttypes.MultiPartArticleSection;
import org.librecms.contenttypes.MultiPartArticleSectionManager;
import org.librecms.contenttypes.MultiPartArticleSectionRepository;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class MultiPartArticleSectionStepController {
@Inject
private ContentItemRepository itemRepo;
@Inject
private MultiPartArticleSectionRepository sectionRepo;
@Inject
private MultiPartArticleSectionManager sectionManager;
public void moveToFirst(final MultiPartArticle article,
final MultiPartArticleSection section) {
final MultiPartArticle theArticle = itemRepo
.findById(article.getObjectId(),
MultiPartArticle.class)
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No MultiPartArticle with ID %d in the database.",
article.getObjectId())));
final MultiPartArticleSection theSection = sectionRepo
.findById(section.getSectionId())
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No MultiPartArticleSection with ID %d in the database.",
section.getSectionId())));
sectionManager.moveToFirst(article, section);
}
}

View File

@ -0,0 +1,165 @@
/*
* 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.ActionLink;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Container;
import com.arsdigita.bebop.DefaultSingleSelectionModel;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.parameters.LongParameter;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.cms.contenttypes.ui.ResettableContainer;
import com.arsdigita.cms.ui.GlobalNavigation;
import com.arsdigita.cms.ui.authoring.AuthoringKitWizard;
import com.arsdigita.globalization.GlobalizedMessage;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.CmsConstants;
import org.librecms.contenttypes.MultiPartArticle;
import org.librecms.contenttypes.MultiPartArticleSection;
import org.librecms.contenttypes.MultiPartArticleSectionManager;
/**
* Authoring kit step to manage the sections of a MultiPartArticle. Process is
* implemented with three main components that manipulate the currently selected
* MultiPartArticle and sections. The visibility of these components is managed
* by this class.
*
* Note: This class was originally called {@code MultiPartArticleViewSections}.
* Starting with version 7.0.0 all authoring step classes should end with
* {@code Step} to make them easily identifiable.
*
* @author <a href="mailto:dturner@arsdigita.com">Dave Turner</a>
* * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class MultiPartArticleSectionsStep extends ResettableContainer {
/* id keys for each editing panel */
public static final String SECTION_TABLE = "sec_tbl";
public static final String SECTION_EDIT = "sec_edt";
public static final String SECTION_PREVIEW = "sec_prv";
public static final String SECTION_DELETE = "sec_del";
public static final String DATA_TABLE = "dataTable";
public static final String ACTION_LINK = "actionLink";
private final AuthoringKitWizard authoringKitWizard;
private final ItemSelectionModel selectedArticleModel;
private final StringParameter selectedLanguageParam;
private SectionSelectionModel<MultiPartArticleSection> selectedSectionModel;
private SectionSelectionModel<MultiPartArticleSection> moveSectionModel;
private LongParameter moveSectionParam;
private SectionTable sectionTable;
private SectionEditForm sectionEditForm;
private SectionPreviewPanel sectionPreviewPanel;
private SectionDeleteForm sectionDeleteForm;
private ActionLink beginLink;
private Label moveSectionLabel;
private final String typeIdStr;
public MultiPartArticleSectionsStep(
final ItemSelectionModel selectedArticleModel,
final AuthoringKitWizard authoringKitWizard,
final StringParameter selectedLanguageParam) {
super();
this.selectedArticleModel = selectedArticleModel;
this.authoringKitWizard = authoringKitWizard;
this.selectedLanguageParam = selectedLanguageParam;
typeIdStr = authoringKitWizard
.getContentType()
.getContentItemClass()
.getName();
addWidgets();
}
private void addWidgets() {
// create the components and set default visibility
add(buildSectionTable(), true);
add(buildSectionEdit(), false);
add(buildSectionDelete(), false);
}
/**
* Builds a {@link Container} to hold a {@link SectionTable} and a link to
* add a new {@link MultiPartArticleSection}.
*
* @return A {@link Container} for the table of sections.
*/
protected Container buildSectionTable() {
final ColumnPanel panel = new ColumnPanel(1);
panel.setKey(SECTION_TABLE + typeIdStr);
panel.setBorderColor("#FFFFFF");
panel.setPadColor("#FFFFFF");
moveSectionParam = new LongParameter("moveSection");
moveSectionModel = new SectionSelectionModel<>(moveSectionParam);
sectionTable = new SectionTable(selectedArticleModel,
moveSectionModel);
sectionTable.setClassAttr(DATA_TABLE);
// selected section is based on the selection in the SectionTable
selectedSectionModel = new SectionSelectionModel<>(sectionTable
.getRowSelectionModel());
sectionTable.setSectionModel(selectedSectionModel);
final Label emptyView = new Label(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.no_sections_yet",
CmsConstants.CMS_BUNDLE));
sectionTable.setEmptyView(this);
moveSectionLabel = new Label(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.section.title",
CmsConstants.CMS_BUNDLE));
panel.add(moveSectionLabel, ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
beginLink = new ActionLink(new GlobalizedMessage(
"cms.contenttypes.ui.mparticle.move_to_beginning",
CmsConstants.CMS_BUNDLE));
panel.add(beginLink);
beginLink.addActionListener(event -> {
final PageState state = event.getPageState();
final MultiPartArticle article
= (MultiPartArticle) selectedArticleModel
.getSelectedObject(state);
final MultiPartArticleSection section = moveSectionModel
.getSelectedSection(state);
final MultiPartArticleSectionStepController controller = CdiUtil
.createCdiUtil()
.findBean(MultiPartArticleSectionStepController.class);
controller.moveToFirst(article, section);
});
}

View File

@ -0,0 +1,137 @@
/*
* Copyright (C) 2002-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.contenttypes.ui.mparticle;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SaveCancelSection;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormSubmissionListener;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.cms.contenttypes.ArticleSection;
import com.arsdigita.cms.contenttypes.MultiPartArticle;
import com.arsdigita.cms.contenttypes.util.MPArticleGlobalizationUtil;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.util.Assert;
import org.apache.log4j.Logger;
/**
* A form to confirm deletion of a single section of a MultiPartArticle.
*
* @author <a href="mailto:dturner@arsdigita.com">Dave Turner</a>
* @version $Id: SectionDeleteForm.java 287 2005-02-22 00:29:02Z sskracic $
*/
public class SectionDeleteForm extends Form
implements FormInitListener, FormSubmissionListener, FormProcessListener
{
private final static Logger log = Logger.getLogger(SectionDeleteForm.class.getName());
protected ItemSelectionModel m_selArticle;
protected ItemSelectionModel m_selSection;
protected SaveCancelSection m_saveCancelSection;
private Label m_sectionNameLabel;
/**
*
* @param selArticle
* @param selSection
*/
public SectionDeleteForm
( ItemSelectionModel selArticle,
ItemSelectionModel selSection) {
super("SectionDeleteForm", new ColumnPanel(2));
m_selArticle = selArticle;
m_selSection = selSection;
ColumnPanel panel = (ColumnPanel)getPanel();
panel.setBorder(false);
panel.setPadColor("#FFFFFF");
panel.setColumnWidth(1, "20%");
panel.setColumnWidth(2, "80%");
panel.setWidth("100%");
m_sectionNameLabel = new Label ("Section Name");
add(m_sectionNameLabel, ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
addSaveCancelSection();
addInitListener(this);
addSubmissionListener(this);
addProcessListener(this);
}
/**
*
* @return
*/
protected SaveCancelSection addSaveCancelSection () {
m_saveCancelSection = new SaveCancelSection();
m_saveCancelSection.getSaveButton().setButtonLabel(
GlobalizationUtil.globalize("cms.ui.delete"));
add(m_saveCancelSection, ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
return m_saveCancelSection;
}
@Override
public void init ( FormSectionEvent event ) throws FormProcessException {
PageState state = event.getPageState();
ArticleSection section = (ArticleSection)m_selSection.getSelectedObject(state);
if ( section == null ) {
log.error("No section selected");
} else {
m_sectionNameLabel.setLabel(section.getTitle(),state);
}
}
@Override
public void submitted ( FormSectionEvent event ) throws FormProcessException {
PageState state = event.getPageState();
if ( m_saveCancelSection.getCancelButton().isSelected(state) ) {
throw new FormProcessException(
"Submission cancelled",
MPArticleGlobalizationUtil.globalize(
"cms.contenttypes.ui.mparticle.submission_cancelled")
);
}
}
@Override
public void process ( FormSectionEvent event ) throws FormProcessException {
PageState state = event.getPageState();
MultiPartArticle article = (MultiPartArticle)m_selArticle.getSelectedObject(state);
ArticleSection section = (ArticleSection)m_selSection.getSelectedObject(state);
Assert.exists(article, MultiPartArticle.class);
Assert.exists(section, ArticleSection.class);
article.removeSection(section);
log.info("section " + m_selSection.getSelectedKey(state) + " delete");
}
}

View File

@ -0,0 +1,399 @@
/*
* Copyright (C) 2002-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.contenttypes.ui.mparticle;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SaveCancelSection;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormSubmissionListener;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.form.CheckboxGroup;
import com.arsdigita.bebop.form.Option;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.parameters.NotNullValidationListener;
import com.arsdigita.bebop.parameters.TrimmedStringParameter;
import com.arsdigita.cms.ReusableImageAsset;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.cms.TextAsset;
import com.arsdigita.cms.contenttypes.ArticleSection;
import com.arsdigita.cms.contenttypes.MultiPartArticle;
import com.arsdigita.cms.ui.CMSDHTMLEditor;
import com.arsdigita.cms.contenttypes.util.MPArticleGlobalizationUtil;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.util.UncheckedWrapperException;
import org.apache.log4j.Logger;
import java.math.BigDecimal;
/**
* Form to edit an ArticleSection for a MultiPartArticle.
*
* @author <a href="mailto:dturner@arsdigita.com">Dave Turner</a>
* @version $Id: SectionEditForm.java 1423 2006-12-19 22:08:04Z apevec $
*/
public class SectionEditForm extends Form {
private final static Logger log = Logger.getLogger(SectionEditForm.class);
private ItemSelectionModel m_selArticle;
private ItemSelectionModel m_selSection;
private BigDecimalParameter m_imageParam;
private ItemSelectionModel m_selImage;
private BigDecimalParameter m_textParam;
private ItemSelectionModel m_selText;
private MultiPartArticleViewSections m_container;
private SaveCancelSection m_saveCancelSection;
private ImageUploadSection m_imageUpload;
public static final String TITLE = "title";
public static final String TEXT = "text";
public static final String IMAGE = "image";
public static final String PAGE_BREAK = "pageBreak";
private static final String TEXT_PARAM = "textParam";
private static final String IMAGE_PARAM = "imageParam";
/**
* Constructor.
*
* @param selArticle the current article
* @param selSection the current section
*/
public SectionEditForm(ItemSelectionModel selArticle,
ItemSelectionModel selSection) {
this(selArticle, selSection, null);
}
/**
* Constructor.
*
* @param selArticle the current article
* @param selSection the current section
* @param container container which this form is added to
*/
public SectionEditForm(ItemSelectionModel selArticle,
ItemSelectionModel selSection,
MultiPartArticleViewSections container) {
super("SectionEditForm", new ColumnPanel(2));
m_selArticle = selArticle;
m_selSection = selSection;
m_container = container;
m_imageParam = new BigDecimalParameter(IMAGE_PARAM);
m_selImage = new ItemSelectionModel(ReusableImageAsset.class.getName(),
ReusableImageAsset.BASE_DATA_OBJECT_TYPE,
m_imageParam);
m_textParam = new BigDecimalParameter(TEXT_PARAM);
m_selText = new ItemSelectionModel(TextAsset.class.getName(),
TextAsset.BASE_DATA_OBJECT_TYPE,
m_textParam);
setMethod(Form.POST);
setEncType("multipart/form-data");
ColumnPanel panel = (ColumnPanel)getPanel();
panel.setBorder(false);
panel.setPadColor("#FFFFFF");
panel.setColumnWidth(1, "20%");
panel.setColumnWidth(2, "80%");
panel.setWidth("100%");
addWidgets();
addSaveCancelSection();
addInitListener(new SectionInitListener());
addSubmissionListener(new SectionSubmissionListener());
addProcessListener(new SectionProcessListener());
}
/**
* Instantiate and add a save/cancel section to the form.
*
* @return the SaveCancelSection that was added
*/
protected SaveCancelSection addSaveCancelSection() {
m_saveCancelSection = new SaveCancelSection();
add(m_saveCancelSection, ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
return m_saveCancelSection;
}
/**
* Returns the save/cancel section from this form.
*/
public SaveCancelSection getSaveCancelSection() {
return m_saveCancelSection;
}
/**
* Add form widgets for a Section.
*/
protected void addWidgets() {
//add(new Label(MPArticleGlobalizationUtil
// .globalize("cms.contenttypes.ui.mparticle.section.title")));
TextField titleWidget = new TextField(
new TrimmedStringParameter(TITLE));
titleWidget.addValidationListener(new NotNullValidationListener());
titleWidget.setLabel(MPArticleGlobalizationUtil
.globalize("cms.contenttypes.ui.mparticle.section.title"));
add(titleWidget);
//add(new Label(MPArticleGlobalizationUtil
// .globalize("cms.contenttypes.ui.mparticle.section.text")),
// ColumnPanel.LEFT | ColumnPanel.FULL_WIDTH);
CMSDHTMLEditor textWidget =
new CMSDHTMLEditor(new TrimmedStringParameter(TEXT));
textWidget.setLabel(MPArticleGlobalizationUtil
.globalize("cms.contenttypes.ui.mparticle.section.text"));
textWidget.setRows(40);
textWidget.setCols(70);
textWidget.setWrap(CMSDHTMLEditor.SOFT);
add(textWidget,
ColumnPanel.LEFT | ColumnPanel.FULL_WIDTH);
//add(new Label(MPArticleGlobalizationUtil
// .globalize("cms.contenttypes.ui.mparticle.section.image")),
// ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
m_imageUpload = new ImageUploadSection("image", m_selImage);
m_imageUpload.setLabel(MPArticleGlobalizationUtil
.globalize("cms.contenttypes.ui.mparticle.section.image"));
add(m_imageUpload, ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
//add(new Label());
CheckboxGroup pageBreak = new CheckboxGroup(PAGE_BREAK);
pageBreak.addOption(new Option("true",
new Label(MPArticleGlobalizationUtil
.globalize("cms.contenttypes.ui.mparticle.section.create_break")) ));
add(pageBreak);
}
/**
* Utility method to create a Section from the form data supplied.
*
* @param event
* @param article
* @return
*/
protected ArticleSection createSection(FormSectionEvent event,
MultiPartArticle article) {
PageState state = event.getPageState();
FormData data = event.getFormData();
ArticleSection section = new ArticleSection();
section.setTitle((String)data.get(TITLE));
section.setName(article.getName() + ": " + (String)data.get(TITLE));
section.setContentSection(article.getContentSection());
return section;
}
/**
*
* @param p
*/
@Override
public void register(Page p) {
super.register(p);
p.addGlobalStateParam(m_imageParam);
p.addGlobalStateParam(m_textParam);
}
/**
* Initialize the form. If there is a selected section, ie. this
* is an 'edit' step rather than a 'create new' step, load the data
* into the form fields.
*/
private class SectionInitListener implements FormInitListener {
@Override
public void init( FormSectionEvent event )
throws FormProcessException {
PageState state = event.getPageState();
FormData data = event.getFormData();
m_selImage.setSelectedObject(state, null);
m_selText.setSelectedObject(state,null);
if ( m_selSection.getSelectedKey(state) != null ) {
BigDecimal id = new BigDecimal(m_selSection
.getSelectedKey(state).toString());
try {
// retrieve the selected Section from the persistence layer
ArticleSection section = new ArticleSection(id);
data.put(TITLE, section.getTitle());
TextAsset t = section.getText();
if ( t != null ) {
m_selText.setSelectedObject(state, t);
data.put(TEXT, t.getText());
}
ReusableImageAsset img = section.getImage();
if (img != null) {
m_selImage.setSelectedObject(state, img);
}
if (section.isPageBreak()) {
data.put(PAGE_BREAK, new Object[] { "true" });
}
} catch ( DataObjectNotFoundException ex ) {
log.error("Section(" + id + ") could not be found");
}
}
// Wait until the image selection model is updated before
// initializing the image section
m_imageUpload.initImageUpload(event);
}
}
/**
* Called on form submission. Check to see if the user clicked the
* cancel button. If they did, don't continue with the form.
*/
private class SectionSubmissionListener implements FormSubmissionListener {
@Override
public void submitted( FormSectionEvent event )
throws FormProcessException {
PageState state = event.getPageState();
if ( m_saveCancelSection.getCancelButton()
.isSelected(state) && m_container != null) {
m_container.onlyShowComponent(
state, MultiPartArticleViewSections.SECTION_TABLE+
m_container.getTypeIDStr());
throw new FormProcessException(
"Submission cancelled",
MPArticleGlobalizationUtil.globalize(
"cms.contenttypes.ui.mparticle.submission_cancelled")
);
} else if ( m_imageUpload.getDeleteImageButton().isSelected(state) ) {
BigDecimal id = new BigDecimal(m_selSection
.getSelectedKey(state).toString());
log.debug("deleting image for MPA section " + id);
try {
ArticleSection section = new ArticleSection(id);
section.setImage(null);
} catch ( DataObjectNotFoundException ex ) {
log.error("Section(" + id + ") could not be found");
}
}
}
}
/**
* Called after form has been validated. Create the new ArticleSection and
* assign it to the current MultiPartArticle.
*/
private class SectionProcessListener implements FormProcessListener {
@Override
public void process( FormSectionEvent event )
throws FormProcessException {
PageState state = event.getPageState();
FormData data = event.getFormData();
// retrieve the current MultiPartArticle
BigDecimal id = new BigDecimal(
m_selArticle.getSelectedKey(state).toString());
MultiPartArticle article = null;
try {
article = new MultiPartArticle(id);
} catch ( DataObjectNotFoundException ex ) {
throw new UncheckedWrapperException(ex);
}
// get the selected section to update or create a new one
ArticleSection section = (ArticleSection)
m_selSection.getSelectedObject(state);
if ( section == null ) {
section = createSection(event, article);
article.addSection(section);
}
section.setTitle((String)data.get(TITLE));
Object[] pageBreakVal = (Object[])data.get(PAGE_BREAK);
boolean pageBreak;
if (pageBreakVal == null ||
pageBreakVal.length == 0 ||
!"true".equals(pageBreakVal[0])) {
pageBreak = false;
} else {
pageBreak = true;
}
section.setPageBreak(pageBreak);
// get the image asset
ReusableImageAsset reusableImageAsset =
m_imageUpload.processImageUpload(event);
if ( reusableImageAsset != null ) {
section.setImage(reusableImageAsset);
m_selImage.setSelectedObject(state, reusableImageAsset);
}
// get the text asset
TextAsset textAsset = (TextAsset)m_selText.getSelectedObject(state);
if ( textAsset == null ) {
textAsset = new TextAsset();
textAsset.setName(section.getName() + " text");
m_selText.setSelectedObject(state, textAsset);
section.setText(textAsset);
}
String text = (String)data.get(TEXT);
if ( text == null ) {
text = "";
}
textAsset.setText(text);
if ( m_container != null) {
m_container.onlyShowComponent(
state,
MultiPartArticleViewSections.SECTION_TABLE+
m_container.getTypeIDStr());
}
}
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright (C) 2002-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.contenttypes.ui.mparticle;
import com.arsdigita.bebop.BoxPanel;
public class SectionPreviewPanel extends BoxPanel
{
}

View File

@ -0,0 +1,168 @@
/*
* 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.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.parameters.LongParameter;
import com.arsdigita.bebop.parameters.ParameterModel;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.UnexpectedErrorException;
import org.librecms.contenttypes.MultiPartArticleSection;
import org.librecms.contenttypes.MultiPartArticleSectionRepository;
/**
* A {@link SingleSelectionModel} implementation for
* {@link MultiPartArticleSection}s.
*
* @param <T>
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class SectionSelectionModel<T extends MultiPartArticleSection>
implements SingleSelectionModel<Long> {
private final Class<T> clazz;
private final SingleSelectionModel<Long> model;
public SectionSelectionModel(final LongParameter parameter) {
this(MultiPartArticleSection.class.getName(), parameter);
}
public SectionSelectionModel(final String parameterName) {
this(MultiPartArticleSection.class.getName(),
new LongParameter(parameterName));
}
public SectionSelectionModel(final Class<T> clazz,
final String parameterName) {
this(clazz, new LongParameter(parameterName));
}
@SuppressWarnings("unchecked")
public SectionSelectionModel(final String className,
final String parameterName) {
try {
clazz = (Class<T>) Class.forName(className);
} catch (ClassNotFoundException ex) {
throw new UnexpectedErrorException(ex);
}
model = new ParameterSingleSelectionModel<>(
new LongParameter(parameterName));
}
public SectionSelectionModel(final Class<T> clazz,
final LongParameter parameter) {
this(clazz, new ParameterSingleSelectionModel<>(parameter));
}
@SuppressWarnings("unchecked")
public SectionSelectionModel(final String className,
final LongParameter parameter) {
try {
clazz = (Class<T>) Class.forName(className);
} catch (ClassNotFoundException ex) {
throw new UnexpectedErrorException(ex);
}
model = new ParameterSingleSelectionModel<>(parameter);
}
public SectionSelectionModel(final Class<T> clazz,
final SingleSelectionModel<Long> model) {
this.clazz = clazz;
this.model = model;
}
@SuppressWarnings("unchecked")
public SectionSelectionModel(final String className,
final SingleSelectionModel<Long> model) {
try {
clazz = (Class<T>) Class.forName(className);
} catch (ClassNotFoundException ex) {
throw new UnexpectedErrorException(ex);
}
this.model = model;
}
@Override
public boolean isSelected(final PageState state) {
return model.isSelected(state);
}
@Override
public Long getSelectedKey(final PageState state) {
final Object key = model.getSelectedKey(state);
if (key == null) {
return null;
} else if (key instanceof Long) {
return (Long) key;
} else if (key instanceof String) {
return Long.parseLong((String) key);
} else {
return Long.parseLong(key.toString());
}
}
@Override
public void setSelectedKey(final PageState state, final Long key) {
model.setSelectedKey(state, key);
}
public T getSelectedSection(final PageState state) {
final Long key = getSelectedKey(state);
final MultiPartArticleSectionRepository sectionRepo = CdiUtil
.createCdiUtil()
.findBean(MultiPartArticleSectionRepository.class);
@SuppressWarnings("unchecked")
final T object = (T) sectionRepo.findById(key).get();
return object;
}
@Override
public void clearSelection(final PageState state) {
model.clearSelection(state);
}
@Override
public void addChangeListener(final ChangeListener changeListener) {
model.addChangeListener(changeListener);
}
@Override
public void removeChangeListener(final ChangeListener changeListener) {
model.removeChangeListener(changeListener);
}
@Override
public ParameterModel getStateParameter() {
return model.getStateParameter();
}
}

View File

@ -0,0 +1,350 @@
/*
* Copyright (C) 2002-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.contenttypes.ui.mparticle;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ControlLink;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.contenttypes.ArticleSection;
import com.arsdigita.cms.contenttypes.ArticleSectionCollection;
import com.arsdigita.cms.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 org.apache.log4j.Logger;
import java.math.BigDecimal;
/**
* A table that displays the sections for the currently
* selected MultiPartArticle.
*
* @author <a href="mailto:dturner@arsdigita.com">Dave Turner</a>
* @version $Id: SectionTable.java 2099 2010-04-17 15:35:14Z pboy $
*/
public class SectionTable extends Table {
private static final Logger s_log = Logger.getLogger(SectionTable.class);
// match columns by (symbolic) index, makes for easier reordering
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";
public static final int COL_INDEX_DELETE = 3; // "Delete";
private ItemSelectionModel m_selArticle;
private ItemSelectionModel m_selSection;
private ItemSelectionModel m_moveSection;
/**
* Constructor. Create an instance of this class.
*
* @param selArticle a selection model that returns the MultiPartArticle
* which holds the sections to display.
* @param moveSection
*/
public SectionTable(ItemSelectionModel selArticle,
ItemSelectionModel moveSection) {
super();
m_selArticle = selArticle;
m_moveSection = moveSection;
TableColumnModel model = getColumnModel();
model.add(new TableColumn(
COL_INDEX_TITLE,
new Label(MPArticleGlobalizationUtil.globalize(
"cms.contenttypes.ui.mparticle.section_table.header_section"))));
model.add(new TableColumn(
COL_INDEX_EDIT,
new Label(MPArticleGlobalizationUtil.globalize(
"cms.contenttypes.ui.mparticle.section_table.header_edit"))));
model.add(new TableColumn(
COL_INDEX_MOVE,
new Label(MPArticleGlobalizationUtil.globalize(
"cms.contenttypes.ui.mparticle.section_table.header_move"))));
model.add(new TableColumn(
COL_INDEX_DELETE,
new Label(MPArticleGlobalizationUtil.globalize(
"cms.contenttypes.ui.mparticle.section_table.header_delete"))));
model.get(1).setCellRenderer(new SectionTableCellRenderer(true));
model.get(2).setCellRenderer(new SectionTableCellRenderer(true));
model.get(3).setCellRenderer(new SectionTableCellRenderer(true));
setModelBuilder(new SectionTableModelBuilder(m_selArticle, m_moveSection));
addTableActionListener(new TableActionListener() {
@Override
public void cellSelected(TableActionEvent event) {
PageState state = event.getPageState();
TableColumn col = getColumnModel().get(event.getColumn()
.intValue());
if (col.getModelIndex() == COL_INDEX_MOVE) {
if (m_moveSection.getSelectedKey(state) == null) {
m_moveSection.setSelectedKey(state,
m_selSection
.getSelectedKey(state));
} else {
MultiPartArticle article = (MultiPartArticle) m_selArticle.
getSelectedObject(state);
BigDecimal id = (BigDecimal) m_moveSection.getSelectedKey(state);
ArticleSection sect = (ArticleSection) DomainObjectFactory.newInstance(
new OID(ArticleSection.BASE_DATA_OBJECT_TYPE, id));
BigDecimal dest =
new BigDecimal((String) event.getRowKey());
ArticleSection destSect = (ArticleSection) DomainObjectFactory.newInstance(
new OID(ArticleSection.BASE_DATA_OBJECT_TYPE, dest));
// if sect is lower in rank than the dest
// then move below is default behavior
int rank = destSect.getRank().intValue();
if (sect.getRank().intValue() > rank) {
// otherwise, add one to get "move below"
rank++;
}
article.changeSectionRank(sect, rank);
m_moveSection.setSelectedKey(state, null);
}
}
}
@Override
public void headSelected(TableActionEvent event) {
// do nothing
}
});
}
public void setSectionModel(ItemSelectionModel selSection) {
if (selSection == null) {
s_log.warn("null item model");
}
m_selSection = selSection;
}
/**
* 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();
}
}
/**
*
*/
public class SectionTableCellRenderer extends LockableImpl
implements TableCellRenderer {
private boolean m_active;
public SectionTableCellRenderer() {
this(false);
}
public SectionTableCellRenderer(boolean active) {
m_active = active;
}
@Override
public Component getComponent(Table table, PageState state,
Object value, boolean isSelected,
Object key, int row, int column) {
Component ret;
SecurityManager sm = CMS.getSecurityManager(state);
ContentItem item = (ContentItem) m_selArticle.getSelectedObject(state);
boolean active = m_active && sm.canAccess(state.getRequest(),
SecurityManager.EDIT_ITEM,
item);
if (value instanceof Label) {
if (active) {
ret = new ControlLink((Component) value);
} else {
ret = (Component) value;
}
} else if (value instanceof String) {
// Backwards compatibility, should be removed asap!
if (active) {
ret = new ControlLink(value.toString());
} else {
ret = new Label(value.toString());
}
} else {
ret = new Label(MPArticleGlobalizationUtil.globalize(
"cms.contenttypes.ui.mparticle.section_table.link_not_defined"),
false);
}
return ret;
}
}
}

View File

@ -37,6 +37,7 @@ import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import static org.librecms.CmsConstants.*;

View File

@ -33,6 +33,8 @@ import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import static org.librecms.CmsConstants.*;
@ -45,6 +47,17 @@ import static org.librecms.CmsConstants.*;
@Entity
@Audited
@Table(name = "MULTIPART_ARTICLE_SECTIONS", schema = DB_SCHEMA)
@NamedQueries({
@NamedQuery(
name = "MultiPartArticleSection.findById",
query = "SELECT s FROM MultiPartArticleSection s "
+ "WHERE s.sectionId = :sectionId")
,
@NamedQuery(
name = "MultiPartArticleSection.findArticleOfSection",
query = "SELECT a FROM MultiPartArticle a "
+ "WHERE :section MEMBER OF a.sections")
})
public class MultiPartArticleSection implements Serializable {
private static final long serialVersionUID = 1109186628988745920L;
@ -121,7 +134,6 @@ public class MultiPartArticleSection implements Serializable {
}
//ToDo: Add image property
@Override
public int hashCode() {
int hash = 5;

View File

@ -0,0 +1,89 @@
/*
* 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.contenttypes;
import org.librecms.contentsection.ContentItemRepository;
import java.util.List;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class MultiPartArticleSectionManager {
@Inject
private ContentItemRepository itemRepo;
@Inject
private MultiPartArticleSectionRepository sectionRepo;
@Transactional(Transactional.TxType.REQUIRED)
public void addSectionToMultiPartArticle(
final MultiPartArticleSection section,
final MultiPartArticle article) {
article.addSection(section);
itemRepo.save(article);
sectionRepo.save(section);
}
@Transactional(Transactional.TxType.REQUIRED)
public void removeSectionFromMultiPartArticle(
final MultiPartArticleSection section,
final MultiPartArticle article) {
article.removeSection(section);
itemRepo.save(article);
sectionRepo.delete(section);
}
@Transactional(Transactional.TxType.REQUIRED)
public void moveToFirst(final MultiPartArticle article,
final MultiPartArticleSection section) {
final List<MultiPartArticleSection> sections = article
.getSections()
.stream()
.sorted((section1, section2) -> Integer.compare(section1.getRank(),
section2.getRank()))
.collect(Collectors.toList());
final int oldRank = section.getRank();
section.setRank(1);
sections
.stream()
.filter(current -> !current.equals(section))
.forEach(current -> current.setRank(current.getRank() + 1));
sections
.forEach(current -> sectionRepo.save(section));
}
}

View File

@ -0,0 +1,81 @@
/*
* 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.contenttypes;
import org.libreccm.auditing.AbstractAuditedEntityRepository;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class MultiPartArticleSectionRepository
extends AbstractAuditedEntityRepository<Long, MultiPartArticleSection> {
@Override
public Long getEntityId(final MultiPartArticleSection entity) {
return entity.getSectionId();
}
@Override
public Class<MultiPartArticleSection> getEntityClass() {
return MultiPartArticleSection.class;
}
@Override
public boolean isNew(final MultiPartArticleSection entity) {
return entity.getSectionId() == 0;
}
@Transactional(Transactional.TxType.REQUIRED)
public Optional<MultiPartArticleSection> findById(
final long sectionId) {
final TypedQuery<MultiPartArticleSection> query = getEntityManager()
.createNamedQuery("MultiPartArticleSection.findById",
MultiPartArticleSection.class);
query.setParameter("sectionId", sectionId);
try {
return Optional.of(query.getSingleResult());
} catch (NoResultException ex) {
return Optional.empty();
}
}
@Transactional(Transactional.TxType.REQUIRED)
public MultiPartArticle findArticleOfSection(
final MultiPartArticleSection section) {
final TypedQuery<MultiPartArticle> query = getEntityManager()
.createNamedQuery("MultiPartArticleSection.findArticleOfSection",
MultiPartArticle.class);
query.setParameter("section", section);
return query.getSingleResult();
}
}

View File

@ -135,7 +135,8 @@ public class CcmObjectSelectionModel<T extends CcmObject>
@Override
public void clearSelection(final PageState state) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
model.clearSelection(state);
}
@Override
@ -145,7 +146,7 @@ public class CcmObjectSelectionModel<T extends CcmObject>
@Override
public void removeChangeListener(final ChangeListener changeListener) {
model.addChangeListener(changeListener);;
model.removeChangeListener(changeListener);;
}
@Override

View File

@ -31,8 +31,6 @@ import org.apache.shiro.subject.Subject;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.security.PermissionChecker;
import java.util.Locale;
import javax.inject.Inject;
/**