Removed depcrecated package com.arsdigita.cms.ui.folder from ccm-cms

pull/28/head
Jens Pelzetter 2022-03-17 20:24:04 +01:00
parent 282fbfe815
commit f0069cba93
33 changed files with 15 additions and 5556 deletions

View File

@ -18,39 +18,26 @@
*/
package com.arsdigita.cms.ui;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Link;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Resettable;
import com.arsdigita.bebop.SegmentedPanel;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.Text;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormSubmissionListener;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.tree.TreeCellRenderer;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ui.folder.FolderRequestLocal;
import com.arsdigita.cms.ui.folder.FolderSelectionModel;
import com.arsdigita.cms.ui.folder.FolderTreeModelBuilder;
import com.arsdigita.cms.ui.folder.FolderTreeModelController;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.toolbox.ui.LayoutPanel;
import com.arsdigita.util.Assert;
import org.libreccm.categorization.Category;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.CcmObject;
import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.ContentSectionManager;
import org.librecms.contentsection.Folder;
import org.librecms.dispatcher.ItemResolver;
import java.util.List;
@ -64,39 +51,11 @@ import java.util.List;
*/
public class BrowsePane extends LayoutPanel implements Resettable {
private final BaseTree tree;
private final SingleSelectionModel selectionModel;
private final FolderSelectionModel folderModel; // To support legacy UI code
private final FolderRequestLocal folderRequestLocal;
private final FlatItemList flatItemList;
private SingleSelectionModel selectionModel;
private FlatItemList flatItemList;
public BrowsePane() {
/* The folder tree displayed on the left side / left column */
tree = new BaseTree(new FolderTreeModelBuilder() {
@Override
protected Folder getRootFolder(final PageState state) {
final ContentSection section = CMS
.getContext()
.getContentSection();
return section.getRootDocumentsFolder();
}
});
selectionModel = tree.getSelectionModel();
folderModel = new FolderSelectionModel(selectionModel) {
@Override
protected Long getRootFolderID(final PageState state) {
final ContentSection section = CMS
.getContext()
.getContentSection();
return section.getRootDocumentsFolder().getObjectId();
}
};
folderRequestLocal = new FolderRequestLocal(folderModel);
final SegmentedPanel left = new SegmentedPanel();
setLeft(left);
@ -104,17 +63,6 @@ public class BrowsePane extends LayoutPanel implements Resettable {
final Label heading = new Label(
new GlobalizedMessage("cms.ui.folder_browser",
CmsConstants.CMS_BUNDLE));
left.addSegment(heading, tree);
flatItemList = new FlatItemList(folderRequestLocal, folderModel);
setBody(flatItemList);
flatItemList.getManipulator().getItemView().addProcessListener(
new ProcessListener());
flatItemList.getManipulator().getTargetSelector().addProcessListener(
new ProcessListener());
flatItemList.getManipulator().getTargetSelector().addSubmissionListener(
new SubmissionListener());
}
@Override
@ -142,13 +90,6 @@ public class BrowsePane extends LayoutPanel implements Resettable {
public final void process(final FormSectionEvent event) {
final PageState state = event.getPageState();
if (event.getSource() == flatItemList.getManipulator().getItemView()) {
// Hide everything except for the flat item list
tree.setVisible(state, false);
} else if (event.getSource() == flatItemList.getManipulator()
.getTargetSelector()) {
tree.setVisible(state, true);
}
}
}
@ -159,13 +100,7 @@ public class BrowsePane extends LayoutPanel implements Resettable {
public final void submitted(final FormSectionEvent event) {
final PageState state = event.getPageState();
if (event.getSource() == flatItemList.getManipulator()
.getTargetSelector()) {
if (!flatItemList.getManipulator().getTargetSelector()
.isVisible(state)) {
tree.setVisible(state, true);
}
}
}
}
@ -219,17 +154,6 @@ public class BrowsePane extends LayoutPanel implements Resettable {
.getContentSection()
.getRootDocumentsFolder();
if (!root.equals(folderRequestLocal.getFolder(state))) {
// Expand the ancestor nodes of the currently
// selected node.
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderTreeModelController controller = cdiUtil.findBean(
FolderTreeModelController.class);
final List<Long> ancestorIds = controller.findAncestorIds(
folderRequestLocal.getFolder(state));
ancestorIds.forEach(id -> tree.expand(id.toString(), state));
}
}
}

View File

@ -34,7 +34,6 @@ import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentSection;
import com.arsdigita.cms.dispatcher.CMSPage;
import com.arsdigita.cms.ui.folder.FolderAdminPane;
import com.arsdigita.cms.ui.workflow.WorkflowAdminPane;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.Assert;
@ -122,8 +121,6 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
private TabbedPane m_tabbedPane;
private FolderAdminPane m_folderPane;
private BrowsePane m_browsePane;
private ItemSearch m_searchPane;
@ -143,7 +140,6 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
add(new GlobalNavigation());
// Initialize the individual panes
m_folderPane = getFolderAdminPane();
m_browsePane = getBrowsePane();
m_searchPane = getSearchPane();
m_workflowPane = getWorkflowAdminPane();
@ -176,7 +172,6 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
m_workflowPane,
permissionChecker.isPermitted(
AdminPrivileges.ADMINISTER_WORKFLOWS));
}
}
@ -184,19 +179,6 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
});
}
/**
* Creates, and then caches, the browse pane. Overriding this method to
* return null will prevent this tab from appearing.
*
* @return
*/
protected FolderAdminPane getFolderAdminPane() {
if (m_folderPane == null) {
m_folderPane = new FolderAdminPane();
}
return m_folderPane;
}
/**
* Creates, and then caches, the browse pane. Overriding this method to
* return null will prevent this tab from appearing.
@ -237,8 +219,6 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
return m_workflowPane;
}
/**
* Adds the specified component, with the specified tab name, to the tabbed
* pane only if it is not null.
@ -319,13 +299,7 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
// } else if (pane == m_imagesPane) {
// m_imagesPane.reset(state);
// } else
if (pane == m_folderPane) {
m_folderPane.reset(state);
//ToDo NG } else if (pane == m_browsePane) {
// m_browsePane.reset(state);
// } else if (pane == m_rolePane) {
// m_rolePane.reset(state);
} else if (pane == m_workflowPane) {
if (pane == m_workflowPane) {
m_workflowPane.reset(state);
}
}

View File

@ -36,17 +36,8 @@ import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormSubmissionListener;
import com.arsdigita.bebop.parameters.LongParameter;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.CMS;
import org.librecms.contentsection.ContentSection;
import com.arsdigita.cms.ui.authoring.CreationSelector;
import com.arsdigita.cms.ui.folder.FolderCreateForm;
import com.arsdigita.cms.ui.folder.FolderEditorForm;
import com.arsdigita.cms.ui.folder.FolderManipulator;
import com.arsdigita.cms.ui.folder.FolderPath;
import com.arsdigita.cms.ui.folder.FolderRequestLocal;
import com.arsdigita.cms.ui.folder.FolderSelectionModel;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.toolbox.ui.ActionGroup;
@ -78,17 +69,9 @@ public class FlatItemList extends SegmentedPanel implements FormProcessListener,
private static final String CONTENT_TYPE_ID = "ct";
// The folder selectors
private final FolderSelectionModel folderSelectionModel;
private final FolderRequestLocal folderRequestLocal;
private final SingleSelectionModel<Long> typeSelectionModel;
private final CreationSelector creationSelector;
private final FolderManipulator folderManipulator;
private final FolderCreateForm folderCreator;
private CreationSelector creationSelector;
private final ActionLink createFolderAction;
@ -105,12 +88,8 @@ public class FlatItemList extends SegmentedPanel implements FormProcessListener,
// Folder edit/rename functionality.
private final ActionLink editFolderAction;
private final FolderEditorForm folderEditor;
private final Label contentLabel;
private final FolderPath folderPath;
private final Label chooseLabel;
private final StringParameter selectedLanguageParam;
@ -123,13 +102,8 @@ public class FlatItemList extends SegmentedPanel implements FormProcessListener,
* @param folderSelectionModel maintains the currently displayed folder.
*/
@SuppressWarnings("unchecked")
public FlatItemList(final FolderRequestLocal folderRequestLocal,
final FolderSelectionModel folderSelectionModel) {
this.folderRequestLocal = folderRequestLocal;
this.folderSelectionModel = folderSelectionModel;
folderSelectionModel.addChangeListener(event -> reset(event
.getPageState()));
public FlatItemList() {
setIdAttr("flat-item-list");
newItemSegment = addSegment();
@ -153,15 +127,7 @@ public class FlatItemList extends SegmentedPanel implements FormProcessListener,
chooseLabel = new Label(globalize("cms.ui.choose_target_folder"),
false);
browseSegment.addHeader(chooseLabel);
folderPath = new FolderPath(folderSelectionModel);
browseSegment.addHeader(folderPath);
folderManipulator = new FolderManipulator(folderSelectionModel);
folderManipulator.getItemView().addProcessListener(this);
folderManipulator.getTargetSelector().addProcessListener(this);
folderManipulator.getTargetSelector().addSubmissionListener(this);
browseActions.setSubject(folderManipulator);
createFolderAction = new ActionLink(new Label(globalize(
"cms.ui.new_folder")));
@ -198,29 +164,19 @@ public class FlatItemList extends SegmentedPanel implements FormProcessListener,
new LongParameter(CONTENT_TYPE_ID));
typeSelectionModel.addChangeListener(this);
creationSelector = new CreationSelector(typeSelectionModel,
folderSelectionModel,
selectedLanguageParam);
newItemSegment.add(creationSelector);
//m_newItemSeg.add(new Label("<br/>", false));
// The 'new folder' segment
newFolderSegment.addHeader(new Label(globalize("cms.ui.new_folder")));
// final Form folderCreate = new Form("fcreat");
folderCreator = new FolderCreateForm("fcreat", folderSelectionModel);
folderCreator.addSubmissionListener(this);
folderCreator.addProcessListener(this);
//folderCreator.add(folderCreator);
newFolderSegment.add(folderCreator);
newFolderSegment.add(new Label("<br/>", false));
editFolderSegment.addHeader(new Label(globalize("cms.ui.edit_folder")));
folderEditor = new FolderEditorForm("fedit", folderSelectionModel);
folderEditor.addSubmissionListener(this);
folderEditor.addProcessListener(this);
//Form folderEditorForm = new Form("fedit_form");
//folderEditorForm.add(folderEditor);
editFolderSegment.add(folderEditor);
editFolderSegment.add(new Label("<br/>", false));
}
@ -263,7 +219,7 @@ public class FlatItemList extends SegmentedPanel implements FormProcessListener,
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PermissionChecker permissionChecker = cdiUtil.findBean(
PermissionChecker.class);
final Folder folder = folderRequestLocal.getFolder(state);
final Folder folder = null;
// MP: This should be checked on the current folder instead of just
// the content section.
@ -295,7 +251,6 @@ public class FlatItemList extends SegmentedPanel implements FormProcessListener,
permissionsSegment.setVisible(state, true);
chooseLabel.setVisible(state, false);
contentLabel.setVisible(state, true);
folderPath.setVisible(state, true);
newItemSegment.setVisible(state, false);
newFolderSegment.setVisible(state, false);
editFolderSegment.setVisible(state, false);
@ -318,40 +273,14 @@ public class FlatItemList extends SegmentedPanel implements FormProcessListener,
throws FormProcessException {
final PageState state = event.getPageState();
if (event.getSource() == folderCreator
&& folderCreator.isCancelled(state)) {
browseMode(state);
throw new FormProcessException(new GlobalizedMessage(
"cms.ui.cancelled", CmsConstants.CMS_BUNDLE));
} else if (event.getSource() == folderEditor
&& folderEditor.isCancelled(state)) {
browseMode(state);
throw new FormProcessException(new GlobalizedMessage(
"cms.ui.cancelled", CmsConstants.CMS_BUNDLE));
} else if (event.getSource() == folderManipulator.getTargetSelector()) {
// This only works if this submission listener is run
// after the target selector's one
if (!folderManipulator.getTargetSelector().isVisible(state)) {
browseMode(state);
}
}
}
@Override
public void process(final FormSectionEvent event) {
final PageState state = event.getPageState();
final Object source = event.getSource();
if (source == folderCreator || source == folderEditor) {
browseMode(state);
} else if (source == folderManipulator.getItemView()) {
// Hide everything except for the browseSeg
permissionsSegment.setVisible(state, false);
chooseLabel.setVisible(state, true);
contentLabel.setVisible(state, false);
folderPath.setVisible(state, false);
} else if (source == folderManipulator.getTargetSelector()) {
browseMode(state);
}
}
@Override
@ -394,7 +323,7 @@ public class FlatItemList extends SegmentedPanel implements FormProcessListener,
}
private void togglePermissions(final PageState state) {
final Folder currentFolder = folderRequestLocal.getFolder(state);
final Folder currentFolder = null;
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PermissionChecker permissionChecker = cdiUtil.findBean(
PermissionChecker.class);
@ -405,15 +334,11 @@ public class FlatItemList extends SegmentedPanel implements FormProcessListener,
@Override
public void reset(final PageState state) {
browseMode(state);
folderManipulator.reset(state);
// switching between folders used to keep showing the permission pane
// in the same perm mode (direct or inherited) regardless
// of the folder status
}
public final FolderManipulator getManipulator() {
return folderManipulator;
}
public void setPermissionLinkVis(final PageState state) {
// final Folder currentFolder = folderRequestLocal.getFolder(state);

View File

@ -31,7 +31,6 @@ import com.arsdigita.bebop.parameters.LongParameter;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.cms.ui.ContentItemPage;
import com.arsdigita.cms.ui.folder.FolderSelectionModel;
import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.web.RedirectSignal;
import com.arsdigita.web.URL;
@ -90,7 +89,6 @@ public class CreationSelector extends MetaForm {
private static final Logger LOGGER = LogManager.getLogger(
CreationSelector.class);
private final FolderSelectionModel folderSelectionModel;
private final SingleSelectionModel<Long> typeSelectionModel;
private final StringParameter selectedLanguageParam;
@ -115,19 +113,14 @@ public class CreationSelector extends MetaForm {
* supply a BigDecimal ID of the content type to
* instantiate
*
* @param folderSelectionModel the {@link FolderSelectionModel} containing
* the folder in which new items are to be
* created
* @param selectedLanguageParam
*/
public CreationSelector(final SingleSelectionModel<Long> typeSelectionModel,
final FolderSelectionModel folderSelectionModel,
final StringParameter selectedLanguageParam) {
super("pageCreate");
this.typeSelectionModel = typeSelectionModel;
this.folderSelectionModel = folderSelectionModel;
this.selectedLanguageParam = selectedLanguageParam;
itemIdParameter = new LongParameter(ITEM_ID);
@ -241,7 +234,7 @@ public class CreationSelector extends MetaForm {
* placed.
*/
public final Folder getFolder(final PageState state) {
return folderSelectionModel.getSelectedObject(state);
throw new UnsupportedOperationException();
}
/**

View File

@ -1,74 +0,0 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.ParameterEvent;
import com.arsdigita.bebop.event.ParameterListener;
import org.libreccm.categorization.Category;
/**
*
*
*/
final class ChildUniqueValidationListener implements ParameterListener {
private final FolderRequestLocal m_parent;
/**
* Constructor.
* @param parent
*/
public ChildUniqueValidationListener(final FolderRequestLocal parent) {
m_parent = parent;
}
/**
*
* @param e
* @throws FormProcessException
*/
@Override
public final void validate(final ParameterEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
final String name = (String) e.getParameterData().getValue();
if (name != null) {
validateNameUniqueness(m_parent.getFolder(state), name);
}
}
/**
*
* @param parent
* @param name
* @throws FormProcessException
*/
private void validateNameUniqueness(final Category parent,
final String name)
throws FormProcessException {
//ToDo
}
}

View File

@ -1,71 +0,0 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.cdi.utils.CdiUtil;
class FolderAddForm extends FolderBaseForm {
private final SingleSelectionModel<Long> m_model;
private final FolderRequestLocal m_parent;
public FolderAddForm(final SingleSelectionModel model,
final FolderRequestLocal parent) {
super("folder-add");
m_model = model;
m_parent = parent;
m_fragment.addValidationListener(new ChildUniqueValidationListener(
parent));
addProcessListener(new ProcessListener());
}
private class ProcessListener implements FormProcessListener {
public final void process(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
final Category folder = new Category();
folder.setParentCategory(m_parent.getFolder(state));
folder.setDisplayName((String) m_title.getValue(state));
folder.setName((String) m_fragment.getValue(state));
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository categoryRepo = cdiUtil.findBean(
CategoryRepository.class);
categoryRepo.save(folder);
m_model.setSelectedKey(state, folder.getObjectId());
}
}
}

View File

@ -1,152 +0,0 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.cms.CMS;
import org.librecms.contentsection.ContentSection;
import com.arsdigita.cms.ui.BaseDeleteForm;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.toolbox.ui.SelectionPanel;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.CmsConstants;
import org.librecms.contentsection.Folder;
/**
* A pane that contains a folder tree on the left and a folder manipulator on
* the right.
*
* @author Justin Ross &lt;jross@redhat.com&gt;
*/
public class FolderAdminPane extends SelectionPanel {
private final FolderRequestLocal m_folder;
private final BigDecimalParameter m_param;
public static final String FOLDER_PARAMETER = "folder";
public FolderAdminPane() {
super(new Label(gz("cms.ui.folder.folders")),
new FolderTreeModelBuilder() {
@Override
protected Folder getRootFolder(final PageState state) {
final ContentSection section = CMS
.getContext()
.getContentSection();
return section.getRootDocumentsFolder();
}
});
m_folder = new FolderRequestLocal(getSelectionModel());
m_param = new BigDecimalParameter(FOLDER_PARAMETER);
setAdd(new ActionLink(new Label(gz("cms.ui.folder.add"))),
new FolderAddForm(getSelectionModel(), m_folder));
setEdit(new ActionLink(new Label(gz("cms.ui.folder.edit"))),
new FolderEditForm(m_folder));
final BaseDeleteForm delete = new BaseDeleteForm(new Label(gz(
"cms.ui.folder.delete_prompt"))) {
@Override
public final void process(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository categoryRepo = cdiUtil.findBean(
CategoryRepository.class);
categoryRepo.delete(m_folder.getFolder(state));
getSelectionModel().clearSelection(state);
}
};
setDelete(new ActionLink(new Label(gz("cms.ui.folder.delete"))),
delete);
setIntroPane(new Label(gz("cms.ui.folder.intro")));
setItemPane(new Label("item XXX"));
addAction(getAddLink());
addAction(getEditLink());
addAction(getDeleteLink());
}
@Override
public void register(final Page page) {
super.register(page);
page.addGlobalStateParam(m_param);
page.addActionListener(new PreselectListener());
}
private class PreselectListener implements ActionListener {
@Override
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
final SingleSelectionModel<Long> model = getSelectionModel();
if (!model.isSelected(state)) {
final Long value = (Long) state.getValue(m_param);
if (value == null) {
final ContentSection section = CMS.getContext()
.getContentSection();
model.setSelectedKey(state, section.getRootDocumentsFolder()
.getObjectId());
} else {
model.setSelectedKey(state, value);
}
}
}
}
private static GlobalizedMessage gz(final String key) {
return new GlobalizedMessage(key, CmsConstants.CMS_FOLDER_BUNDLE);
}
private static String lz(final String key) {
return (String) gz(key).localize();
}
}

View File

@ -1,119 +0,0 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.GridPanel;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SaveCancelSection;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.parameters.NotNullValidationListener;
import com.arsdigita.bebop.parameters.TrimmedStringParameter;
import com.arsdigita.cms.ui.CMSForm;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.web.Web;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.librecms.CmsConstants;
/**
* Class FolderForm implements the basic form for creating or renaming folders.
*
* @author Jon Orris &lt;jorris@redhat.com&gt;
*/
abstract class FolderBaseForm extends CMSForm {
private static Logger LOGGER = LogManager.getLogger(FolderBaseForm.class);
public static final String NAME = "ContentItemName";
public static final String TITLE = "ContentPageTitle";
private static final String TITLE_ON_FOCUS = "if (this.form." + NAME + ".value == '') {"
+ " defaulting = true;" + " this.form."
+ NAME + ".value = urlize(this.value);" + "}";
private static final String TITLE_ON_KEY_UP = "if (defaulting) {" + " this.form." + NAME
+ ".value = urlize(this.value)" + "}";
private static final String FRAGMENT_ON_FOCUS = "defaulting = false";
private static final String FRAGMENT_ON_BLUR = "if (this.value == '') {"
+ " defaulting = true;"
+ " this.value = urlize(this.form." + TITLE
+ ".value)" + "} else {"
+ " this.value = urlize(this.value);" + "}";
private Label m_script = new Label(
String.format(
"<script language=\"javascript\" src=\"%s/javascript/manipulate-input.js\"></script>",
Web.getWebappContextPath()),
false);
final TextField m_title;
final TextField m_fragment;
final SaveCancelSection m_submits;
public FolderBaseForm(final String name) {
super(name);
add(m_script, GridPanel.FULL_WIDTH);
// Title
add(new Label(gz("cms.ui.folder.name")));
m_title = new TextField(new TrimmedStringParameter(TITLE));
add(m_title);
m_title.addValidationListener(new NotNullValidationListener());
m_title.setOnFocus(TITLE_ON_FOCUS);
m_title.setOnFocus(TITLE_ON_FOCUS);
m_title.setOnKeyUp(TITLE_ON_KEY_UP);
// Fragment
add(new Label(gz("cms.ui.folder.fragment")));
m_fragment = new TextField(new TrimmedStringParameter(NAME));
add(m_fragment);
m_fragment.addValidationListener(new NotNullValidationListener());
m_fragment.setOnFocus(FRAGMENT_ON_FOCUS);
m_fragment.setOnBlur(FRAGMENT_ON_BLUR);
m_submits = new SaveCancelSection();
add(m_submits, GridPanel.FULL_WIDTH);
}
public final boolean isCancelled(final PageState state) {
return m_submits.getCancelButton().isSelected(state);
}
private static GlobalizedMessage gz(final String key) {
return new GlobalizedMessage(key, CmsConstants.CMS_FOLDER_BUNDLE);
}
private static String lz(final String key) {
return (String) gz(key).localize();
}
}

View File

@ -1,546 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ControlLink;
import com.arsdigita.bebop.Image;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Link;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Paginator;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.Text;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.TableActionAdapter;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.table.DefaultTableCellRenderer;
import com.arsdigita.bebop.table.DefaultTableColumnModel;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableHeader;
import com.arsdigita.cms.CMS;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.Assert;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import javax.servlet.ServletException;
import org.libreccm.categorization.Category;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.security.PermissionChecker;
import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.ContentSectionManager;
import org.librecms.contentsection.privileges.ItemPrivileges;
import org.librecms.dispatcher.ItemResolver;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* Browse folders and items. If the user clicks on a folder, the folder
* selection model is updated. If the user clicks on any other item, an separate
* item selection model is updated.
*
* @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a>
* @author <a href="mailto:quasi@quasiweb.de">Sören Bernstein</a>
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class FolderBrowser extends Table {
private static final GlobalizedMessage[] HEADERS = {
globalize("cms.ui.folder.name"),
globalize("cms.ui.folder.languages"),
globalize("cms.ui.folder.title"),
// globalize("cms.ui.folder.additionalInfo"),
globalize("cms.ui.folder.type"),
globalize("cms.ui.folder.creation_date"),
globalize("cms.ui.folder.last_modified"),
globalize("cms.ui.folder.action")};
protected static final String SORT_ACTION_UP = "sortActionUp";
protected static final String SORT_ACTION_DOWN = "sortActionDown";
protected final static String SORT_KEY_NAME = "name";
protected final static String SORT_KEY_TITLE = "title";
protected final static String SORT_KEY_TYPE = "type";
protected final static String SORT_KEY_LAST_MODIFIED_DATE = "lastModified";
protected final static String SORT_KEY_CREATION_DATE = "creationDate";
private final FolderSelectionModel folderSelectionModel;
private final TableActionListener folderChanger;
private final TableActionListener folderDeleter;
// private TableActionListener m_indexChanger;
private final TableColumn nameColumn;
private final TableColumn deleteColumn;
// private TableColumn m_indexColumn;
private final StringParameter sortTypeParameter = new StringParameter(
"sortType");
private final StringParameter sortDirectionParameter = new StringParameter(
"sortDirn");
private StringParameter atozFilterParameter = null;
private StringParameter filterParameter = null;
private FolderManipulator folderManipulator;
private Paginator paginator;
// private FolderManipulator.FilterForm filterForm;
private long folderSize;
public FolderBrowser(final FolderSelectionModel folderSelectionModel) {
super();
sortTypeParameter.setDefaultValue(SORT_KEY_NAME);
sortDirectionParameter.setDefaultValue(SORT_ACTION_UP);
setModelBuilder(new FolderBrowserTableModelBuilder());
setColumnModel(new DefaultTableColumnModel(HEADERS));
setHeader(new TableHeader(getColumnModel()));
this.folderSelectionModel = folderSelectionModel;
setClassAttr("dataTable");
getHeader().setDefaultRenderer(
new com.arsdigita.cms.ui.util.DefaultTableCellRenderer());
nameColumn = getColumn(0);
nameColumn.setCellRenderer(new NameCellRenderer());
nameColumn.setHeaderRenderer(new HeaderCellRenderer(SORT_KEY_NAME));
getColumn(1).setCellRenderer(new LanguagesCellRenderer());
getColumn(4).setHeaderRenderer(new HeaderCellRenderer(
SORT_KEY_CREATION_DATE));
getColumn(4).setCellRenderer(new DateCellRenderer());
getColumn(5).setCellRenderer(new DateCellRenderer());
getColumn(5).setHeaderRenderer(new HeaderCellRenderer(
SORT_KEY_LAST_MODIFIED_DATE));
deleteColumn = getColumn(6);
deleteColumn.setCellRenderer(new ActionCellRenderer());
deleteColumn.setAlign("center");
folderChanger = new FolderChanger();
addTableActionListener(folderChanger);
folderDeleter = new ItemDeleter();
addTableActionListener(folderDeleter);
setEmptyView(new Label(globalize("cms.ui.folder.no_items")));
Assert.exists(folderSelectionModel.getStateParameter());
}
@Override
public void register(final Page page) {
super.register(page);
page.addComponentStateParam(this,
folderSelectionModel.getStateParameter());
page.addComponentStateParam(this,
sortTypeParameter);
page.addComponentStateParam(this,
sortDirectionParameter);
page.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent event) {
final PageState state = event.getPageState();
if (state.isVisibleOnPage(FolderBrowser.this)) {
showHideFolderActions(state);
}
}
});
}
private void showHideFolderActions(final PageState state) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PermissionChecker permissionChecker = cdiUtil.findBean(
PermissionChecker.class);
final Category folder = (Category) folderSelectionModel
.getSelectedObject(state);
final boolean canDelete = permissionChecker.isPermitted(
ItemPrivileges.DELETE, folder);
deleteColumn.setVisible(state, canDelete);
}
@Override
public void respond(final PageState state) throws ServletException {
final String key = state.getControlEventName();
final String value = state.getControlEventValue();
if (SORT_ACTION_UP.equals(key)) {
state.setValue(sortTypeParameter, value);
state.setValue(sortDirectionParameter, SORT_ACTION_UP);
} else if (SORT_ACTION_DOWN.equals(key)) {
state.setValue(sortTypeParameter, value);
state.setValue(sortDirectionParameter, SORT_ACTION_DOWN);
} else {
super.respond(state);
}
}
public FolderSelectionModel getFolderSelectionModel() {
return folderSelectionModel;
}
protected void setFolderManipulator(
final FolderManipulator folderManipulator) {
this.folderManipulator = folderManipulator;
}
// protected void setFilterForm(final FolderManipulator.FilterForm filterForm) {
// this.filterForm = filterForm;
// }
protected void setAtoZfilterParameter(
final StringParameter atozFilterParameter) {
this.atozFilterParameter = atozFilterParameter;
}
protected void setFilterParameter(final StringParameter filterParameter) {
this.filterParameter = filterParameter;
}
protected long getFolderSize() {
return folderSize;
}
protected Paginator getPaginator() {
return paginator;
}
protected void setPaginator(final Paginator paginator) {
this.paginator = paginator;
}
protected String getFilter(final PageState state) {
return (String) state.getValue(filterParameter);
}
protected String getAtoZfilter(final PageState state) {
return (String) state.getValue(atozFilterParameter);
}
protected String getSortType(final PageState state) {
return (String) state.getValue(sortTypeParameter);
}
protected String getSortDirection(final PageState state) {
return (String) state.getValue(sortDirectionParameter);
}
private class HeaderCellRenderer
extends com.arsdigita.cms.ui.util.DefaultTableCellRenderer {
private final String headerKey;
public HeaderCellRenderer(final String headerKey) {
super(true);
this.headerKey = headerKey;
}
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
final GlobalizedMessage headerName = (GlobalizedMessage) value;
final String sortKey = (String) state.getValue(sortTypeParameter);
final boolean isCurrentKey = sortKey.equals(key);
final String currentSortDirection = (String) state.getValue(
sortDirectionParameter);
final String imageURLStub;
if (SORT_ACTION_UP.equals(currentSortDirection)) {
imageURLStub = "gray-triangle-up.gif";
} else {
imageURLStub = "gray-triangle-down.gif";
}
final ControlLink link = new ControlLink(new Label(headerName)) {
@Override
public void setControlEvent(final PageState state) {
String sortDirectionAction;
// by default, everything sorts "up" unless it
// is the current key and it is already pointing up
if (SORT_ACTION_UP.equals(currentSortDirection)
&& isCurrentKey) {
sortDirectionAction = SORT_ACTION_DOWN;
} else {
sortDirectionAction = SORT_ACTION_UP;
}
state.setControlEvent(table,
sortDirectionAction,
headerKey);
}
};
final Label label = new Label();
label.setLabel(headerName);
label.setClassAttr("folderBrowserLink");
label.setOutputEscaping(false);
label.setFontWeight(Label.BOLD);
final SimpleContainer container = new SimpleContainer();
container.add(label);
if (isCurrentKey) {
Image image = new Image("/assets/" + imageURLStub);
image.setBorder("0");
container.add(image);
}
link.setChild(container);
return link;
}
}
//
/**
* Produce links to view an item or control links for folders to change into
* the folder.
*/
private class NameCellRenderer extends DefaultTableCellRenderer {
public NameCellRenderer() {
super(true);
}
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
final String name = (String) value;
final ContentSection section = CMS.getContext().getContentSection();
final ContentSectionManager sectionManager = CdiUtil.createCdiUtil()
.findBean(ContentSectionManager.class);
final ItemResolver itemResolver = sectionManager.getItemResolver(
section);
final boolean isFolder = ((FolderBrowserTableModel) table
.getTableModel(state)).isFolder();
final long objectId = getObjectId(key);
if (isFolder) {
//return new ControlLink(new Text(name));
return super.getComponent(table,
state,
value,
isSelected,
objectId,
row,
column);
} else {
return new Link(new Text(name),
itemResolver.generateItemURL(state,
objectId,
name,
section,
"DRAFT"));
}
}
}
/**
* Added by: Sören Bernstein <quasi@quasiweb.de>
*
* Produce links to view an item in a specific language and show all
* existing language version and the live status in the folder browser.
*/
private class LanguagesCellRenderer extends DefaultTableCellRenderer {
public LanguagesCellRenderer() {
super(true);
}
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
final SimpleContainer container = new SimpleContainer();
final ContentSection section = CMS.getContext().getContentSection();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ContentSectionManager sectionManager = cdiUtil.findBean(
ContentSectionManager.class);
final ItemResolver itemResolver = sectionManager.getItemResolver(
section);
@SuppressWarnings("unchecked")
final List<Locale> availableLocales = (List<Locale>) value;
availableLocales.forEach(locale -> container.add(new Link(
new Text(locale.toString()),
itemResolver.generateItemURL(
state,
getObjectId(key),
locale.toString(),
section,
"DRAFT"))));
return container;
}
}
private class DateCellRenderer implements TableCellRenderer {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
if (value instanceof Date) {
final Date date = (Date) value;
return new Text(String.format("%1$TF %1$TT", date));
} else if (value == null) {
return new Text("");
} else {
return new Text(value.toString());
}
}
}
/**
* Produce delete links for items and non-empty folders.
*/
private static class ActionCellRenderer implements TableCellRenderer {
private static final Logger LOGGER = LogManager.getLogger(
ActionCellRenderer.class);
private static final Label noActionLabel;
private static final ControlLink link;
static {
LOGGER.debug("Static initializer is starting...");
noActionLabel = new Label("&nbsp;", false);
noActionLabel.lock();
link = new ControlLink(
new Label(globalize("cms.ui.folder.delete")));
link.setConfirmation(
globalize("cms.ui.folder.delete_confirmation"));
LOGGER.debug("Static initializer finished.");
}
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
if (((Boolean) value)) {
return link;
} else {
return noActionLabel;
}
}
}
// Deletes an item
private class ItemDeleter extends TableActionAdapter {
@Override
public void cellSelected(final TableActionEvent event) {
int col = event.getColumn();
if (deleteColumn != getColumn(col)) {
return;
}
final PageState state = event.getPageState();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderBrowserController controller = cdiUtil.findBean(
FolderBrowserController.class);
controller.deleteObject((String) event.getRowKey());
((Table) event.getSource()).clearSelection(state);
}
}
private class FolderChanger extends TableActionAdapter {
@Override
public void cellSelected(final TableActionEvent event) {
final PageState state = event.getPageState();
final int col = event.getColumn();
if (nameColumn != getColumn(col)) {
return;
}
clearSelection(state);
getFolderSelectionModel().setSelectedKey(
state,
getObjectId(event.getRowKey()));
}
}
/**
* Getting the GlobalizedMessage using a CMS Class targetBundle.
*
* @param key The resource key
*/
private static GlobalizedMessage globalize(String key) {
return new GlobalizedMessage(key, CmsConstants.CMS_FOLDER_BUNDLE);
}
private long getObjectId(final Object key) {
final String keyStr = (String) key;
if (keyStr.startsWith("folder-")) {
return Long.parseLong(keyStr.substring("folder-".length()));
} else if (keyStr.startsWith("item-")) {
return Long.parseLong(keyStr.substring("item-".length()));
} else {
return Long.parseLong(keyStr);
}
}
}

View File

@ -1,955 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.kernel.KernelConfig;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.categorization.Categorization;
import org.libreccm.categorization.CategoryManager;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.core.CcmObject;
import org.libreccm.core.CcmObjectRepository;
import org.libreccm.l10n.GlobalizationHelper;
import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemL10NManager;
import org.librecms.contentsection.ContentItemManager;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.ContentItemVersion;
import org.librecms.contentsection.ContentType;
import org.librecms.contentsection.Folder;
import org.librecms.contentsection.FolderRepository;
import org.librecms.contenttypes.ContentTypeInfo;
import org.librecms.contenttypes.ContentTypesManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Path;
import org.librecms.contentsection.FolderManager;
import javax.persistence.criteria.Subquery;
import static org.librecms.CmsConstants.*;
/**
* The {@code FolderBrowserController} wraps all database operations (queries)
* required by the {@link FolderBrowser}, the
* {@link FolderBrowserTableModelBuilder} and the
* {@link FolderBrowserTableModel}.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class FolderBrowserController {
private static final Logger LOGGER = LogManager
.getLogger(FolderBrowserController.class);
@Inject
private EntityManager entityManager;
@Inject
private CcmObjectRepository ccmObjectRepo;
@Inject
private CategoryManager categoryManager;
@Inject
private CcmObjectRepository objectRepo;
@Inject
private ConfigurationManager confManager;
@Inject
private GlobalizationHelper globalizationHelper;
@Inject
private ContentItemRepository itemRepo;
@Inject
private ContentItemManager itemManager;
@Inject
private ContentItemL10NManager itemL10NManager;
@Inject
private ContentTypesManager typesManager;
@Inject
private FolderRepository folderRepo;
@Inject
private FolderManager folderManager;
private Locale defaultLocale;
/**
* Initialisation method called by the CDI-Container after an instance of
* this class has be created by the container. Sets the
* {@link #defaultLocale} property using the the value from the
* {@link KernelConfig}.
*/
@PostConstruct
private void init() {
final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class);
defaultLocale = kernelConfig.getDefaultLocale();
}
/**
* Count the objects (subfolders and content items) in the provided folder.
*
* @param folder The folder.
*
* @return The number of objects (subfolders and content items) in the
* provided {@code folder}.
*/
public long countObjects(final Folder folder) {
return countObjects(folder, "%");
}
/**
* Count all objects (subfolders and content items) in the provided folder
* which match the provided filter term.
*
* @param folder The folder.
* @param filterTerm The filter term.
*
* @return The number of objects (subfolders and content items) in the
* provided {@code folder} which match the provided
* {@code filterTerm}.
*/
public long countObjects(final Folder folder,
final String filterTerm) {
Objects.requireNonNull(folder, "Can't count objects in Folder null.");
Objects.requireNonNull(filterTerm, "Can't filter for 'null'.");
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
final Root<CcmObject> from = criteriaQuery.from(CcmObject.class);
criteriaQuery = criteriaQuery.select(builder.count(from));
final List<Folder> subFolders = findSubFolders(folder,
filterTerm,
FolderBrowser.SORT_KEY_NAME,
FolderBrowser.SORT_ACTION_UP,
-1,
-1);
final List<ContentItem> items = findItemsInFolder(folder,
filterTerm,
FolderBrowser.SORT_KEY_NAME,
FolderBrowser.SORT_ACTION_UP,
-1,
-1);
if (subFolders.isEmpty() && items.isEmpty()) {
return 0;
} else if (subFolders.isEmpty() && !items.isEmpty()) {
criteriaQuery = criteriaQuery.where(from.in(items));
} else if (!subFolders.isEmpty() && items.isEmpty()) {
criteriaQuery = criteriaQuery.where(from.in(subFolders));
} else {
criteriaQuery = criteriaQuery.where(builder.or(
from.in(subFolders),
from.in(items)));
}
return entityManager.createQuery(criteriaQuery).getSingleResult();
}
/**
* Create {@link FolderBrowserTableRow} objects for all objects in the
* provided folder.
*
* @param folder The folder which contains the objects.
* @param orderBy The field used to order the objects.
* @param orderDirection The direction for ordering the objects.
*
* @return A list with {@link FolderBrowserTableRow} objects for each object
* in the provided {@code folder} ordered by the provided field and
* in the provided direction.
*/
@Transactional(Transactional.TxType.REQUIRED)
List<FolderBrowserTableRow> getObjectRows(final Folder folder,
final String orderBy,
final String orderDirection) {
return getObjectRows(folder, "%", orderBy, orderDirection, -1, -1);
}
/**
* Create {@link FolderBrowserTableRow} objects for all objects in the
* provided folder which match provided filter term.
*
* @param folder The folder which contains the objects.
* @param filterTerm The filter term.
* @param orderBy The field used to order the objects.
* @param orderDirection The direction for ordering the objects.
*
* @return A list with {@link FolderBrowserTableRow} objects for each object
* in the provided {@code folder} which matches the provided
* {@code filterTerm}, ordered by the provided field and in the
* provided direction.
*/
@Transactional(Transactional.TxType.REQUIRED)
List<FolderBrowserTableRow> getObjectRows(final Folder folder,
final String filterTerm,
final String orderBy,
final String orderDirection) {
return getObjectRows(folder,
filterTerm,
orderBy,
orderDirection,
-1,
-1);
}
/**
* Create {@link FolderBrowserTableRow} objects for the objects in the
* provided folder which are in the range provided by {@code firstResult}
* and {@code maxResult}
*
* @param folder The folder which contains the objects.
* @param orderBy The field used to order the objects.
* @param orderDirection The direction for ordering the objects.
* @param firstResult The index of the first object to use.
* @param maxResults The maximum number of objects to retrieve.
*
* @return A list with {@link FolderBrowserTableRow} objects for each object
* in the provided {@code folder} ordered by the provided field and
* in the provided direction. The list will start with the object
* with index provided as {@code firstResult} and contain at most
* {@code maxResults} items.
*/
@Transactional(Transactional.TxType.REQUIRED)
List<FolderBrowserTableRow> getObjectRows(final Folder folder,
final String orderBy,
final String orderDirection,
final int firstResult,
final int maxResults) {
return getObjectRows(folder,
"%",
orderBy,
orderDirection,
firstResult,
maxResults);
}
/**
* Create {@link FolderBrowserTableRow} objects for the objects in the
* provided folder which match the provided filter term and which are in the
* range provided by {@code firstResult} and {@code maxResult}
*
* @param folder The folder which contains the objects.
* @param filterTerm The filter term.
* @param orderBy The field used to order the objects.
* @param orderDirection The direction for ordering the objects.
* @param firstResult The index of the first object to use.
* @param maxResults The maximum number of objects to retrieve.
*
* @return A list with {@link FolderBrowserTableRow} objects for each object
* in the provided {@code folder} which matches the provided
* {@code filterTerm}, ordered by the provided field and in the
* provided direction. The list will start with the object with
* index provided as {@code firstResult} and contain at most
* {@code maxResults} items.
*/
@Transactional(Transactional.TxType.REQUIRED)
List<FolderBrowserTableRow> getObjectRows(final Folder folder,
final String filterTerm,
final String orderBy,
final String orderDirection,
final int firstResult,
final int maxResults) {
final List<CcmObject> objects = findObjectsInFolder(folder,
filterTerm,
orderBy,
orderDirection,
firstResult,
maxResults);
LOGGER.debug("Found {} objects for folder \"{}\".",
objects.size(),
folder.getDisplayName());
final List<FolderBrowserTableRow> rows = objects
.stream()
.map(object -> buildRow(object))
.collect(Collectors.toList());
return rows;
// final List<Folder> subFolders = findSubFolders(folder,
// filterTerm,
// orderBy,
// orderDirection,
// firstResult,
// maxResults);
// final List<FolderBrowserTableRow> subFolderRows = subFolders
// .stream()
// .map(subFolder -> buildRow(subFolder))
// .collect(Collectors.toList());
//
// if (subFolders.size() >= maxResults) {
// return subFolderRows;
// } else {
// final int maxItems = maxResults - subFolders.size();
// final int firstItem = firstResult - subFolders.size();
//
// final List<ContentItem> items = findItemsInFolder(folder,
// filterTerm,
// orderBy,
// orderDirection,
// firstItem,
// maxItems);
// final List<FolderBrowserTableRow> itemRows = items.stream()
// .map(item -> buildRow(item))
// .collect(Collectors.toList());
//
// final List<FolderBrowserTableRow> rows = new ArrayList<>();
// rows.addAll(subFolderRows);
// rows.addAll(itemRows);
//
// return rows;
// }
}
private FolderBrowserTableRow buildRow(final CcmObject object) {
if (object instanceof Folder) {
return buildRow((Folder) object);
} else if(object instanceof ContentItem) {
return buildRow((ContentItem) object);
} else{
throw new IllegalArgumentException(
"Only Folders and ContentItems are supported.");
}
}
/**
* Helper method for building a {@link FolderBrowserTableRow} from a
* {@link Folder}.
*
* @param folder The {@link Folder} to use for building the
* {@link FolderBrowserTableRow}.
*
* @return A {@link FolderBrowserTableRow} containing the data needed by the
* {@link FolderBrowser} to display the provided {@code folder}.
*/
private FolderBrowserTableRow buildRow(final Folder folder) {
final FolderBrowserTableRow row = new FolderBrowserTableRow();
row.setObjectId(folder.getObjectId());
row.setObjectUuid(folder.getUuid());
row.setName(folder.getName());
row.setLanguages(Collections.emptyList());
if (folder.getTitle().hasValue(globalizationHelper
.getNegotiatedLocale())) {
row.setTitle(folder.getTitle().getValue(globalizationHelper
.getNegotiatedLocale()));
} else {
row.setTitle(folder.getTitle().getValue(defaultLocale));
}
row.setFolder(true);
row.setDeletable(!categoryManager.hasSubCategories(folder)
&& !categoryManager.hasObjects(folder));
return row;
}
/**
* Helper method for building a {@link FolderBrowserTableRow} from a
* {@link ContentItem}.
*
* @param item The {@link ContentItem} to use for building the
* {@link FolderBrowserTableRow}.
*
* @return A {@link FolderBrowserTableRow} containing the data needed by the
* {@link FolderBrowser} to display the provided {@code item}.
*/
private FolderBrowserTableRow buildRow(final ContentItem item) {
final FolderBrowserTableRow row = new FolderBrowserTableRow();
final Locale negotiatedLocale = globalizationHelper
.getNegotiatedLocale();
row.setObjectId(item.getObjectId());
row.setObjectUuid(item.getItemUuid());
if (item.getName().hasValue(negotiatedLocale)) {
row.setName(item.getName().getValue(negotiatedLocale));
} else {
row.setName(item.getName().getValue(defaultLocale));
}
final List<Locale> languages = new ArrayList<>(itemL10NManager
.availableLanguages(item));
languages.sort((lang1, lang2) -> lang1.toString().compareTo(
lang2.toString()));
row.setLanguages(languages);
if (item.getTitle().hasValue(negotiatedLocale)) {
row.setTitle(item.getTitle().getValue(negotiatedLocale));
} else {
row.setTitle(item.getTitle().getValue(defaultLocale));
}
final ContentType type = item.getContentType();
final ContentTypeInfo typeInfo = typesManager.getContentTypeInfo(
type);
row.setTypeLabelBundle(typeInfo.getLabelBundle());
row.setTypeLabelKey(typeInfo.getLabelKey());
row.setDeletable(!itemManager.isLive(item));
row.setCreated(item.getCreationDate());
row.setLastModified(item.getLastModified());
row.setFolder(false);
return row;
}
/**
* Called by the {@link FolderBrowser} to delete an object.
*
* @param objectId
*/
@Transactional(Transactional.TxType.REQUIRED)
protected void deleteObject(final String objectId) {
Objects.requireNonNull(objectId);
if (objectId.startsWith("folder-")) {
final long folderId = Long.parseLong(
objectId.substring("folder-".length()));
folderRepo
.findById(folderId)
.ifPresent(folderRepo::delete);
} else if (objectId.startsWith("item-")) {
final long itemId = Long.parseLong(
objectId.substring("item-".length()));
itemRepo
.findById(itemId)
.ifPresent(itemRepo::delete);
} else {
throw new IllegalArgumentException(
"The objectId is expected to start with 'folder-' or 'item.'.");
}
}
private List<CcmObject> findObjectsInFolder(final Folder folder,
final String filterTerm,
final String orderBy,
final String orderDirection,
final int firstResult,
final int maxResults) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<CcmObject> criteriaQuery = builder
.createQuery(CcmObject.class);
final Root<CcmObject> from = criteriaQuery.from(CcmObject.class);
criteriaQuery.select(from);
final Subquery<Folder> folderCriteriaQuery = criteriaQuery
.subquery(Folder.class);
final Root<Folder> fromFolder = folderCriteriaQuery.from(Folder.class);
folderCriteriaQuery.select(fromFolder);
folderCriteriaQuery.where(
builder.and(
builder.equal(fromFolder.get("parentCategory"), folder),
builder.like(builder.lower(fromFolder.get("name")),
filterTerm)));
final Subquery<ContentItem> itemCriteriaQuery = criteriaQuery
.subquery(ContentItem.class);
final Root<ContentItem> fromItem = itemCriteriaQuery
.from(ContentItem.class);
itemCriteriaQuery.select(fromItem);
final Join<ContentItem, Categorization> itemCategoryJoin = fromItem
.join("categories");
itemCriteriaQuery.where(builder
.and(
builder.equal(itemCategoryJoin.get("category"), folder),
builder.equal(itemCategoryJoin.get("type"),
CmsConstants.CATEGORIZATION_TYPE_FOLDER),
builder.equal(fromItem.get("version"),
ContentItemVersion.DRAFT),
builder.like(builder.lower(fromItem.get("displayName")),
filterTerm)));
criteriaQuery.where(
builder.or(
builder.in(from).value(folderCriteriaQuery),
builder.in(from).value(itemCriteriaQuery)
));
criteriaQuery.orderBy(builder.asc(from.get("displayName")));
final TypedQuery<CcmObject> query = entityManager
.createQuery(criteriaQuery);
if (maxResults > 0) {
query.setMaxResults(maxResults);
}
if (firstResult > 0) {
query.setFirstResult(firstResult);
}
return query.getResultList();
}
/**
* Retrieves all subfolders of a folder matching the provided filter term.
* Because {@link Folder} does not have any of the fields despite the name
* which can be used to order the objects ordering is done as follows:
*
* If {@code orderBy} has any value other than
* {@link FolderBrowser#SORT_KEY_NAME} the subfolders are ordered in
* ascending order by their name. If {@code orderBy} is
* {@link FolderBrowser#SORT_KEY_NAME} the subfolders are ordered by their
* name in ascending and descending order depending on the value of
* {@code orderDirection}.
*
* @param folder The folder which contains the subfolders.
* @param filterTerm The filter term.
* @param orderBy Field to use for ordering. If the value is negative
* the parameter is ignored.
* @param orderDirection Direction for ordering. If the value is negative
* the parameter is ignored.
* @param firstResult Index of the first result to retrieve.
* @param maxResults Maxium number of results to retrieve.
*
*
* @return A list of the subfolders of the provided {@code folder} which
* match the provided {@code filterTerm}. The list is ordered as
* described above. The list will contain at most {@code maxResults}
* starting with the result with the index provided as
* {@code firstResult}.
*/
private List<Folder> findSubFolders(final Folder folder,
final String filterTerm,
final String orderBy,
final String orderDirection,
final int firstResult,
final int maxResults) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Folder> criteria = builder
.createQuery(Folder.class);
final Root<Folder> from = criteria.from(Folder.class);
final Order order;
if (FolderBrowser.SORT_KEY_NAME.equals(orderBy)
&& FolderBrowser.SORT_ACTION_DOWN.equals(orderDirection)) {
order = builder.desc(from.get("name"));
} else {
order = builder.asc(from.get("name"));
}
final TypedQuery<Folder> query = entityManager
.createQuery(
criteria.where(
builder.and(
builder.equal(from.get("parentCategory"), folder),
builder
.like(builder.lower(from.get("name")),
filterTerm)
)
)
.orderBy(order)
);
if (firstResult >= 0) {
query.setFirstResult(firstResult);
}
if (maxResults >= 0) {
query.setMaxResults(maxResults);
}
return query.getResultList();
}
/**
* Retrieves all items of a folder matching the provided filter term.
*
* @param folder The folder which contains the subfolders.
* @param filterTerm The filter term.
* @param orderBy Field to use for ordering. If the value is negative
* the parameter is ignored.
* @param orderDirection Direction for ordering. If the value is negative
* the parameter is ignored.
* @param firstResult Index of the first result to retrieve.
* @param maxResults Maxium number of results to retrieve.
*
*
* @return A list of the subfolders of the provided {@code folder} which
* match the provided {@code filterTerm}. The list is ordered the
* field provided as {@code orderBy} in the direction provided by
* {@code orderDirection}. The list will contain at most
* {@code maxResults} starting with the result with the index
* provided as {@code firstResult}.
*/
private List<ContentItem> findItemsInFolder(final Folder folder,
final String filterTerm,
final String orderBy,
final String orderDirection,
final int firstResult,
final int maxResults) {
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<ContentItem> criteria = builder
.createQuery(ContentItem.class);
final Root<ContentItem> fromItem = criteria.from(ContentItem.class);
final Join<ContentItem, Categorization> join = fromItem
.join("categories");
final Path<?> orderPath;
switch (orderBy) {
case FolderBrowser.SORT_KEY_NAME:
orderPath = fromItem.get("displayName");
break;
case FolderBrowser.SORT_KEY_CREATION_DATE:
orderPath = fromItem.get("creationDate");
break;
case FolderBrowser.SORT_KEY_LAST_MODIFIED_DATE:
orderPath = fromItem.get("lastModifed");
break;
default:
orderPath = fromItem.get("displayName");
break;
}
final Order order;
if (FolderBrowser.SORT_ACTION_DOWN.equals(orderDirection)) {
order = builder.desc(orderPath);
} else {
order = builder.asc(orderPath);
}
final TypedQuery<ContentItem> query = entityManager
.createQuery(
criteria.select(fromItem)
.where(
builder.and(
builder.equal(join.get("category"), folder),
builder.equal(join.get("type"),
CmsConstants.CATEGORIZATION_TYPE_FOLDER),
builder.equal(fromItem.get("version"),
ContentItemVersion.DRAFT),
builder.like(builder.lower(fromItem.get(
"displayName")),
filterTerm)
)
)
.orderBy(order)
);
if (firstResult >= 0) {
query.setFirstResult(firstResult);
}
if (maxResults >= 0) {
query.setMaxResults(maxResults);
}
return query.getResultList();
}
/**
* Check if a folder or its subfolders contains at least one live item.
*
* @param folder The folder to check for live items.
*
* @return {@code true} if the {@code folder} or on of its subfolders
* contains at least one live item, {@code false} otherwise.
*/
@Transactional(Transactional.TxType.REQUIRED)
public boolean hasLiveItems(final Folder folder) {
Objects.requireNonNull(folder,
"Folder to check for live items can't be null.");
//Ensure that we use an non detached entity.
final Folder theFolder = folderRepo.findById(folder.getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No folder with id %s in the database. Where did that ID come from?",
folder.getObjectId())));
final boolean hasLiveItem = theFolder.getObjects()
.stream()
.map(categorization -> categorization.getCategorizedObject())
.filter(object -> object instanceof ContentItem)
.map(object -> (ContentItem) object)
.filter(item -> itemManager.isLive(item))
.anyMatch(item -> itemManager.isLive(item));
if (hasLiveItem) {
return true;
} else {
return theFolder.getSubFolders()
.stream()
.anyMatch(currentFolder -> hasLiveItems(currentFolder));
}
}
/**
* Get the IDs of the folders invalid for copy/move actions.
*
* @param sources
*
* @return
*/
@Transactional(Transactional.TxType.REQUIRED)
public List<String> createInvalidTargetsList(final List<String> sources) {
Objects.requireNonNull(sources);
final List<String> sourceFolderIds = sources
.stream()
.filter(source -> source.startsWith(
FOLDER_BROWSER_KEY_PREFIX_FOLDER))
.collect(Collectors.toList());
final List<String> parentFolderIds = sourceFolderIds
.stream()
.map(sourceFolderId -> findParentFolderId(sourceFolderId))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
final List<List<String>> subFolderIds = sourceFolderIds
.stream()
.map(sourceFolderId -> findSubFolderIds(sourceFolderId))
.collect(Collectors.toList());
final List<String> invalidTargetIds = new ArrayList<>();
invalidTargetIds.addAll(sourceFolderIds);
invalidTargetIds.addAll(parentFolderIds);
for (final List<String> subFolderIdList : subFolderIds) {
invalidTargetIds.addAll(subFolderIdList);
}
return invalidTargetIds;
}
private Optional<String> findParentFolderId(final String folderId) {
Objects.requireNonNull(folderId);
if (!folderId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
throw new IllegalArgumentException(String.format(
"Provided string '%s' is not an ID of a folder.",
folderId));
}
final long objectId = Long.parseLong(folderId.substring(
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length()));
final Folder folder = folderRepo.findById(objectId)
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No folder with ID %d found in database. "
+ "Where did that ID come form?",
objectId)));
final Optional<Folder> parentFolder = folderManager.getParentFolder(
folder);
if (parentFolder.isPresent()) {
return Optional.empty();
} else {
return Optional.ofNullable(String.format(
"%s%d",
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
parentFolder.get().getObjectId()));
}
}
private List<String> findSubFolderIds(final String folderId) {
Objects.requireNonNull(folderId);
if (!folderId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
throw new IllegalArgumentException(String.format(
"Provided string '%s' is not the ID of a folder.",
folderId));
}
final long objectId = Long.parseLong(folderId.substring(
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length()));
final Folder folder = folderRepo.findById(objectId)
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No folder with ID %d found in database. "
+ "Where did that ID come form?",
objectId)));
return findSubFolders(folder)
.stream()
.map(subFolder -> String.format("%s%d",
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
subFolder.getObjectId()))
.collect(Collectors.toList());
}
private List<Folder> findSubFolders(final Folder folder) {
Objects.requireNonNull(folder);
if (folder.getSubFolders() == null
|| folder.getSubFolders().isEmpty()) {
return Collections.emptyList();
}
final List<Folder> subFolders = new ArrayList<>();
for (final Folder subFolder : folder.getSubFolders()) {
subFolders.add(subFolder);
subFolders.addAll(findSubFolders(subFolder));
}
return subFolders;
}
@Transactional(Transactional.TxType.REQUIRED)
public void moveObjects(final Folder targetFolder,
final String[] objectIds) {
Objects.requireNonNull(targetFolder);
Objects.requireNonNull(objectIds);
for (final String objectId : objectIds) {
if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
moveFolder(targetFolder,
Long.parseLong(objectId.substring(
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length())));
} else if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_ITEM)) {
moveItem(targetFolder,
Long.parseLong(objectId.substring(
FOLDER_BROWSER_KEY_PREFIX_ITEM.length())));
} else {
throw new IllegalArgumentException(String.format(
"ID '%s' does not start with '%s' or '%s'.",
objectId,
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
FOLDER_BROWSER_KEY_PREFIX_ITEM));
}
}
}
private void moveFolder(final Folder targetFolder, final long folderId) {
Objects.requireNonNull(targetFolder);
final Folder folder = folderRepo.findById(folderId)
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No folder with ID %d in the database. "
+ "Where did that ID come from?",
folderId)));
folderManager.moveFolder(folder, targetFolder);
}
private void moveItem(final Folder targetFolder, final long itemId) {
Objects.requireNonNull(targetFolder);
final ContentItem item = itemRepo
.findById(itemId)
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No content item with ID %d in the database. "
+ "Where did that ID come from?",
itemId)));
itemManager.move(item, targetFolder);
}
@Transactional(Transactional.TxType.REQUIRED)
public void copyObjects(final Folder targetFolder,
final String[] objectIds) {
Objects.requireNonNull(targetFolder);
Objects.requireNonNull(objectIds);
for (final String objectId : objectIds) {
if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
copyFolder(targetFolder,
Long.parseLong(objectId.substring(
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length())));
} else if (objectId.startsWith(FOLDER_BROWSER_KEY_PREFIX_ITEM)) {
copyItem(targetFolder,
Long.parseLong(objectId.substring(
FOLDER_BROWSER_KEY_PREFIX_ITEM.length())));
} else {
throw new IllegalArgumentException(String.format(
"ID '%s' does not start with '%s' or '%s'.",
objectId,
FOLDER_BROWSER_KEY_PREFIX_FOLDER,
FOLDER_BROWSER_KEY_PREFIX_ITEM));
}
}
}
private void copyFolder(final Folder targetFolder,
final long folderId) {
Objects.requireNonNull(targetFolder);
final Folder folder = folderRepo.findById(folderId)
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No folder with ID %d in the database. "
+ "Where did that ID come from?",
folderId)));
folderManager.copyFolder(folder, targetFolder);
}
private void copyItem(final Folder targetFolder,
final long itemId) {
Objects.requireNonNull(targetFolder);
final ContentItem item = itemRepo
.findById(itemId)
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No content item with ID %d in the database. "
+ "Where did that ID come from?",
itemId)));
itemManager.copy(item, targetFolder);
}
}

View File

@ -1,73 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.PageState;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.Folder;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class FolderBrowserFilterFormModelBuilder
implements FolderManipulator.FilterFormModelBuilder{
private final FolderBrowser folderBrowser;
public FolderBrowserFilterFormModelBuilder(final FolderBrowser folderBrowser) {
this.folderBrowser = folderBrowser;
}
@Override
public long getFolderSize(final PageState state) {
final FolderSelectionModel folderSelectionModel = folderBrowser
.getFolderSelectionModel();
final Folder folder = folderSelectionModel.getSelectedObject(state);
if (folder == null) {
return 0;
} else {
folderBrowser.getRowSelectionModel().clearSelection(state);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderBrowserController controller = cdiUtil.findBean(
FolderBrowserController.class);
final String filter = folderBrowser.getFilter(state);
final String atozFilter = folderBrowser.getAtoZfilter(state);
final String filterTerm;
if (filter != null && !filter.trim().isEmpty()) {
filterTerm = filter.trim();
} else if (atozFilter != null && !atozFilter.trim().isEmpty()) {
filterTerm = atozFilter.trim();
} else {
filterTerm = null;
}
if (filterTerm == null) {
return controller.countObjects(folder);
} else {
return controller.countObjects(folder);
}
}
}
}

View File

@ -1,81 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.PaginationModelBuilder;
import com.arsdigita.bebop.Paginator;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.Folder;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class FolderBrowserPaginationModelBuilder implements PaginationModelBuilder {
private final FolderBrowser folderBrowser;
public FolderBrowserPaginationModelBuilder(final FolderBrowser folderBrowser) {
this.folderBrowser = folderBrowser;
}
@Override
public int getTotalSize(final Paginator paginator, final PageState state) {
final FolderSelectionModel folderSelectionModel = folderBrowser
.getFolderSelectionModel();
final Folder folder = folderSelectionModel.getSelectedObject(state);
if (folder == null) {
return 0;
} else {
folderBrowser.getRowSelectionModel().clearSelection(state);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderBrowserController controller = cdiUtil.findBean(
FolderBrowserController.class);
final String filter = folderBrowser.getFilter(state);
final String atozFilter = folderBrowser.getAtoZfilter(state);
final int first = paginator.getFirst(state);
final int pageSize = paginator.getPageSize(state);
final String filterTerm;
if (filter != null && !filter.trim().isEmpty()) {
filterTerm = filter.trim();
} else if (atozFilter != null && !atozFilter.trim().isEmpty()) {
filterTerm = atozFilter.trim();
} else {
filterTerm = null;
}
if (filterTerm == null) {
return (int) controller.countObjects(folder);
} else {
return (int) controller.countObjects(folder,
filter);
}
}
}
@Override
public boolean isVisible(final PageState state) {
return folderBrowser != null && folderBrowser.isVisible(state);
}
}

View File

@ -1,115 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.globalization.GlobalizedMessage;
import org.librecms.CmsConstants;
import java.util.Iterator;
import java.util.List;
/**
* Table model for the {@link FolderBrowser}.
*
* @see {FolderBrowserTableModelBuilder}
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class FolderBrowserTableModel implements TableModel {
private static final int COL_NAME = 0;
private static final int COL_LANGUAGES = 1;
private static final int COL_TITLE = 2;
private static final int COL_TYPE = 3;
private static final int COL_CREATION_DATE = 4;
private static final int COL_LAST_MODIFIED = 5;
private static final int COL_DELETEABLE = 6;
private final Iterator<FolderBrowserTableRow> iterator;
private FolderBrowserTableRow currentRow;
public FolderBrowserTableModel(final List<FolderBrowserTableRow> rows) {
iterator = rows.iterator();
}
@Override
public int getColumnCount() {
return 7;
}
@Override
public boolean nextRow() {
if (iterator.hasNext()) {
currentRow = iterator.next();
return true;
} else {
return false;
}
}
@Override
public Object getElementAt(final int columnIndex) {
switch (columnIndex) {
case COL_NAME:
return currentRow.getName();
case COL_LANGUAGES:
return currentRow.getLanguages();
case COL_TITLE:
return currentRow.getTitle();
case COL_TYPE:
final String typeLabelBundle = currentRow.getTypeLabelBundle();
final String typeLabelKey = currentRow.getTypeLabelKey();
if (typeLabelKey == null) {
return new GlobalizedMessage("empty_text",
CmsConstants.CMS_BUNDLE);
} else {
return new GlobalizedMessage(typeLabelKey, typeLabelBundle);
}
case COL_CREATION_DATE:
return currentRow.getCreated();
case COL_LAST_MODIFIED:
return currentRow.getLastModified();
case COL_DELETEABLE:
return currentRow.isDeletable();
default:
throw new IllegalArgumentException(String.format(
"Illegal column index %d.", columnIndex));
}
}
@Override
public Object getKeyAt(final int columnIndex) {
if (currentRow.isFolder()) {
return String.format("folder-%d", currentRow.getObjectId());
} else {
return String.format("item-%d", currentRow.getObjectId());
}
// return currentRow.getObjectId();
}
public boolean isFolder() {
return currentRow.isFolder();
}
}

View File

@ -1,117 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Paginator;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.util.LockableImpl;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.Folder;
import java.util.List;
/**
* Creates the {@link TableModel} for the {@link FolderBrowser}.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class FolderBrowserTableModelBuilder
extends LockableImpl
implements TableModelBuilder {
private final static Logger LOGGER = LogManager.getLogger(
FolderBrowserTableModelBuilder.class);
@Override
public TableModel makeModel(final Table table,
final PageState state) {
if (!(table instanceof FolderBrowser)) {
throw new IllegalArgumentException(
"The FolderBrowserTableModelBuilder can only be used for the "
+ "FolderBrowser.");
}
final FolderBrowser folderBrowser = (FolderBrowser) table;
final FolderSelectionModel folderSelectionModel = folderBrowser
.getFolderSelectionModel();
final Folder folder = folderSelectionModel.getSelectedObject(state);
if (folder == null) {
return Table.EMPTY_MODEL;
} else {
folderBrowser.getRowSelectionModel().clearSelection(state);
final Paginator paginator = folderBrowser.getPaginator();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderBrowserController controller = cdiUtil
.findBean(FolderBrowserController.class);
final String filter = folderBrowser.getFilter(state);
final String orderBy;
if (folderBrowser.getSortType(state) == null) {
orderBy = FolderBrowser.SORT_KEY_NAME;
} else {
orderBy = folderBrowser.getSortType(state);
}
final String orderDirection;
if (folderBrowser.getSortDirection(state) == null) {
orderDirection = FolderBrowser.SORT_ACTION_UP;
} else {
orderDirection = folderBrowser.getSortDirection(state);
}
final String atozFilter = folderBrowser.getAtoZfilter(state);
final int first = paginator.getFirst(state);
final int pageSize = paginator.getPageSize(state);
final String filterTerm;
if (filter != null && !filter.trim().isEmpty()) {
filterTerm = String.format("%s%%", filter.trim());
} else if (atozFilter != null && !atozFilter.trim().isEmpty()) {
filterTerm = String.format("%s%%", atozFilter.trim());
} else {
filterTerm = null;
}
final long start = System.currentTimeMillis();
LOGGER.debug("Retrieving table rows...");
final List<FolderBrowserTableRow> rows;
if (filterTerm == null) {
rows = controller.getObjectRows(folder,
orderBy,
orderDirection,
first - 1,
pageSize);
} else {
rows = controller.getObjectRows(folder,
filterTerm,
orderBy,
orderDirection,
first - 1,
pageSize);
}
LOGGER.debug("Retrieve table rows in {} ms.",
System.currentTimeMillis() - start);
return new FolderBrowserTableModel(rows);
}
}
}

View File

@ -1,152 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* A simple data transfer object containing the data required by the
* {@link FolderBrowser} to display its rows. Used by the
* {@link FolderBrowserTableModelBuilder} to transfer the data from the
* {@link FolderBrowserController} to the {@link FolderBrowserTableModel}.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class FolderBrowserTableRow {
private long objectId;
private String objectUuid;
private String name;
private List<Locale> languages;
private String title;
private String typeLabelBundle;
private String typeLabelKey;
private Date created;
private Date lastModified;
private boolean deletable;
private boolean folder;
public long getObjectId() {
return objectId;
}
protected void setObjectId(final long objectId) {
this.objectId = objectId;
}
public String getObjectUuid() {
return objectUuid;
}
protected void setObjectUuid(final String objectUuid) {
this.objectUuid = objectUuid;
}
public String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
public List<Locale> getLanguages() {
return Collections.unmodifiableList(languages);
}
protected void setLanguages(final List<Locale> languages) {
this.languages = languages;
}
public String getTitle() {
return title;
}
protected void setTitle(final String title) {
this.title = title;
}
public String getTypeLabelBundle() {
return typeLabelBundle;
}
protected void setTypeLabelBundle(final String typeLabelBundle) {
this.typeLabelBundle = typeLabelBundle;
}
public String getTypeLabelKey() {
return typeLabelKey;
}
protected void setTypeLabelKey(final String typeLabelKey) {
this.typeLabelKey = typeLabelKey;
}
public Date getCreated() {
if (created == null) {
return null;
} else {
return new Date(created.getTime());
}
}
protected void setCreated(final Date created) {
if (created == null) {
this.created = null;
} else {
this.created = new Date(created.getTime());
}
}
public Date getLastModified() {
if (lastModified == null) {
return null;
} else {
return new Date(lastModified.getTime());
}
}
protected void setLastModified(final Date lastModified) {
if (lastModified == null) {
this.lastModified = null;
} else {
this.lastModified = new Date(lastModified.getTime());
}
}
public boolean isDeletable() {
return deletable;
}
protected void setDeletable(final boolean deletable) {
this.deletable = deletable;
}
public boolean isFolder() {
return folder;
}
protected void setFolder(final boolean folder) {
this.folder = folder;
}
}

View File

@ -1,103 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.categorization.CategoryManager;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.ConfigurationManager;
import org.librecms.CmsConstants;
import org.librecms.contentsection.Folder;
import org.librecms.contentsection.FolderManager;
import org.librecms.contentsection.FolderRepository;
import static com.arsdigita.cms.ui.folder.FolderForm.*;
public class FolderCreateForm extends FolderForm {
public FolderCreateForm(final String name, final FolderSelectionModel parent) {
super(name, parent);
}
@Override
public void init(final FormSectionEvent event) throws FormProcessException {
final PageState state = event.getPageState();
final FolderSelectionModel model = getFolderSelectionModel();
}
/**
* Validates the form. Checks for name uniqueness.
*
* @param event
* @throws com.arsdigita.bebop.FormProcessException
*
*/
@Override
public void validate(final FormSectionEvent event)
throws FormProcessException {
final Folder folder = getCurrentFolder(event.getPageState());
final FormData data = event.getFormData();
final String name = data.getString(NAME);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryManager categoryManager = cdiUtil.findBean(
CategoryManager.class);
if (categoryManager.hasSubCategoryWithName(folder, name)) {
data.addError(new GlobalizedMessage(
"cms.ui.folderform.error.child.name_not_unique",
CmsConstants.CMS_BUNDLE,
new Object[]{name}));
}
}
@Override
public void process(final FormSectionEvent event) throws
FormProcessException {
final PageState state = event.getPageState();
final FormData data = event.getFormData();
final Folder parent = getCurrentFolder(state);
final String name = data.getString(NAME);
final String title = data.getString(TITLE);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderRepository folderRepo = cdiUtil.findBean(
FolderRepository.class);
final FolderManager folderManager = cdiUtil
.findBean(FolderManager.class);
final ConfigurationManager confManager = cdiUtil.findBean(
ConfigurationManager.class);
final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class);
final Folder folder = folderManager.createFolder(name, parent);
folder.getTitle().putValue(kernelConfig.getDefaultLocale(), title);
folderRepo.save(folder);
}
}

View File

@ -1,93 +0,0 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.FolderManager;
class FolderEditForm extends FolderBaseForm {
private static Logger LOGGER = LogManager.getLogger(FolderEditForm.class);
private final FolderRequestLocal folderRequestLocal;
public FolderEditForm(final FolderRequestLocal folder) {
super("folder-edit");
folderRequestLocal = folder;
// XXX need to do name uniqueness valdation on m_fragment here
// as well.
addInitListener(new InitListener());
addProcessListener(new ProcessListener());
}
private static FolderRequestLocal parent(final FolderRequestLocal folder) {
final FolderRequestLocal parent = new FolderRequestLocal(null) {
@Override
protected final Object initialValue(final PageState state) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderManager folderManager = cdiUtil.findBean(
FolderManager.class);
return folderManager.getParentFolder(getFolder(state))
.orElse(null);
}
};
return parent;
}
private class InitListener implements FormInitListener {
public final void init(final FormSectionEvent e) {
final PageState state = e.getPageState();
final Category folder = folderRequestLocal.getFolder(state);
m_title.setValue(state, folder.getDisplayName());
m_fragment.setValue(state, folder.getName());
}
}
private class ProcessListener implements FormProcessListener {
public final void process(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
final Category folder = folderRequestLocal.getFolder(state);
folder.setDisplayName((String) m_title.getValue(state));
folder.setName((String) m_fragment.getValue(state));
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository categoryRepo = cdiUtil.findBean(CategoryRepository.class);
categoryRepo.save(folder);
}
}
}

View File

@ -1,109 +0,0 @@
/*
* 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.ui.folder;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryManager;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.ConfigurationManager;
import org.librecms.CmsConstants;
import org.librecms.contentsection.Folder;
import static com.arsdigita.cms.ui.folder.FolderForm.*;
/**
* Implements functionality for renaming a folder. Most code taken from
* FolderCreator. Need to refactor out base functionality of FolderEditorForm &
* Creator.
*
* @author <a href="mailto:jorris@arsdigita.com">Jon Orris</a>
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens >Pelzetter</a>
*
*/
public class FolderEditorForm extends FolderForm {
public FolderEditorForm(final String name, final FolderSelectionModel folder) {
super(name, folder);
}
/**
* Initialise the form with name & label of folder being edited.
*
* @param event
*
* @throws com.arsdigita.bebop.FormProcessException
*/
@Override
public void init(final FormSectionEvent event) throws FormProcessException {
final PageState state = event.getPageState();
final FormData data = event.getFormData();
final Folder folder = getCurrentFolder(state);
data.put(NAME, folder.getName());
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderEditorFormController controller = cdiUtil.findBean(
FolderEditorFormController.class
);
data.put(TITLE, controller.getFolderTitle(folder));
}
/**
* Validates the form. Checks for name uniqueness.
*
* @param event
*
* @throws com.arsdigita.bebop.FormProcessException
*/
@Override
public void validate(final FormSectionEvent event)
throws FormProcessException {
final Category folder = getCurrentFolder(event.getPageState())
.getParentCategory();
final FormData data = event.getFormData();
final String name = data.getString(NAME);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryManager categoryManager = cdiUtil.findBean(
CategoryManager.class);
if (categoryManager.hasSubCategoryWithName(folder, name)) {
data.addError(new GlobalizedMessage(
"cms.ui.folderform.error.parent.name_not_unique",
CmsConstants.CMS_BUNDLE,
new Object[]{name}));
}
}
@Override
public void process(final FormSectionEvent event) throws
FormProcessException {
final PageState state = event.getPageState();
final FormData data = event.getFormData();
final Folder folder = getCurrentFolder(state);
updateFolder(folder, (String) data.get(NAME), (String) data.get(TITLE));
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright (C) 2021 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.configuration.ConfigurationManager;
import org.librecms.contentsection.Folder;
import org.librecms.contentsection.FolderRepository;
import java.util.Objects;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class FolderEditorFormController {
@Inject
private ConfigurationManager confManager;
@Inject
private FolderRepository folderRepository;
@Transactional(Transactional.TxType.REQUIRED)
public String getFolderTitle(final Folder ofFolder) {
final Folder folder = folderRepository
.findById(Objects.requireNonNull(ofFolder).getObjectId())
.orElseThrow(
() -> new IllegalArgumentException(
String.format("No folder with ID %d available.",
ofFolder.getObjectId())
)
);
final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class
);
return folder.getTitle().getValue(kernelConfig.getDefaultLocale());
}
}

View File

@ -1,413 +0,0 @@
/*
* 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.ui.folder;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.FormSection;
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.FormValidationListener;
import com.arsdigita.bebop.form.Hidden;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.parameters.NotNullValidationListener;
import com.arsdigita.bebop.parameters.TrimmedStringParameter;
import com.arsdigita.bebop.parameters.URLTokenValidationListener;
import com.arsdigita.cms.ui.authoring.BasicItemForm;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.util.Assert;
import com.arsdigita.web.Web;
import com.arsdigita.xml.Element;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.l10n.GlobalizationHelper;
import org.librecms.CmsConstants;
import org.librecms.contentsection.Folder;
import org.librecms.contentsection.FolderManager;
/**
* Class FolderForm implements the basic form for creating or editing folders.
*
* Originally folders were ContentItems. For CCM NG we changed that and now use
* Categories to provide the folder hierarchy. Thus this class originally
* extended the {@link BasicItemForm} class. Now this class is separate. Some
* parts have been created by simply coping the relevant parts from
* {@link BasicItemForm}. Therefore it is possible that comments etc still refer
* to {@link BasicItemForm}.
*
* @author <a href="mailto:jorris@arsdigita.com">Jon Orris</a>
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public abstract class FolderForm extends Form implements FormInitListener,
FormProcessListener,
FormValidationListener {
public static final Logger LOGGER = LogManager.getLogger(FolderForm.class);
public static final String FOLDER_ID = "FolderId";
public static final String NAME = "FolderName";
public static final String TITLE = "FolderTitle";
public static final String DESC = "FolderDesc";
private final FolderSelectionModel currentFolder;
private final SaveCancelSection saveCancelSection;
// private final FormSection widgetSection;
// /**
// * Currently, to insert javascript code the Label Widget is "abused".
// */
// private final Label m_script = new Label(String.format(
// "<script language=\"javascript\" src=\"%s/javascript/manipulate-input.js\"></script>",
// Web.getWebappContextPath()),
// false);
/**
* Create a new folder form.
*
* @param formName Name of the form
* @param currentFolder SelectionModel containing the current folder being
* operated on.
*
* @pre name != null && folder != null
*/
public FolderForm(final String formName,
final FolderSelectionModel currentFolder) {
super(formName, new ColumnPanel(2));
// widgetSection = new FormSection(new ColumnPanel(2, true));
// super.add(widgetSection, ColumnPanel.INSERT);
this.currentFolder = currentFolder;
final ColumnPanel panel = (ColumnPanel) getPanel();
panel.setBorder(false);
panel.setPadColor("#FFFFFF");
panel.setColumnWidth(1, "20%");
panel.setColumnWidth(2, "80%");
panel.setWidth("100%");
/* Add basic contents */
addWidgets();
saveCancelSection = new SaveCancelSection();
super.add(saveCancelSection,
ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
addInitListener(this);
addProcessListener(this);
addValidationListener(this);
}
/**
* Constructs a new {@code FolderForm} with a specified number of
* {@link ColumnPanel}s and without content.
*
* @param formName
* @param columnPanel
* @param currentFolder
*/
public FolderForm(final String formName,
final ColumnPanel columnPanel,
final FolderSelectionModel currentFolder) {
super(formName, columnPanel);
// widgetSection = new FormSection(
// new ColumnPanel(columnPanel.getNumCols()));
// super.add(widgetSection, ColumnPanel.INSERT);
this.currentFolder = currentFolder;
saveCancelSection = new SaveCancelSection();
super.add(saveCancelSection,
ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
}
/**
* Add basic widgets to the form.
*
* Widgets added are 'title' and 'name (url)'. Child classes will override
* this method to perform all their widget-adding needs but are supposed to
* use super() to add the basic widgets.
*/
protected void addWidgets() {
final Hidden id = new Hidden(FOLDER_ID);
add(id);
// JavaScript auto-name generation is off by default.
// It is turned on under the following circumstances
//
// * If the name is null, upon starting edit of the title
// * If the name is null, upon finishing edit of name
//
// The rationale is that, auto-name generation is useful
// if the name is currently null, but once a name has been
// created you don't want to subsequently change it since
// it breaks URLs & potentially overwrites the user's
// customizations.
final TextField titleWidget = new TextField(new TrimmedStringParameter(
TITLE));
titleWidget.setLabel(getTitleLabel());
titleWidget.setHint(getTitleHint());
titleWidget.addValidationListener(new NotNullValidationListener());
titleWidget.setOnFocus("if (this.form." + NAME + ".value == '') { "
+ " defaulting = true; this.form." + NAME
+ ".value = urlize(this.value); }");
titleWidget.setOnKeyUp(
"if (defaulting) { this.form." + NAME
+ ".value = urlize(this.value) }");
add(titleWidget);
final TextField nameWidget = new TextField(new TrimmedStringParameter(
NAME));
nameWidget.setLabel(getNameLabel());
nameWidget.setHint(getNameHint());
// We just check parameter specific properties here! Additionally,
// context properties as uniqueness in folder must be validated
// for the form es the whole (using the validate method required by
// implementing FormValidationListener in this form.
nameWidget.addValidationListener(new NotNullValidationListener());
nameWidget.addValidationListener(new URLTokenValidationListener());
nameWidget.setMaxLength(190);
nameWidget.setOnFocus("defaulting = false");
nameWidget.setOnBlur(
"if (this.value == '') "
+ "{ defaulting = true; this.value = urlize(this.form."
+ TITLE
+ ".value) } "
+ " else { this.value = urlize(this.value); }");
add(nameWidget);
}
@Override
public void register(final Page page) {
super.register(page);
page.addComponentStateParam(this, currentFolder.getStateParameter());
}
@Override
public void generateXML(final PageState state, final Element parent) {
// m_script.generateXML(state, parent);
super.generateXML(state, parent);
}
/**
* Perform form initialisation. Children should override this this method to
* pre-fill the widgets with data, instantiate the content item, etc.
*
* @param event
*
* @throws FormProcessException
*/
@Override
public abstract void init(final FormSectionEvent event)
throws FormProcessException;
/**
* Process the form. Children have to override this method to save the
* user's changes to the database.
*
* @param event
*
* @throws FormProcessException
*/
@Override
public abstract void process(final FormSectionEvent event)
throws FormProcessException;
/**
* Validates the form. Checks for name uniqueness.
*
* @param event
*
* @throws com.arsdigita.bebop.FormProcessException
*/
@Override
public void validate(final FormSectionEvent event)
throws FormProcessException {
final Folder folder = getCurrentFolder(event.getPageState());
final FormData data = event.getFormData();
final String name = data.getString(NAME);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryManager categoryManager = cdiUtil.findBean(
CategoryManager.class);
if (categoryManager.hasSubCategoryWithName(folder, name)) {
data.addError(new GlobalizedMessage(
"cms.ui.folderform.error.child.name_not_unique",
CmsConstants.CMS_BUNDLE,
new Object[]{name}));
}
}
/**
* Adds a component to this container.
*
* @param component the component to add to this FolderForm
*
*/
// @Override
// public void add(final Component component) {
// widgetSection.add(component);
// }
/**
* Adds a component with the specified layout constraints to this container.
* Layout constraints are defined in each layout container as static ints.
* Use a bitwise OR to specify multiple constraints.
*
* @param component the component to add to this container
* @param constraints layout constraints (a bitwise OR of static ints in the
* particular layout)
*/
// @Override
// public void add(final Component component, final int constraints) {
// widgetSection.add(component, constraints);
// }
/**
* This method can be overridden to change the label of the title field. To
* change to label of the title field can be useful for some content types.
* For example, for an organization the label "Title" for the field may be
* confusing for the normal user. For such a content type, the label would
* be changed to something like "Name of the organization".
*
* @return (Content for the) Label for the title field as string
*/
protected GlobalizedMessage getTitleLabel() {
return new GlobalizedMessage("cms.contenttypes.ui.title",
CmsConstants.CMS_BUNDLE);
}
/**
* Provides the text for the user hint providing some detailed information
* how to use this widget. This method can be overwritten to adjust the text
* for some content types. {@link #getTitleLabel()}
*
* @return
*/
protected GlobalizedMessage getTitleHint() {
return new GlobalizedMessage("cms.contenttypes.ui.title_hint",
CmsConstants.CMS_BUNDLE);
}
/**
* This method does the same as {@link #getTitleLabel() } for the labe l of
* the name (URL) field.
*
* @return (Content for the) Label for the name field as string
*/
protected GlobalizedMessage getNameLabel() {
return new GlobalizedMessage("cms.contenttypes.ui.name",
CmsConstants.CMS_BUNDLE);
}
/**
* Provides the text for the user hint providing some detailed information
* how to use this widget. This method can be overwritten to adjust the text
* for some content types. {@link #getNameLabel()}
*
* @return
*/
protected GlobalizedMessage getNameHint() {
return new GlobalizedMessage("cms.contenttypes.ui.name_hint",
CmsConstants.CMS_BUNDLE);
}
/**
* Returns true if the form submission was cancelled.
*
* @param state
*
* @return
*/
public boolean isCancelled(final PageState state) {
return saveCancelSection.getCancelButton().isSelected(state);
}
/**
* Updates a folder with a new parent, name, and label.
*
* @param folder The folder to update
* @param parent The new parent folder. May be null.
* @param name The new name of the folder
* @param label The new label for the folder
*/
final protected void updateFolder(final Folder folder,
final Category parent,
final String name,
final String label) {
folder.setParentCategory(parent);
updateFolder(folder, name, label);
}
/**
* Updates a folder with a new name and label.
*
* @param folder The folder to update
* @param name The new name of the folder
* @param label The new label for the folder
*/
final protected void updateFolder(final Folder folder,
final String name,
final String label) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ConfigurationManager confManager = cdiUtil.findBean(
ConfigurationManager.class);
final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class);
folder.setName(name);
folder.setDisplayName(name);
folder.getTitle().putValue(kernelConfig.getDefaultLocale(), label);
final CategoryRepository categoryRepo = cdiUtil.findBean(
CategoryRepository.class);
categoryRepo.save(folder);
}
/**
* Returns the current folder being operated on.
*
* @param state
*
* @return The current folder
*
*/
final protected Folder getCurrentFolder(final PageState state) {
final Folder folder = currentFolder.getSelectedObject(state);
return folder;
}
final protected FolderSelectionModel getFolderSelectionModel() {
return currentFolder;
}
}

View File

@ -1,37 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.List;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class FolderPath extends List {
public FolderPath(final FolderSelectionModel folderSelectionModel) {
super(new FolderPathListModelBuilder(folderSelectionModel));
setAttribute("type", "item-path");
setSelectionModel(folderSelectionModel);
}
}

View File

@ -1,89 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.list.ListModel;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.ConfigurationManager;
import org.librecms.contentsection.Folder;
import org.librecms.contentsection.FolderManager;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class FolderPathListModel implements ListModel {
private final Locale defaultLocale;
private final Iterator<Folder> pathFolders;
private Folder currentFolder;
public FolderPathListModel(final Folder folder) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderManager folderManager = cdiUtil
.findBean(FolderManager.class);
final List<Folder> parentFolders = folderManager
.getParentFolders(folder);
final List<Folder> path = new ArrayList<>();
path.addAll(parentFolders);
path.add(folder);
pathFolders = path.iterator();
final ConfigurationManager confManager = cdiUtil.findBean(
ConfigurationManager.class);
final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class);
defaultLocale = kernelConfig.getDefaultLocale();
}
@Override
public boolean next() {
if (pathFolders.hasNext()) {
currentFolder = pathFolders.next();
return true;
} else {
return false;
}
}
@Override
public Object getElement() {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderPathListModelController controller = cdiUtil
.findBean(FolderPathListModelController.class);
return controller.getElement(currentFolder, defaultLocale);
}
@Override
public String getKey() {
return Long.toString(currentFolder.getObjectId());
}
}

View File

@ -1,51 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.List;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.list.ListModel;
import com.arsdigita.bebop.list.ListModelBuilder;
import com.arsdigita.util.LockableImpl;
import org.librecms.contentsection.Folder;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class FolderPathListModelBuilder extends LockableImpl
implements ListModelBuilder {
private final FolderSelectionModel folderSelectionModel;
public FolderPathListModelBuilder(
final FolderSelectionModel folderSelectionModel) {
this.folderSelectionModel = folderSelectionModel;
}
@Override
public ListModel makeModel(final List list, final PageState state) {
return new FolderPathListModel(
folderSelectionModel.getSelectedObject(state));
}
}

View File

@ -1,51 +0,0 @@
/*
* Copyright (C) 2019 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import org.librecms.contentsection.Folder;
import org.librecms.contentsection.FolderRepository;
import java.util.Locale;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class FolderPathListModelController {
@Inject
private FolderRepository folderRepository;
@Transactional(Transactional.TxType.REQUIRED)
public String getElement(final Folder folder, final Locale locale) {
final Folder result = folderRepository
.findById(folder.getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No folder wit ID %d found.", folder.getObjectId())));
return result.getTitle().getValue(locale);
}
}

View File

@ -1,68 +0,0 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.cms.ui.CcmObjectRequestLocal;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.Folder;
import java.util.Optional;
public class FolderRequestLocal extends CcmObjectRequestLocal {
private final SingleSelectionModel m_model;
public FolderRequestLocal(final SingleSelectionModel model) {
m_model = model;
}
public FolderRequestLocal() {
m_model = null;
}
@Override
protected Object initialValue(final PageState state) {
if (m_model == null) {
return null;
} else {
final String id = m_model.getSelectedKey(state).toString();
return CdiUtil.createCdiUtil().findBean(CategoryRepository.class)
.findById(Long.parseLong(id));
}
}
public final Folder getFolder(final PageState state) {
final Object object = get(state);
final Object selected;
if (object instanceof Optional) {
selected = ((Optional<?>) object).get();
} else {
selected = object;
}
return (Folder) selected;
}
}

View File

@ -1,103 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.ui.CcmObjectSelectionModel;
import org.libreccm.categorization.Category;
import org.librecms.contentsection.Folder;
/**
* Keeps track of the selection of an item in a folder. The objects that are
* selected by this model are all subclasses of {@link
* com.arsdigita.cms.Folder}.
*
* @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a>
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public abstract class FolderSelectionModel extends CcmObjectSelectionModel<Folder> {
public FolderSelectionModel(final String name) {
super(Category.class.getName(), name);
}
public FolderSelectionModel(final SingleSelectionModel<Long> model) {
super(Category.class.getName(), model);
}
@Override
public Long getSelectedKey(final PageState state) {
// FIXME: this code will go away once parameter models support init listeners
Long result = super.getSelectedKey(state);
if (result == null) {
result = getRootFolderID(state);
setSelectedKey(state, result);
}
return result;
}
@Override
public void setSelectedKey(final PageState state, final Long key) {
super.setSelectedKey(state, key);
}
/**
* Clear the selection by resetting it to the root folder id.
*
* @param state represents the current request.
*/
@Override
public void clearSelection(final PageState state) {
setSelectedKey(state, getRootFolderID(state));
}
/**
* Return the ID of the root folder. By default, this is the root folder of
* the content section in which the current request is made. If this model
* is to be used outside a content section, this method has to be overriden
* appropriately.
*
* @param state represents the current request
* @return the ID of the root folder
*
* @pre s != null
* @post return != null
*/
protected abstract Long getRootFolderID(final PageState state);
// {
// ContentSection sec = CMS.getContext().getContentSection();
// return sec.getRootDocumentsFolder().getObjectId();
// }
/**
* Return true, since this selection model will always have a folder
* selected in it
*
* @param state
* @return
*/
@Override
public boolean isSelected(final PageState state) {
return true;
}
}

View File

@ -1,70 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Tree;
import com.arsdigita.cms.CMS;
import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.Folder;
import static org.librecms.CmsConstants.*;
public class FolderTree extends Tree {
public FolderTree(final FolderSelectionModel folderSel) {
super(new FolderTreeModelBuilder() {
@Override
protected Folder getRootFolder(final PageState state) {
final ContentSection section = CMS
.getContext()
.getContentSection();
return section.getRootDocumentsFolder();
}
});
setSelectionModel(folderSel);
}
@Override
public void setSelectedKey(final PageState state, final Object key) {
if (key instanceof String) {
final Long keyAsLong;
if (((String) key).startsWith(
FOLDER_BROWSER_KEY_PREFIX_FOLDER)) {
keyAsLong = Long.parseLong(((String) key).substring(
FOLDER_BROWSER_KEY_PREFIX_FOLDER.length()));
} else {
keyAsLong = Long.parseLong((String) key);
}
super.setSelectedKey(state, keyAsLong);
} else if (key instanceof Long) {
super.setSelectedKey(state, key);
} else {
//We know that a FolderSelectionModel only takes keys of type Long.
//Therefore we try to cast here
final Long keyAsLong = (Long) key;
super.setSelectedKey(state, keyAsLong);
}
}
}

View File

@ -1,192 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.tree.TreeModel;
import com.arsdigita.bebop.tree.TreeModelBuilder;
import com.arsdigita.bebop.tree.TreeNode;
import com.arsdigita.cms.CMS;
import com.arsdigita.kernel.KernelConfig;
import org.librecms.contentsection.ContentSection;
import com.arsdigita.util.LockableImpl;
import java.util.Collections;
import java.util.Iterator;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.l10n.GlobalizationHelper;
import org.librecms.contentsection.Folder;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import org.libreccm.configuration.ConfigurationManager;
/**
* A {@link com.arsdigita.bebop.tree.TreeModelBuilder} that produces trees
* containing the folder structure underneath a root folder. The root folder can
* be changed by overriding {@link #getRoot getRoot}.
*
* @author <a href="mailto:tri@arsdigita.com">Tri Tran</a>
* @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a>
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public abstract class FolderTreeModelBuilder
extends LockableImpl
implements TreeModelBuilder {
/**
* Make a tree model that lists the hierarchy of folders underneath the
* folder returned by {@link #getRoot getRoot}.
*
* @param tree the tree in which the model is used
* @param state represents the current request
*
* @return a tree model that lists the hierarchy of folders underneath the
* folder returned by {@link #getRoot getRoot}.
*/
@Override
public TreeModel makeModel(final Tree tree, final PageState state) {
return new TreeModel() {
@Override
public TreeNode getRoot(final PageState state) {
return new FolderTreeNode(getRootFolder(state));
}
@Override
public boolean hasChildren(final TreeNode node,
final PageState state) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderTreeModelController controller = cdiUtil.findBean(
FolderTreeModelController.class);
return controller.hasChildren(node);
}
@Override
public Iterator<TreeNode> getChildren(final TreeNode node,
final PageState state) {
final String nodeKey = node.getKey().toString();
// Always expand root node
if (nodeKey.equals(getRoot(state).getKey().toString())
&& tree.isCollapsed(nodeKey, state)) {
tree.expand(nodeKey, state);
}
if (tree.isCollapsed(nodeKey, state)) {
return Collections.emptyIterator();
}
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final FolderTreeModelController controller = cdiUtil.findBean(
FolderTreeModelController.class);
final List<Folder> subFolders = controller.getChildren(node);
return subFolders.stream()
.map(folder -> generateTreeNode(folder))
.sorted((node1, node2) -> {
return ((String) node1.getElement())
.compareTo((String) node2.getElement());
})
.collect(Collectors.toList())
.iterator();
}
private TreeNode generateTreeNode(final Folder folder) {
final FolderTreeNode node = new FolderTreeNode(folder);
return node;
}
};
}
// /**
// * Return the root folder for the tree model in the current request.
// *
// * @param state represents the current request
// *
// * @return the root folder for the tree
// *
// */
//// protected Folder getRootFolder(final PageState state)
// throws IllegalStateException {
//
// final ContentSection section = CMS.getContext().getContentSection();
// return section.getRootDocumentsFolder();
// }
/**
* Return the root folder for the tree model in the current request.
*
* @param state represents the current request
*
* @return the root folder for the tree
*
*/
protected abstract Folder getRootFolder(final PageState state);
private class FolderTreeNode implements TreeNode {
private final Folder folder;
public FolderTreeNode(final Folder folder) {
this.folder = folder;
}
@Override
public Object getKey() {
return folder.getObjectId();
}
@Override
public Object getElement() {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final GlobalizationHelper globalizationHelper = cdiUtil.findBean(
GlobalizationHelper.class);
final FolderTreeModelController controller = cdiUtil
.findBean(FolderTreeModelController.class);
final Locale locale = globalizationHelper.getNegotiatedLocale();
if (controller.hasTitleValue(folder, locale)) {
return controller.getTitleValue(folder, locale);
} else {
final ConfigurationManager confManager = cdiUtil.findBean(
ConfigurationManager.class);
final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class);
final String value = controller
.getTitleValue(folder,
kernelConfig.getDefaultLocale());
if (value == null) {
return folder.getName();
} else {
return value;
}
}
}
}
}

View File

@ -1,125 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.tree.TreeNode;
import org.libreccm.categorization.Category;
import org.libreccm.core.UnexpectedErrorException;
import org.librecms.contentsection.Folder;
import org.librecms.contentsection.FolderRepository;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class FolderTreeModelController {
@Inject
private FolderRepository folderRepo;
private Folder getCurrentFolder(final TreeNode node) {
if (node == null) {
throw new IllegalArgumentException(
"Can't get current folder from null.");
}
// final Folder current = (Folder) node.getElement();
final Optional<Folder> folder = folderRepo
.findById((long) node.getKey());
if (folder.isPresent()) {
return folder.get();
} else {
throw new IllegalArgumentException(String.format(
"The provided TreeNode contains a folder (%s) which is not in "
+ "the database.",
folder.toString()));
}
}
@Transactional(Transactional.TxType.REQUIRED)
public boolean hasTitleValue(final Folder ofFolder,
final Locale forLocale) {
final Folder folder = folderRepo
.findById(ofFolder.getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No folder with Id %d found.",
ofFolder.getObjectId())));
return folder.getTitle().hasValue(forLocale);
}
@Transactional(Transactional.TxType.REQUIRED)
public String getTitleValue(final Folder ofFolder,
final Locale forLocale) {
final Folder folder = folderRepo
.findById(ofFolder.getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No folder with Id %d found.",
ofFolder.getObjectId())));
return folder.getTitle().getValue(forLocale);
}
@Transactional(Transactional.TxType.REQUIRED)
public boolean hasChildren(final TreeNode node) {
return !getCurrentFolder(node).getSubCategories().isEmpty();
}
@Transactional(Transactional.TxType.REQUIRED)
public List<Folder> getChildren(final TreeNode node) {
return getCurrentFolder(node).getSubFolders();
}
@Transactional(Transactional.TxType.REQUIRED)
public List<Long> findAncestorIds(final Folder folder) {
Objects.requireNonNull(folder,
"Can't find ids of the ancestors of folder null.");
final Optional<Folder> theFolder = folderRepo.findById(folder
.getObjectId());
if (!theFolder.isPresent()) {
throw new UnexpectedErrorException(String.format(
"The folder %s was not found in the database, but it should be there.",
Objects.toString(folder)));
}
final List<Long> ancestorIds = new ArrayList<>();
Category current = theFolder.get();
while (current != null) {
ancestorIds.add(current.getObjectId());
current = current.getParentCategory();
}
return ancestorIds;
}
}

View File

@ -1,39 +0,0 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.List;
import com.arsdigita.cms.ItemSelectionModel;
/**
* Produce a list of the items starting from the selected item's root down to
* the item itself.
*
* @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a>
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ItemPath extends List {
public ItemPath(final ItemSelectionModel itemSelectionModel) {
super(new ItemPathListModelBuilder(itemSelectionModel));
setAttribute("type", "item-path");
setSelectionModel(itemSelectionModel);
}
}

View File

@ -1,66 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.list.ListModel;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemManager;
import org.librecms.contentsection.Folder;
import java.util.Iterator;
/**
* Model for {@link ItemPath}. This was originally a inner class.
*
* @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a>
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class ItemPathListModel implements ListModel {
private final Iterator<Folder> pathFolders;
private Folder currentFolder;
public ItemPathListModel(final ContentItem item) {
pathFolders = CdiUtil.createCdiUtil().findBean(
ContentItemManager.class).getItemFolders(item).iterator();
}
@Override
public boolean next() {
if (pathFolders.hasNext()) {
currentFolder = pathFolders.next();
return true;
} else {
return false;
}
}
@Override
public Object getElement() {
return currentFolder.getName();
}
@Override
public String getKey() {
return Long.toString(currentFolder.getObjectId());
}
}

View File

@ -1,51 +0,0 @@
/*
* Copyright (C) 2017 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.List;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.list.ListModelBuilder;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.util.LockableImpl;
/**
* ModelBuilder for {@link ItemPath}. This was originally an inner class.
*
* @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a>
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class ItemPathListModelBuilder extends LockableImpl implements ListModelBuilder {
private final ItemSelectionModel itemSelectionModel;
public ItemPathListModelBuilder(
final ItemSelectionModel itemSelectionModel) {
this.itemSelectionModel = itemSelectionModel;
}
@Override
public com.arsdigita.bebop.list.ListModel makeModel(
final List list, final PageState state) {
return new ItemPathListModel(itemSelectionModel.getSelectedObject(
state));
}
}