CCM NG/ccm-cms: BrowsePane migrated to NG APIs
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4527 8810af33-2d31-482b-a856-94f89814c4dfccm-docs
parent
26455a2ae4
commit
fafba0080d
|
|
@ -0,0 +1 @@
|
|||
mvn clean package site site:stage -Dmaven.test.failure.ignore=true -Pwildfly-remote-h2-mem
|
||||
|
|
@ -36,11 +36,7 @@ import com.arsdigita.cms.ui.folder.FolderTreeModelBuilder;
|
|||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.toolbox.ui.LayoutPanel;
|
||||
import com.arsdigita.util.Assert;
|
||||
import com.arsdigita.web.Web;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.librecms.CmsConstants;
|
||||
|
|
@ -51,25 +47,23 @@ import org.librecms.CmsConstants;
|
|||
* the "Browse" tab.
|
||||
*
|
||||
* @author David LutterKort <dlutter@redhat.com>
|
||||
* @version $Id: BrowsePane.java 1325 2006-09-22 08:11:33Z sskracic $
|
||||
* @author <a href="jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class BrowsePane extends LayoutPanel implements Resettable {
|
||||
|
||||
private static final Logger s_log = Logger.getLogger(BrowsePane.class);
|
||||
|
||||
private final BaseTree m_tree;
|
||||
private final SingleSelectionModel m_model;
|
||||
private final FolderSelectionModel m_folderModel; // To support legacy UI code
|
||||
private final FolderRequestLocal m_folder;
|
||||
private final FlatItemList m_fil;
|
||||
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;
|
||||
|
||||
public BrowsePane() {
|
||||
|
||||
/* The folder tree displayed on the left side / left column */
|
||||
m_tree = new BaseTree(new FolderTreeModelBuilder());
|
||||
m_model = m_tree.getSelectionModel();
|
||||
m_folderModel = new FolderSelectionModel(m_model);
|
||||
m_folder = new FolderRequestLocal(m_folderModel);
|
||||
tree = new BaseTree(new FolderTreeModelBuilder());
|
||||
selectionModel = tree.getSelectionModel();
|
||||
folderModel = new FolderSelectionModel(selectionModel);
|
||||
folderRequestLocal = new FolderRequestLocal(folderModel);
|
||||
|
||||
final SegmentedPanel left = new SegmentedPanel();
|
||||
setLeft(left);
|
||||
|
|
@ -77,21 +71,21 @@ public class BrowsePane extends LayoutPanel implements Resettable {
|
|||
final Label heading = new Label(
|
||||
new GlobalizedMessage("cms.ui.folder_browser",
|
||||
CmsConstants.CMS_FOLDER_BUNDLE));
|
||||
left.addSegment(heading, m_tree);
|
||||
left.addSegment(heading, tree);
|
||||
|
||||
m_fil = new FlatItemList(m_folder, m_folderModel);
|
||||
setBody(m_fil);
|
||||
flatItemList = new FlatItemList(folderRequestLocal, folderModel);
|
||||
setBody(flatItemList);
|
||||
|
||||
m_fil.getManipulator().getItemView().addProcessListener(
|
||||
flatItemList.getManipulator().getItemView().addProcessListener(
|
||||
new ProcessListener());
|
||||
m_fil.getManipulator().getTargetSelector().addProcessListener(
|
||||
flatItemList.getManipulator().getTargetSelector().addProcessListener(
|
||||
new ProcessListener());
|
||||
m_fil.getManipulator().getTargetSelector().addSubmissionListener(
|
||||
flatItemList.getManipulator().getTargetSelector().addSubmissionListener(
|
||||
new SubmissionListener());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void register(Page page) {
|
||||
public final void register(final Page page) {
|
||||
super.register(page);
|
||||
|
||||
page.addActionListener(new FolderListener());
|
||||
|
|
@ -99,10 +93,10 @@ public class BrowsePane extends LayoutPanel implements Resettable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public final void reset(PageState state) {
|
||||
public final void reset(final PageState state) {
|
||||
super.reset(state);
|
||||
|
||||
m_fil.reset(state);
|
||||
flatItemList.reset(state);
|
||||
}
|
||||
|
||||
// Private classes and methods
|
||||
|
|
@ -111,19 +105,16 @@ public class BrowsePane extends LayoutPanel implements Resettable {
|
|||
*/
|
||||
private final class ProcessListener implements FormProcessListener {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
public final void process(final FormSectionEvent e) {
|
||||
final PageState state = e.getPageState();
|
||||
@Override
|
||||
public final void process(final FormSectionEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
if (e.getSource() == m_fil.getManipulator().getItemView()) {
|
||||
if (event.getSource() == flatItemList.getManipulator().getItemView()) {
|
||||
// Hide everything except for the flat item list
|
||||
m_tree.setVisible(state, false);
|
||||
} else if (e.getSource() == m_fil.getManipulator()
|
||||
tree.setVisible(state, false);
|
||||
} else if (event.getSource() == flatItemList.getManipulator()
|
||||
.getTargetSelector()) {
|
||||
m_tree.setVisible(state, true);
|
||||
tree.setVisible(state, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -131,12 +122,15 @@ public class BrowsePane extends LayoutPanel implements Resettable {
|
|||
|
||||
private final class SubmissionListener implements FormSubmissionListener {
|
||||
|
||||
public final void submitted(final FormSectionEvent e) {
|
||||
final PageState s = e.getPageState();
|
||||
@Override
|
||||
public final void submitted(final FormSectionEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
if (e.getSource() == m_fil.getManipulator().getTargetSelector()) {
|
||||
if (!m_fil.getManipulator().getTargetSelector().isVisible(s)) {
|
||||
m_tree.setVisible(s, true);
|
||||
if (event.getSource() == flatItemList.getManipulator()
|
||||
.getTargetSelector()) {
|
||||
if (!flatItemList.getManipulator().getTargetSelector()
|
||||
.isVisible(state)) {
|
||||
tree.setVisible(state, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -145,17 +139,18 @@ public class BrowsePane extends LayoutPanel implements Resettable {
|
|||
|
||||
private final class FolderListener implements ActionListener {
|
||||
|
||||
public final void actionPerformed(final ActionEvent e) {
|
||||
final PageState state = e.getPageState();
|
||||
@Override
|
||||
public final void actionPerformed(final ActionEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
if (!m_model.isSelected(state)) {
|
||||
if (!selectionModel.isSelected(state)) {
|
||||
final String folder = state.getRequest().getParameter(
|
||||
ContentSectionPage.SET_FOLDER);
|
||||
|
||||
if (folder == null) {
|
||||
final Category root = CMS.getContext().getContentSection()
|
||||
.getRootDocumentsFolder();
|
||||
Long folderID = root.getObjectId();
|
||||
final Long folderID = root.getObjectId();
|
||||
|
||||
/*
|
||||
ToDo
|
||||
|
|
@ -168,9 +163,9 @@ public class BrowsePane extends LayoutPanel implements Resettable {
|
|||
}
|
||||
|
||||
}*/
|
||||
m_model.setSelectedKey(state, folderID);
|
||||
selectionModel.setSelectedKey(state, folderID);
|
||||
} else {
|
||||
m_model.setSelectedKey(state, folder);
|
||||
selectionModel.setSelectedKey(state, folder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -179,21 +174,22 @@ public class BrowsePane extends LayoutPanel implements Resettable {
|
|||
|
||||
private final class TreeListener implements ActionListener {
|
||||
|
||||
public final void actionPerformed(final ActionEvent e) {
|
||||
final PageState state = e.getPageState();
|
||||
@Override
|
||||
public final void actionPerformed(final ActionEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
if (Assert.isEnabled()) {
|
||||
Assert.isTrue(m_model.isSelected(state));
|
||||
Assert.isTrue(selectionModel.isSelected(state));
|
||||
}
|
||||
|
||||
final Category root = CMS.getContext().getContentSection()
|
||||
.getRootDocumentsFolder();
|
||||
|
||||
if (!root.equals(m_folder.getFolder(state))) {
|
||||
if (!root.equals(folderRequestLocal.getFolder(state))) {
|
||||
// Expand the ancestor nodes of the currently
|
||||
// selected node.
|
||||
|
||||
CcmObject object = m_folder.getFolder(state);
|
||||
CcmObject object = folderRequestLocal.getFolder(state);
|
||||
|
||||
while (object != null) {
|
||||
if (object instanceof Category) {
|
||||
|
|
@ -204,7 +200,7 @@ public class BrowsePane extends LayoutPanel implements Resettable {
|
|||
|
||||
if (result instanceof Category) {
|
||||
object = result;
|
||||
m_tree.expand(
|
||||
tree.expand(
|
||||
((Long) object.getObjectId()).toString(),
|
||||
state);
|
||||
} else {
|
||||
|
|
@ -119,7 +119,7 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
|
|||
|
||||
private TabbedPane m_tabbedPane;
|
||||
private FolderAdminPane m_folderPane;
|
||||
//ToDo NG private BrowsePane m_browsePane;
|
||||
private BrowsePane m_browsePane;
|
||||
private ItemSearch m_searchPane;
|
||||
//ToDo NG private ImagesPane m_imagesPane;
|
||||
private RoleAdminPane m_rolePane;
|
||||
|
|
@ -146,7 +146,7 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
|
|||
|
||||
// Initialize the individual panes
|
||||
m_folderPane = getFolderAdminPane();
|
||||
//ToDo NG m_browsePane = getBrowsePane();
|
||||
m_browsePane = getBrowsePane();
|
||||
m_searchPane = getSearchPane();
|
||||
//ToDo NG m_imagesPane = getImagesPane();
|
||||
m_rolePane = getRoleAdminPane();
|
||||
|
|
@ -237,13 +237,12 @@ public class ContentSectionPage extends CMSPage implements ActionListener {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
// ToDo NG
|
||||
// protected BrowsePane getBrowsePane() {
|
||||
// if (m_browsePane == null) {
|
||||
// m_browsePane = new BrowsePane();
|
||||
// }
|
||||
// return m_browsePane;
|
||||
// }
|
||||
protected BrowsePane getBrowsePane() {
|
||||
if (m_browsePane == null) {
|
||||
m_browsePane = new BrowsePane();
|
||||
}
|
||||
return m_browsePane;
|
||||
}
|
||||
/**
|
||||
* Creates, and then caches, the search pane. Overriding this method to
|
||||
* return null will prevent this tab from appearing.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,535 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import com.arsdigita.bebop.ActionLink;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.FormProcessException;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.Page;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.ParameterSingleSelectionModel;
|
||||
import com.arsdigita.bebop.Resettable;
|
||||
import com.arsdigita.bebop.SegmentedPanel;
|
||||
import com.arsdigita.bebop.SingleSelectionModel;
|
||||
import com.arsdigita.bebop.event.ActionEvent;
|
||||
import com.arsdigita.bebop.event.ActionListener;
|
||||
import com.arsdigita.bebop.event.ChangeEvent;
|
||||
import com.arsdigita.bebop.event.ChangeListener;
|
||||
import com.arsdigita.bebop.event.FormProcessListener;
|
||||
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||
import com.arsdigita.bebop.event.FormSubmissionListener;
|
||||
import com.arsdigita.bebop.event.PrintEvent;
|
||||
import com.arsdigita.bebop.event.PrintListener;
|
||||
import com.arsdigita.bebop.parameters.LongParameter;
|
||||
import com.arsdigita.cms.CMS;
|
||||
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
|
||||
import com.arsdigita.cms.ui.authoring.CreationSelector;
|
||||
import com.arsdigita.cms.ui.authoring.NewItemForm;
|
||||
import com.arsdigita.cms.ui.folder.FolderCreator;
|
||||
import com.arsdigita.cms.ui.folder.FolderEditor;
|
||||
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.cms.ui.permissions.CMSPermissionsPane;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
|
||||
import com.arsdigita.toolbox.ui.ActionGroup;
|
||||
import com.arsdigita.ui.CcmObjectSelectionModel;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
import org.libreccm.security.PermissionManager;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.contentsection.Folder;
|
||||
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Encapsulates a {@link FolderManipulator} in order to create a flat item
|
||||
* listing. Also contains a new item form.
|
||||
*
|
||||
* @author <a href="mailto:sfreidin@arsdigita.com">Stanislav Freidin</a>
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class FlatItemList extends SegmentedPanel implements FormProcessListener,
|
||||
ChangeListener,
|
||||
FormSubmissionListener,
|
||||
Resettable,
|
||||
ActionListener {
|
||||
|
||||
private static final String CONTENT_TYPE_ID = "ct";
|
||||
// The folder selectors
|
||||
private final FolderSelectionModel folderSelectionModel;
|
||||
private final FolderRequestLocal folderRequestLocal;
|
||||
private final NewItemForm newItemForm;
|
||||
private final SingleSelectionModel<Long> typeSelectionModel;
|
||||
private final CreationSelector creationSelector;
|
||||
private final FolderManipulator folderManipulator;
|
||||
private final FolderCreator folderCreator;
|
||||
// private final ActionLink m_setHomeFolderAction;
|
||||
// private final ActionLink m_removeHomeFolderAction;
|
||||
private final ActionLink createFolderAction;
|
||||
private final ActionLink togglePrivateAction;
|
||||
// private final Label m_homeFolderLabel;
|
||||
private final Segment browseSegment;
|
||||
private final Segment newItemSegment;
|
||||
private final Segment newFolderSegment;
|
||||
private final Segment editFolderSegment;
|
||||
private final Segment permissionsSegment;
|
||||
private final CMSPermissionsPane permissionsPane;
|
||||
// Folder edit/rename functionality.
|
||||
private final ActionLink editFolderAction;
|
||||
private final FolderEditor folderEditor;
|
||||
private final Label contentLabel;
|
||||
private final FolderPath folderPath;
|
||||
private final Label chooseLabel;
|
||||
|
||||
/**
|
||||
* Construct a new item listing pane. The provided folder selection model is
|
||||
* used to keep track of the currently displayed folder.
|
||||
*
|
||||
* @param folderRequestLocal
|
||||
* @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()));
|
||||
|
||||
setIdAttr("flat-item-list");
|
||||
|
||||
newItemSegment = addSegment();
|
||||
newItemSegment.setIdAttr("folder-new-item");
|
||||
|
||||
newFolderSegment = addSegment();
|
||||
newFolderSegment.setIdAttr("folder-new-folder");
|
||||
|
||||
editFolderSegment = addSegment();
|
||||
editFolderSegment.setIdAttr("folder-edit-folder");
|
||||
|
||||
browseSegment = addSegment();
|
||||
browseSegment.setIdAttr("folder-browse");
|
||||
|
||||
final ActionGroup browseActions = new ActionGroup();
|
||||
browseSegment.add(browseActions);
|
||||
|
||||
// The top 'browse' segment
|
||||
contentLabel = new Label(globalize("cms.ui.contents_of"), false);
|
||||
browseSegment.addHeader(contentLabel);
|
||||
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);
|
||||
|
||||
// The actions
|
||||
createFolderAction = new ActionLink(new Label(globalize(
|
||||
"cms.ui.new_folder")));
|
||||
createFolderAction.addActionListener(this);
|
||||
browseActions.addAction(createFolderAction);
|
||||
|
||||
editFolderAction = new ActionLink(new Label(globalize(
|
||||
"cms.ui.edit_folder")));
|
||||
editFolderAction.addActionListener(this);
|
||||
browseActions.addAction(editFolderAction);
|
||||
|
||||
// m_setHomeFolderAction = new ActionLink(new Label(globalize(
|
||||
// "cms.ui.set_home_folder")));
|
||||
// m_setHomeFolderAction.addActionListener(this);
|
||||
// browseActions.addAction(m_setHomeFolderAction);
|
||||
// m_homeFolderLabel = new Label(new PrintListener() {
|
||||
//
|
||||
// @Override
|
||||
// public final void prepare(final PrintEvent event) {
|
||||
// Label label = (Label) event.getTarget();
|
||||
// User user = Web.getWebContext().getUser();
|
||||
//
|
||||
// Folder folder = Folder.getUserHomeFolder(user, CMS.getContext()
|
||||
// .getContentSection());
|
||||
// if (folder != null) {
|
||||
// String url = folder.getContentSection().getURL()
|
||||
// + PageLocations.SECTION_PAGE + "?"
|
||||
// + ContentSectionPage.SET_FOLDER + "="
|
||||
// + folder.getID();
|
||||
// //label.setLabel("Go to home folder: <a href=\"" + url + "\">" + folder.getLabel() + "</a>");
|
||||
// String[] parts = new String[3];
|
||||
// parts[0] = "";
|
||||
// parts[1] = url;
|
||||
// parts[2] = folder.getLabel();
|
||||
// // label.setLabel(String.format("%s: <a href=\"%s\">%s</a>",
|
||||
// // (String) globalize("cms.ui.go_to_home_folder").localize(),
|
||||
// // url,
|
||||
// // folder.getLabel()));
|
||||
// label.setLabel(globalize("cms.ui.go_to_home_folder", parts));
|
||||
// } else {
|
||||
// //label.setLabel("<font color=\"red\">No home folder selected</font>");
|
||||
// String[] parts = new String[3];
|
||||
// parts[0] = "";
|
||||
// parts[1] = "";
|
||||
// //label.setLabel(String.format("<span style=\"color: red\">%s</span>",
|
||||
// // (String)globalize("cms.ui.no_home_folder_selected").localize()));
|
||||
// label.setLabel(globalize("cms.ui.no_home_folder_selected",
|
||||
// parts));
|
||||
// }
|
||||
// label.setOutputEscaping(false);
|
||||
// }
|
||||
//
|
||||
// });
|
||||
// browseActions.addAction(m_homeFolderLabel);
|
||||
// m_removeHomeFolderAction = new ActionLink(new Label(globalize(
|
||||
// "cms.ui.remove_home_folder")));
|
||||
// m_removeHomeFolderAction.addActionListener(this);
|
||||
// browseActions.addAction(m_removeHomeFolderAction);
|
||||
|
||||
/* */
|
||||
newItemForm = new SectionNewItemForm("newItem");
|
||||
newItemForm.addProcessListener(this);
|
||||
browseActions.addAction(newItemForm);
|
||||
|
||||
/* permission */
|
||||
permissionsSegment = addSegment();
|
||||
permissionsSegment.setIdAttr("folder-permissions");
|
||||
|
||||
final ActionGroup permissionActions = new ActionGroup();
|
||||
permissionsSegment.add(permissionActions);
|
||||
|
||||
// The permissions segment
|
||||
permissionsSegment.addHeader(new Label(new GlobalizedMessage(
|
||||
"cms.ui.permissions", CmsConstants.CMS_BUNDLE)));
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionManager permissionManager = cdiUtil.findBean(
|
||||
PermissionManager.class);
|
||||
final List<String> privileges = permissionManager
|
||||
.listDefiniedPrivileges(ItemPrivileges.class);
|
||||
final Map<String, String> privNameMap = new HashMap<>();
|
||||
privileges.forEach(privilege -> privNameMap.put(privilege, privilege));
|
||||
|
||||
permissionsPane = new CMSPermissionsPane(
|
||||
privileges.toArray(new String[]{}),
|
||||
privNameMap,
|
||||
(CcmObjectSelectionModel) folderSelectionModel);
|
||||
permissionActions.setSubject(permissionsPane);
|
||||
|
||||
// An action
|
||||
togglePrivateAction = new ActionLink(new Label(new PrintListener() {
|
||||
|
||||
@Override
|
||||
public void prepare(final PrintEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
final Label target = (Label) event.getTarget();
|
||||
final Folder currentFolder = folderRequestLocal.getFolder(state);
|
||||
// ACSObject parent = currentFolder.getParent();
|
||||
|
||||
// if (context == null) {
|
||||
target.setLabel(new GlobalizedMessage(
|
||||
"cms.ui.restore_default_permissions",
|
||||
CmsConstants.CMS_BUNDLE));
|
||||
// } else {
|
||||
// target.setLabel(GlobalizationUtil
|
||||
// .globalize("cms.ui.use_custom_permissions"));
|
||||
// }
|
||||
}
|
||||
|
||||
}));
|
||||
togglePrivateAction.addActionListener(this);
|
||||
permissionActions.addAction(togglePrivateAction);
|
||||
|
||||
// The 'new item' segment
|
||||
newItemSegment.addHeader(new Label(globalize("cms.ui.new_item")));
|
||||
typeSelectionModel = new ParameterSingleSelectionModel<>(
|
||||
new LongParameter(CONTENT_TYPE_ID));
|
||||
typeSelectionModel.addChangeListener(this);
|
||||
|
||||
creationSelector = new CreationSelector(typeSelectionModel,
|
||||
folderSelectionModel);
|
||||
newItemSegment.add(creationSelector);
|
||||
//m_newItemSeg.add(new Label("<br/>", false));
|
||||
|
||||
// The 'new folder' segment
|
||||
newFolderSegment.addHeader(new Label(globalize("cms.ui.new_folder")));
|
||||
Form folderCreate = new Form("fcreat");
|
||||
folderCreator = new FolderCreator("fcreat", folderSelectionModel);
|
||||
folderCreator.addSubmissionListener(this);
|
||||
folderCreator.addProcessListener(this);
|
||||
folderCreate.add(folderCreator);
|
||||
newFolderSegment.add(folderCreate);
|
||||
newFolderSegment.add(new Label("<br/>", false));
|
||||
|
||||
editFolderSegment.addHeader(new Label(globalize("cms.ui.edit_folder")));
|
||||
folderEditor = new FolderEditor("fedit", folderSelectionModel);
|
||||
folderEditor.addSubmissionListener(this);
|
||||
folderEditor.addProcessListener(this);
|
||||
|
||||
Form folderEditorForm = new Form("fedit_form");
|
||||
folderEditorForm.add(folderEditor);
|
||||
editFolderSegment.add(folderEditorForm);
|
||||
editFolderSegment.add(new Label("<br/>", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(final Page page) {
|
||||
super.register(page);
|
||||
|
||||
page.setVisibleDefault(chooseLabel, false);
|
||||
page.setVisibleDefault(newItemSegment, false);
|
||||
page.setVisibleDefault(newFolderSegment, false);
|
||||
page.setVisibleDefault(editFolderSegment, false);
|
||||
|
||||
page
|
||||
.addComponentStateParam(this, typeSelectionModel.getStateParameter());
|
||||
|
||||
page.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
if (state.isVisibleOnPage(FlatItemList.this)) {
|
||||
showHideSegments(state);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show/hide segments based on access checks.
|
||||
*
|
||||
* @param state The page state
|
||||
*
|
||||
* @pre ( state != null )
|
||||
*/
|
||||
private void showHideSegments(final PageState state) {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
final Folder folder = folderRequestLocal.getFolder(state);
|
||||
|
||||
// MP: This should be checked on the current folder instead of just
|
||||
// the content section.
|
||||
final boolean newItem = permissionChecker.isPermitted(
|
||||
ItemPrivileges.CREATE_NEW, folder);
|
||||
|
||||
if (!newItem) {
|
||||
browseMode(state);
|
||||
}
|
||||
createFolderAction.setVisible(state, newItem);
|
||||
newItemForm.setVisible(state, newItem);
|
||||
|
||||
final boolean editItem = permissionChecker.isPermitted(
|
||||
ItemPrivileges.EDIT, folder);
|
||||
|
||||
editFolderAction.setVisible(state, editItem);
|
||||
|
||||
if (permissionChecker.isPermitted(ItemPrivileges.ADMINISTER, folder)) {
|
||||
permissionsSegment.setVisible(state, true);
|
||||
} else {
|
||||
permissionsSegment.setVisible(state, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void browseMode(final PageState state) {
|
||||
browseSegment.setVisible(state, true);
|
||||
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);
|
||||
|
||||
typeSelectionModel.clearSelection(state);
|
||||
}
|
||||
|
||||
private void newItemMode(final PageState state) {
|
||||
permissionsSegment.setVisible(state, false);
|
||||
newItemSegment.setVisible(state, true);
|
||||
}
|
||||
|
||||
private void newFolderMode(final PageState state) {
|
||||
permissionsSegment.setVisible(state, false);
|
||||
newFolderSegment.setVisible(state, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitted(final FormSectionEvent event)
|
||||
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 == newItemForm) {
|
||||
final Long typeID = newItemForm.getTypeID(state);
|
||||
typeSelectionModel.setSelectedKey(state, typeID);
|
||||
newItemMode(state);
|
||||
} else 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
|
||||
public void stateChanged(final ChangeEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
if (event.getSource().equals(typeSelectionModel)) {
|
||||
if (!typeSelectionModel.isSelected(state)) {
|
||||
browseMode(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
final Object source = event.getSource();
|
||||
if (source == createFolderAction) {
|
||||
newFolderMode(state);
|
||||
} else if (source == editFolderAction) {
|
||||
permissionsSegment.setVisible(state, false);
|
||||
editFolderSegment.setVisible(state, true);
|
||||
} else if (source == togglePrivateAction) {
|
||||
togglePermissions(state);
|
||||
}
|
||||
// } else if (source == m_setHomeFolderAction) {
|
||||
// User user = Web.getWebContext().getUser();
|
||||
// Folder folder = m_folder.getFolder(state);
|
||||
// user = (User) DomainObjectFactory.newInstance(user.getOID());
|
||||
// Folder.setUserHomeFolder(user, folder);
|
||||
// } else if (source == m_removeHomeFolderAction) {
|
||||
// User user = Web.getWebContext().getUser();
|
||||
// ContentSection section = CMS.getContext().getContentSection();
|
||||
// UserHomeFolderMap map = UserHomeFolderMap
|
||||
// .findUserHomeFolderMap(user, section);
|
||||
// if (map != null) {
|
||||
// map.delete();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private void togglePermissions(final PageState state) {
|
||||
final Folder currentFolder = folderRequestLocal.getFolder(state);
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
permissionChecker.checkPermission(ItemPrivileges.ADMINISTER,
|
||||
currentFolder);
|
||||
|
||||
permissionsPane.reset(state);
|
||||
}
|
||||
|
||||
@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
|
||||
permissionsPane.reset(state);
|
||||
}
|
||||
|
||||
public final FolderManipulator getManipulator() {
|
||||
return folderManipulator;
|
||||
}
|
||||
|
||||
public final CMSPermissionsPane getPermissionsPane() {
|
||||
return permissionsPane;
|
||||
}
|
||||
|
||||
public void setPermissionLinkVis(PageState state) {
|
||||
final Folder currentFolder = folderRequestLocal.getFolder(state);
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
if (!permissionChecker.isPermitted(ItemPrivileges.ADMINISTER,
|
||||
currentFolder)) {
|
||||
togglePrivateAction.setVisible(state, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SectionNewItemForm extends NewItemForm {
|
||||
|
||||
public SectionNewItemForm(final String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentSection getContentSection(final PageState state) {
|
||||
return CMS.getContext().getContentSection();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting the GlobalizedMessage using a CMS Class targetBundle.
|
||||
*
|
||||
* @param key The resource key
|
||||
*
|
||||
* @pre ( key != null )
|
||||
*/
|
||||
private static GlobalizedMessage globalize(final String key) {
|
||||
return ContentSectionPage.globalize(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,604 +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;
|
||||
|
||||
import com.arsdigita.bebop.ActionLink;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.FormProcessException;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.Page;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.ParameterSingleSelectionModel;
|
||||
import com.arsdigita.bebop.Resettable;
|
||||
import com.arsdigita.bebop.SegmentedPanel;
|
||||
import com.arsdigita.bebop.SingleSelectionModel;
|
||||
import com.arsdigita.bebop.event.ActionEvent;
|
||||
import com.arsdigita.bebop.event.ActionListener;
|
||||
import com.arsdigita.bebop.event.ChangeEvent;
|
||||
import com.arsdigita.bebop.event.ChangeListener;
|
||||
import com.arsdigita.bebop.event.FormProcessListener;
|
||||
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||
import com.arsdigita.bebop.event.FormSubmissionListener;
|
||||
import com.arsdigita.bebop.event.PrintEvent;
|
||||
import com.arsdigita.bebop.event.PrintListener;
|
||||
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
||||
import com.arsdigita.cms.CMS;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import com.arsdigita.cms.dispatcher.Utilities;
|
||||
import com.arsdigita.cms.ui.authoring.CreationSelector;
|
||||
import com.arsdigita.cms.ui.authoring.NewItemForm;
|
||||
import com.arsdigita.cms.ui.folder.FolderCreator;
|
||||
import com.arsdigita.cms.ui.folder.FolderEditor;
|
||||
import com.arsdigita.cms.ui.folder.FolderManipulator;
|
||||
import com.arsdigita.cms.ui.folder.FolderRequestLocal;
|
||||
import com.arsdigita.cms.ui.folder.FolderSelectionModel;
|
||||
import com.arsdigita.cms.ui.folder.ItemPath;
|
||||
import com.arsdigita.cms.ui.permissions.CMSPermissionsPane;
|
||||
import com.arsdigita.cms.util.GlobalizationUtil;
|
||||
import com.arsdigita.domain.DomainObjectFactory;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.kernel.ACSObject;
|
||||
import com.arsdigita.kernel.Kernel;
|
||||
import com.arsdigita.kernel.User;
|
||||
import com.arsdigita.kernel.permissions.ObjectPermissionCollection;
|
||||
import com.arsdigita.kernel.permissions.PermissionDescriptor;
|
||||
import com.arsdigita.kernel.permissions.PermissionService;
|
||||
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
|
||||
import com.arsdigita.persistence.DataObject;
|
||||
import com.arsdigita.persistence.DataQuery;
|
||||
import com.arsdigita.persistence.SessionManager;
|
||||
import com.arsdigita.toolbox.ui.ActionGroup;
|
||||
import com.arsdigita.util.Assert;
|
||||
import com.arsdigita.web.Web;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Encapsulates a {@link FolderManipulator} in order to create a flat item
|
||||
* listing. Also contains a new item form.
|
||||
*
|
||||
* @author <a href="mailto:sfreidin@arsdigita.com">Stanislav Freidin</a>
|
||||
* @version $Id: FlatItemList.java 1538 2007-03-23 16:26:36Z apevec $
|
||||
*/
|
||||
public class FlatItemList extends SegmentedPanel
|
||||
implements FormProcessListener, ChangeListener, FormSubmissionListener,
|
||||
Resettable, ActionListener {
|
||||
|
||||
private static final String CONTENT_TYPE_ID = "ct";
|
||||
private static final String CMS_PRIVILEGES = "com.arsdigita.cms.getPrivileges";
|
||||
private static final String PRIVILEGE = "privilege";
|
||||
private static final String PRIVILEGE_NAME = "prettyName";
|
||||
// The folder selectors
|
||||
private final FolderSelectionModel m_folderSel;
|
||||
private FolderRequestLocal m_folder;
|
||||
private final NewItemForm m_newItem;
|
||||
private final SingleSelectionModel m_typeSel;
|
||||
private final CreationSelector m_selector;
|
||||
private final FolderManipulator m_folderManip;
|
||||
private final FolderCreator m_folderCreator;
|
||||
private final ActionLink m_setHomeFolderAction;
|
||||
private final ActionLink m_removeHomeFolderAction;
|
||||
private final ActionLink m_createFolderAction;
|
||||
private final ActionLink m_togglePrivateAction;
|
||||
private final Label m_homeFolderLabel;
|
||||
private final Segment m_browseSeg;
|
||||
private final Segment m_newItemSeg;
|
||||
private final Segment m_newFolderSeg;
|
||||
private final Segment m_editFolderSeg;
|
||||
private final Segment m_permissionsSeg;
|
||||
private final CMSPermissionsPane m_permPane;
|
||||
// Folder edit/rename functionality.
|
||||
private final ActionLink m_editFolderAction;
|
||||
private final FolderEditor m_folderEditor;
|
||||
private final Label m_contentLabel;
|
||||
private final ItemPath m_itemPath;
|
||||
private final Label m_chooseLabel;
|
||||
|
||||
/**
|
||||
* Construct a new item listing pane. The provided folder selection model
|
||||
* is used to keep track of the currently displayed folder.
|
||||
*
|
||||
* @param folder
|
||||
* @param model maintains the currently displayed folder.
|
||||
*/
|
||||
public FlatItemList(final FolderRequestLocal folder,
|
||||
final FolderSelectionModel model) {
|
||||
m_folder = folder;
|
||||
m_folderSel = model;
|
||||
m_folderSel.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
PageState s = e.getPageState();
|
||||
reset(s);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
setIdAttr("flat-item-list");
|
||||
|
||||
m_newItemSeg = addSegment();
|
||||
m_newItemSeg.setIdAttr("folder-new-item");
|
||||
|
||||
m_newFolderSeg = addSegment();
|
||||
m_newFolderSeg.setIdAttr("folder-new-folder");
|
||||
|
||||
m_editFolderSeg = addSegment();
|
||||
m_editFolderSeg.setIdAttr("folder-edit-folder");
|
||||
|
||||
m_browseSeg = addSegment();
|
||||
m_browseSeg.setIdAttr("folder-browse");
|
||||
|
||||
final ActionGroup browseActions = new ActionGroup();
|
||||
m_browseSeg.add(browseActions);
|
||||
|
||||
// The top 'browse' segment
|
||||
m_contentLabel = new Label(globalize("cms.ui.contents_of"), false);
|
||||
m_browseSeg.addHeader(m_contentLabel);
|
||||
m_chooseLabel = new Label(globalize("cms.ui.choose_target_folder"), false);
|
||||
m_browseSeg.addHeader(m_chooseLabel);
|
||||
m_itemPath = new ItemPath(m_folderSel);
|
||||
//m_itemPath = new Label(new PrintListener() {
|
||||
// public final void prepare(final PrintEvent e) {
|
||||
// final Folder f = m_folder.getFolder(e.getPageState());
|
||||
// ((Label) e.getTarget()).setLabel(f.getDisplayName());
|
||||
// }
|
||||
// });
|
||||
|
||||
m_browseSeg.addHeader(m_itemPath);
|
||||
m_folderManip = new FolderManipulator(m_folderSel);
|
||||
m_folderManip.getItemView().addProcessListener(this);
|
||||
m_folderManip.getTargetSelector().addProcessListener(this);
|
||||
m_folderManip.getTargetSelector().addSubmissionListener(this);
|
||||
|
||||
browseActions.setSubject(m_folderManip);
|
||||
|
||||
// The actions
|
||||
|
||||
m_createFolderAction = new ActionLink(new Label(globalize("cms.ui.new_folder")));
|
||||
m_createFolderAction.addActionListener(this);
|
||||
browseActions.addAction(m_createFolderAction);
|
||||
|
||||
m_editFolderAction = new ActionLink(new Label(globalize("cms.ui.edit_folder")));
|
||||
m_editFolderAction.addActionListener(this);
|
||||
browseActions.addAction(m_editFolderAction);
|
||||
|
||||
m_setHomeFolderAction = new ActionLink(new Label(globalize("cms.ui.set_home_folder")));
|
||||
m_setHomeFolderAction.addActionListener(this);
|
||||
browseActions.addAction(m_setHomeFolderAction);
|
||||
|
||||
m_homeFolderLabel = new Label(new PrintListener() {
|
||||
@Override
|
||||
public final void prepare(final PrintEvent e) {
|
||||
Label label = (Label) e.getTarget();
|
||||
User user = Web.getWebContext().getUser();
|
||||
|
||||
Folder folder = Folder.getUserHomeFolder(user, CMS.getContext().getContentSection());
|
||||
if (folder != null) {
|
||||
String url = folder.getContentSection().getURL() + PageLocations.SECTION_PAGE + "?"
|
||||
+ ContentSectionPage.SET_FOLDER + "=" + folder.getID();
|
||||
//label.setLabel("Go to home folder: <a href=\"" + url + "\">" + folder.getLabel() + "</a>");
|
||||
String[] parts = new String[3];
|
||||
parts[0] = "";
|
||||
parts[1] = url;
|
||||
parts[2] = folder.getLabel();
|
||||
// label.setLabel(String.format("%s: <a href=\"%s\">%s</a>",
|
||||
// (String) globalize("cms.ui.go_to_home_folder").localize(),
|
||||
// url,
|
||||
// folder.getLabel()));
|
||||
label.setLabel( globalize("cms.ui.go_to_home_folder",parts) );
|
||||
} else {
|
||||
//label.setLabel("<font color=\"red\">No home folder selected</font>");
|
||||
String[] parts = new String[3];
|
||||
parts[0] = "";
|
||||
parts[1] = "";
|
||||
//label.setLabel(String.format("<span style=\"color: red\">%s</span>",
|
||||
// (String)globalize("cms.ui.no_home_folder_selected").localize()));
|
||||
label.setLabel( globalize("cms.ui.no_home_folder_selected",parts) );
|
||||
}
|
||||
label.setOutputEscaping(false);
|
||||
}
|
||||
|
||||
});
|
||||
browseActions.addAction(m_homeFolderLabel);
|
||||
|
||||
m_removeHomeFolderAction = new ActionLink(new Label(globalize("cms.ui.remove_home_folder")));
|
||||
m_removeHomeFolderAction.addActionListener(this);
|
||||
browseActions.addAction(m_removeHomeFolderAction);
|
||||
|
||||
/* */
|
||||
m_newItem = new SectionNewItemForm("newItem");
|
||||
m_newItem.addProcessListener(this);
|
||||
browseActions.addAction(m_newItem);
|
||||
|
||||
/* permission */
|
||||
m_permissionsSeg = addSegment();
|
||||
m_permissionsSeg.setIdAttr("folder-permissions");
|
||||
|
||||
final ActionGroup permActions = new ActionGroup();
|
||||
m_permissionsSeg.add(permActions);
|
||||
|
||||
// The permissions segment
|
||||
m_permissionsSeg.addHeader(new Label(GlobalizationUtil.globalize("cms.ui.permissions")));
|
||||
|
||||
List privs = new ArrayList();
|
||||
Map privNameMap = new HashMap();
|
||||
DataQuery query = SessionManager.getSession().retrieveQuery(CMS_PRIVILEGES);
|
||||
query.addFilter("scope != 'section'");
|
||||
query.addOrder("sortOrder");
|
||||
while (query.next()) {
|
||||
String privilege = (String) query.get(PRIVILEGE);
|
||||
String privilegeName = (String) query.get(PRIVILEGE_NAME);
|
||||
privs.add(PrivilegeDescriptor.get(privilege));
|
||||
privNameMap.put(privilege, privilegeName);
|
||||
}
|
||||
query.close();
|
||||
|
||||
m_permPane =
|
||||
new CMSPermissionsPane((PrivilegeDescriptor[]) privs.toArray(new PrivilegeDescriptor[privs.size()]),
|
||||
privNameMap,
|
||||
m_folderSel);
|
||||
permActions.setSubject(m_permPane);
|
||||
|
||||
// An action
|
||||
|
||||
m_togglePrivateAction = new ActionLink(new Label(new PrintListener() {
|
||||
public void prepare(PrintEvent e) {
|
||||
PageState state = e.getPageState();
|
||||
Label target = (Label) e.getTarget();
|
||||
Folder currentFolder = m_folder.getFolder(state);
|
||||
// ACSObject parent = currentFolder.getParent();
|
||||
DataObject context = PermissionService.getContext(currentFolder);
|
||||
if (context == null) {
|
||||
target.setLabel(GlobalizationUtil
|
||||
.globalize("cms.ui.restore_default_permissions"));
|
||||
} else {
|
||||
target.setLabel(GlobalizationUtil
|
||||
.globalize("cms.ui.use_custom_permissions"));
|
||||
}
|
||||
}
|
||||
|
||||
}));
|
||||
m_togglePrivateAction.addActionListener(this);
|
||||
permActions.addAction(m_togglePrivateAction);
|
||||
|
||||
// The 'new item' segment
|
||||
m_newItemSeg.addHeader(new Label(globalize("cms.ui.new_item")));
|
||||
m_typeSel = new ParameterSingleSelectionModel(new BigDecimalParameter(CONTENT_TYPE_ID));
|
||||
m_typeSel.addChangeListener(this);
|
||||
|
||||
m_selector = new CreationSelector(m_typeSel, m_folderSel);
|
||||
m_newItemSeg.add(m_selector);
|
||||
//m_newItemSeg.add(new Label("<br/>", false));
|
||||
|
||||
// The 'new folder' segment
|
||||
m_newFolderSeg.addHeader(new Label(globalize("cms.ui.new_folder")));
|
||||
Form folderCreate = new Form("fcreat");
|
||||
m_folderCreator = new FolderCreator("fcreat", m_folderSel);
|
||||
m_folderCreator.addSubmissionListener(this);
|
||||
m_folderCreator.addProcessListener(this);
|
||||
folderCreate.add(m_folderCreator);
|
||||
m_newFolderSeg.add(folderCreate);
|
||||
m_newFolderSeg.add(new Label("<br/>", false));
|
||||
|
||||
m_editFolderSeg.addHeader(new Label(globalize("cms.ui.edit_folder")));
|
||||
m_folderEditor = new FolderEditor("fedit", m_folderSel);
|
||||
m_folderEditor.addSubmissionListener(this);
|
||||
m_folderEditor.addProcessListener(this);
|
||||
|
||||
Form folderEditorForm = new Form("fedit_form");
|
||||
folderEditorForm.add(m_folderEditor);
|
||||
m_editFolderSeg.add(folderEditorForm);
|
||||
m_editFolderSeg.add(new Label("<br/>", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Page p) {
|
||||
super.register(p);
|
||||
|
||||
p.setVisibleDefault(m_chooseLabel, false);
|
||||
p.setVisibleDefault(m_newItemSeg, false);
|
||||
p.setVisibleDefault(m_newFolderSeg, false);
|
||||
p.setVisibleDefault(m_editFolderSeg, false);
|
||||
|
||||
p.addComponentStateParam(this, m_typeSel.getStateParameter());
|
||||
|
||||
p.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final PageState state = e.getPageState();
|
||||
|
||||
if (state.isVisibleOnPage(FlatItemList.this)) {
|
||||
showHideSegments(state);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show/hide segments based on access checks.
|
||||
*
|
||||
* @param state The page state
|
||||
* @pre ( state != null )
|
||||
*/
|
||||
private void showHideSegments(PageState state) {
|
||||
SecurityManager sm = Utilities.getSecurityManager(state);
|
||||
Folder folder = m_folder.getFolder(state);
|
||||
Assert.exists(folder);
|
||||
|
||||
// MP: This should be checked on the current folder instead of just
|
||||
// the content section.
|
||||
boolean newItem =
|
||||
sm.canAccess(state.getRequest(),
|
||||
SecurityManager.NEW_ITEM,
|
||||
folder);
|
||||
|
||||
if (!newItem) {
|
||||
browseMode(state);
|
||||
}
|
||||
m_createFolderAction.setVisible(state, newItem);
|
||||
m_newItem.setVisible(state, newItem);
|
||||
|
||||
final boolean editItem = sm.canAccess(state.getRequest(),
|
||||
SecurityManager.EDIT_ITEM,
|
||||
folder);
|
||||
|
||||
m_editFolderAction.setVisible(state, editItem);
|
||||
|
||||
User user = (User) Kernel.getContext().getParty();
|
||||
PermissionDescriptor perm =
|
||||
new PermissionDescriptor(PrivilegeDescriptor.ADMIN,
|
||||
folder,
|
||||
user);
|
||||
|
||||
if (PermissionService.checkPermission(perm)) {
|
||||
m_permissionsSeg.setVisible(state, true);
|
||||
} else {
|
||||
m_permissionsSeg.setVisible(state, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void browseMode(PageState s) {
|
||||
m_browseSeg.setVisible(s, true);
|
||||
m_permissionsSeg.setVisible(s, true);
|
||||
m_chooseLabel.setVisible(s, false);
|
||||
m_contentLabel.setVisible(s, true);
|
||||
m_itemPath.setVisible(s, true);
|
||||
m_newItemSeg.setVisible(s, false);
|
||||
m_newFolderSeg.setVisible(s, false);
|
||||
m_editFolderSeg.setVisible(s, false);
|
||||
|
||||
m_typeSel.clearSelection(s);
|
||||
}
|
||||
|
||||
private void newItemMode(PageState s) {
|
||||
m_permissionsSeg.setVisible(s, false);
|
||||
m_newItemSeg.setVisible(s, true);
|
||||
}
|
||||
|
||||
private void newFolderMode(PageState s) {
|
||||
m_permissionsSeg.setVisible(s, false);
|
||||
m_newFolderSeg.setVisible(s, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitted(FormSectionEvent e)
|
||||
throws FormProcessException {
|
||||
PageState s = e.getPageState();
|
||||
if (e.getSource() == m_folderCreator
|
||||
&& m_folderCreator.isCancelled(s)) {
|
||||
browseMode(s);
|
||||
throw new FormProcessException(GlobalizationUtil.globalize("cms.ui.cancelled"));
|
||||
} else if (e.getSource() == m_folderEditor && m_folderEditor.isCancelled(s)) {
|
||||
browseMode(s);
|
||||
throw new FormProcessException(GlobalizationUtil.globalize("cms.ui.cancelled"));
|
||||
} else if (e.getSource() == m_folderManip.getTargetSelector()) {
|
||||
// This only works if this submission listener is run
|
||||
// after the target selector's one
|
||||
if (!m_folderManip.getTargetSelector().isVisible(s)) {
|
||||
browseMode(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(FormSectionEvent e) {
|
||||
PageState s = e.getPageState();
|
||||
final Object source = e.getSource();
|
||||
if (source == m_newItem) {
|
||||
BigDecimal typeID = m_newItem.getTypeID(s);
|
||||
m_typeSel.setSelectedKey(s, typeID);
|
||||
newItemMode(s);
|
||||
} else if (source == m_folderCreator || source == m_folderEditor) {
|
||||
browseMode(s);
|
||||
} else if (source == m_folderManip.getItemView()) {
|
||||
// Hide everything except for the browseSeg
|
||||
m_permissionsSeg.setVisible(s, false);
|
||||
m_chooseLabel.setVisible(s, true);
|
||||
m_contentLabel.setVisible(s, false);
|
||||
m_itemPath.setVisible(s, false);
|
||||
} else if (source == m_folderManip.getTargetSelector()) {
|
||||
browseMode(s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
PageState s = e.getPageState();
|
||||
if (e.getSource().equals(m_typeSel)) {
|
||||
if (!m_typeSel.isSelected(s)) {
|
||||
browseMode(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
PageState s = e.getPageState();
|
||||
Object source = e.getSource();
|
||||
if (source == m_createFolderAction) {
|
||||
newFolderMode(s);
|
||||
} else if (source == m_editFolderAction) {
|
||||
m_permissionsSeg.setVisible(s, false);
|
||||
m_editFolderSeg.setVisible(s, true);
|
||||
} else if (source == m_togglePrivateAction) {
|
||||
togglePermissions(s);
|
||||
} else if (source == m_setHomeFolderAction) {
|
||||
User user = Web.getWebContext().getUser();
|
||||
Folder folder = m_folder.getFolder(s);
|
||||
user = (User) DomainObjectFactory.newInstance(user.getOID());
|
||||
Folder.setUserHomeFolder(user, folder);
|
||||
} else if( source == m_removeHomeFolderAction) {
|
||||
User user = Web.getWebContext().getUser();
|
||||
ContentSection section = CMS.getContext().getContentSection();
|
||||
UserHomeFolderMap map = UserHomeFolderMap.findUserHomeFolderMap(user, section);
|
||||
if (map != null) {
|
||||
map.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void togglePermissions(PageState state) {
|
||||
Folder currentFolder = m_folder.getFolder(state);
|
||||
if (!Utilities.getSecurityManager(state).canAccess(state.getRequest(), SecurityManager.STAFF_ADMIN)) {
|
||||
throw new com.arsdigita.cms.dispatcher.AccessDeniedException();
|
||||
}
|
||||
DataObject context = PermissionService.getContext(currentFolder);
|
||||
if (context != null) {
|
||||
PermissionService.clonePermissions(currentFolder);
|
||||
Folder liveFolder = (Folder) currentFolder.getLiveVersion();
|
||||
if (liveFolder != null) {
|
||||
PermissionService.setContext(liveFolder, currentFolder);
|
||||
}
|
||||
} else {
|
||||
ACSObject parent = currentFolder.getParent();
|
||||
if (parent != null) {
|
||||
PermissionService.setContext(currentFolder, parent);
|
||||
} else {
|
||||
// if the folder has no parent, it must be a root folder or template folder
|
||||
// in this case, set it's context to the ContentSection
|
||||
ContentSection section = currentFolder.getContentSection();
|
||||
if (section != null) {
|
||||
PermissionService.setContext(currentFolder, section);
|
||||
} else {
|
||||
throw new IllegalStateException("Cannot set the context for a folder with "
|
||||
+ "no parent and no Content Section");
|
||||
}
|
||||
}
|
||||
|
||||
Folder liveVersion = (Folder) currentFolder.getLiveVersion();
|
||||
if (liveVersion != null) {
|
||||
ACSObject liveParent = liveVersion.getParent();
|
||||
if (liveParent != null) {
|
||||
PermissionService.setContext(liveVersion, liveParent);
|
||||
} else {
|
||||
ContentSection liveSection = liveVersion.getContentSection();
|
||||
if (liveSection != null) {
|
||||
PermissionService.setContext(liveVersion, liveSection);
|
||||
} else {
|
||||
throw new IllegalStateException("Cannot set the context for a folder with "
|
||||
+ "no parent and no Content Section");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// revoke all direct permissions so folder will only have inherited permissions
|
||||
ObjectPermissionCollection perms = PermissionService.getGrantedPermissions(currentFolder.getOID());
|
||||
while (perms.next()) {
|
||||
if (!perms.isInherited() && !perms.getPrivilege().equals(PrivilegeDescriptor.ADMIN)) {
|
||||
PermissionDescriptor desc = new PermissionDescriptor(perms.getPrivilege(), currentFolder.getOID(),
|
||||
perms.getGranteeOID());
|
||||
PermissionService.revokePermission(desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (liveVersion != null) {
|
||||
ObjectPermissionCollection livePerms = PermissionService.getGrantedPermissions(liveVersion.getOID());
|
||||
while (livePerms.next()) {
|
||||
if (!livePerms.isInherited()) {
|
||||
PermissionDescriptor desc2 = new PermissionDescriptor(livePerms.getPrivilege(), liveVersion.
|
||||
getOID(),
|
||||
livePerms.getGranteeOID());
|
||||
PermissionService.revokePermission(desc2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
m_permPane.reset(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(PageState s) {
|
||||
browseMode(s);
|
||||
m_folderManip.reset(s);
|
||||
// switching between folders used to keep showing the permission pane
|
||||
// in the same perm mode (direct or inherited) regardless
|
||||
// of the folder status
|
||||
m_permPane.reset(s);
|
||||
}
|
||||
|
||||
public final FolderManipulator getManipulator() {
|
||||
return m_folderManip;
|
||||
}
|
||||
|
||||
public final CMSPermissionsPane getPermissionsPane() {
|
||||
return m_permPane;
|
||||
}
|
||||
|
||||
public void setPermissionLinkVis(PageState state) {
|
||||
if (!Utilities.getSecurityManager(state).
|
||||
canAccess(state.getRequest(), SecurityManager.STAFF_ADMIN)) {
|
||||
m_togglePrivateAction.setVisible(state, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SectionNewItemForm extends NewItemForm {
|
||||
|
||||
public SectionNewItemForm(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentSection getContentSection(PageState s) {
|
||||
return CMS.getContext().getContentSection();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting the GlobalizedMessage using a CMS Class targetBundle.
|
||||
*
|
||||
* @param key The resource key
|
||||
* @pre ( key != null )
|
||||
*/
|
||||
private static GlobalizedMessage globalize(String key) {
|
||||
return ContentSectionPage.globalize(key);
|
||||
}
|
||||
|
||||
private static GlobalizedMessage globalize(final String key,
|
||||
final Object[] args) {
|
||||
return ContentSectionPage.globalize(key, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -113,11 +113,11 @@ public abstract class UserAddForm extends SimpleContainer
|
|||
|
||||
m_form = makeForm(name);
|
||||
|
||||
Label title = new Label(new GlobalizedMessage("cms.ui.matches",
|
||||
final Label title = new Label(new GlobalizedMessage("cms.ui.matches",
|
||||
CmsConstants.CMS_BUNDLE));
|
||||
title.setFontWeight(Label.BOLD);
|
||||
|
||||
Label label = new Label(new GlobalizedMessage(
|
||||
final Label label = new Label(new GlobalizedMessage(
|
||||
"cms.ui.there_was_no_one_matching_the_search_criteria",
|
||||
CmsConstants.CMS_BUNDLE));
|
||||
label.setFontWeight("em");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* 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.authoring;
|
||||
|
||||
import com.arsdigita.bebop.ColumnPanel;
|
||||
import com.arsdigita.bebop.Component;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.MetaForm;
|
||||
import com.arsdigita.bebop.Page;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.SingleSelectionModel;
|
||||
import com.arsdigita.bebop.form.FormErrorDisplay;
|
||||
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
||||
import com.arsdigita.bebop.parameters.LongParameter;
|
||||
import com.arsdigita.cms.ItemSelectionModel;
|
||||
import com.arsdigita.cms.ui.ContentItemPage;
|
||||
import com.arsdigita.cms.ui.folder.FolderSelectionModel;
|
||||
import com.arsdigita.cms.ui.item.ItemCreateForm;
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
import com.arsdigita.web.RedirectSignal;
|
||||
import com.arsdigita.web.URL;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentType;
|
||||
import org.librecms.contentsection.ContentTypeManager;
|
||||
import org.librecms.contentsection.ContentTypeRepository;
|
||||
import org.librecms.contentsection.Folder;
|
||||
import org.librecms.contenttypes.AuthoringKit;
|
||||
import org.librecms.contenttypes.AuthoringKitInfo;
|
||||
import org.librecms.contenttypes.ContentTypeInfo;
|
||||
import org.librecms.contenttypes.ContentTypesManager;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* An invisible component which contains all the possible creation components.
|
||||
* The components are loaded from the database at construction time. The
|
||||
* selector uses a {@link SingleSelectionModel} in order to get the ID of the
|
||||
* current content type.
|
||||
*
|
||||
* <strong>Important:</strong> This component is passed in the constructor to
|
||||
* every authoring kit creation component (such as {@link PageCreate}). The
|
||||
* creation component is supposed to follow the following pattern:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* // The member variable m_parent points to the CreationSelector
|
||||
* SomeContentItem item = somehowCreateTheItem(state);
|
||||
* item.setParent(m_parent.getFolder(state));
|
||||
* m_parent.editItem(state, item);
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* If the creation component wishes to cancel the creation process, it should
|
||||
* call
|
||||
*
|
||||
* <blockquote><pre>m_parent.redirectBack(state);</pre></blockquote>
|
||||
*
|
||||
* The component may also call
|
||||
*
|
||||
* <blockquote><pre>m_parent.getContentSection(state);</pre></blockquote>
|
||||
*
|
||||
* in order to get the current content section.
|
||||
*
|
||||
* @author unknown
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class CreationSelector extends MetaForm {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(
|
||||
CreationSelector.class);
|
||||
|
||||
private final FolderSelectionModel folderSelectionModel;
|
||||
private final SingleSelectionModel<Long> typeSelectionModel;
|
||||
|
||||
private static Class[] arguments = new Class[]{
|
||||
ItemSelectionModel.class,
|
||||
CreationSelector.class
|
||||
};
|
||||
|
||||
private Object[] values;
|
||||
|
||||
private final ItemSelectionModel itemSelectionModel;
|
||||
private final LongParameter itemIdParameter;
|
||||
|
||||
public static final String ITEM_ID = "iid";
|
||||
|
||||
/**
|
||||
* Constructs a new <code>CreationSelector</code>. Load all the possible
|
||||
* creation components from the database and stick them in the Map.
|
||||
*
|
||||
* @param typeSelectionModel the {@link SingleSelectionModel} which will
|
||||
* 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
|
||||
*/
|
||||
public CreationSelector(final SingleSelectionModel<Long> typeSelectionModel,
|
||||
final FolderSelectionModel folderSelectionModel) {
|
||||
|
||||
super("pageCreate");
|
||||
|
||||
this.typeSelectionModel = typeSelectionModel;
|
||||
this.folderSelectionModel = folderSelectionModel;
|
||||
|
||||
itemIdParameter = new LongParameter(ITEM_ID);
|
||||
itemSelectionModel = new ItemSelectionModel(itemIdParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param state
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Form buildForm(final PageState state) {
|
||||
final Long typeId = typeSelectionModel.getSelectedKey(state);
|
||||
final Component component;
|
||||
final Form returnForm = new Form("pageCreate");
|
||||
final FormErrorDisplay formErrorDisplay = new FormErrorDisplay(this);
|
||||
formErrorDisplay.setStateParamsAreRegistered(false);
|
||||
returnForm.add(formErrorDisplay, ColumnPanel.FULL_WIDTH
|
||||
| ColumnPanel.LEFT);
|
||||
|
||||
if (typeId != null) {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final ContentTypeRepository typeRepo = cdiUtil.findBean(
|
||||
ContentTypeRepository.class);
|
||||
final ContentTypeManager typeManager = cdiUtil.findBean(
|
||||
ContentTypeManager.class);
|
||||
final ContentTypesManager typesManager = cdiUtil.findBean(
|
||||
ContentTypesManager.class);
|
||||
|
||||
final ContentType type = typeRepo.findById(typeId);
|
||||
if (type == null) {
|
||||
throw new UncheckedWrapperException(String.format(
|
||||
"Type with id %d not found.", typeId));
|
||||
}
|
||||
final ContentTypeInfo typeInfo = typesManager.getContentTypeInfo(
|
||||
type);
|
||||
final AuthoringKitInfo kit = typeInfo.getAuthoringKit();
|
||||
component = instantiateKitComponent(kit, type);
|
||||
if (component != null) {
|
||||
returnForm.add(component);
|
||||
returnForm.setMethod(Form.POST);
|
||||
returnForm.setEncType("multipart/form-data");
|
||||
}
|
||||
}
|
||||
return returnForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the item_id parameter.
|
||||
*
|
||||
* @param page
|
||||
*/
|
||||
@Override
|
||||
public void register(final Page page) {
|
||||
super.register(page);
|
||||
page.addComponentStateParam(this, itemIdParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the creation component.
|
||||
*
|
||||
* @param kit
|
||||
* @param type
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected Component instantiateKitComponent(final AuthoringKitInfo kit,
|
||||
final ContentType type) {
|
||||
final Class<? extends ItemCreateForm> createClass = kit
|
||||
.getCreateComponent();
|
||||
final Object[] vals;
|
||||
|
||||
try {
|
||||
final ItemSelectionModel itemModel = new ItemSelectionModel(type,
|
||||
itemIdParameter);
|
||||
vals = new Object[]{itemModel, this};
|
||||
|
||||
final Constructor<? extends ItemCreateForm> constructor
|
||||
= createClass
|
||||
.getConstructor(arguments);
|
||||
final Component component = (Component) constructor
|
||||
.newInstance(vals);
|
||||
return component;
|
||||
} catch (IllegalAccessException
|
||||
| IllegalArgumentException
|
||||
| InstantiationException
|
||||
| NoSuchMethodException
|
||||
| SecurityException
|
||||
| InvocationTargetException ex) {
|
||||
LOGGER.error("\"Failed to instantiate creation component \"{}\".",
|
||||
kit.getCreateComponent().getName());
|
||||
LOGGER.error(ex);
|
||||
throw new UncheckedWrapperException(String.format(
|
||||
"Failed to instantiate creation component \"%s\".",
|
||||
kit.getCreateComponent().getName()),
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the currently selected folder. Creation components will place new
|
||||
* items in this folder.
|
||||
*
|
||||
* @param state represents the current request
|
||||
*
|
||||
* @return the currently selected folder, in which new items should be
|
||||
* placed.
|
||||
*/
|
||||
public final Folder getFolder(final PageState state) {
|
||||
return (Folder) folderSelectionModel.getSelectedObject(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the currently selected content section. New items created by
|
||||
* creation components will belong to this section. This is the content
|
||||
* section to which the folder returned by {@link #getFolder getFolder}
|
||||
* belongs.
|
||||
*
|
||||
* @param state represents the current request
|
||||
*
|
||||
* @return the currently selected content section.
|
||||
*/
|
||||
public final ContentSection getContentSection(final PageState state) {
|
||||
final ContentSection section = getFolder(state).getSection();
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward to the item editing UI. The creation component of an authoring
|
||||
* kit may call this method to indicate that the creation process is
|
||||
* complete.
|
||||
*
|
||||
* @param state the page state
|
||||
* @param item the newly created item
|
||||
*/
|
||||
public void editItem(final PageState state, final ContentItem item) {
|
||||
final ContentSection section = getContentSection(state);
|
||||
|
||||
final String nodeUrl = String.join("", URL.getDispatcherPath(),
|
||||
section.getPrimaryUrl(),
|
||||
"/");
|
||||
final String target = ContentItemPage.getItemURL(
|
||||
nodeUrl, item.getObjectId(), ContentItemPage.AUTHORING_TAB, true);
|
||||
|
||||
throw new RedirectSignal(target, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel item editing and go back to where the user came from
|
||||
*
|
||||
* @param state the page state
|
||||
*/
|
||||
public void redirectBack(final PageState state) {
|
||||
typeSelectionModel.clearSelection(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,258 +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.authoring;
|
||||
|
||||
import com.arsdigita.bebop.ColumnPanel;
|
||||
import com.arsdigita.bebop.Component;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.MetaForm;
|
||||
import com.arsdigita.bebop.Page;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.SingleSelectionModel;
|
||||
import com.arsdigita.bebop.form.FormErrorDisplay;
|
||||
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
||||
import com.arsdigita.cms.AuthoringKit;
|
||||
import com.arsdigita.cms.ContentBundle;
|
||||
import com.arsdigita.cms.ContentItem;
|
||||
import com.arsdigita.cms.ContentSection;
|
||||
import com.arsdigita.cms.ContentType;
|
||||
import com.arsdigita.cms.Folder;
|
||||
import com.arsdigita.cms.ItemSelectionModel;
|
||||
import com.arsdigita.cms.ui.ContentItemPage;
|
||||
import com.arsdigita.cms.ui.folder.FolderSelectionModel;
|
||||
import com.arsdigita.domain.DataObjectNotFoundException;
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
import com.arsdigita.web.RedirectSignal;
|
||||
import com.arsdigita.web.URL;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* An invisible component which contains all the possible creation
|
||||
* components. The components are loaded from the database at
|
||||
* construction time. The selector uses a {@link SingleSelectionModel}
|
||||
* in order to get the ID of the current content type.
|
||||
*
|
||||
* <strong>Important:</strong> This component is passed in the
|
||||
* constructor to every authoring kit creation component (such as
|
||||
* {@link PageCreate}). The creation component is supposed to follow
|
||||
* the following pattern:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* // The member variable m_parent points to the CreationSelector
|
||||
* SomeContentItem item = somehowCreateTheItem(state);
|
||||
* item.setParent(m_parent.getFolder(state));
|
||||
* m_parent.editItem(state, item);
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* If the creation component wishes to cancel the creation process,
|
||||
* it should call
|
||||
*
|
||||
* <blockquote><pre>m_parent.redirectBack(state);</pre></blockquote>
|
||||
*
|
||||
* The component may also call
|
||||
*
|
||||
* <blockquote><pre>m_parent.getContentSection(state);</pre></blockquote>
|
||||
*
|
||||
* in order to get the current content section.
|
||||
*
|
||||
* @version $Id: CreationSelector.java 2185 2011-06-20 21:16:02Z pboy $
|
||||
*/
|
||||
public class CreationSelector extends MetaForm {
|
||||
|
||||
private static Logger s_log = Logger.getLogger(CreationSelector.class);
|
||||
|
||||
private final FolderSelectionModel m_folderSel;
|
||||
private final SingleSelectionModel m_typeSel;
|
||||
|
||||
private static Class[] s_args = new Class[] {
|
||||
ItemSelectionModel.class,
|
||||
CreationSelector.class
|
||||
};
|
||||
|
||||
private Object[] m_vals;
|
||||
|
||||
private ItemSelectionModel m_itemSel;
|
||||
private BigDecimalParameter m_itemId;
|
||||
|
||||
private ItemSelectionModel m_bundleSel;
|
||||
private BigDecimalParameter m_bundleId;
|
||||
|
||||
public static final String ITEM_ID = "iid";
|
||||
public static final String BUNDLE_ID = "bid";
|
||||
|
||||
/**
|
||||
* Constructs a new <code>CreationSelector</code>. Load all the
|
||||
* possible creation components from the database and stick them
|
||||
* in the Map.
|
||||
*
|
||||
* @param typeModel the {@link SingleSelectionModel} which will
|
||||
* supply a BigDecimal ID of the content type to instantiate
|
||||
*
|
||||
* @param folderModel the {@link FolderSelectionModel} containing
|
||||
* the folder in which new items are to be created
|
||||
*/
|
||||
public CreationSelector(final SingleSelectionModel typeModel,
|
||||
final FolderSelectionModel folderModel) {
|
||||
super("pageCreate");
|
||||
|
||||
m_typeSel = typeModel;
|
||||
|
||||
m_folderSel = folderModel;
|
||||
m_itemId = new BigDecimalParameter(ITEM_ID);
|
||||
m_bundleId = new BigDecimalParameter(BUNDLE_ID);
|
||||
m_bundleSel = new ItemSelectionModel(ContentBundle.class.getName(),
|
||||
ContentBundle.BASE_DATA_OBJECT_TYPE, m_bundleId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param state
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Form buildForm(PageState state) {
|
||||
BigDecimal typeID = (BigDecimal)m_typeSel.getSelectedKey(state);
|
||||
Component c = null;
|
||||
Form returnForm = new Form("pageCreate");
|
||||
FormErrorDisplay fed = new FormErrorDisplay(this);
|
||||
fed.setStateParamsAreRegistered(false);
|
||||
returnForm.add(fed , ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
|
||||
if (typeID != null) {
|
||||
try {
|
||||
ContentType type = new ContentType(typeID);
|
||||
AuthoringKit kit = type.getAuthoringKit();
|
||||
if(kit != null) {
|
||||
c = instantiateKitComponent(kit, type);
|
||||
if(c != null) {
|
||||
returnForm.add(c);
|
||||
returnForm.setMethod(Form.POST);
|
||||
returnForm.setEncType("multipart/form-data");
|
||||
}
|
||||
}
|
||||
} catch (DataObjectNotFoundException e) {
|
||||
// content type not found
|
||||
}
|
||||
}
|
||||
return returnForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the item_id parameter.
|
||||
*
|
||||
* @param p
|
||||
*/
|
||||
@Override
|
||||
public void register(Page p) {
|
||||
super.register(p);
|
||||
p.addComponentStateParam(this, m_itemId);
|
||||
p.addComponentStateParam(this, m_bundleId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the creation component.
|
||||
*
|
||||
* @param kit
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
protected Component instantiateKitComponent
|
||||
(final AuthoringKit kit, final ContentType type) {
|
||||
String creatorName = kit.getCreateComponent();
|
||||
Object[] vals;
|
||||
|
||||
if(creatorName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
Class createClass = Class.forName(creatorName);
|
||||
ItemSelectionModel itemModel = new ItemSelectionModel(type, m_itemId);
|
||||
vals = new Object[]{itemModel, this};
|
||||
Constructor constr = createClass.getConstructor(s_args);
|
||||
Component c = (Component)constr.newInstance(vals);
|
||||
return c;
|
||||
} catch (Exception e) {
|
||||
s_log.error("Instantiation failure", e);
|
||||
throw new UncheckedWrapperException (
|
||||
"Failed to instantiate creation component " +
|
||||
kit.getCreateComponent() + ": " + e.getMessage(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the currently selected folder. Creation components will place
|
||||
* new items in this folder.
|
||||
*
|
||||
* @param s represents the current request
|
||||
* @return the currently selected folder, in which new items should be
|
||||
* placed.
|
||||
*/
|
||||
public final Folder getFolder(PageState s) {
|
||||
return (Folder) m_folderSel.getSelectedObject(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the currently selected content section. New items created by
|
||||
* creation components will belong to this section. This is the content
|
||||
* section to which the folder returned by {@link #getFolder getFolder}
|
||||
* belongs.
|
||||
*
|
||||
* @param s represents the current request
|
||||
* @return the currently selected content section.
|
||||
*/
|
||||
public final ContentSection getContentSection(PageState s) {
|
||||
final ContentSection section = (ContentSection)
|
||||
getFolder(s).getContentSection();
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward to the item editing UI. The creation component of an authoring
|
||||
* kit may call this method to indicate that the creation process is
|
||||
* complete.
|
||||
*
|
||||
* @param s the page state
|
||||
* @param item the newly created item
|
||||
*/
|
||||
public void editItem(PageState s, ContentItem item) {
|
||||
ContentSection sec = getContentSection(s);
|
||||
|
||||
String nodeURL = URL.getDispatcherPath() + sec.getPath() + "/";
|
||||
String target = ContentItemPage.getItemURL
|
||||
(nodeURL, item.getID(), ContentItemPage.AUTHORING_TAB,true);
|
||||
|
||||
throw new RedirectSignal(target, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel item editing and go back to where the user came from
|
||||
*
|
||||
* @param s the page state
|
||||
*/
|
||||
public void redirectBack(PageState state) {
|
||||
m_typeSel.clearSelection(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* 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.authoring;
|
||||
|
||||
import com.arsdigita.bebop.BoxPanel;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.event.PrintEvent;
|
||||
import com.arsdigita.bebop.event.PrintListener;
|
||||
import com.arsdigita.bebop.form.OptionGroup;
|
||||
import com.arsdigita.bebop.form.SingleSelect;
|
||||
import com.arsdigita.bebop.form.Submit;
|
||||
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
||||
import com.arsdigita.bebop.parameters.LongParameter;
|
||||
import com.arsdigita.cms.ui.ItemSearch;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
import com.arsdigita.xml.Element;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentType;
|
||||
import org.librecms.contentsection.ContentTypeRepository;
|
||||
import org.librecms.contentsection.privileges.TypePrivileges;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.TooManyListenersException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* A form element which displays a select box of all content types available
|
||||
* under the given content section, and forwards to the item creation UI when
|
||||
* the user selects a content type to instantiate.
|
||||
*
|
||||
* @author Stanislav Freidin (sfreidin@arsdigtia.com)
|
||||
* @author <a href="jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public abstract class NewItemForm extends Form {
|
||||
|
||||
public static final String TYPE_ID = "tid";
|
||||
|
||||
private final SingleSelect typeSelect;
|
||||
private final Submit submit;
|
||||
private final Label emptyLabel;
|
||||
private final Label createLabel;
|
||||
|
||||
public NewItemForm(final String name) {
|
||||
this(name, BoxPanel.HORIZONTAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new NewItemForm. It sets a vertical BoxPanel as the component
|
||||
* container.
|
||||
*
|
||||
* @param name the name attribute of the form.
|
||||
* @param orientation
|
||||
*/
|
||||
public NewItemForm(final String name, final int orientation) {
|
||||
|
||||
super(name, new BoxPanel(BoxPanel.VERTICAL));
|
||||
setIdAttr("new_item_form");
|
||||
|
||||
final BoxPanel panel = new BoxPanel(orientation);
|
||||
panel.setWidth("2%");
|
||||
panel.setBorder(0);
|
||||
|
||||
// create and add an "empty" component
|
||||
emptyLabel = new Label(
|
||||
new GlobalizedMessage("cms.ui.authoring.no_types_registered",
|
||||
CmsConstants.CMS_BUNDLE),
|
||||
false);
|
||||
emptyLabel.setIdAttr("empty_label");
|
||||
panel.add(emptyLabel);
|
||||
|
||||
createLabel = new Label(
|
||||
new GlobalizedMessage("cms.ui.authoring.create_new",
|
||||
CmsConstants.CMS_BUNDLE),
|
||||
false);
|
||||
createLabel.setIdAttr("create_label");
|
||||
panel.add(createLabel);
|
||||
|
||||
typeSelect = new SingleSelect(new BigDecimalParameter(TYPE_ID),
|
||||
OptionGroup.SortMode.ALPHABETICAL_ASCENDING);
|
||||
try {
|
||||
typeSelect.addPrintListener(new PrintListener() {
|
||||
|
||||
// Read the content section's content types and add them as options
|
||||
@Override
|
||||
public void prepare(final PrintEvent event) {
|
||||
final OptionGroup optionGroup = (OptionGroup) event
|
||||
.getTarget();
|
||||
optionGroup.clearOptions();
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
// gather the content types of this section into a list
|
||||
final ContentSection section = getContentSection(state);
|
||||
final ContentType parentType;
|
||||
final List<ContentType> typesCollection;
|
||||
final Long singleTypeID = (Long) state.getValue(
|
||||
new LongParameter(ItemSearch.SINGLE_TYPE_PARAM));
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final ContentTypeRepository typeRepo = cdiUtil.findBean(
|
||||
ContentTypeRepository.class);
|
||||
final PermissionChecker permissionChecker = cdiUtil
|
||||
.findBean(PermissionChecker.class);
|
||||
|
||||
if (singleTypeID == null) {
|
||||
parentType = null;
|
||||
} else {
|
||||
parentType = typeRepo.findById(singleTypeID);
|
||||
}
|
||||
|
||||
typesCollection = section.getContentTypes().stream()
|
||||
.filter(type -> permissionChecker.isPermitted(
|
||||
TypePrivileges.USE_TYPE,
|
||||
type))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
});
|
||||
} catch (TooManyListenersException ex) {
|
||||
throw new UncheckedWrapperException("Too many listeners.", ex);
|
||||
}
|
||||
|
||||
panel.add(typeSelect);
|
||||
|
||||
submit = new Submit("new",
|
||||
new GlobalizedMessage("cms.ui.authoring.go",
|
||||
CmsConstants.CMS_BUNDLE));
|
||||
panel.add(submit);
|
||||
|
||||
add(panel);
|
||||
}
|
||||
|
||||
public abstract ContentSection getContentSection(PageState state);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param state
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Long getTypeID(final PageState state) {
|
||||
return (Long) typeSelect.getValue(state);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public final SingleSelect getTypeSelect() {
|
||||
return typeSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate XML - show/hide labels/widgets
|
||||
*
|
||||
* @param state
|
||||
* @param parent
|
||||
*/
|
||||
@Override
|
||||
public void generateXML(final PageState state, final Element parent) {
|
||||
|
||||
if (isVisible(state)) {
|
||||
final ContentSection section = getContentSection(state);
|
||||
|
||||
final List<ContentType> types = section.getContentTypes();
|
||||
boolean isEmpty = types.isEmpty();
|
||||
|
||||
createLabel.setVisible(state, !isEmpty);
|
||||
typeSelect.setVisible(state, !isEmpty);
|
||||
submit.setVisible(state, !isEmpty);
|
||||
emptyLabel.setVisible(state, isEmpty);
|
||||
|
||||
super.generateXML(state, parent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,247 +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.authoring;
|
||||
|
||||
import com.arsdigita.bebop.BoxPanel;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.event.PrintEvent;
|
||||
import com.arsdigita.bebop.event.PrintListener;
|
||||
import com.arsdigita.bebop.form.Option;
|
||||
import com.arsdigita.bebop.form.OptionGroup;
|
||||
import com.arsdigita.bebop.form.SingleSelect;
|
||||
import com.arsdigita.bebop.form.Submit;
|
||||
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
||||
import com.arsdigita.cms.ui.ItemSearch;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.ui.admin.GlobalizationUtil;
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
import com.arsdigita.xml.Element;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.libreccm.security.Party;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentType;
|
||||
|
||||
import java.awt.image.Kernel;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A form element which displays a select box of all content types available
|
||||
* under the given content section, and forwards to the item creation UI when
|
||||
* the user selects a content type to instantiate.
|
||||
*
|
||||
* @author Stanislav Freidin (sfreidin@arsdigtia.com)
|
||||
* @version $Revision: #12 $ $DateTime: 2004/08/17 23:15:09 $
|
||||
* @version $Id: NewItemForm.java 2161 2011-02-02 00:16:13Z pboy $
|
||||
*/
|
||||
public abstract class NewItemForm extends Form {
|
||||
|
||||
/**
|
||||
* Internal logger instance to faciliate debugging. Enable logging output by
|
||||
* editing /WEB-INF/conf/log4j.properties int hte runtime environment and
|
||||
* set com.arsdigita.cms.ui.authoring.NewItemForm=DEBUG by uncommenting or
|
||||
* adding the line.
|
||||
*/
|
||||
private static final Logger s_log = Logger.getLogger(NewItemForm.class);
|
||||
|
||||
private final SingleSelect m_typeWidget;
|
||||
private final Submit m_submit;
|
||||
private final Label m_emptyLabel;
|
||||
private final Label m_createLabel;
|
||||
public static final String TYPE_ID = "tid";
|
||||
|
||||
public NewItemForm(String name) {
|
||||
this(name, BoxPanel.HORIZONTAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new NewItemForm. It sets a vertical BoxPanel as the component
|
||||
* container.
|
||||
*
|
||||
* @param name the name attribute of the form.
|
||||
*/
|
||||
public NewItemForm(String name, int orientation) {
|
||||
|
||||
super(name, new BoxPanel(BoxPanel.VERTICAL));
|
||||
setIdAttr("new_item_form");
|
||||
|
||||
//BoxPanel panel = new BoxPanel(BoxPanel.HORIZONTAL);
|
||||
BoxPanel panel = new BoxPanel(orientation);
|
||||
panel.setWidth("2%");
|
||||
panel.setBorder(0);
|
||||
|
||||
// create and add an "empty" component
|
||||
m_emptyLabel = new Label(new GlobalizedMessage(
|
||||
"cms.ui.authoring.no_types_registered", CmsConstants.CMS_BUNDLE),
|
||||
false);
|
||||
m_emptyLabel.setIdAttr("empty_label");
|
||||
panel.add(m_emptyLabel);
|
||||
|
||||
m_createLabel = new Label(new GlobalizedMessage(
|
||||
"cms.ui.authoring.create_new", CmsConstants.CMS_BUNDLE),
|
||||
false);
|
||||
m_createLabel.setIdAttr("create_label");
|
||||
panel.add(m_createLabel);
|
||||
|
||||
m_typeWidget = new SingleSelect(new BigDecimalParameter(TYPE_ID),
|
||||
OptionGroup.SortMode.ALPHABETICAL_ASCENDING);
|
||||
try {
|
||||
m_typeWidget.addPrintListener(new PrintListener() {
|
||||
|
||||
// Read the content section's content types and add them as options
|
||||
@Override
|
||||
public void prepare(PrintEvent e) {
|
||||
OptionGroup o = (OptionGroup) e.getTarget();
|
||||
o.clearOptions();
|
||||
PageState state = e.getPageState();
|
||||
|
||||
// gather the content types of this section into a list
|
||||
ContentSection section = getContentSection(state);
|
||||
ContentType parentType = null;
|
||||
List<ContentType> typesCollection = null;
|
||||
BigDecimal singleTypeID = (BigDecimal) state.getValue(
|
||||
new BigDecimalParameter(
|
||||
ItemSearch.SINGLE_TYPE_PARAM));
|
||||
|
||||
if (singleTypeID != null) {
|
||||
try {
|
||||
parentType = new ContentType(singleTypeID);
|
||||
} catch (DataObjectNotFoundException ex) {
|
||||
parentType = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (parentType == null) {
|
||||
typesCollection = section.getCreatableContentTypes();
|
||||
} else {
|
||||
typesCollection = section.getDescendantsOfContentType(
|
||||
parentType);
|
||||
}
|
||||
|
||||
typesCollection.addOrder(ContentType.LABEL);
|
||||
|
||||
if (!typesCollection.isEmpty()) {
|
||||
// Add content types
|
||||
while (typesCollection.next()) {
|
||||
boolean list = true;
|
||||
ContentType type = typesCollection.getContentType();
|
||||
if (PermissionService
|
||||
.getDirectGrantedPermissions(type.getOID())
|
||||
.size() > 0) {
|
||||
// chris gilbert - allow restriction of some types
|
||||
// to certain users/groups. No interface to do
|
||||
// this, but group could be created and permission
|
||||
// granted in a content type loader
|
||||
//
|
||||
// can't permission filter the collection because
|
||||
// most types will have no permissions granted.
|
||||
// This approach involves a small overhead getting
|
||||
// the count of granted permissions for each type
|
||||
// (mitigated by only checking DIRECT permissions)
|
||||
|
||||
Party party = Kernel.getContext().getParty();
|
||||
if (party == null) {
|
||||
party = Kernel.getPublicUser();
|
||||
}
|
||||
PermissionDescriptor create
|
||||
= new PermissionDescriptor(
|
||||
PrivilegeDescriptor
|
||||
.get(SecurityManager.CMS_NEW_ITEM),
|
||||
type,
|
||||
party);
|
||||
list = PermissionService.checkPermission(create);
|
||||
|
||||
}
|
||||
if (list) {
|
||||
// o.addOption(new Option(type.getID().toString(), type.getName()));
|
||||
o.addOption(new Option(type.getID().toString(),
|
||||
new Label(type.getLabel())));
|
||||
}
|
||||
|
||||
}
|
||||
typesCollection.reset();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
} catch (java.util.TooManyListenersException e) {
|
||||
throw new UncheckedWrapperException("Too many listeners: " + e
|
||||
.getMessage(), e);
|
||||
}
|
||||
|
||||
panel.add(m_typeWidget);
|
||||
|
||||
m_submit = new Submit("new", GlobalizationUtil.globalize(
|
||||
"cms.ui.authoring.go"));
|
||||
panel.add(m_submit);
|
||||
|
||||
add(panel);
|
||||
}
|
||||
|
||||
public abstract ContentSection getContentSection(PageState state);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param state
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public BigDecimal getTypeID(PageState state) {
|
||||
return (BigDecimal) m_typeWidget.getValue(state);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public final SingleSelect getTypeSelect() {
|
||||
return m_typeWidget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate XML - show/hide labels/widgets
|
||||
*
|
||||
* @param state
|
||||
* @param parent
|
||||
*/
|
||||
@Override
|
||||
public void generateXML(PageState state, Element parent) {
|
||||
|
||||
if (isVisible(state)) {
|
||||
ContentSection section = getContentSection(state);
|
||||
|
||||
ContentTypeCollection c = section.getCreatableContentTypes();
|
||||
boolean isEmpty = c.isEmpty();
|
||||
c.close();
|
||||
|
||||
m_createLabel.setVisible(state, !isEmpty);
|
||||
m_typeWidget.setVisible(state, !isEmpty);
|
||||
m_submit.setVisible(state, !isEmpty);
|
||||
m_emptyLabel.setVisible(state, isEmpty);
|
||||
|
||||
super.generateXML(state, parent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.Folder;
|
||||
import org.librecms.contentsection.FolderManager;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class FolderPathListModel implements ListModel {
|
||||
|
||||
private final Iterator<Folder> pathFolders;
|
||||
private Folder currentFolder;
|
||||
|
||||
public FolderPathListModel(final Folder folder) {
|
||||
pathFolders = CdiUtil.createCdiUtil().findBean(FolderManager.class)
|
||||
.getParentFolders(folder).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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ import org.apache.log4j.Logger;
|
|||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.categorization.CategoryRepository;
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.librecms.contentsection.Folder;
|
||||
|
||||
|
||||
public class FolderRequestLocal extends CcmObjectRequestLocal {
|
||||
|
|
@ -55,8 +56,8 @@ public class FolderRequestLocal extends CcmObjectRequestLocal {
|
|||
}
|
||||
}
|
||||
|
||||
public final Category getFolder(final PageState state) {
|
||||
return (Category) get(state);
|
||||
public final Folder getFolder(final PageState state) {
|
||||
return (Folder) get(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import com.arsdigita.ui.CcmObjectSelectionModel;
|
|||
|
||||
import org.apache.log4j.Category;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.Folder;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -34,15 +35,15 @@ import org.librecms.contentsection.ContentSection;
|
|||
* com.arsdigita.cms.Folder}.
|
||||
*
|
||||
* @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a>
|
||||
* @version $Id$
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class FolderSelectionModel extends CcmObjectSelectionModel {
|
||||
public class FolderSelectionModel extends CcmObjectSelectionModel<Folder> {
|
||||
|
||||
public FolderSelectionModel(String name) {
|
||||
super(Category.class.getName(), name);
|
||||
}
|
||||
|
||||
public FolderSelectionModel(final SingleSelectionModel model) {
|
||||
public FolderSelectionModel(final SingleSelectionModel<Long> model) {
|
||||
super(Category.class.getName(), model);
|
||||
}
|
||||
|
||||
|
|
@ -60,10 +61,11 @@ public class FolderSelectionModel extends CcmObjectSelectionModel {
|
|||
/**
|
||||
* Clear the selection by resetting it to the root folder id.
|
||||
*
|
||||
* @param s represents the curent request.
|
||||
* @param state represents the cuerent request.
|
||||
*/
|
||||
public void clearSelection(PageState s) {
|
||||
setSelectedKey(s, getRootFolderID(s));
|
||||
@Override
|
||||
public void clearSelection(final PageState state) {
|
||||
setSelectedKey(state, getRootFolderID(state));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -72,13 +74,13 @@ public class FolderSelectionModel extends CcmObjectSelectionModel {
|
|||
* is to be used outside a content section, this method has to be overriden
|
||||
* appropriately.
|
||||
*
|
||||
* @param s represents the current request
|
||||
* @param state represents the current request
|
||||
* @return the ID of the root folder
|
||||
*
|
||||
* @pre s != null
|
||||
* @post return != null
|
||||
*/
|
||||
protected Long getRootFolderID(PageState s) {
|
||||
protected Long getRootFolderID(final PageState state) {
|
||||
ContentSection sec = CMS.getContext().getContentSection();
|
||||
return sec.getRootDocumentsFolder().getObjectId();
|
||||
}
|
||||
|
|
@ -86,8 +88,11 @@ public class FolderSelectionModel extends CcmObjectSelectionModel {
|
|||
/**
|
||||
* Return true, since this selection model will always have a folder
|
||||
* selected in it
|
||||
* @param state
|
||||
* @return
|
||||
*/
|
||||
public boolean isSelected(PageState s) {
|
||||
@Override
|
||||
public boolean isSelected(final PageState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,70 +19,21 @@
|
|||
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.cms.ItemSelectionModel;
|
||||
import com.arsdigita.util.LockableImpl;
|
||||
|
||||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contentsection.ContentItemManager;
|
||||
import org.librecms.contentsection.Folder;
|
||||
|
||||
/**
|
||||
* Produce a list of the items starting from the selected item's root down to
|
||||
* the item itself.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
* @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(ItemSelectionModel folderSel) {
|
||||
super(new ItemPathListModelBuilder(folderSel));
|
||||
public ItemPath(final ItemSelectionModel itemSelectionModel) {
|
||||
super(new ItemPathListModelBuilder(itemSelectionModel));
|
||||
setAttribute("type", "item-path");
|
||||
setSelectionModel(folderSel);
|
||||
setSelectionModel(itemSelectionModel);
|
||||
}
|
||||
|
||||
public static class ItemPathListModel implements ListModel {
|
||||
|
||||
private final java.util.List<Folder> pathFolders;
|
||||
private int index = -1;
|
||||
|
||||
public ItemPathListModel(final ContentItem item) {
|
||||
pathFolders = CdiUtil.createCdiUtil().findBean(ContentItemManager.class).getItemFolders(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean next() {
|
||||
index++;
|
||||
return index < pathFolders.size();
|
||||
}
|
||||
|
||||
public Object getElement() {
|
||||
return pathFolders.get(index).getName();
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return Long.toString(pathFolders.get(index).getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
public static class ItemPathListModelBuilder extends LockableImpl
|
||||
implements ListModelBuilder {
|
||||
|
||||
ItemSelectionModel m_itemSel;
|
||||
|
||||
public ItemPathListModelBuilder(ItemSelectionModel itemSel) {
|
||||
m_itemSel = itemSel;
|
||||
}
|
||||
|
||||
public com.arsdigita.bebop.list.ListModel makeModel(List l,
|
||||
final PageState s) {
|
||||
return new ItemPathListModel((ContentItem) m_itemSel.
|
||||
getSelectedObject(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* 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.permissions;
|
||||
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
|
||||
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||
|
||||
/**
|
||||
* This interface is used to centralise constants and labels used in the
|
||||
* Permissions UI package.
|
||||
*
|
||||
* @author Stefan Deusch (stefan@arsdigita.com)
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class CMSPermissionsConstants {
|
||||
|
||||
private CMSPermissionsConstants() {
|
||||
//Nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* These are our five default privileges.
|
||||
*/
|
||||
public static final String[] DEFAULT_PRIVILEGES = new String[]{
|
||||
ItemPrivileges.VIEW_PUBLISHED,
|
||||
ItemPrivileges.EDIT,
|
||||
ItemPrivileges.CREATE_NEW,
|
||||
ItemPrivileges.DELETE,};
|
||||
|
||||
public static final String BUNDLE_NAME
|
||||
= "com.arsdigita.ui.permissions.PermissionsResources";
|
||||
|
||||
public static final GlobalizedMessage SEARCH_LABEL = new GlobalizedMessage(
|
||||
"permissions.userSearchForm.label", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage SEARCH_BUTTON = new GlobalizedMessage(
|
||||
"permissions.button.search", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage SAVE_BUTTON = new GlobalizedMessage(
|
||||
"permissions.button.save", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage NO_RESULTS = new GlobalizedMessage(
|
||||
"permissions.userSearchForm.noResults", BUNDLE_NAME);
|
||||
|
||||
// Direct / Indirect permissions
|
||||
public static final GlobalizedMessage PERM_TABLE_DIRECT_HEADING
|
||||
= new GlobalizedMessage(
|
||||
"permissions.directPermissions.heading", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PERM_TABLE_DIRECT_EXPLANATION
|
||||
= new GlobalizedMessage(
|
||||
"permissions.directPermissions.explanation", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PERM_TABLE_INDIRECT_HEADING
|
||||
= new GlobalizedMessage(
|
||||
"permissions.indirectPermissions.heading", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PERM_TABLE_INDIRECT_EXPLANATION
|
||||
= new GlobalizedMessage(
|
||||
"permissions.indirectPermissions.explanation", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PERM_TABLE_INDIRECT_CONTEXT
|
||||
= new GlobalizedMessage(
|
||||
"permissions.indirectPermissions.context", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PERM_TABLE_GRANTEE
|
||||
= new GlobalizedMessage(
|
||||
"permissions.table.grantee", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PERM_TABLE_ACTIONS
|
||||
= new GlobalizedMessage(
|
||||
"permissions.table.actions", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage REMOVE_ALL_CONFIRM
|
||||
= new GlobalizedMessage(
|
||||
"permissions.table.actions.removeAll", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PERM_TABLE_INHERITED
|
||||
= new GlobalizedMessage(
|
||||
"permissions.table.inherited", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PERM_TABLE_NO_PARENT_CONTEXT
|
||||
= new GlobalizedMessage(
|
||||
"permissions.table.parent.context.null", BUNDLE_NAME);
|
||||
|
||||
// Permissions header
|
||||
public static final GlobalizedMessage PAGE_TITLE = new GlobalizedMessage(
|
||||
"permissions.one.title", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage MAIN_SITE = new GlobalizedMessage(
|
||||
"permissions.main.site", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PERSONAL_SITE = new GlobalizedMessage(
|
||||
"permissions.personal.site", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PERMISSIONS_INDEX
|
||||
= new GlobalizedMessage(
|
||||
"permissions.index.title", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PERMISSIONS_INDEX_NAVBAR
|
||||
= new GlobalizedMessage(
|
||||
"permissions.index.navbarItem", BUNDLE_NAME);
|
||||
|
||||
// Permissions grant form
|
||||
public static final GlobalizedMessage PAGE_GRANT_TITLE
|
||||
= new GlobalizedMessage(
|
||||
"permissions.one.grant.title", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PAGE_GRANT_LEFT
|
||||
= new GlobalizedMessage(
|
||||
"permissions.one.grant.explanation.left", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PAGE_GRANT_RIGHT
|
||||
= new GlobalizedMessage(
|
||||
"permissions.one.grant.explanation.right", BUNDLE_NAME);
|
||||
|
||||
// Access denied page
|
||||
public static final GlobalizedMessage PAGE_DENIED_TITLE
|
||||
= new GlobalizedMessage(
|
||||
"permissions.denied.title", BUNDLE_NAME);
|
||||
|
||||
// Index page
|
||||
public static final GlobalizedMessage PAGE_OBJECT_INDEX
|
||||
= new GlobalizedMessage(
|
||||
"permissions.index.adminObjects", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PAGE_OBJECT_PANEL_TITLE
|
||||
= new GlobalizedMessage(
|
||||
"permissions.index.panelTitle", BUNDLE_NAME);
|
||||
|
||||
public static final GlobalizedMessage PAGE_OBJECT_NONE
|
||||
= new GlobalizedMessage(
|
||||
"permissions.index.noAdminObjects", BUNDLE_NAME);
|
||||
|
||||
// Flats for permission types
|
||||
public static final int DIRECT = 0;
|
||||
public static final int INHERITED = 1;
|
||||
|
||||
// Form constants
|
||||
public static final String OBJECT_ID = "po_id";
|
||||
public static final String DIRECT_PERMISSIONS = "direct";
|
||||
public static final String INDIRECT_PERMISSIONS = "indirect";
|
||||
public static final String SEARCH_QUERY = "query";
|
||||
public static final String PRIV_SET = "privs_set";
|
||||
|
||||
// shared query
|
||||
public static final String RETRIEVE_USERS
|
||||
= "com.arsdigita.kernel.RetrieveUsers";
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* 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.permissions;
|
||||
|
||||
import com.arsdigita.bebop.BoxPanel;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.FormData;
|
||||
import com.arsdigita.bebop.FormProcessException;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.SegmentedPanel;
|
||||
import com.arsdigita.bebop.Text;
|
||||
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||
import com.arsdigita.bebop.event.FormSubmissionListener;
|
||||
import com.arsdigita.bebop.event.PrintEvent;
|
||||
import com.arsdigita.bebop.event.PrintListener;
|
||||
import com.arsdigita.bebop.form.CheckboxGroup;
|
||||
import com.arsdigita.bebop.form.Option;
|
||||
import com.arsdigita.bebop.form.OptionGroup;
|
||||
import com.arsdigita.bebop.form.Submit;
|
||||
import com.arsdigita.bebop.parameters.ArrayParameter;
|
||||
import com.arsdigita.bebop.parameters.StringParameter;
|
||||
|
||||
import com.arsdigita.util.StringUtils;
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.security.PermissionManager;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.TooManyListenersException;
|
||||
|
||||
import static com.arsdigita.cms.ui.permissions.CMSPermissionsConstants.*;
|
||||
|
||||
/**
|
||||
* Permissions Grant container for permissions assignment. Widgets are currently
|
||||
* organised on a bebop SegmentedPanel.
|
||||
*
|
||||
* @author Stefan Deusch (sdeusch@arsdigita.com)
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class CMSPermissionsGrant {
|
||||
|
||||
private final static String PARTIES_CBG = "parties_cbg";
|
||||
private final static String PRIVILEGES_CBG = "privs_cbg";
|
||||
|
||||
// data keys
|
||||
private static final String USER_ID = "userID";
|
||||
private static final String SCREEN_NAME = "screenName";
|
||||
private static final String FIRST_NAME = "firstName";
|
||||
private static final String LAST_NAME = "lastName";
|
||||
|
||||
private final CMSPermissionsPane parent;
|
||||
private final SegmentedPanel grantPanel;
|
||||
private CheckboxGroup partiesCheckboxGroup;
|
||||
private CheckboxGroup privilegesCheckboxGroup;
|
||||
private Form form;
|
||||
private Submit saveSubmit;
|
||||
|
||||
/**
|
||||
* Creates a PermissionsGrant object that will be contained with another
|
||||
* component. This is currently used inside the permissions pane.
|
||||
*
|
||||
* @param parent the enclosing container
|
||||
*/
|
||||
public CMSPermissionsGrant(final CMSPermissionsPane parent) {
|
||||
this.parent = parent;
|
||||
makeForm();
|
||||
grantPanel = new SegmentedPanel();
|
||||
grantPanel.addSegment(new Label(PAGE_GRANT_TITLE), form);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the form used to grant pivileges to users and groups.
|
||||
*/
|
||||
private void makeForm() {
|
||||
form = new Form("GrantPrivileges", new BoxPanel());
|
||||
form.setMethod(Form.POST);
|
||||
form.addSubmissionListener(new GrantFormSubmissionListener());
|
||||
form.add(new Label(PAGE_GRANT_LEFT));
|
||||
partiesCheckboxGroup = new CheckboxGroup(PARTIES_CBG);
|
||||
try {
|
||||
partiesCheckboxGroup.addPrintListener(new UserSearchPrintListener());
|
||||
} catch (TooManyListenersException e) {
|
||||
throw new UncheckedWrapperException("TooManyListeners: " + e
|
||||
.getMessage(), e);
|
||||
}
|
||||
form.add(partiesCheckboxGroup);
|
||||
|
||||
form.add(new Label(PAGE_GRANT_RIGHT));
|
||||
privilegesCheckboxGroup = new CheckboxGroup(PRIVILEGES_CBG);
|
||||
try {
|
||||
privilegesCheckboxGroup.addPrintListener(
|
||||
new PrivilegePrintListener());
|
||||
} catch (TooManyListenersException e) {
|
||||
throw new UncheckedWrapperException("TooManyListeners: " + e
|
||||
.getMessage(), e);
|
||||
}
|
||||
form.add(privilegesCheckboxGroup);
|
||||
|
||||
saveSubmit = new Submit("save", SAVE_BUTTON);
|
||||
form.add(saveSubmit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SegmentedPanel with the permissions grant Form
|
||||
*
|
||||
* @return the SegmentedPanel with the permissions grant form
|
||||
*/
|
||||
public SegmentedPanel getPanel() {
|
||||
return grantPanel;
|
||||
}
|
||||
|
||||
private class GrantFormSubmissionListener
|
||||
implements FormSubmissionListener {
|
||||
|
||||
@Override
|
||||
public void submitted(FormSectionEvent event) throws
|
||||
FormProcessException {
|
||||
final PageState state = event.getPageState();
|
||||
final FormData data = event.getFormData();
|
||||
final String[] gids = (String[]) data.get(PARTIES_CBG);
|
||||
final String[] privs = (String[]) data.get(PRIVILEGES_CBG);
|
||||
if (privs != null && gids != null) {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionManager permissionManager = cdiUtil.findBean(
|
||||
PermissionManager.class);
|
||||
|
||||
final Long oID = parent.getObject(state).getObjectId();
|
||||
for (String gid : gids) {
|
||||
final Long gID = Long.parseLong(gid);
|
||||
final CMSUserObjectStruct userObjectStruct
|
||||
= new CMSUserObjectStruct(gID,
|
||||
oID);
|
||||
for (String priv : privs) {
|
||||
permissionManager.grantPrivilege(
|
||||
priv,
|
||||
userObjectStruct.getRole(),
|
||||
userObjectStruct.getObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
parent.showAdmin(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class UserSearchPrintListener implements PrintListener {
|
||||
|
||||
@Override
|
||||
public void prepare(final PrintEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
final OptionGroup target = (OptionGroup) event.getTarget();
|
||||
|
||||
// get query string
|
||||
final String search = StringUtils.stripWhiteSpace((String) state.
|
||||
getValue(new StringParameter(SEARCH_QUERY)));
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final RoleRepository roleRepo = cdiUtil.findBean(
|
||||
RoleRepository.class);
|
||||
|
||||
final List<Role> roles = roleRepo.searchByName(search);
|
||||
|
||||
roles.forEach(role -> target.addOption(new Option(
|
||||
Long.toString(role.getRoleId()),
|
||||
new Text(role.getName()))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class PrivilegePrintListener implements PrintListener {
|
||||
|
||||
@Override
|
||||
public void prepare(final PrintEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
final OptionGroup target = (OptionGroup) event.getTarget();
|
||||
|
||||
// get privileges from page state
|
||||
final Object[] privileges = (Object[]) state.getValue(
|
||||
new ArrayParameter(
|
||||
PRIV_SET));
|
||||
|
||||
// print ceckbox group with privileges
|
||||
for (Object privilege : privileges) {
|
||||
target.addOption(new Option((String) privilege,
|
||||
new Text(parent.getPrivilegeName(
|
||||
(String) privilege))));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* 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.permissions;
|
||||
|
||||
import com.arsdigita.bebop.BoxPanel;
|
||||
import com.arsdigita.bebop.DimensionalNavbar;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.Link;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.event.PrintEvent;
|
||||
import com.arsdigita.bebop.event.PrintListener;
|
||||
|
||||
import org.libreccm.core.CcmObject;
|
||||
|
||||
import static com.arsdigita.cms.ui.permissions.CMSPermissionsConstants.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* Component that Renders the Header of the Permissions Admin pages
|
||||
*
|
||||
* @author sdeusch@arsdigita.com
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class CMSPermissionsHeader extends BoxPanel {
|
||||
|
||||
private final CMSPermissionsPane parent;
|
||||
private final Label title;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
CMSPermissionsHeader(final CMSPermissionsPane parent) {
|
||||
this.parent = parent;
|
||||
title = new Label();
|
||||
title.addPrintListener(new PrintListener() {
|
||||
|
||||
@Override
|
||||
public void prepare(final PrintEvent event) {
|
||||
final Label target = (Label) event.getTarget();
|
||||
target.setLabel(PAGE_TITLE);
|
||||
}
|
||||
|
||||
});
|
||||
title.setClassAttr("heading");
|
||||
add(title);
|
||||
|
||||
// Used to render the object name in the navbar
|
||||
final Label objectName = new Label();
|
||||
objectName.addPrintListener(new PrintListener() {
|
||||
|
||||
public void prepare(final PrintEvent event) {
|
||||
final Label target = (Label) event.getTarget();
|
||||
target.setLabel(getObjectName(event));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
final DimensionalNavbar navbar = new DimensionalNavbar();
|
||||
navbar.add(new Link(new Label(PERSONAL_SITE), "/pvt/home"));
|
||||
navbar.add(new Link(new Label(MAIN_SITE), "/"));
|
||||
navbar.add(new Link(new Label(PERMISSIONS_INDEX), "/permissions/"));
|
||||
navbar.add(objectName);
|
||||
navbar.setClassAttr("permNavBar");
|
||||
add(navbar);
|
||||
}
|
||||
|
||||
private String getObjectName(final PrintEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
final CcmObject object = parent.getObject(state);
|
||||
final String objectName = String.format("%s (ID %d)",
|
||||
object.getDisplayName(),
|
||||
object.getObjectId());
|
||||
return objectName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object used to render the title of the panel.
|
||||
*/
|
||||
Label getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,501 @@
|
|||
/*
|
||||
* 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.permissions;
|
||||
|
||||
import com.arsdigita.bebop.BoxPanel;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.Page;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.RequestLocal;
|
||||
import com.arsdigita.bebop.Resettable;
|
||||
import com.arsdigita.bebop.SegmentedPanel;
|
||||
import com.arsdigita.bebop.SimpleComponent;
|
||||
import com.arsdigita.bebop.SimpleContainer;
|
||||
import com.arsdigita.bebop.Text;
|
||||
import com.arsdigita.bebop.event.ActionEvent;
|
||||
import com.arsdigita.bebop.event.ActionListener;
|
||||
import com.arsdigita.bebop.event.RequestEvent;
|
||||
import com.arsdigita.bebop.event.RequestListener;
|
||||
import com.arsdigita.bebop.parameters.ArrayParameter;
|
||||
import com.arsdigita.bebop.parameters.ParameterModel;
|
||||
import com.arsdigita.bebop.parameters.StringParameter;
|
||||
import com.arsdigita.dispatcher.DispatcherHelper;
|
||||
import com.arsdigita.ui.CcmObjectSelectionModel;
|
||||
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
import org.libreccm.security.Role;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contentsection.Folder;
|
||||
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A pane used to administer the permissions of one {@link
|
||||
* ACSObject}. This is a reusable component that can be embedded into a page to
|
||||
* provide a generic UI. The page must have the "?po_id=" parameter to supply to
|
||||
* ACSObject id of the item one is managing permissions for.
|
||||
*
|
||||
* @author sdeusch@arsdigita.com
|
||||
* @authro <a href="jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class CMSPermissionsPane extends SimpleContainer
|
||||
implements Resettable,
|
||||
ActionListener,
|
||||
RequestListener {
|
||||
|
||||
// non-shared parameter models; leave package scope for access from its members.
|
||||
private ParameterModel searchString = new StringParameter(
|
||||
CMSPermissionsConstants.SEARCH_QUERY);
|
||||
private ParameterModel privilegeArray = new ArrayParameter(
|
||||
CMSPermissionsConstants.PRIV_SET);
|
||||
|
||||
private String[] privileges;
|
||||
private Map<String, String> privilegeNameMap;
|
||||
private CMSPermissionsTables allPermissions;
|
||||
private CMSPermissionsHeader PermissionsHeader;
|
||||
private SimpleContainer directPermissions;
|
||||
private Form roleSearchForm;
|
||||
private SimpleContainer inheritedPermissions;
|
||||
private SimpleComponent contextPanel;
|
||||
private SimpleContainer permissionsGrantPanel;
|
||||
private SimpleContainer noResultsPanel;
|
||||
private ObjectAdminListing adminListing;
|
||||
private CcmObjectSelectionModel<CcmObject> selectionModel;
|
||||
|
||||
private RequestLocal userObjectInfo;
|
||||
|
||||
/**
|
||||
* Default constructor creates components that show the default privileges
|
||||
* as defined in PermissionsConstants interface
|
||||
*
|
||||
* @param model
|
||||
*/
|
||||
public CMSPermissionsPane(final CcmObjectSelectionModel<CcmObject> model) {
|
||||
this(CMSPermissionsConstants.DEFAULT_PRIVILEGES, new HashMap<>(), model);
|
||||
privilegeNameMap.put("read", "Read");
|
||||
privilegeNameMap.put("write", "Write");
|
||||
privilegeNameMap.put("create", "Create");
|
||||
privilegeNameMap.put("delete", "Delete");
|
||||
privilegeNameMap.put("admin", "Admin");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PermissionsPane with components showing the privileges that are
|
||||
* passed in as argument.
|
||||
*
|
||||
* @param privileges
|
||||
* @param privilegeNameMap
|
||||
* @param selectionModel
|
||||
*/
|
||||
public CMSPermissionsPane(
|
||||
final String[] privileges,
|
||||
final Map<String, String> privilegeNameMap,
|
||||
final CcmObjectSelectionModel<CcmObject> selectionModel) {
|
||||
|
||||
userObjectInfo = new RequestLocal() {
|
||||
|
||||
@Override
|
||||
protected Object initialValue(final PageState state) {
|
||||
return new CMSUserObjectStruct(state, selectionModel);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.privileges = privileges;
|
||||
this.selectionModel = selectionModel;
|
||||
this.privilegeNameMap = privilegeNameMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite this method to construct your default Permissions Pane with the
|
||||
* components you need. You can subclass anonymously overwriting just the
|
||||
* register method. Note: the getXXX methods are lazy instantiators, i.e.
|
||||
* they produce the components only if not already there. (You can even
|
||||
* overwrite the getXXX components with your own implementation, e.g., if
|
||||
* you want to show a List instead of a Table for the direct permissions,
|
||||
* but still use a Table for the inherited permissions.
|
||||
*
|
||||
* @param page
|
||||
*/
|
||||
@Override
|
||||
public void register(final Page page) {
|
||||
super.register(page);
|
||||
|
||||
// add permissions components to this specific implementation
|
||||
// add(getPermissionsHeader());
|
||||
add(getContextPanel());
|
||||
add(getDirectPermissionsPanel());
|
||||
add(getUserSearchForm());
|
||||
add(getInheritedPermissionsPanel());
|
||||
add(getPermissionGrantPanel());
|
||||
add(getNoSearchResultPanel());
|
||||
add(getAdminListingPanel());
|
||||
|
||||
// set initial visibility of components
|
||||
// p.setVisibleDefault(getPermissionsHeader(), true);
|
||||
page.setVisibleDefault(getDirectPermissionsPanel(), true);
|
||||
page.setVisibleDefault(getUserSearchForm(), true);
|
||||
page.setVisibleDefault(getInheritedPermissionsPanel(), true);
|
||||
page.setVisibleDefault(getContextPanel(), true);
|
||||
page.setVisibleDefault(getPermissionGrantPanel(), false);
|
||||
page.setVisibleDefault(getNoSearchResultPanel(), false);
|
||||
page.setVisibleDefault(getAdminListingPanel(), false);
|
||||
|
||||
// p.addActionListener(this);
|
||||
// p.addRequestListener(this);
|
||||
// add state parameters
|
||||
page.addGlobalStateParam(searchString);
|
||||
page.addGlobalStateParam(privilegeArray);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of interface bebop.Resettable. Use {@code reset} to reset
|
||||
* permissions component to initial state, e.g. if you embed it into another
|
||||
* container.
|
||||
*/
|
||||
@Override
|
||||
public void reset(final PageState state) {
|
||||
showAdmin(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to get the authenticated user or group
|
||||
*
|
||||
* @param state
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Role getRequestingRole(final PageState state) {
|
||||
return ((CMSUserObjectStruct) userObjectInfo.get(state)).getRole();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to get the ACSObject from the page state
|
||||
*
|
||||
* @param state
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CcmObject getObject(final PageState state) {
|
||||
return ((CMSUserObjectStruct) userObjectInfo.get(state)).getObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title "Permissions on object articles", e.g.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Label getTitle() {
|
||||
return ((CMSPermissionsHeader) getPermissionsHeader()).getTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string array of privilege names as defined in the constructor
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String[] getPrivileges() {
|
||||
return Arrays.copyOf(privileges, privileges.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the direct and inherited permission tables to the privileges
|
||||
* defined in the constructor.
|
||||
*
|
||||
* @see #getDirectPermissionsPanel(), getInheritedPermissionsPanel()
|
||||
*/
|
||||
private CMSPermissionsTables getPermissionsTables() {
|
||||
if (allPermissions == null) {
|
||||
allPermissions = new CMSPermissionsTables(privileges, this);
|
||||
}
|
||||
return allPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bebop component with a table for the direct permission on the
|
||||
* privileges defined in the constructor
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @see #getInheritedPermissionsPanel()
|
||||
*/
|
||||
public SimpleContainer getDirectPermissionsPanel() {
|
||||
directPermissions = getPermissionsTables().getPermissions(
|
||||
CMSPermissionsConstants.DIRECT);
|
||||
return directPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bebop component with a table for the inherited permission on
|
||||
* the privileges defined in the constructor. The table is non-editable.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @see #getDirectPermissionsPanel()
|
||||
*/
|
||||
public SimpleContainer getInheritedPermissionsPanel() {
|
||||
inheritedPermissions = getPermissionsTables()
|
||||
.getPermissions(CMSPermissionsConstants.INHERITED);
|
||||
return inheritedPermissions;
|
||||
}
|
||||
|
||||
public SimpleContainer getAdminListingPanel() {
|
||||
if (adminListing == null) {
|
||||
adminListing = new ObjectAdminListing(selectionModel);
|
||||
}
|
||||
return adminListing;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an outstanding item.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public SegmentedPanel getUniversalPermissionsPanel() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bebop form for user and group search.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Form getUserSearchForm() {
|
||||
if (roleSearchForm == null) {
|
||||
roleSearchForm = new CMSUserSearchForm(this);
|
||||
}
|
||||
return roleSearchForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a panel with a form with 2 checkbox groups, one for parties to
|
||||
* choose, one for privileges to assign.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public SimpleContainer getPermissionGrantPanel() {
|
||||
if (permissionsGrantPanel == null) {
|
||||
CMSPermissionsGrant permGrant = new CMSPermissionsGrant(this);
|
||||
permissionsGrantPanel = permGrant.getPanel();
|
||||
}
|
||||
return permissionsGrantPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bebop container with the title to this object and a navigation
|
||||
* bar, specific for the UI at /permissions/.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public SimpleContainer getPermissionsHeader() {
|
||||
if (PermissionsHeader == null) {
|
||||
PermissionsHeader = new CMSPermissionsHeader(this);
|
||||
}
|
||||
return PermissionsHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bebop panel indicating that the user search yielded no results.
|
||||
* It is customised in the xsl stylesheet.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public SimpleContainer getNoSearchResultPanel() {
|
||||
if (noResultsPanel == null) {
|
||||
final Label errorMsg = new Label(CMSPermissionsConstants.NO_RESULTS);
|
||||
errorMsg.setClassAttr("errorBullet");
|
||||
final BoxPanel panel = new BoxPanel();
|
||||
panel.add(errorMsg);
|
||||
panel.add(new CMSUserSearchForm(this));
|
||||
noResultsPanel = new SegmentedPanel().addSegment(new Text(" "),
|
||||
panel);
|
||||
}
|
||||
return noResultsPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bebop panel with a link to the permissions administration page
|
||||
* of the object's direct ancestor (parent).
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public SimpleComponent getContextPanel() {
|
||||
if (contextPanel == null) {
|
||||
contextPanel = getPermissionsTables().makeContextPanel();
|
||||
}
|
||||
return contextPanel;
|
||||
}
|
||||
|
||||
ParameterModel getSearchString() {
|
||||
return searchString;
|
||||
}
|
||||
|
||||
ParameterModel getPrivilegeParam() {
|
||||
return privilegeArray;
|
||||
}
|
||||
|
||||
CcmObjectSelectionModel<CcmObject> getSelectionModel() {
|
||||
return selectionModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows panel with no results to user search.
|
||||
*
|
||||
* @param state
|
||||
*/
|
||||
public void showNoResults(final PageState state) {
|
||||
getDirectPermissionsPanel().setVisible(state, false);
|
||||
getInheritedPermissionsPanel().setVisible(state, false);
|
||||
getContextPanel().setVisible(state, false);
|
||||
getUserSearchForm().setVisible(state, false);
|
||||
getPermissionGrantPanel().setVisible(state, false);
|
||||
getNoSearchResultPanel().setVisible(state, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the Grant privileges panel
|
||||
*
|
||||
* @param state
|
||||
*/
|
||||
public void showGrant(final PageState state) {
|
||||
getDirectPermissionsPanel().setVisible(state, false);
|
||||
getInheritedPermissionsPanel().setVisible(state, false);
|
||||
getContextPanel().setVisible(state, false);
|
||||
getUserSearchForm().setVisible(state, false);
|
||||
getNoSearchResultPanel().setVisible(state, false);
|
||||
getPermissionGrantPanel().setVisible(state, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the administration page of permissions to one object.
|
||||
*
|
||||
* @param state
|
||||
*/
|
||||
public void showAdmin(final PageState state) {
|
||||
final CcmObject object = getObject(state);
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
|
||||
final boolean canAccess;
|
||||
if (object == null) {
|
||||
throw new UncheckedWrapperException(
|
||||
"Unexpected null value for object.");
|
||||
} else if (object instanceof ContentItem) {
|
||||
canAccess = permissionChecker.isPermitted(ItemPrivileges.ADMINISTER,
|
||||
object);
|
||||
} else if (object instanceof Folder) {
|
||||
canAccess = permissionChecker.isPermitted(ItemPrivileges.ADMINISTER,
|
||||
object);
|
||||
} else {
|
||||
throw new UncheckedWrapperException(String.format(
|
||||
"The object is of type \"%s\" which is not supported here.",
|
||||
object.getClass().getName()));
|
||||
}
|
||||
|
||||
if (canAccess) {
|
||||
showCustom(state, true);
|
||||
|
||||
// showCustom(state, false);
|
||||
getContextPanel().setVisible(state, true);
|
||||
|
||||
} else {
|
||||
// do not have permission to set permissions, so don't show them
|
||||
getDirectPermissionsPanel().setVisible(state, false);
|
||||
getInheritedPermissionsPanel().setVisible(state, false);
|
||||
getUserSearchForm().setVisible(state, false);
|
||||
getContextPanel().setVisible(state, false);
|
||||
}
|
||||
|
||||
getPermissionGrantPanel().setVisible(state, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
/**
|
||||
* check if viewing user has admin privilege on this Object, after
|
||||
* Action Event fires everytime the component is visible.
|
||||
*
|
||||
*/
|
||||
if (this.isVisible(state)) {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
|
||||
if (!permissionChecker.isPermitted(ItemPrivileges.ADMINISTER,
|
||||
getObject(state))) {
|
||||
try {
|
||||
DispatcherHelper.sendRedirect(state.getRequest(),
|
||||
state.getResponse(),
|
||||
"/permissions/denied");
|
||||
} catch (IOException ex) {
|
||||
throw new UncheckedWrapperException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void showCustom(final PageState state, final boolean custom) {
|
||||
if (custom) {
|
||||
getDirectPermissionsPanel().setVisible(state, true);
|
||||
getInheritedPermissionsPanel().setVisible(state, false);
|
||||
getUserSearchForm().setVisible(state, true);
|
||||
getAdminListingPanel().setVisible(state, true);
|
||||
} else {
|
||||
getDirectPermissionsPanel().setVisible(state, false);
|
||||
getInheritedPermissionsPanel().setVisible(state, true);
|
||||
getUserSearchForm().setVisible(state, false);
|
||||
getAdminListingPanel().setVisible(state, false);
|
||||
}
|
||||
}
|
||||
|
||||
public String getPrivilegeName(final String privilege) {
|
||||
return privilegeNameMap.get(privilege);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pageRequested(final RequestEvent event) {
|
||||
// PageState s = e.getPageState();
|
||||
// ACSObject object = getObject(s);
|
||||
// if (object != null) {
|
||||
// DataObject context = PermissionService.getContext(object);
|
||||
// if (context != null) {
|
||||
// showCustom(s, false);
|
||||
// } else {
|
||||
// showCustom(s, true);
|
||||
// }
|
||||
// } else {
|
||||
// throw new IllegalStateException( (String) GlobalizationUtil.globalize("cms.ui.permissions.current_object_is_null").localize());
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,652 @@
|
|||
/*
|
||||
* 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.permissions;
|
||||
|
||||
import com.arsdigita.bebop.ActionLink;
|
||||
import com.arsdigita.bebop.Component;
|
||||
import com.arsdigita.bebop.ControlLink;
|
||||
import com.arsdigita.bebop.GridPanel;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.SimpleComponent;
|
||||
import com.arsdigita.bebop.SimpleContainer;
|
||||
import com.arsdigita.bebop.Table;
|
||||
import com.arsdigita.bebop.event.PrintEvent;
|
||||
import com.arsdigita.bebop.event.PrintListener;
|
||||
import com.arsdigita.bebop.event.TableActionEvent;
|
||||
import com.arsdigita.bebop.event.TableActionListener;
|
||||
import com.arsdigita.bebop.table.TableCellRenderer;
|
||||
import com.arsdigita.bebop.table.TableModel;
|
||||
import com.arsdigita.bebop.table.TableModelBuilder;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.util.LockableImpl;
|
||||
import com.arsdigita.util.StringUtils;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.security.Permission;
|
||||
import org.libreccm.security.PermissionManager;
|
||||
import org.libreccm.security.Role;
|
||||
import org.librecms.CmsConstants;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.arsdigita.cms.ui.permissions.CMSPermissionsConstants.*;
|
||||
|
||||
/**
|
||||
* Class to represent direct and inherited permissions of an CcmObject. This
|
||||
* class provides two SegmentPanels with the direct and the inherited
|
||||
* permissions tables, respectively. The expected pageState contains a variable
|
||||
* "id=123" of which the permissions are rendered. The viewing user must be
|
||||
* authenticated. The permissions representations can be swapped , e.g. with a
|
||||
* List, if scalability warrants.
|
||||
*
|
||||
* @author Stefan Deusch
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class CMSPermissionsTables {
|
||||
|
||||
private static Logger LOGGER = LogManager.getLogger(
|
||||
CMSPermissionsTables.class);
|
||||
|
||||
private CMSPermissionsPane parent;
|
||||
private String[] privileges;
|
||||
private final GridPanel permissionsPanel[] = new GridPanel[2];
|
||||
private final int[] tableColumns = new int[2];
|
||||
|
||||
/**
|
||||
* Default constructor uses the DEFAULT_PRIVILEGES as defined in
|
||||
* PermissionsConstants.
|
||||
*/
|
||||
CMSPermissionsTables(final CMSPermissionsPane parent) {
|
||||
this(DEFAULT_PRIVILEGES, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that takes an array of PrivilegeDescriptors and builds the
|
||||
* grantee - privilege matrix. <strong>The permissions tables contain the
|
||||
* set of privileges that are passed into this constructor.</strong>
|
||||
*
|
||||
* @param privileges the array of PrivilegeDesrciptors with which go into
|
||||
* table
|
||||
* @param parent the Bebop parent container
|
||||
*/
|
||||
CMSPermissionsTables(final String[] privileges,
|
||||
final CMSPermissionsPane parent) {
|
||||
|
||||
this.parent = parent;
|
||||
|
||||
// fixed table information
|
||||
this.privileges = privileges;
|
||||
tableColumns[DIRECT] = privileges.length + 2;
|
||||
tableColumns[INHERITED] = privileges.length + 1;
|
||||
|
||||
// Construct Direct Permissions Panel
|
||||
permissionsPanel[DIRECT] = new GridPanel(1);
|
||||
final Table directTable = new Table(
|
||||
new PermissionsTableModelBuilder(DIRECT),
|
||||
getHeaders(DIRECT));
|
||||
directTable.setClassAttr("dataTable");
|
||||
setCellRenderers(directTable, DIRECT);
|
||||
directTable.addTableActionListener(
|
||||
new DirectPermissionsTableActionListener());
|
||||
permissionsPanel[DIRECT].add(new Label(new GlobalizedMessage(
|
||||
"cms.ui.permissions.these_are_the_custom_permissions"
|
||||
+ "_that_have_been_granted_on_this_object",
|
||||
CmsConstants.CMS_BUNDLE)));
|
||||
permissionsPanel[DIRECT].add(directTable);
|
||||
|
||||
// Construct Inherited Permissions Panel
|
||||
permissionsPanel[INHERITED] = new GridPanel(1);
|
||||
final Table inheritedTable = new Table(
|
||||
new PermissionsTableModelBuilder(INHERITED),
|
||||
getHeaders(INHERITED));
|
||||
inheritedTable.setClassAttr("dataTable");
|
||||
setCellRenderers(inheritedTable, INHERITED);
|
||||
permissionsPanel[INHERITED].add(new Label(new GlobalizedMessage(
|
||||
"cms.ui.permissions.these_are_the_current_permissions_for_this_folder",
|
||||
CmsConstants.CMS_BUNDLE)));
|
||||
permissionsPanel[INHERITED].add(inheritedTable);
|
||||
|
||||
//m_permPanel[INHERITED].addSegment(new Label(PERM_TABLE_INDIRECT_HEADING),
|
||||
// boxpanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SegmentedPanel with either the direct or the indirect
|
||||
* permissions table.
|
||||
*
|
||||
* @param use PermissionsContants.DIRECT or PermissionsContants.INHERITED
|
||||
*/
|
||||
GridPanel getPermissions(int type) {
|
||||
return permissionsPanel[type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of privileges of the permission tables as a String array.
|
||||
*/
|
||||
String[] getPrivileges() {
|
||||
return Arrays.copyOf(privileges, privileges.length);
|
||||
}
|
||||
|
||||
SimpleComponent makeContextPanel() {
|
||||
final SimpleContainer contextPanel = new SimpleContainer();
|
||||
final Label contextLabel1 = new Label();
|
||||
contextLabel1.addPrintListener(new PrintListener() {
|
||||
|
||||
@Override
|
||||
public void prepare(final PrintEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
final Label label = (Label) event.getTarget();
|
||||
final CcmObject context = getContext(state);
|
||||
if (context != null) {
|
||||
label.setLabel(PERM_TABLE_INDIRECT_CONTEXT);
|
||||
contextLabel1.setVisible(state, true);
|
||||
} else {
|
||||
label.setLabel(PERM_TABLE_NO_PARENT_CONTEXT);
|
||||
contextLabel1.setVisible(state, false);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
final Label contextLabel2 = new Label();
|
||||
contextLabel2.addPrintListener(new PrintListener() {
|
||||
|
||||
@Override
|
||||
public void prepare(final PrintEvent event) {
|
||||
final PageState state = event.getPageState();
|
||||
final Label label = (Label) event.getTarget();
|
||||
final CcmObject context = getContext(state);
|
||||
if (context != null) {
|
||||
label.setLabel(context.getDisplayName());
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
contextLabel2.setFontWeight(Label.BOLD);
|
||||
|
||||
contextPanel.add(contextLabel1);
|
||||
contextPanel.add(contextLabel2);
|
||||
return contextPanel;
|
||||
}
|
||||
|
||||
CcmObject getContext(final PageState state) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String[] getHeaders(final int type) {
|
||||
String[] headers = new String[tableColumns[type]];
|
||||
headers[0] = PERM_TABLE_GRANTEE.localize() + "";
|
||||
for (int j = 0; j < privileges.length; j++) {
|
||||
headers[j + 1] = parent.getPrivilegeName(privileges[j]);
|
||||
}
|
||||
if (type == DIRECT) {
|
||||
headers[privileges.length + 1] = PERM_TABLE_ACTIONS.localize()
|
||||
+ "";
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
private void setCellRenderers(final Table table, final int type) {
|
||||
int j;
|
||||
if (type == DIRECT) {
|
||||
for (j = 1; j < table.getColumnModel().size() - 1; j++) {
|
||||
table.getColumn(j).setCellRenderer(
|
||||
new PermissionToggleRenderer());
|
||||
}
|
||||
table.getColumn(j).setCellRenderer(new LinkRenderer());
|
||||
} else {
|
||||
for (j = 1; j < table.getColumnModel().size(); j++) {
|
||||
table.getColumn(j).setCellRenderer(
|
||||
new PermissionStatusRenderer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DirectPermissionsTableActionListener
|
||||
implements TableActionListener {
|
||||
|
||||
@Override
|
||||
public void cellSelected(TableActionEvent event) {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
final int col = event.getColumn();
|
||||
final String rowkey = (String) event.getRowKey();
|
||||
if (rowkey == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Table table = (Table) event.getSource();
|
||||
final int no_cols = table.getColumnModel().size();
|
||||
final int lastCol = no_cols - 1;
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionManager permissionManager = cdiUtil.findBean(
|
||||
PermissionManager.class);
|
||||
|
||||
if (col > 0 && col < lastCol) {
|
||||
|
||||
final PermissionStatus pmds = UserPrivilegeKey
|
||||
.undescribe(rowkey);
|
||||
LOGGER.debug("Do perm toggle on {} for {} of {}",
|
||||
pmds.getObject().getObjectId(),
|
||||
pmds.getRole().getName(),
|
||||
pmds.getPrivilege());
|
||||
|
||||
if (pmds.isGranted()) {
|
||||
|
||||
LOGGER.debug("Do revoke permission");
|
||||
|
||||
permissionManager.revokePrivilege(pmds.getPrivilege(),
|
||||
pmds.getRole(),
|
||||
pmds.getObject());
|
||||
} else {
|
||||
LOGGER.debug("Do grant permission");
|
||||
|
||||
permissionManager.grantPrivilege(pmds.getPrivilege(),
|
||||
pmds.getRole(),
|
||||
pmds.getObject());
|
||||
}
|
||||
|
||||
} else if (col == lastCol) {
|
||||
// Process Remove All Link
|
||||
final String[] tokens = StringUtils.split(rowkey, '.');
|
||||
final Long pID = Long.parseLong(tokens[0]);
|
||||
|
||||
/*
|
||||
* Remove all indicated privileges from user
|
||||
* enumerated in tokens array
|
||||
*/
|
||||
final CcmObject obj = parent.getObject(state);
|
||||
final Role role = CMSUserObjectStruct.loadRole(pID);
|
||||
|
||||
LOGGER.debug("Revoke all on {} for {}.",
|
||||
obj.getObjectId(),
|
||||
role.getName());
|
||||
|
||||
for (final String token : tokens) {
|
||||
permissionManager.revokePrivilege(token, role, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void headSelected(final TableActionEvent event) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class PermissionsTableModelBuilder
|
||||
extends LockableImpl implements TableModelBuilder {
|
||||
|
||||
private final int m_type;
|
||||
|
||||
PermissionsTableModelBuilder(final int type) {
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
/*
|
||||
* this can be optimized to run the query only
|
||||
* once for both tables
|
||||
*/
|
||||
@Override
|
||||
public TableModel makeModel(final Table table,
|
||||
final PageState state) {
|
||||
final CcmObject object = parent.getObject(state);
|
||||
final List<Permission> permissions = object.getPermissions();
|
||||
|
||||
switch (m_type) {
|
||||
case DIRECT:
|
||||
return new DirectPermissionsTableModel(permissions,
|
||||
object);
|
||||
case INHERITED:
|
||||
return new DirectPermissionsTableModel(permissions,
|
||||
object);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class DirectPermissionsTableModel implements TableModel {
|
||||
|
||||
private final List<String> userPrivileges = new ArrayList<>();
|
||||
|
||||
private final Iterator<Permission> iterator;
|
||||
private Permission currentPermission;
|
||||
|
||||
public DirectPermissionsTableModel(final List<Permission> permissions,
|
||||
final CcmObject object) {
|
||||
this.iterator = permissions.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return tableColumns[DIRECT];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(final int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
|
||||
// the Grantee column
|
||||
return currentPermission.getGrantee().getName();
|
||||
|
||||
} else if (columnIndex == getColumnCount() - 1) {
|
||||
|
||||
// the Action column
|
||||
return "Remove All";
|
||||
|
||||
} else {
|
||||
if (userHasPermission(columnIndex - 1)) {
|
||||
return Boolean.TRUE;
|
||||
} else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getKeyAt(final int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
|
||||
// the key for the grantee
|
||||
return currentPermission.getGrantee().getRoleId();
|
||||
|
||||
} else if (columnIndex == getColumnCount() - 1) {
|
||||
|
||||
// key for 'Remove All' link
|
||||
return makeRemoveAllKey();
|
||||
|
||||
} else {
|
||||
// key for a user privilege
|
||||
return (new UserPrivilegeKey(
|
||||
currentPermission.getObject().getObjectId(),
|
||||
currentPermission.getGrantee().getRoleId(),
|
||||
privileges[columnIndex - 1],
|
||||
userHasPermission(columnIndex - 1)))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nextRow() {
|
||||
if (iterator.hasNext()) {
|
||||
currentPermission = iterator.next();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean userHasPermission(final int idx) {
|
||||
return userPrivileges.contains(privileges[idx]);
|
||||
}
|
||||
|
||||
private String makeRemoveAllKey() {
|
||||
final StringBuffer buffer = new StringBuffer();
|
||||
buffer.append(Long.toString(currentPermission.getGrantee()
|
||||
.getRoleId()));
|
||||
for (int i = 0; i < privileges.length; i++) {
|
||||
if (userHasPermission(i)) {
|
||||
buffer.append(".").append(privileges[i]);
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
void addPrivilege(final String privilege) {
|
||||
for (String current : privileges) {
|
||||
if (current.equals(current)) {
|
||||
userPrivileges.add(current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Permission getCurrentPermission() {
|
||||
return currentPermission;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension of DirectPermissionsTableModel to accomodate Inherited
|
||||
* permissions table model.
|
||||
*/
|
||||
private final class InheritedPermissionsTableModel
|
||||
extends DirectPermissionsTableModel {
|
||||
|
||||
public InheritedPermissionsTableModel(final List<Permission> permissions,
|
||||
final CcmObject object) {
|
||||
super(permissions, object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return tableColumns[INHERITED];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(final int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
|
||||
// the Grantee column
|
||||
return getCurrentPermission().getGrantee().getName();
|
||||
|
||||
} else {
|
||||
if (userHasPermission(columnIndex - 1)) {
|
||||
return Boolean.TRUE;
|
||||
} else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getKeyAt(final int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
// the key for the grantee
|
||||
return getCurrentPermission().getGrantee().getRoleId();
|
||||
|
||||
}
|
||||
// no keys for inherited permissions
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class PermissionToggleRenderer 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) {
|
||||
|
||||
final ControlLink link = new ControlLink("");
|
||||
|
||||
if (((Boolean) value)) {
|
||||
link.setClassAttr("checkBoxChecked");
|
||||
} else {
|
||||
link.setClassAttr("checkBoxUnchecked");
|
||||
}
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class PermissionStatusRenderer 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) {
|
||||
|
||||
final Label link = new Label();
|
||||
|
||||
if (((Boolean) value)) {
|
||||
link.setClassAttr("checkBoxGreyChecked");
|
||||
} else {
|
||||
link.setClassAttr("checkBoxGreyUnchecked");
|
||||
}
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class LinkRenderer 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) {
|
||||
final ControlLink link = new ControlLink((String) value);
|
||||
link.setConfirmation(REMOVE_ALL_CONFIRM);
|
||||
return link;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class to encode a user privilege in the bebop table
|
||||
*/
|
||||
final class UserPrivilegeKey {
|
||||
|
||||
private final String objectId;
|
||||
private final String granteeId;
|
||||
private final String privilege;
|
||||
private final boolean granted;
|
||||
|
||||
public UserPrivilegeKey(final Long objectId,
|
||||
final Long granteeId,
|
||||
final String privilege,
|
||||
final boolean granted) {
|
||||
this.objectId = objectId.toString();
|
||||
this.granteeId = granteeId.toString();
|
||||
this.privilege = privilege;
|
||||
this.granted = granted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s{ %s }",
|
||||
super.toString(),
|
||||
String.join(".", privilege,
|
||||
objectId,
|
||||
granteeId,
|
||||
Boolean.toString(granted)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the information in a key into the helper class
|
||||
*
|
||||
* @see PermissionStatus
|
||||
*/
|
||||
static PermissionStatus undescribe(final String key) {
|
||||
|
||||
final int i = key.indexOf(".");
|
||||
final int j = key.indexOf(".", i + 1);
|
||||
final int k = key.lastIndexOf(".");
|
||||
|
||||
final String privilege = key.substring(0, i);
|
||||
final Long oID = Long.parseLong(key.substring(i + 1, j));
|
||||
final Long gID = Long.parseLong(key.substring(j + 1, k));
|
||||
|
||||
boolean granted = false;
|
||||
final CMSUserObjectStruct uos;
|
||||
try {
|
||||
granted = Boolean.parseBoolean(key.substring(k + 1, k + 2));
|
||||
uos = new CMSUserObjectStruct(gID, oID);
|
||||
} catch (NumberFormatException ex) {
|
||||
// cannot decode
|
||||
throw new IllegalArgumentException(ex.getMessage());
|
||||
}
|
||||
|
||||
return new PermissionStatus(privilege,
|
||||
uos.getObject(),
|
||||
uos.getRole(),
|
||||
granted);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Structure to hold a permission and its current grant state
|
||||
*/
|
||||
final class PermissionStatus {
|
||||
|
||||
private final boolean granted;
|
||||
private final CcmObject object;
|
||||
private final Role role;
|
||||
private final String privilege;
|
||||
|
||||
PermissionStatus(final String privilege,
|
||||
final CcmObject object,
|
||||
final Role role,
|
||||
final boolean granted) {
|
||||
|
||||
this.granted = granted;
|
||||
|
||||
this.object = object;
|
||||
this.role = role;
|
||||
this.privilege = privilege;
|
||||
}
|
||||
|
||||
boolean isGranted() {
|
||||
return granted;
|
||||
}
|
||||
|
||||
CcmObject getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
Role getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
String getPrivilege() {
|
||||
return privilege;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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.permissions;
|
||||
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.ui.CcmObjectSelectionModel;
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.core.CcmObjectRepository;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
|
||||
/**
|
||||
* This class is mainly instantiated from a PageState It is very context
|
||||
* specific for permissions. It tries to read the object_id and load the
|
||||
* corresponding ACSObject, as well as the party_id and the corresponding
|
||||
* entity.
|
||||
*
|
||||
* @author Stefan Deusch (sdeusch@arsdigita.com)
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class CMSUserObjectStruct {
|
||||
|
||||
private final Role role;
|
||||
private final CcmObject object;
|
||||
|
||||
CMSUserObjectStruct(final PageState state,
|
||||
final CcmObjectSelectionModel selectionModel) {
|
||||
this(getRole(state), getObject(state, selectionModel));
|
||||
}
|
||||
|
||||
CMSUserObjectStruct(final Long partyId,
|
||||
final Long objectId) {
|
||||
this(loadRole(partyId), loadObject(objectId));
|
||||
}
|
||||
|
||||
CMSUserObjectStruct(final Role role, final CcmObject object) {
|
||||
this.role = role;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
Role getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
CcmObject getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
// Utility factory methods
|
||||
static CcmObject loadObject(final Long objectId) {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final CcmObjectRepository objectRepo = cdiUtil.findBean(
|
||||
CcmObjectRepository.class);
|
||||
|
||||
final CcmObject ccmObject = objectRepo.findById(objectId);
|
||||
if (ccmObject == null) {
|
||||
throw new UncheckedWrapperException(String.format(
|
||||
"Failed to find object with ID %d.", objectId));
|
||||
}
|
||||
|
||||
return ccmObject;
|
||||
}
|
||||
|
||||
// use in package
|
||||
static Role loadRole(final Long roleId) {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final RoleRepository roleRepo = cdiUtil
|
||||
.findBean(RoleRepository.class);
|
||||
|
||||
final Role role = roleRepo.findById(roleId);
|
||||
|
||||
if (role == null) {
|
||||
throw new UncheckedWrapperException(String.format(
|
||||
"Failed to find party with ID %d.", roleId));
|
||||
}
|
||||
|
||||
return role;
|
||||
}
|
||||
|
||||
public static Role getRole(final PageState state) {
|
||||
// final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
// final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
||||
//
|
||||
// return shiro.getUser();
|
||||
return null;
|
||||
}
|
||||
|
||||
public static CcmObject getObject(
|
||||
final PageState state, final CcmObjectSelectionModel selectionModel) {
|
||||
return selectionModel.getSelectedObject(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* 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.permissions;
|
||||
|
||||
import com.arsdigita.bebop.ColumnPanel;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.FormData;
|
||||
import com.arsdigita.bebop.FormProcessException;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.SimpleContainer;
|
||||
import com.arsdigita.bebop.event.FormProcessListener;
|
||||
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||
import com.arsdigita.bebop.form.Submit;
|
||||
import com.arsdigita.bebop.form.TextField;
|
||||
import com.arsdigita.bebop.parameters.NotEmptyValidationListener;
|
||||
import com.arsdigita.bebop.parameters.ParameterModel;
|
||||
import com.arsdigita.bebop.parameters.StringParameter;
|
||||
import com.arsdigita.util.StringUtils;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.security.Party;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.arsdigita.cms.ui.permissions.CMSPermissionsConstants.*;
|
||||
|
||||
/**
|
||||
* User Search Form for permissions.
|
||||
*
|
||||
* @author Stefan Deusch (stefan@arsdigita.com)
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class CMSUserSearchForm extends Form implements FormProcessListener {
|
||||
|
||||
private CMSPermissionsPane parent;
|
||||
private TextField searchField;
|
||||
|
||||
public CMSUserSearchForm(CMSPermissionsPane parent) {
|
||||
this(DEFAULT_PRIVILEGES, parent);
|
||||
}
|
||||
|
||||
public CMSUserSearchForm(final String[] privileges,
|
||||
final CMSPermissionsPane parent) {
|
||||
super("RoleSearchUsers", new SimpleContainer());
|
||||
|
||||
this.parent = parent;
|
||||
setMethod(Form.POST);
|
||||
|
||||
addProcessListener(this);
|
||||
|
||||
add(new Label(SEARCH_LABEL));
|
||||
add(new Label(" ", false));
|
||||
|
||||
final StringParameter searchParam = new StringParameter(SEARCH_QUERY);
|
||||
searchField = new TextField(searchParam);
|
||||
searchField.addValidationListener(new NotEmptyValidationListener());
|
||||
searchField.setSize(20);
|
||||
add(searchField, ColumnPanel.RIGHT);
|
||||
|
||||
final Submit submit = new Submit(SEARCH_BUTTON);
|
||||
add(submit, ColumnPanel.LEFT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(final FormSectionEvent event) throws
|
||||
FormProcessException {
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
final FormData data = event.getFormData();
|
||||
final String search = StringUtils.stripWhiteSpace((String) data.get(
|
||||
SEARCH_QUERY));
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final RoleRepository roleRepo = cdiUtil.findBean(RoleRepository.class);
|
||||
|
||||
final List<Role> roles = roleRepo.searchByName(search);
|
||||
|
||||
if (roles.isEmpty()) {
|
||||
parent.showNoResults(state);
|
||||
} else {
|
||||
// put search string into Page
|
||||
state.setValue(getSearchString(), data.get(SEARCH_QUERY));
|
||||
|
||||
// put privileges into Page
|
||||
state.setValue(getPrivilegeModel(), getPrivileges());
|
||||
|
||||
parent.showGrant(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide Delegate pattern, if parent's implementation changes.
|
||||
*/
|
||||
private ParameterModel getSearchString() {
|
||||
return parent.getSearchString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Detto
|
||||
*/
|
||||
private ParameterModel getPrivilegeModel() {
|
||||
return parent.getPrivilegeParam();
|
||||
}
|
||||
|
||||
/**
|
||||
* Detto
|
||||
*/
|
||||
private Object[] getPrivileges() {
|
||||
return parent.getPrivileges();
|
||||
}
|
||||
|
||||
public TextField getSearchWidget() {
|
||||
return searchField;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* 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.permissions;
|
||||
|
||||
import com.arsdigita.bebop.ColumnPanel;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.FormData;
|
||||
import com.arsdigita.bebop.FormProcessException;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.RequestLocal;
|
||||
import com.arsdigita.bebop.SimpleContainer;
|
||||
import com.arsdigita.bebop.Text;
|
||||
import com.arsdigita.bebop.event.FormProcessListener;
|
||||
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||
import com.arsdigita.bebop.event.PrintEvent;
|
||||
import com.arsdigita.bebop.event.PrintListener;
|
||||
import com.arsdigita.bebop.form.CheckboxGroup;
|
||||
import com.arsdigita.bebop.form.Hidden;
|
||||
import com.arsdigita.bebop.form.Option;
|
||||
import com.arsdigita.bebop.form.OptionGroup;
|
||||
import com.arsdigita.bebop.form.Submit;
|
||||
import com.arsdigita.bebop.form.TextField;
|
||||
import com.arsdigita.bebop.form.Widget;
|
||||
import com.arsdigita.bebop.parameters.NotNullValidationListener;
|
||||
import com.arsdigita.cms.ui.CMSContainer;
|
||||
import com.arsdigita.cms.ui.CMSForm;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.ui.CcmObjectSelectionModel;
|
||||
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.security.User;
|
||||
|
||||
import com.arsdigita.util.Assert;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
import org.libreccm.security.PermissionManager;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
import org.libreccm.security.UserRepository;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.TooManyListenersException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This component is a form for adding object administrators
|
||||
*
|
||||
* @author Michael Pih (pihman@arsdigita.com)
|
||||
* @author Uday Mathur (umathur@arsdigita.com)
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class ObjectAddAdmin extends SimpleContainer
|
||||
implements FormProcessListener {
|
||||
|
||||
private final static String SEARCH_QUERY = "searchQuery";
|
||||
private final static String USERS = "roles";
|
||||
private final static String SUBMIT = "addSubmit";
|
||||
private final static String CANCEL = "addCancel";
|
||||
|
||||
private Widget searchWidget;
|
||||
private final RequestLocal queryRequestLocal;
|
||||
private String labelText;
|
||||
private String m_submitText;
|
||||
|
||||
private final CMSContainer noMatchesContainer;
|
||||
private final CMSContainer matchesContainer;
|
||||
|
||||
private final Form form;
|
||||
private Hidden searchQuery;
|
||||
private CheckboxGroup rolesCheckboxGroup;
|
||||
private Submit submit;
|
||||
private Submit cancel;
|
||||
|
||||
private final CcmObjectSelectionModel<CcmObject> objectSelectionModel;
|
||||
|
||||
public ObjectAddAdmin(
|
||||
final CcmObjectSelectionModel<CcmObject> objectSelectionModel,
|
||||
final TextField search) {
|
||||
|
||||
// super(search, "ObjectAddAdmin");
|
||||
labelText = "Check the box next to the name of the person(s) to assign.";
|
||||
m_submitText = "Add Members";
|
||||
searchWidget = search;
|
||||
queryRequestLocal = new RequestLocal() {
|
||||
|
||||
@Override
|
||||
protected Object initialValue(final PageState state) {
|
||||
return makeQuery(state);
|
||||
}
|
||||
|
||||
};
|
||||
this.objectSelectionModel = objectSelectionModel;
|
||||
|
||||
form = makeForm("ObjectAddAdmin");
|
||||
final Label title = new Label(new GlobalizedMessage("cms.ui.matches",
|
||||
CmsConstants.CMS_BUNDLE));
|
||||
title.setFontWeight(Label.BOLD);
|
||||
|
||||
final Label label = new Label(new GlobalizedMessage(
|
||||
"cms.ui.there_was_no_one_matching_the_search_criteria",
|
||||
CmsConstants.CMS_BUNDLE));
|
||||
label.setFontWeight("em");
|
||||
|
||||
noMatchesContainer = new CMSContainer();
|
||||
noMatchesContainer.add(title);
|
||||
noMatchesContainer.add(label);
|
||||
add(noMatchesContainer);
|
||||
|
||||
matchesContainer = new CMSContainer();
|
||||
matchesContainer.add(title);
|
||||
matchesContainer.add(form);
|
||||
add(matchesContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the form used to add roles.
|
||||
*
|
||||
* @param name
|
||||
*
|
||||
* @return The form
|
||||
*/
|
||||
protected Form makeForm(final String name) {
|
||||
final CMSForm form = new CMSForm(name) {
|
||||
|
||||
public final boolean isCancelled(final PageState state) {
|
||||
return cancel.isSelected(state);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// This hidden field will store the search query. A hidden widget is
|
||||
// used instead of a request local variable because the search query
|
||||
// should only be updated when the search form is submitted.
|
||||
searchQuery = new Hidden(SEARCH_QUERY);
|
||||
form.add(searchQuery, ColumnPanel.FULL_WIDTH);
|
||||
|
||||
final Text label = new Text(labelText);
|
||||
form.add(label, ColumnPanel.FULL_WIDTH);
|
||||
|
||||
// Add the list of roles that can be added.
|
||||
rolesCheckboxGroup = new CheckboxGroup(USERS);
|
||||
rolesCheckboxGroup
|
||||
.addValidationListener(new NotNullValidationListener());
|
||||
try {
|
||||
rolesCheckboxGroup.addPrintListener(new PrintListener() {
|
||||
|
||||
@Override
|
||||
public void prepare(PrintEvent event) {
|
||||
final CheckboxGroup target = (CheckboxGroup) event
|
||||
.getTarget();
|
||||
final PageState state = event.getPageState();
|
||||
// Ensures that the init listener gets fired before the
|
||||
// print listeners.
|
||||
addRoles(state, target);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (TooManyListenersException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
form.add(rolesCheckboxGroup, ColumnPanel.FULL_WIDTH);
|
||||
|
||||
// Submit and Cancel buttons.
|
||||
final SimpleContainer container = new SimpleContainer();
|
||||
submit = new Submit(SUBMIT, m_submitText);
|
||||
container.add(submit);
|
||||
cancel = new Submit(CANCEL, "Cancel");
|
||||
container.add(cancel);
|
||||
form.add(container, ColumnPanel.FULL_WIDTH | ColumnPanel.CENTER);
|
||||
|
||||
form.addProcessListener(this);
|
||||
|
||||
return form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the form for adding users.
|
||||
*
|
||||
* @return The "add user" form
|
||||
*/
|
||||
public Form getForm() {
|
||||
return form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the widget that contains the search string.
|
||||
*
|
||||
* @return The widget that contains the search string
|
||||
*/
|
||||
protected Widget getSearchWidget() {
|
||||
return searchQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds roles to the option group.
|
||||
*
|
||||
* @param state The page state
|
||||
* @param target The option group
|
||||
*
|
||||
* @pre ( state != null && target != null )
|
||||
*/
|
||||
protected void addRoles(final PageState state, final OptionGroup target) {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final List<Role> roles = (List<Role>) queryRequestLocal.get(state);
|
||||
|
||||
roles.forEach(role -> target.addOption(
|
||||
new Option(Long.toString(role.getRoleId()), role.getName())));
|
||||
}
|
||||
|
||||
protected List<User> makeQuery(final PageState state) {
|
||||
Assert.isTrue(objectSelectionModel.isSelected(state));
|
||||
|
||||
final CcmObject object = (CcmObject) objectSelectionModel
|
||||
.getSelectedObject(state);
|
||||
final String searchQuery = (String) getSearchWidget().getValue(state);
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final UserRepository userRepo = cdiUtil.findBean(UserRepository.class);
|
||||
|
||||
return userRepo.filtered(searchQuery);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(final FormSectionEvent event) throws
|
||||
FormProcessException {
|
||||
final FormData data = event.getFormData();
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
final PermissionManager permissionManager = cdiUtil.findBean(
|
||||
PermissionManager.class);
|
||||
final RoleRepository roleRepo = cdiUtil.findBean(RoleRepository.class);
|
||||
|
||||
final CcmObject object = objectSelectionModel.getSelectedObject(state);
|
||||
|
||||
permissionChecker.checkPermission(ItemPrivileges.ADMINISTER, object);
|
||||
|
||||
final String[] roleIds = (String[]) data.get("roles");
|
||||
if (roleIds != null) {
|
||||
|
||||
// Add each checked user to the object
|
||||
for (final String roleId : roleIds) {
|
||||
final Role role = roleRepo.findById(Long.parseLong(roleId));
|
||||
if (role == null) {
|
||||
throw new FormProcessException(new GlobalizedMessage(
|
||||
"cms.ui.permissions.cannot_add_user",
|
||||
CmsConstants.CMS_BUNDLE));
|
||||
}
|
||||
permissionManager.grantPrivilege(ItemPrivileges.ADMINISTER,
|
||||
role,
|
||||
object);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new FormProcessException(new GlobalizedMessage(
|
||||
"cms.ui.permissions.no_roles_were_selected",
|
||||
CmsConstants.CMS_BUNDLE));
|
||||
}
|
||||
|
||||
fireCompletionEvent(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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.permissions;
|
||||
|
||||
import com.arsdigita.bebop.ActionLink;
|
||||
import com.arsdigita.bebop.FormData;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.SimpleContainer;
|
||||
import com.arsdigita.bebop.event.ActionEvent;
|
||||
import com.arsdigita.bebop.event.ActionListener;
|
||||
import com.arsdigita.cms.ui.UserSearchForm;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.ui.CcmObjectSelectionModel;
|
||||
import com.arsdigita.xml.Element;
|
||||
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.librecms.CmsConstants;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This panel allows a staff administrator to search for users and add them to a
|
||||
* staff role for the content section.</p>
|
||||
*
|
||||
* @author Michael Pih (pihman@arsdigita.com)
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class ObjectAddSearchAdmin extends SimpleContainer {
|
||||
|
||||
private final CcmObjectSelectionModel<CcmObject> objectSelectionModel;
|
||||
|
||||
private final UserSearchForm searchForm;
|
||||
private final ObjectAddAdmin addPanel;
|
||||
private final ActionLink returnLink;
|
||||
|
||||
public ObjectAddSearchAdmin(
|
||||
final CcmObjectSelectionModel<CcmObject> objectSelectionModel) {
|
||||
|
||||
super();
|
||||
|
||||
this.objectSelectionModel = objectSelectionModel;
|
||||
|
||||
searchForm = new UserSearchForm("ObjectAdminSearch");
|
||||
add(searchForm);
|
||||
|
||||
addPanel = getObjectAddAdmin(objectSelectionModel, searchForm);
|
||||
add(addPanel);
|
||||
|
||||
addPanel.addCompletionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
fireCompletionEvent(event.getPageState());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
returnLink = new ActionLink(new GlobalizedMessage(
|
||||
"cms.ui.permissions.return_to_object_info", CmsConstants.CMS_BUNDLE));
|
||||
returnLink.setClassAttr("actionLink");
|
||||
returnLink.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
fireCompletionEvent(event.getPageState());
|
||||
}
|
||||
|
||||
});
|
||||
add(returnLink);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the appropriate form(s).
|
||||
*
|
||||
* @param parent
|
||||
*/
|
||||
@Override
|
||||
public void generateXML(final PageState state, final Element parent) {
|
||||
final FormData data = searchForm.getFormData(state);
|
||||
final FormData data2 = addPanel.getForm().getFormData(state);
|
||||
|
||||
if (data != null && (data.isSubmission() || data2.isSubmission())) {
|
||||
addPanel.setVisible(state, true);
|
||||
} else {
|
||||
addPanel.setVisible(state, false);
|
||||
}
|
||||
super.generateXML(state, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the form for adding object administrators
|
||||
*
|
||||
* @param model
|
||||
* @param searchForm
|
||||
* @return
|
||||
*/
|
||||
protected ObjectAddAdmin getObjectAddAdmin(
|
||||
final CcmObjectSelectionModel<CcmObject> model,
|
||||
final UserSearchForm searchForm) {
|
||||
return new ObjectAddAdmin(model, searchForm.getSearchWidget());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* 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.permissions;
|
||||
|
||||
import com.arsdigita.bebop.ActionLink;
|
||||
import com.arsdigita.bebop.Component;
|
||||
import com.arsdigita.bebop.ControlLink;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.Page;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
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.TableActionEvent;
|
||||
import com.arsdigita.bebop.event.TableActionListener;
|
||||
import com.arsdigita.bebop.table.TableCellRenderer;
|
||||
import com.arsdigita.bebop.table.TableModel;
|
||||
import com.arsdigita.bebop.table.TableModelBuilder;
|
||||
import com.arsdigita.cms.CMS;
|
||||
import com.arsdigita.cms.dispatcher.Utilities;
|
||||
import com.arsdigita.dispatcher.AccessDeniedException;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.ui.CcmObjectSelectionModel;
|
||||
import com.arsdigita.util.LockableImpl;
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.security.Party;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
import org.libreccm.security.PermissionManager;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ObjectAdminListing extends SimpleContainer {
|
||||
|
||||
private final Table adminTable;
|
||||
private ActionLink addUserLink;
|
||||
private final CcmObjectSelectionModel<CcmObject> objectSelectionModel;
|
||||
private ObjectAddSearchAdmin objectAddSearchAdmin;
|
||||
|
||||
public ObjectAdminListing(
|
||||
final CcmObjectSelectionModel<CcmObject> objectSelectionModel) {
|
||||
|
||||
super("cms:roleAdmin", CMS.CMS_XML_NS);
|
||||
|
||||
this.objectSelectionModel = objectSelectionModel;
|
||||
|
||||
adminTable = new Table(getTableModelBuilder(objectSelectionModel),
|
||||
new String[]{"Member", "Action"});
|
||||
adminTable.setDefaultCellRenderer(new ObjectAdminTableRenderer());
|
||||
adminTable.setEmptyView(new Label(
|
||||
"There are no administrators for this object"));
|
||||
adminTable.setClassAttr("dataTable");
|
||||
adminTable.addTableActionListener(new ObjectAdminActionListener());
|
||||
|
||||
addUserLink = new ActionLink(new GlobalizedMessage(
|
||||
"cms.ui.permissions.add_administrator", CmsConstants.CMS_BUNDLE));
|
||||
addUserLink.setClassAttr("actionLink");
|
||||
|
||||
objectAddSearchAdmin = getObjectAddSearchAdmin(objectSelectionModel);
|
||||
|
||||
addUserLink.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
objectAddSearchAdmin.setVisible(event.getPageState(), true);
|
||||
addUserLink.setVisible(event.getPageState(), false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
objectAddSearchAdmin.addCompletionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
objectAddSearchAdmin.setVisible(event.getPageState(), false);
|
||||
addUserLink.setVisible(event.getPageState(), true);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
add(adminTable);
|
||||
add(addUserLink);
|
||||
add(objectAddSearchAdmin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(final Page page) {
|
||||
super.register(page);
|
||||
|
||||
page.setVisibleDefault(objectAddSearchAdmin, false);
|
||||
}
|
||||
|
||||
// This returns the add search admin form to use for this object
|
||||
protected ObjectAddSearchAdmin getObjectAddSearchAdmin(
|
||||
CcmObjectSelectionModel<CcmObject> model) {
|
||||
|
||||
return new ObjectAddSearchAdmin(model);
|
||||
}
|
||||
|
||||
private class ObjectAdminActionListener implements TableActionListener {
|
||||
|
||||
@Override
|
||||
public void cellSelected(final TableActionEvent event) {
|
||||
if (event.getColumn() == 1) {
|
||||
final PageState state = event.getPageState();
|
||||
|
||||
final CcmObject object = objectSelectionModel.getSelectedObject(
|
||||
state);
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
final PermissionManager permissionManager = cdiUtil.findBean(
|
||||
PermissionManager.class);
|
||||
final RoleRepository roleRepo = cdiUtil.findBean(
|
||||
RoleRepository.class);
|
||||
|
||||
permissionChecker.checkPermission(
|
||||
ItemPrivileges.ADMINISTER, object);
|
||||
|
||||
final String roleId = (String) event.getRowKey();
|
||||
final Role role = roleRepo.findById(Long.parseLong(roleId));
|
||||
if (role == null) {
|
||||
throw new UncheckedWrapperException(String.format(
|
||||
"No role with id %s found.", roleId));
|
||||
}
|
||||
|
||||
permissionManager.revokePrivilege(ItemPrivileges.ADMINISTER,
|
||||
role,
|
||||
object);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void headSelected(final TableActionEvent event) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected TableModelBuilder getTableModelBuilder(
|
||||
final CcmObjectSelectionModel<CcmObject> model) {
|
||||
|
||||
return new ObjectTableModelBuilder(model);
|
||||
}
|
||||
|
||||
private class ObjectTableModelBuilder extends LockableImpl
|
||||
implements TableModelBuilder {
|
||||
|
||||
private final CcmObjectSelectionModel<CcmObject> model;
|
||||
|
||||
ObjectTableModelBuilder(final CcmObjectSelectionModel<CcmObject> model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableModel makeModel(final Table table, final PageState state) {
|
||||
final CcmObject object = model.getSelectedObject(state);
|
||||
|
||||
final List<Role> roles = object.getPermissions().stream()
|
||||
.filter(permission -> ItemPrivileges.ADMINISTER.equals(
|
||||
permission.getGrantedPrivilege()))
|
||||
.map(permission -> permission.getGrantee())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return new ObjectAdminTableModel(roles);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ObjectAdminTableModel implements TableModel {
|
||||
|
||||
private final Iterator<Role> roles;
|
||||
private Role currentRole;
|
||||
|
||||
public ObjectAdminTableModel(final List<Role> roles) {
|
||||
this.roles = roles.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nextRow() {
|
||||
if (roles.hasNext()) {
|
||||
currentRole = roles.next();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(final int column) {
|
||||
return currentRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getKeyAt(final int column) {
|
||||
return currentRole.getRoleId();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ObjectAdminTableRenderer implements TableCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getComponent(final Table list,
|
||||
final PageState state,
|
||||
final Object value,
|
||||
final boolean isSelected,
|
||||
final Object key,
|
||||
final int row,
|
||||
final int column) {
|
||||
|
||||
final Role role = (Role) value;
|
||||
|
||||
switch (column) {
|
||||
case 0:
|
||||
return new Text(role.getName());
|
||||
case 1:
|
||||
return new ControlLink(new Text("remove"));
|
||||
default:
|
||||
throw new IllegalArgumentException("Column index " + column
|
||||
+ " out of bounds 0..1");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -169,6 +169,7 @@ public class ContentSectionSetup extends AbstractCcmApplicationSetup {
|
|||
|
||||
grantPermissions(manager,
|
||||
rootFolder,
|
||||
ItemPrivileges.ADMINISTER,
|
||||
ItemPrivileges.CATEGORIZE,
|
||||
ItemPrivileges.CREATE_NEW,
|
||||
ItemPrivileges.EDIT,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.librecms.contentsection;
|
|||
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
|
||||
import org.libreccm.categorization.Categorization;
|
||||
import org.libreccm.categorization.CategoryManager;
|
||||
import org.libreccm.configuration.ConfigurationManager;
|
||||
|
||||
|
|
@ -443,4 +444,31 @@ public class FolderManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates list with a parent folders of the provided folder.
|
||||
*
|
||||
* @param folder The folder.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<Folder> getParentFolders(final Folder folder) {
|
||||
|
||||
if (folder == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't create a list of parent folder for folder null.");
|
||||
}
|
||||
|
||||
final List<Folder> folders = new ArrayList<>();
|
||||
if (folder.getParentFolder() != null) {
|
||||
Folder currentFolder = folder.getParentFolder();
|
||||
while(currentFolder != null) {
|
||||
folders.add(currentFolder);
|
||||
currentFolder = folder.getParentFolder();
|
||||
}
|
||||
}
|
||||
|
||||
Collections.reverse(folders);
|
||||
return folders;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ import org.librecms.contentsection.ContentItem;
|
|||
*/
|
||||
public final class ItemPrivileges {
|
||||
|
||||
/**
|
||||
* Allows the user to edit the permissions for items.
|
||||
*/
|
||||
public static final String ADMINISTER = "administer_items";
|
||||
|
||||
/**
|
||||
* Allows the user to approve {@link ContentItem}s.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.librecms.contenttypes;
|
||||
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
|
||||
import org.libreccm.modules.CcmModule;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* 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.bebop;
|
||||
|
||||
import com.arsdigita.bebop.util.Traversal;
|
||||
import com.arsdigita.xml.Element;
|
||||
|
||||
/**
|
||||
* A form that is instantiated on a per-request basis. This class
|
||||
* functions as a placeholder and decorator of the request-specific form
|
||||
* in a Bebop {@link Page}.
|
||||
*
|
||||
* <p> Subclasses only need to override {@link #buildForm buildForm} to
|
||||
* return the request-specific form. The meta form takes care of
|
||||
* interfacing that form with the normal control flow of serving a Bebop
|
||||
* <code>Page</code>. The meta form will fool the request-specific forms
|
||||
* into thinking that they are part of a static Bebop <code>Page</code>.
|
||||
* The properties of the meta form should be used to initialize the
|
||||
* correspoding properties of the request-specific form whenever
|
||||
* possible. These properties include <code>name</code>,
|
||||
* <code>method</code>, and <code>encType</code>.
|
||||
*
|
||||
* <p> Listeners can be added directly to the meta form and are run
|
||||
* whenever the corresponding listeners would be run on an ordinary
|
||||
* form. The source of the <code>FormSectionEvent</code> will be the meta
|
||||
* form.
|
||||
*
|
||||
* @author Stas Freidin
|
||||
* @author David Lutterkort
|
||||
*/
|
||||
|
||||
public abstract class MetaForm extends Form {
|
||||
|
||||
private RequestLocal m_dynamicForm;
|
||||
|
||||
/**
|
||||
* Constructs a new meta form.
|
||||
*
|
||||
* @param name the name of the form
|
||||
*/
|
||||
public MetaForm(String name) {
|
||||
super(name);
|
||||
m_dynamicForm = new RequestLocal() {
|
||||
protected Object initialValue(PageState s) {
|
||||
Form result = buildForm(s);
|
||||
result.getModel().mergeModel(getModel());
|
||||
// form isn't part of the page, so it is invisible
|
||||
// on the page (vacuously). We should consider it
|
||||
// visible iff the static container MetaForm is visible.
|
||||
result.setProcessInvisible(
|
||||
MetaForm.this.getProcessInvisible() ||
|
||||
s.isVisibleOnPage(MetaForm.this));
|
||||
result.traverse();
|
||||
Traversal t = new Traversal() {
|
||||
public void act(Component c) {
|
||||
c.lock();
|
||||
}
|
||||
};
|
||||
t.preorder(result);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the form for the request represented by
|
||||
* <code>state</code>. If the form hasn't been built
|
||||
* yet, calls {@link #buildForm buildForm} to build the
|
||||
* form.
|
||||
*
|
||||
* @param state describes the current request
|
||||
* @return a custom-built form for this request.
|
||||
* @pre state != null
|
||||
* @post return != null
|
||||
*/
|
||||
protected Form getDynamicForm(PageState state) {
|
||||
return (Form) m_dynamicForm.get(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the dynamic form. Subclasses should override this method to
|
||||
* build the form based on the request represented by <code>state</code>.
|
||||
*
|
||||
* @param state describes the current request
|
||||
* @return the form to be used for this request.
|
||||
* @pre state != null
|
||||
* @post return != null
|
||||
*/
|
||||
public abstract Form buildForm(PageState state);
|
||||
|
||||
/**
|
||||
* Force a rebuilding and updating of the dynamic form. Calls
|
||||
* <code>buildForm</code> again and sets the dynamic form to the form
|
||||
* returned by it.
|
||||
*
|
||||
* @param s describes the current request
|
||||
*/
|
||||
public void rebuildForm(PageState s) {
|
||||
m_dynamicForm.set(s, m_dynamicForm.initialValue(s));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the form data constructed by {@link #process process} for the
|
||||
* request described by <code>state</code>. If the form for this request
|
||||
* hasn't been built yet, calls {@link #buildForm buildForm}.
|
||||
*
|
||||
* @param state describes the current request
|
||||
* @return the values extracted from the HTTP request contained
|
||||
* in <code>state</code>, or <code>null</code> if the form has not
|
||||
* yet been processed.
|
||||
* @pre state != null
|
||||
*/
|
||||
public FormData getFormData(PageState state) {
|
||||
return getDynamicForm(state).getFormData(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the XML representing the form and its widgets, but not
|
||||
* the state information, from <code>s</code>. The XML generation is
|
||||
* delegated to the request-specific form by calling {@link
|
||||
* #generateXMLSansState generateXMLSansState} on it.
|
||||
*
|
||||
* @param s represents the curent request
|
||||
* @return the top-level element for the form.
|
||||
*/
|
||||
protected Element generateXMLSansState(PageState s, Element parent) {
|
||||
return getDynamicForm(s).generateXMLSansState(s, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the request-specific form for the request represented by
|
||||
* <code>state</code>.
|
||||
*
|
||||
* @param state describes the current request
|
||||
* @return the form data extracted from the current request.
|
||||
* @pre state != null
|
||||
* @post return != null
|
||||
* @see Form#process Form.process(...)
|
||||
* @see FormModel#process FormModel.process(...)
|
||||
*/
|
||||
public FormData process(PageState state)
|
||||
throws FormProcessException {
|
||||
|
||||
if (state.isVisibleOnPage(this))
|
||||
return getDynamicForm(state).process(state);
|
||||
return null; // XXX is this ok ?
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing; the dynamic form will take care of the tag.
|
||||
*/
|
||||
protected void addMagicTag() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented because meta forms currently don't support mixing static and
|
||||
* dynamic widgets.
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public void add(Component pc, int constraints) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented.
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public Container getPanel() {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue