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-94f89814c4dfccm-docs
parent
47633c259d
commit
245ce9bb5d
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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.*;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -53,7 +66,7 @@ public class MultiPartArticleSection implements Serializable {
|
|||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@Column(name = "SECTION_ID")
|
||||
private long sectionId;
|
||||
|
||||
|
||||
@Embedded
|
||||
@AssociationOverride(
|
||||
name = "values",
|
||||
|
|
@ -83,11 +96,11 @@ public class MultiPartArticleSection implements Serializable {
|
|||
public long getSectionId() {
|
||||
return sectionId;
|
||||
}
|
||||
|
||||
|
||||
protected void setSectionId(final long sectionId) {
|
||||
this.sectionId = sectionId;
|
||||
}
|
||||
|
||||
|
||||
public LocalizedString getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
|
@ -121,7 +134,6 @@ public class MultiPartArticleSection implements Serializable {
|
|||
}
|
||||
|
||||
//ToDo: Add image property
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue