- Copied several classes for the UI for ccm-cms from trunk (mostly disabled for now, will be refactored to work with CCM NG step by step)
    - Some work on the JSF/PrimeFaces prototype


git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4221 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2016-08-15 18:14:48 +00:00
parent 790959901b
commit 76e5784e2e
40 changed files with 6628 additions and 32 deletions

View File

@ -45,6 +45,9 @@
<Logger name="org.libreccm.security.Shiro" <Logger name="org.libreccm.security.Shiro"
level="debug"> level="debug">
</Logger> </Logger>
<Logger name="org.libreccm.ui.admin.usersgroupsroles.RolesController"
level="debug">
</Logger>
<Logger name="org.librecms.contentsection.ContentSectionSetup" <Logger name="org.librecms.contentsection.ContentSectionSetup"
level="debug"> level="debug">
</Logger> </Logger>

View File

@ -42,4 +42,8 @@
<param-name>javax.faces.PROJECT_STAGE</param-name> <param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value> <param-value>Development</param-value>
</context-param> </context-param>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
</web-app> </web-app>

View File

@ -211,11 +211,8 @@ public class ContentSectionServlet extends BaseApplicationServlet {
getClass().getName()); getClass().getName());
} }
// NEW STUFF here will be used to process the pages in this servlet //ToDo addPage(CmsConstants.CONTENT_SECTION_PAGE, new ContentSectionPage()); // index page at address ~/cs
// Currently NOT working //ToDo addPage(CmsConstants.CONTENT_SECTION_ITEM_PAGE, new ContentSectionPage());
// addPage("/admin", new MainPage()); // index page at address ~/cs
// addPage("/admin/index.jsp", new MainPage());
// addPage("/admin/item.jsp", new MainPage());
} }
/** /**

View File

@ -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;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.kernel.ui.ACSObjectSelectionModel;
import com.arsdigita.util.UncheckedWrapperException;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.CcmObject;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentType;
import org.librecms.contentsection.ContentTypeRepository;
import javax.servlet.ServletException;
import java.math.BigDecimal;
/**
* <p>
* Loads a subclass of a {@link com.arsdigita.cms.ContentItem} from the
* database. This model should be used as a parameter to the constructor of
* authoring kit components.</p>
*
* <p>
* It is possible to instantiate this model with a {@link
* com.arsdigita.cms.ContentType} as a constructor parameter. In this case, the
* model will only instantiate items that are of the specified content type, or
* one of it subclasses.</p>
*
* @author Stanislav Freidin (stas@arsdigita.com)
* @version $Revision$ $DateTime: 2004/08/17 23:15:09 $
* @see com.arsdigita.kernel.ui.ACSObjectSelectionModel
* @see com.arsdigita.bebop.SingleSelectionModel
*/
public class ItemSelectionModel extends ACSObjectSelectionModel {
private Long m_typeId;
private static final Logger s_log = Logger.getLogger(
ItemSelectionModel.class);
/**
* Construct a new <code>ItemSelectionModel</code>. This model will produce
* instances of <code>ContentItem</code> by automatically instantiating the
* correct Java subclass using the
* {@link com.arsdigita.domain.DomainObjectFactory}.
*
* @param parameter The state parameter which should be used to store the
* object ID
*/
public ItemSelectionModel(BigDecimalParameter parameter) {
this(null, null, parameter);
}
/**
* Construct a new <code>ItemSelectionModel</code>. This model will produce
* instances of <code>ContentItem</code> by automatically instantiating the
* correct Java subclass using the
* {@link com.arsdigita.domain.DomainObjectFactory}.
*
* @param parameterName The name of the state parameter which will be used
* to store the object ID.
*/
public ItemSelectionModel(String parameterName) {
this(null, null, new BigDecimalParameter(parameterName));
}
/**
* Construct a new <code>ItemSelectionModel</code>. This model will produce
* instances of <code>ContentItem</code> by automatically instantiating the
* correct Java subclass using the
* {@link com.arsdigita.domain.DomainObjectFactory}.
*
* @param model The {@link SingleSelectionModel} which will supply a
* {@link BigDecimal} ID of the currently selected item
*/
public ItemSelectionModel(SingleSelectionModel model) {
this(null, null, model);
}
/**
* Construct a new <code>ItemSelectionModel</code>
*
* @param type The content type for the items this model will
* generate
*
* @param parameterName The name of the state parameter which will be used
* to store the item.
*/
public ItemSelectionModel(ContentType type, String parameterName) {
this(type, new BigDecimalParameter(parameterName));
}
/**
* Construct a new <code>ItemSelectionModel</code>
*
* @param type The content type for the items this model will generate
*
* @param parameter The state parameter which should be used by this item
*
*/
public ItemSelectionModel(ContentType type, BigDecimalParameter parameter) {
super(type.getContentItemClass(), type.getContentItemClass(), parameter);
m_typeId = type.getObjectId();
}
/**
* Construct a new <code>ItemSelectionModel</code>
*
* @param type The content type for the items this model will generate
*
* @param model The {@link SingleSelectionModel} which will supply a
* {@link BigDecimal} id of the currently selected object
*
*/
public ItemSelectionModel(ContentType type, SingleSelectionModel model) {
super(type.getContentItemClass(), type.getContentItemClass(), model);
m_typeId = type.getObjectId();
}
/**
* Construct a new <code>ItemSelectionModel</code>
*
* @param itemClass The name of the Java class which represents the
* content item. Must be a subclass of ContentItem. In
* addition, the class must have a constructor with a
* single OID parameter.
* @param objectType The name of the persistence metadata object type
* which represents the content item. In practice, will
* often be the same as the itemClass.
* @param parameterName The name of the state parameter which will be used
* to store the item.
*/
public ItemSelectionModel(String itemClass,
String objectType,
String parameterName) {
super(itemClass, objectType, new BigDecimalParameter(parameterName));
}
/**
* Construct a new <code>ItemSelectionModel</code>
*
* @param itemClass The name of the Java class which represents the content
* item. Must be a subclass of ContentItem. In addition,
* the class must have a constructor with a single OID
* parameter.
* @param objectType The name of the persistence metadata object type which
* represents the content item. In practice, will often be
* the same as the itemClass.
* @param parameter The state parameter which should be used by this item
*/
public ItemSelectionModel(String itemClass, String objectType,
BigDecimalParameter parameter) {
super(itemClass, objectType, parameter);
}
/**
* Construct a new <code>ItemSelectionModel</code>
*
* @param itemClass The name of the Java class which represents the content
* item. Must be a subclass of ContentItem. In addition,
* the class must have a constructor with a single OID
* parameter.
* @param objectType The name of the persistence metadata object type which
* represents the content item. In practice, will often be
* the same as the itemClass.
* @param model The {@link SingleSelectionModel} which will supply a
* {@link BigDecimal} id of the currently selected object
*
*/
public ItemSelectionModel(String itemClass,
String objectType,
SingleSelectionModel model) {
super(itemClass, objectType, model);
}
/**
* A utility function which creates a new item with the given ID. Uses
* reflection to create the instance of the class supplied in the
* constructor to this ItemSelectionModel.
*
* @param id The id of the new item -- this is now ignored
*
* @return The newly created item
*
* @deprecated use createItem() instead
*/
public ContentItem createItem(BigDecimal id) throws ServletException {
return (ContentItem) createACSObject();
}
/**
* A utility function which creates a new item. Uses reflection to create
* the instance of the class supplied in the constructor to this
* ItemSelectionModel.
*
* @return The newly created item
*/
public ContentItem createItem() throws ServletException {
return (ContentItem) createACSObject();
}
/**
* A convenience method that gets the currently selected object and casts it
* to a <code>ContentItem</code>
*
* @param s the current page state
*
* @return the currently selected <code>ContentItem</code>, or null if no
* item was selected.
*/
public final ContentItem getSelectedItem(PageState s) {
return (ContentItem) getSelectedObject(s);
}
/**
* A utility function which creates a new item with the given ID. Uses
* reflection to create the instance of the class supplied in the
* constructor to this ItemSelectionModel.
*
* @param id The id of the new item -- this is now ignored
*
* @return The newly created item
*
* @deprecated Use createACSObject() instead
*/
public CcmObject createACSObject(BigDecimal id) throws ServletException {
return createACSObject();
}
/**
* A utility function which creates a new item. Uses reflection to create
* the instance of the class supplied in the constructor to this
* ItemSelectionModel.
*
* @return The newly created item
*/
public CcmObject createACSObject() throws ServletException {
ContentType type = getContentType();
ContentItem item = (ContentItem) super.createACSObject();
if (type != null) {
item.setContentType(type);
}
return item;
}
/**
*
* @return The content type of the items which are produced by this model,
* or null if the content type has not been specified in the
* constructor.
*/
public ContentType getContentType() {
ContentType type = null;
if (m_typeId != null) {
type = CdiUtil.createCdiUtil().findBean(ContentTypeRepository.class).findById(m_typeId);
}
return type;
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.event.TreeExpansionEvent;
import com.arsdigita.bebop.event.TreeExpansionListener;
import com.arsdigita.bebop.tree.TreeModelBuilder;
import org.apache.log4j.Logger;
/**
* A convenience class for CMS trees.
*
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id$
*/
public class BaseTree extends Tree {
private static final Logger s_log = Logger.getLogger(BaseTree.class);
public BaseTree(final TreeModelBuilder builder) {
super(builder);
addChangeListener(new Change());
addTreeExpansionListener(new TreeExpansion());
}
private class Change implements ChangeListener {
public final void stateChanged(final ChangeEvent e) {
final PageState state = e.getPageState();
final Object key = BaseTree.this.getSelectedKey(state);
if (key != null) {
expand(key.toString(), state);
}
}
}
private class TreeExpansion implements TreeExpansionListener {
public final void treeExpanded(final TreeExpansionEvent e) {
//s_log.error("expanded");
}
public final void treeCollapsed(final TreeExpansionEvent e) {
//s_log.error("collapsed");
}
}
}

View File

@ -0,0 +1,226 @@
/*
* 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.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Resettable;
import com.arsdigita.bebop.SegmentedPanel;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormSubmissionListener;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ui.folder.FolderRequestLocal;
import com.arsdigita.cms.ui.folder.FolderSelectionModel;
import com.arsdigita.cms.ui.folder.FolderTreeModelBuilder;
import com.arsdigita.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;
/**
* A pane that contains a folder tree on the left and a folder manipulator on
* the right. It is a part of the content section main page and is displayed as
* the "Browse" tab.
*
* @author David LutterKort &lt;dlutter@redhat.com&gt;
* @version $Id: BrowsePane.java 1325 2006-09-22 08:11:33Z sskracic $
*/
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;
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);
final SegmentedPanel left = new SegmentedPanel();
setLeft(left);
final Label heading = new Label(
new GlobalizedMessage("cms.ui.folder_browser",
CmsConstants.CMS_FOLDER_BUNDLE));
left.addSegment(heading, m_tree);
m_fil = new FlatItemList(m_folder, m_folderModel);
setBody(m_fil);
m_fil.getManipulator().getItemView().addProcessListener(
new ProcessListener());
m_fil.getManipulator().getTargetSelector().addProcessListener(
new ProcessListener());
m_fil.getManipulator().getTargetSelector().addSubmissionListener(
new SubmissionListener());
}
@Override
public final void register(Page page) {
super.register(page);
page.addActionListener(new FolderListener());
page.addActionListener(new TreeListener());
}
@Override
public final void reset(PageState state) {
super.reset(state);
m_fil.reset(state);
}
// Private classes and methods
/**
*
*/
private final class ProcessListener implements FormProcessListener {
/**
*
* @param e
*/
public final void process(final FormSectionEvent e) {
final PageState state = e.getPageState();
if (e.getSource() == m_fil.getManipulator().getItemView()) {
// Hide everything except for the flat item list
m_tree.setVisible(state, false);
} else if (e.getSource() == m_fil.getManipulator()
.getTargetSelector()) {
m_tree.setVisible(state, true);
}
}
}
private final class SubmissionListener implements FormSubmissionListener {
public final void submitted(final FormSectionEvent e) {
final PageState s = e.getPageState();
if (e.getSource() == m_fil.getManipulator().getTargetSelector()) {
if (!m_fil.getManipulator().getTargetSelector().isVisible(s)) {
m_tree.setVisible(s, true);
}
}
}
}
private final class FolderListener implements ActionListener {
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
if (!m_model.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();
/*
ToDo
User user = Web.getWebContext().getUser();
if (user != null) {
Folder homeFolder = Folder.getUserHomeFolder(
user, CMS.getContext().getContentSection());
if (homeFolder != null) {
folderID = homeFolder.getID();
}
}*/
m_model.setSelectedKey(state, folderID);
} else {
m_model.setSelectedKey(state, folder);
}
}
}
}
private final class TreeListener implements ActionListener {
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
if (Assert.isEnabled()) {
Assert.isTrue(m_model.isSelected(state));
}
final Category root = CMS.getContext().getContentSection()
.getRootDocumentsFolder();
if (!root.equals(m_folder.getFolder(state))) {
// Expand the ancestor nodes of the currently
// selected node.
CcmObject object = m_folder.getFolder(state);
while (object != null) {
if (object instanceof Category) {
final Category category = (Category) object;
if (category.getParent().isPresent()) {
final CcmObject result = category.getParent().get();
if (result instanceof Category) {
object = result;
m_tree.expand(
((Long) object.getObjectId()).toString(),
state);
} else {
object = null;
}
} else {
object = null;
}
} else {
object = null;
}
}
}
}
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.RequestLocal;
import org.apache.log4j.Logger;
import org.libreccm.core.CcmObject;
/**
*
* @version $Id$
*/
public class CcmObjectRequestLocal extends RequestLocal {
private static final Logger s_log = Logger.getLogger
(CcmObjectRequestLocal.class);
public final CcmObject getACSObject(final PageState state) {
return (CcmObject) get(state);
}
}

View File

@ -0,0 +1,156 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui;
import com.arsdigita.bebop.PageState;
import com.arsdigita.cms.CMS;
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.PageLocations;
import com.arsdigita.cms.Template;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.web.ParameterMap;
import com.arsdigita.web.URL;
import java.math.BigDecimal;
import java.util.List;
import java.util.Stack;
import org.apache.log4j.Logger;
/**
* The context bar of the content section UI.
*
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id: ContentSectionContextBar.java 287 2005-02-22 00:29:02Z sskracic $
*/
// class ContentSectionContextBar extends WorkspaceContextBar {
public class ContentSectionContextBar extends WorkspaceContextBar {
private static final Logger s_log = Logger.getLogger
(ContentSectionContextBar.class);
@Override
protected List entries(final PageState state) {
/* Include breadcrumb entries already set by content-center (i.e. the
* URL of the content center itself */
final List entries = super.entries(state);
final ContentSection section = CMS.getContext().getContentSection();
final Stack folderEntryStack = new Stack();
String currentFolderLabel = null;
ParameterMap params = new ParameterMap();
boolean isTemplate = false;
BigDecimal templateID = null;
if (CMS.getContext().hasContentItem()) {
final ContentItem item = CMS.getContext().getContentItem();
if (item == null) {
s_log.warn("item is null");
} else if(item.getContentType() == null) {
s_log.warn("item.getContentType() returns null. item.class.getName(): "
+ item.getClass().getName());
}
isTemplate =
item.getContentType().equals(ContentType
.findByAssociatedObjectType(Template.BASE_DATA_OBJECT_TYPE));
if (isTemplate) {
templateID = item.getID();
}
ACSObject parent = item.getParent();
while (!isTemplate && parent != null && parent instanceof ContentItem) {
if (currentFolderLabel != null) {
final URL folderURL = URL.there
(state.getRequest(),
section.getPath() + "/" + PageLocations.SECTION_PAGE,
params);
folderEntryStack.push(new Entry(currentFolderLabel, folderURL));
currentFolderLabel = null;
params = new ParameterMap();
}
final ContentItem pitem = (ContentItem) parent;
if (pitem instanceof Folder) {
final Folder folder = (Folder) pitem;
parent = folder.getParent();
currentFolderLabel = folder.getLabel();
if (parent != null || folder.equals(section.getRootFolder())) {
params.setParameter
(ContentSectionPage.SET_FOLDER, folder.getID());
}
} else if (pitem instanceof ContentBundle) {
final ACSObject ppitem = pitem.getParent();
if (ppitem != null && ppitem instanceof Folder) {
final Folder folder = (Folder) ppitem;
parent = folder.getParent();
currentFolderLabel = folder.getLabel();
if (parent != null || folder.equals(section
.getRootFolder())) {
params.setParameter
(ContentSectionPage.SET_FOLDER, folder.getID());
}
} else {
parent = null;
}
} else {
parent = null;
}
}
}
if (isTemplate) {
params.setParameter
( ContentSectionPage.SET_TAB,
new BigDecimal(ContentSectionPage.CONTENTTYPES_TAB) );
params.setParameter(ContentSectionPage.SET_TEMPLATE, templateID);
}
// add section-level entry. if this is for an item page, the URL
// will be for the root folder.
final URL url = URL.there
(state.getRequest(),
section.getPath() + "/" + PageLocations.SECTION_PAGE,
params);
final String sectionTitle = lz("cms.ui.content_section");
final String title = sectionTitle + ": " + section.getName();
entries.add(new Entry(title, url));
// add any folders to the path now
while (!folderEntryStack.empty()) {
entries.add(folderEntryStack.pop());
}
return entries;
}
private static String lz(final String key) {
return (String) ContentSectionPage.globalize(key).localize();
}
}

View File

@ -0,0 +1,524 @@
/*
* 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.Component;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleComponent;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.TabbedPane;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.cms.CMS;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentSection;
import com.arsdigita.cms.dispatcher.CMSPage;
import com.arsdigita.cms.ui.category.CategoryAdminPane;
import com.arsdigita.cms.ui.cse.ContentSoonExpiredPane;
import com.arsdigita.cms.ui.folder.FolderAdminPane;
import com.arsdigita.cms.ui.lifecycle.LifecycleAdminPane;
import com.arsdigita.cms.ui.role.RoleAdminPane;
import com.arsdigita.cms.ui.type.ContentTypeAdminPane;
import com.arsdigita.cms.ui.workflow.WorkflowAdminPane;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.toolbox.ui.LayoutPanel;
import com.arsdigita.util.Assert;
import com.arsdigita.web.Web;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.arsdigita.cms.CMSConfig;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.security.PermissionChecker;
import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentItemVersion;
import org.librecms.contentsection.ContentSectionConfig;
/**
* Contains the entire admin UI for a content section.
*
* Developers Note: It is based on the dispatcher model is is going to be
* replaced by the newer servlet based model. @see
* c.ad.cms.ui.contentsection.MainPage (currently not active).
*
* @author Jack Chung
* @author Michael Pih
* @author Xixi D'Moon &lt;xdmoon@redhat.com&gt;
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id: ContentSectionPage.java 2224 2011-08-01 07:45:23Z pboy $
*/
public class ContentSectionPage extends CMSPage implements ActionListener {
private static final Logger s_log = Logger.getLogger(
ContentSectionPage.class);
public static final String RESOURCE_BUNDLE
= "com.arsdigita.cms.CMSResources";
/**
* The URL parameter that can be passed in in order to set the current
* folder. This is used in getting back to the correct level of folder
* expansion from content item page.
*/
public static final String SET_FOLDER = "set_folder";
/**
* The URL parameter that can be passed in in order to set the current
* template (for setting the content type)
*/
public static final String SET_TEMPLATE = "set_template";
/**
* The URL parameter that can be passed in in order to set the current tab.
* This is a KLUDGE right now because the TabbedDialog's current tab is
* selected with a local state parameter.
*/
public static final String SET_TAB = "set_tab";
/**
* Index of the search tab
*/
public static final int SEARCH_TAB = 0;
/**
* Index of the browse tab
*/
public static final int BROWSE_TAB = 1;
/**
* Index of the roles tab
*/
public static final int ROLES_TAB = 2;
/**
* Index of the workflows tab
*/
public static final int WORKFLOW_TAB = 3;
/**
* Index of the lifecycles tab
*/
public static final int LIFECYCLES_TAB = 4;
/**
* Index of the categories tab
*/
public static final int CATEGORIES_TAB = 5;
/**
* Index of the content types tab
*/
public static final int CONTENTTYPES_TAB = 6;
public static final int USER_ADMIN_TAB = 7;
private TabbedPane m_tabbedPane;
private FolderAdminPane m_folderPane;
private BrowsePane m_browsePane;
private ItemSearch m_searchPane;
private ImagesPane m_imagesPane;
private RoleAdminPane m_rolePane;
private WorkflowAdminPane m_workflowPane;
private LifecycleAdminPane m_lifecyclePane;
private CategoryAdminPane m_categoryPane;
private ContentTypeAdminPane m_typePane;
//private LayoutPanel m_userAdminPane;
private LayoutPanel m_csePane;
private ReportPane m_reportPane;
/**
* Creates the content section index page containing - a Navigaton bar for
* the various tasks (items, search, images, ....) - a breadcrumb - ....
* Contains the UI for administering a content section.
*/
public ContentSectionPage() {
super(new Label(new TitlePrinter()), new SimpleContainer());
setClassAttr("cms-admin");
add(new GlobalNavigation());
add(new ContentSectionContextBar());
// Initialize the individual panes
m_folderPane = getFolderAdminPane();
m_browsePane = getBrowsePane();
m_searchPane = getSearchPane();
m_imagesPane = getImagesPane();
m_rolePane = getRoleAdminPane();
m_workflowPane = getWorkflowAdminPane();
m_lifecyclePane = getLifecycleAdminPane();
m_categoryPane = getCategoryAdminPane();
m_typePane = getContentTypeAdminPane();
// userAdminPane removed, used to contain just one item (reset user
// folder) which moved to the FolderAdminPane
//m_userAdminPane = getUserAdminPane();
m_csePane = getCSEPane();
m_reportPane = getReportPane();
// The panes
m_tabbedPane = createTabbedPane();
m_tabbedPane.setIdAttr("page-body");
m_tabbedPane.addActionListener(this);
add(m_tabbedPane);
addActionListener(new ActionListener() {
@Override
public final void actionPerformed(ActionEvent e) {
final PageState state = e.getPageState();
final String tab = state.getRequest().getParameter(SET_TAB);
if (tab != null) {
m_tabbedPane.setSelectedIndex(state, Integer.valueOf(tab)
.intValue());
}
final PermissionChecker permissionChecker = CdiUtil
.createCdiUtil().findBean(PermissionChecker.class);
//m_tabbedPane.setTabVisible(state, m_userAdminPane, sm.canAccess(user, SecurityConstants.STAFF_ADMIN));
if (CMSConfig.getConfig().isHideAdminTabs()) {
m_tabbedPane.setTabVisible(
state,
m_workflowPane,
permissionChecker.isPermitted(
CmsConstants.PRIVILEGE_ADMINISTER_WORKFLOW));
m_tabbedPane.setTabVisible(
state, m_categoryPane,
permissionChecker.isPermitted(
CmsConstants.PRIVILEGE_ADMINISTER_CATEGORIES));
m_tabbedPane.setTabVisible(
state,
m_lifecyclePane,
permissionChecker.isPermitted(
CmsConstants.PRIVILEGE_ADMINISTER_LIFECYLES));
m_tabbedPane.setTabVisible(
state,
m_typePane,
permissionChecker.isPermitted(
CmsConstants.PRIVILEGE_ADMINISTER_CONTENT_TYPES));
m_tabbedPane.setTabVisible(
state,
m_rolePane,
permissionChecker.isPermitted(
CmsConstants.PRIVILEGE_ADMINISTER_ROLES));
// csePane: should check permission
m_tabbedPane.setTabVisible(state, m_csePane, true);
// TODO Check for reportPane as well
}
}
});
}
/**
* Creates, and then caches, the browse pane. Overriding this method to
* return null will prevent this tab from appearing.
* @return
*/
protected FolderAdminPane getFolderAdminPane() {
if (m_folderPane == null) {
m_folderPane = new FolderAdminPane();
}
return m_folderPane;
}
/**
* Creates, and then caches, the browse pane. Overriding this method to
* return null will prevent this tab from appearing.
*
* @return
*/
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.
* @return
*/
protected ItemSearch getSearchPane() {
if (m_searchPane == null) {
m_searchPane
= new ItemSearch(
ContentItemVersion.DRAFT.toString(),
CMSConfig.getConfig().isLimitItemSearchToContentSection());
}
return m_searchPane;
}
protected ImagesPane getImagesPane() {
if (m_imagesPane == null) {
m_imagesPane = new ImagesPane();
}
return m_imagesPane;
}
protected RoleAdminPane getRoleAdminPane() {
if (m_rolePane == null) {
m_rolePane = new RoleAdminPane();
}
return m_rolePane;
}
/**
* Creates, and then caches, the workflow administration pane. Overriding
* this method to return null will prevent this tab from appearing.
*/
protected WorkflowAdminPane getWorkflowAdminPane() {
if (m_workflowPane == null) {
m_workflowPane = new WorkflowAdminPane();
}
return m_workflowPane;
}
/**
* Creates, and then caches, the lifecycle administration pane. Overriding
* this method to return null will prevent this tab from appearing.
*/
protected LifecycleAdminPane getLifecycleAdminPane() {
if (m_lifecyclePane == null) {
m_lifecyclePane = new LifecycleAdminPane();
}
return m_lifecyclePane;
}
/**
* Creates, and then caches, the category administration pane. Overriding
* this method to return null will prevent this tab from appearing.
*/
protected CategoryAdminPane getCategoryAdminPane() {
if (m_categoryPane == null) {
m_categoryPane = new CategoryAdminPane();
}
return m_categoryPane;
}
/**
* Creates, and then caches, the content type administration pane.
* Overriding this method to return null will prevent this tab from
* appearing.
*/
protected ContentTypeAdminPane getContentTypeAdminPane() {
if (m_typePane == null) {
m_typePane = new ContentTypeAdminPane();
}
return m_typePane;
}
// protected LayoutPanel getUserAdminPane() {
// if (m_userAdminPane == null) {
// m_userAdminPane = new LayoutPanel();
// m_userAdminPane.setLeft(new SimpleComponent());
// m_userAdminPane.setBody(new UserAdminPane());
// }
// return m_userAdminPane;
// }
protected LayoutPanel getCSEPane() {
if (m_csePane == null) {
m_csePane = new LayoutPanel();
m_csePane.setLeft(new SimpleComponent());
m_csePane.setBody(new ContentSoonExpiredPane());
}
return m_csePane;
}
protected ReportPane getReportPane() {
if (m_reportPane == null) {
m_reportPane = new ReportPane();
}
return m_reportPane;
}
/**
* Adds the specified component, with the specified tab name, to the tabbed
* pane only if it is not null.
*
* @param pane The pane to which to add the tab
* @param tabName The name of the tab if it's added
* @param comp The component to add to the pane
*/
protected void addToPane(TabbedPane pane, String tabName, Component comp) {
if (comp != null) {
pane.addTab(new Label(tabName), comp);
}
}
private void tab(final TabbedPane pane,
final String key,
final Component tab) {
if (tab != null) {
pane.addTab(new Label(gz(key)), tab);
}
}
/**
* <p>
* Created the TabbedPane to use for this page. Adds the tabs to the pane.
* The default implementation uses a {@link
* com.arsdigita.bebop.TabbedPane}. This implementation also adds browse,
* search, staff admin, viewers admin, workflow admin, category admin, and
* content type panes.</p>
*
* <p>
* Developers can override this method to add only the tabs they want, or to
* add additional tabs after the default CMS tabs are added.</p>
*
* @return
*/
protected TabbedPane createTabbedPane() {
final TabbedPane pane = new TabbedPane();
//tab(pane, "cms.ui.folders", getFolderAdminPane());
tab(pane, "cms.ui.browse", getBrowsePane());
tab(pane, "cms.ui.search", getSearchPane());
tab(pane, "cms.ui.images", getImagesPane());
tab(pane, "cms.ui.roles", getRoleAdminPane());
tab(pane, "cms.ui.workflows", getWorkflowAdminPane());
tab(pane, "cms.ui.lifecycles", getLifecycleAdminPane());
tab(pane, "cms.ui.categories", getCategoryAdminPane());
tab(pane, "cms.ui.content_types", getContentTypeAdminPane());
// user admin tab removed from tab bar and the only one widget there
// (reset home folder) moved to folder browser
// tab(pane, "cms.ui.user_admin", getUserAdminPane());
tab(pane, "cms.ui.cse", getCSEPane());
//if (DbHelper.getDatabase() == DbHelper.DB_ORACLE) {
tab(pane, "cms.ui.reports", getReportPane());
//}
return pane;
}
/**
* Fetch the request-local content section.
*
* @param request The HTTP request
*
* @return The current content section
*/
@Override
public ContentSection getContentSection(HttpServletRequest request) {
// Resets all content sections associations.
ContentSection section = super.getContentSection(request);
Assert.exists(section);
return section;
}
/**
* When a new tab is selected, reset the state of the formerly-selected
* pane.
*
* @param event The event fired by selecting a tab
*/
@Override
public void actionPerformed(ActionEvent event) {
final PageState state = event.getPageState();
final Component pane = m_tabbedPane.getCurrentPane(state);
if (pane == m_searchPane) {
m_searchPane.reset(state);
} else if (pane == m_imagesPane) {
m_imagesPane.reset(state);
} else if (pane == m_folderPane) {
m_folderPane.reset(state);
} else if (pane == m_browsePane) {
m_browsePane.reset(state);
} else if (pane == m_rolePane) {
m_rolePane.reset(state);
} else if (pane == m_workflowPane) {
m_workflowPane.reset(state);
} else if (pane == m_lifecyclePane) {
m_lifecyclePane.reset(state);
} else if (pane == m_categoryPane) {
m_categoryPane.reset(state);
} else if (pane == m_typePane) {
m_typePane.reset(state);
// } else if (pane == m_userAdminPane) {
//m_userAdminPane.reset(state);
} else if (pane == m_csePane) {
//m_csePane.reset(state);
}
}
/**
* Construct a URL for displaying the tab
*
* @param item The item from which we get the corresponding content section
* @param tab The index of the tab to display
*
* @return
*/
public static String getSectionURL(ContentItem item, int tab) {
// Get the content section associated with the content item.
ContentSection section = ContentSection.getContentSection(item);
String url = section.getURL() + PageLocations.SECTION_PAGE
+ "?" + SET_TAB + "=" + tab;
return url;
}
private static GlobalizedMessage gz(final String key) {
return new GlobalizedMessage(key, RESOURCE_BUNDLE);
}
/**
* Getting the GlobalizedMessage using a CMS Class targetBundle.
*
* @param key The resource key
*
* @return
*
* @pre key != null
*/
public static GlobalizedMessage globalize(final String key) {
return new GlobalizedMessage(key, RESOURCE_BUNDLE);
}
/**
*
* @param key
* @param args
*
* @return
*/
public static GlobalizedMessage globalize(final String key,
final Object[] args) {
return new GlobalizedMessage(key, RESOURCE_BUNDLE, args);
}
/**
* Helper class to be able to use a PrintListener to set the titel of the
* page.
*/
private static class TitlePrinter implements PrintListener {
/**
*
* @param e
*/
@Override
public void prepare(PrintEvent e) {
final Label l = (Label) e.getTarget();
l.setLabel(CMS.getContext().getContentSection().getName());
}
}
}

View File

@ -0,0 +1,604 @@
/*
* 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);
}
}

View File

@ -0,0 +1,265 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.arsdigita.cms.ui;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.FormModel;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.List;
import com.arsdigita.bebop.MapComponentSelectionModel;
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.SegmentedPanel.Segment;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.list.ListModel;
import com.arsdigita.bebop.list.ListModelBuilder;
import com.arsdigita.bebop.parameters.ParameterModel;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.toolbox.ui.ActionGroup;
import com.arsdigita.toolbox.ui.LayoutPanel;
import com.arsdigita.toolbox.ui.Section;
import com.arsdigita.util.Assert;
import com.arsdigita.util.LockableImpl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.log4j.Logger;
/**
* A {@link LayoutPanel} to insert into {@link ContentSectionPage}.
*
* @author Sören Bernstein <quasi@quasiweb.de>
*/
public class ImagesPane extends LayoutPanel implements Resettable {
public static final Logger S_LOG = Logger.getLogger(ImagesPane.class);
private final StringParameter m_imageComponentKey;
private final MapComponentSelectionModel m_imageComponent;
private final ImageComponentAdminListener m_adminListener;
final private SegmentedPanel m_body;
private HashMap<String, Segment> m_bodySegments = new HashMap();
private final ResettableParameterSingleSelectionModel m_model;
private final List m_links;
private final LinksSection m_modes;
public ImagesPane() {
super();
m_model = new ResettableParameterSingleSelectionModel(new
StringParameter(List.SELECTED));
m_model.setDefaultSelection(ImageComponent.LIBRARY);
m_model.addChangeListener(new ImageAdminSelectionListener());
m_links = new List(new ImageAdminListModelBuilder());
m_links.setSelectionModel(m_model);
final SimpleContainer left = new SimpleContainer();
setLeft(left);
m_modes = new LinksSection();
left.add(m_modes);
m_body = new SegmentedPanel();
setBody(m_body);
m_imageComponentKey = new StringParameter("imageComponent");
final ParameterSingleSelectionModel componentModel = new
ParameterSingleSelectionModel(m_imageComponentKey);
m_imageComponent = new MapComponentSelectionModel(componentModel,
new HashMap());
final Map selectors = m_imageComponent.getComponentsMap();
m_adminListener = new ImageComponentAdminListener(m_imageComponent, this);
// Image library component
final ImageLibraryComponent library = new
ImageLibraryComponent(ImageComponent.ADMIN_IMAGES);
library.getForm().addInitListener(m_adminListener);
library.getForm().addProcessListener(m_adminListener);
selectors.put(ImageComponent.LIBRARY, library);
m_bodySegments.put(ImageComponent.LIBRARY, m_body.addSegment(
new Label(GlobalizationUtil.globalize(
"cms.contentasset.image.ui.image_library")),
library));
// Image upload component
final ImageUploadComponent upload = new
ImageUploadComponent(ImageComponent.ADMIN_IMAGES);
upload.getForm().addInitListener(m_adminListener);
upload.getForm().addSubmissionListener(m_adminListener);
upload.getForm().addProcessListener(m_adminListener);
selectors.put(ImageComponent.UPLOAD, upload);
m_bodySegments.put(ImageComponent.UPLOAD, m_body.addSegment(
new Label(GlobalizationUtil.globalize(
"cms.contentasset.image.ui.image_upload")),
upload));
}
@Override
public final void register(final Page page) {
super.register(page);
Iterator<String> keys = m_bodySegments.keySet().iterator();
while (keys.hasNext()) {
String key = keys.next();
page.setVisibleDefault(m_bodySegments.get(key),
m_model.getDefaultSelection().equals(key));
}
page.addComponentStateParam(this, m_imageComponentKey);
}
/**
* Resets this pane and all its resettable components.
*
* @param state Page state
*/
@Override
public final void reset(final PageState state) {
super.reset(state);
m_model.reset(state);
this.setActiveImageComponent(state, m_model.getDefaultSelection());
}
public final void setActiveImageComponent(PageState state, String activeComp) {
Iterator<String> keys = m_bodySegments.keySet().iterator();
m_imageComponent.setSelectedKey(state, activeComp);
while (keys.hasNext()) {
String key = keys.next();
final boolean visibility = key.equals(activeComp);
state.setVisible(m_bodySegments.get(key), visibility);
for (int index = 0; index < m_bodySegments.get(key).size(); index++) {
Component component = m_bodySegments.get(key).get(index);
// Reset all components if they are of type Resettable
if (component instanceof Resettable) {
((Resettable) component).reset(state);
}
// Set visibility
component.setVisible(state, visibility);
}
}
}
/**
*
*/
private class ResettableParameterSingleSelectionModel
extends ParameterSingleSelectionModel
implements Resettable {
private String defaultKey;
public ResettableParameterSingleSelectionModel(ParameterModel m) {
super(m);
}
public void setDefaultSelection(String selKey) {
this.defaultKey = selKey;
}
public String getDefaultSelection() {
return defaultKey;
}
public void reset(PageState state) {
if (Assert.isEnabled()) {
final FormModel model = state.getPage().getStateModel();
Assert.isTrue(model.containsFormParam(getStateParameter()));
}
state.setValue(getStateParameter(), this.defaultKey);
}
}
/**
*
*/
private class ImageAdminListModel implements ListModel {
private ArrayList<String> m_keys;
private int m_index = -1;
public ImageAdminListModel(ArrayList keys) {
m_keys = keys;
}
public boolean next() {
return (m_index++ < m_keys.size() - 1);
}
public Object getElement() {
return GlobalizationUtil.globalize(
"cms.contentasset.image.ui.image_" + m_keys.get(m_index)).localize();
}
public String getKey() {
return m_keys.get(m_index);
}
}
private class ImageAdminListModelBuilder extends LockableImpl
implements ListModelBuilder {
public ListModel makeModel(final List list, final PageState state) {
ArrayList<String> keys = new ArrayList(2);
keys.add(ImageComponent.LIBRARY);
keys.add(ImageComponent.UPLOAD);
return new ImageAdminListModel(keys);
}
}
private class ImageAdminSelectionListener implements ChangeListener {
public final void stateChanged(final ChangeEvent e) {
S_LOG.debug("Selection state changed; I may change "
+"the body's visible pane");
final PageState state = e.getPageState();
// ImagesPane.this.reset(state);
if (m_model.isSelected(state)) {
S_LOG.debug("The selection model is selected; displaying "
+"the item pane");
ImagesPane.this.setActiveImageComponent(
state,
state.getControlEventValue());
}
}
}
private class LinksSection extends Section {
LinksSection() {
setHeading(GlobalizationUtil.globalize(
"cms.contentasset.image.ui.images"));
final ActionGroup group = new ActionGroup();
setBody(group);
group.setSubject(m_links);
}
}
}

View File

@ -0,0 +1,158 @@
/*
* Copyright (C) 2009 Permeance Technologies Pty Ltd. 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 java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.List;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.list.ListModel;
import com.arsdigita.bebop.list.ListModelBuilder;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.ui.report.ContentSectionSummaryTable;
import com.arsdigita.cms.ui.report.Report;
import com.arsdigita.cms.ui.report.ReportListModel;
import com.arsdigita.toolbox.ui.ActionGroup;
import com.arsdigita.toolbox.ui.Section;
import com.arsdigita.util.LockableImpl;
/**
* A pane that shows selectable reports and their results.
* A selectable list of reports is shown on the left-hand side, a selected report is shown as
* body.
*
* @author <a href="https://sourceforge.net/users/thomas-buckel/">thomas-buckel</a>
* @author <a href="https://sourceforge.net/users/tim-permeance/">tim-permeance</a>
*/
public class ReportPane extends BaseAdminPane {
private final SingleSelectionModel m_selectionModel;
private final java.util.List<Report> m_availableReports;
public ReportPane() {
m_availableReports = getReports();
m_selectionModel = new ParameterSingleSelectionModel(new StringParameter(List.SELECTED));
m_selectionModel.addChangeListener(new SelectionListener());
setSelectionModel(m_selectionModel);
List m_reports = new List(new ReportListModelBuilder(m_availableReports));
m_reports.setSelectionModel(m_selectionModel);
final ReportsListSection reportsListSection = new ReportsListSection(m_reports);
setLeft(reportsListSection);
// Register the actual components of the reports for later usage
for (Report report : m_availableReports) {
getBody().add(report.getComponent());
}
setIntroPane(new Label(gz("cms.ui.reports.intro")));
}
/**
* @return List of available reports.
*/
private java.util.List<Report> getReports() {
java.util.List<Report> reports = new ArrayList<Report>();
reports.add(new Report("cms.ui.reports.css.reportName", new ContentSectionSummaryTable()));
// Add other reports as required
Collections.sort(reports, new Comparator<Report>() {
@Override
public int compare(Report r1, Report r2) {
return r1.getName().compareTo(r2.getName());
}
});
return reports;
}
/**
* Get the report model that matches the given key.
* @param key Key to match.
* @return Report model that matches that given key, null if no matching report was found.
*/
private Report getReportByKey(String key) {
for (Report report : m_availableReports) {
if (report.getKey().equals(key)) {
return report;
}
}
return null;
}
/**
* UI section for left-hand list of reports.
*/
private class ReportsListSection extends Section {
ReportsListSection(List reports) {
setHeading(gz("cms.ui.reports.header"));
ActionGroup group = new ActionGroup();
setBody(group);
group.setSubject(reports);
}
}
/**
* SelectionListener for selected report. It shows the selected report in the body of this
* component.
*/
private class SelectionListener implements ChangeListener {
public final void stateChanged(final ChangeEvent e) {
final PageState state = e.getPageState();
getBody().reset(state);
if (m_selectionModel.isSelected(state)) {
Report selectedReport = getReportByKey(m_selectionModel.getSelectedKey(state).toString());
if (selectedReport != null) {
getBody().push(state, selectedReport.getComponent());
}
}
}
}
/**
* ListModelBuilder creating a ReportListModel for a list of reports.
*/
private static class ReportListModelBuilder extends LockableImpl implements ListModelBuilder {
private java.util.List<Report> reports;
private ReportListModelBuilder(java.util.List<Report> reports) {
this.reports = reports;
}
public final ListModel makeModel(final List list,
final PageState state) {
return new ReportListModel(reports);
}
}
}

View File

@ -0,0 +1,258 @@
/*
* 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);
}
}

View File

@ -0,0 +1,334 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.category;
import com.arsdigita.bebop.*;
import com.arsdigita.bebop.event.*;
import com.arsdigita.bebop.parameters.ParameterModel;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.categorization.CategorizedCollection;
import com.arsdigita.categorization.Category;
import com.arsdigita.categorization.CategoryCollection;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.ui.BaseAdminPane;
import com.arsdigita.cms.ui.BaseDeleteForm;
import com.arsdigita.cms.ui.BaseTree;
import com.arsdigita.cms.ui.VisibilityComponent;
import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.permissions.PermissionDescriptor;
import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.toolbox.ui.ActionGroup;
import com.arsdigita.toolbox.ui.Section;
import com.arsdigita.xml.Element;
import java.math.BigDecimal;
import org.apache.log4j.Logger;
/**
* A split pane for the Category Administration UI.
*
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id: CategoryAdminPane.java 2090 2010-04-17 08:04:14Z pboy $
*/
public final class CategoryAdminPane extends BaseAdminPane {
public static final String CONTEXT_SELECTED = "sel_context";
private static final String DEFAULT_USE_CONTEXT =
CategoryUseContextModelBuilder.DEFAULT_USE_CONTEXT;
private static final Logger s_log = Logger.getLogger(CategoryAdminPane.class);
private final SingleSelectionModel m_contextModel;
private final Tree m_categoryTree;
private final SingleSelectionModel m_model;
private final CategoryRequestLocal m_parent;
private final CategoryRequestLocal m_category;
public CategoryAdminPane() {
super();
m_contextModel = new UseContextSelectionModel(new StringParameter(CONTEXT_SELECTED));
/* Left column */
/* Use context section */
List list = new List(new CategoryUseContextModelBuilder());
list.setSelectionModel(m_contextModel);
list.addChangeListener(new ContextSelectionListener());
/* Category tree section */
m_categoryTree = new BaseTree(new CategoryTreeModelBuilder(m_contextModel));
m_categoryTree.addChangeListener(new SelectionListener());
m_model = m_categoryTree.getSelectionModel();
setSelectionModel(m_model);
setSelector(m_categoryTree);
/* setup use context form */
final Section contextSection = new Section();
contextSection.setHeading(new Label(gz("cms.ui.category.use_contexts")));
ActionGroup contextGroup = new ActionGroup();
contextSection.setBody(contextGroup);
contextGroup.setSubject(list);
if (CMS.getConfig().getAllowCategoryCreateUseContext()) {
ActionLink addContextAction = new ActionLink(new Label(gz(
"cms.ui.category.add_use_context")));
Form addContextForm = new AddUseContextForm(m_contextModel);
getBody().add(addContextForm);
getBody().connect(addContextAction, addContextForm);
contextGroup.addAction(new VisibilityComponent(addContextAction,
SecurityManager.CATEGORY_ADMIN));
}
final Section categorySection = new Section();
categorySection.setHeading(new Label(gz("cms.ui.categories")));
ActionGroup categoryGroup = new ActionGroup();
categorySection.setBody(categoryGroup);
categoryGroup.setSubject(m_categoryTree);
final SimpleContainer leftContainer = new SimpleContainer();
leftContainer.add(contextSection);
leftContainer.add(categorySection);
setLeft(leftContainer);
m_parent = new ParentRequestLocal();
m_category = new SelectionRequestLocal();
setAdd(gz("cms.ui.category.add"),
new CategoryAddForm(m_category, m_model));
setEdit(gz("cms.ui.category.edit"),
new CategoryEditForm(m_parent, m_category));
setDelete(new DeleteLink(new Label(gz("cms.ui.category.delete"))), new DeleteForm(
new SimpleContainer()));
setIntroPane(new Label(gz("cms.ui.category.intro")));
setItemPane(new CategoryItemPane(m_model,
m_contextModel,
m_category,
getAddLink(),
getEditLink(),
getDeleteLink()));
//m_contextList = new List(new ContextListModelBuilder());
//m_contextList.adChangeListener(new ContextListSelectionListener());
//m_contextModel = m_contextList.getSelectionModel();
}
@Override
public void register(final Page page) {
super.register(page);
page.addActionListener(new RootListener());
}
private final class DeleteLink extends ActionLink {
private final Label m_alternativeLabel;
DeleteLink(Label label) {
super(label);
m_alternativeLabel = new Label(gz("cms.ui.category.undeletable"));
}
@Override
public void generateXML(PageState state, Element parent) {
if (!isVisible(state)) {
return;
}
Category cat = m_category.getCategory(state);
String context = getUseContext(state);
boolean isDefaultContext =
(context == null) || DEFAULT_USE_CONTEXT.equals(context);
if (cat.isRoot() || !cat.getChildren().isEmpty()) {
m_alternativeLabel.generateXML(state, parent);
} else {
super.generateXML(state, parent);
}
}
}
private final class DeleteForm extends BaseDeleteForm {
DeleteForm(SimpleContainer prompt) {
super(prompt);
prompt.add(new Label(gz("cms.ui.category.delete_prompt")));
Label catLabel = new Label();
catLabel.addPrintListener(new PrintListener() {
public void prepare(PrintEvent pe) {
Label label = (Label) pe.getTarget();
Category cat =
m_category.getCategory(pe.getPageState());
CategoryCollection descendants = cat.getDescendants();
final long nDescendants = descendants.size() - 1;
descendants.close();
CategorizedCollection descObjects =
cat.getDescendantObjects();
final long nDescObjects = descObjects.size();
descObjects.close();
StringBuffer sb = new StringBuffer(" ");
if (nDescendants > 0) {
sb.append("This category has ");
sb.append(nDescendants);
sb.append(" descendant category(ies). ");
}
if (nDescObjects > 0) {
sb.append("It has ").append(nDescObjects);
sb.append(" descendant object(s). ");
}
if (nDescendants > 0 || nDescObjects > 0) {
sb.append("Descendants will be orphaned, if this category is removed.");
}
label.setLabel(sb.toString());
}
});
prompt.add(catLabel);
}
public final void process(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
final Category category = m_category.getCategory(state);
if (category == null) {
return;
}
PermissionService.assertPermission(new PermissionDescriptor(PrivilegeDescriptor.DELETE,
category,
Kernel.getContext().
getParty()));
if (category.isRoot()) {
Category root =
Category.getRootForObject(CMS.getContext().getContentSection(),
getUseContext(state));
if (category.equals(root)) {
Category.clearRootForObject(CMS.getContext().getContentSection(),
getUseContext(state));
}
m_contextModel.setSelectedKey(state, DEFAULT_USE_CONTEXT);
} else {
Category parent = category.getDefaultParentCategory();
m_model.setSelectedKey(state, parent.getID());
}
category.deleteCategoryAndOrphan();
}
}
private final class SelectionRequestLocal extends CategoryRequestLocal {
@Override
protected final Object initialValue(final PageState state) {
final String id = m_model.getSelectedKey(state).toString();
if (id == null) {
return null;
} else {
return new Category(new BigDecimal(id));
}
}
}
private final class ParentRequestLocal extends CategoryRequestLocal {
@Override
protected final Object initialValue(final PageState state) {
return m_category.getCategory(state).getDefaultParentCategory();
}
}
private final class RootListener implements ActionListener {
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
if (!m_model.isSelected(state)) {
final Category root =
Category.getRootForObject(CMS.getContext().getContentSection(),
getUseContext(state));
if (root != null) {
m_model.setSelectedKey(state, root.getID());
}
}
}
}
private class UseContextSelectionModel extends ParameterSingleSelectionModel {
public UseContextSelectionModel(ParameterModel m) {
super(m);
}
@Override
public Object getSelectedKey(PageState state) {
Object val = super.getSelectedKey(state);
if (val == null || ((String) val).length() == 0) {
val = DEFAULT_USE_CONTEXT;
state.setValue(getStateParameter(), val);
fireStateChanged(state);
}
return val;
}
}
public String getUseContext(PageState state) {
String selected = (String) m_contextModel.getSelectedKey(state);
return (DEFAULT_USE_CONTEXT).equals(selected) ? (String) null : selected;
}
public class ContextSelectionListener implements ChangeListener {
public final void stateChanged(final ChangeEvent e) {
s_log.debug("Selection state changed; I may change " + "the body's visible pane");
final PageState state = e.getPageState();
getBody().reset(state);
if (m_contextModel.isSelected(state)) {
final Category root =
Category.getRootForObject(CMS.getContext().getContentSection(),
getUseContext(state));
if (root != null) {
m_model.setSelectedKey(state, root.getID());
//m_categoryTree.reset(state);
}
}
if (m_model.isSelected(state)) {
s_log.debug("The selection model is selected; displaying " + "the item pane");
getBody().push(state, getItemPane());
}
}
}
}

View File

@ -0,0 +1,296 @@
/*
* Copyright (C) 2002-2005 Runtime Collective Ltd. 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.cse;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Link;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.ui.ContentItemPage;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.cms.util.SecurityConstants;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.User;
import com.arsdigita.kernel.permissions.PermissionDescriptor;
import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.persistence.DataQuery;
import com.arsdigita.persistence.Filter;
import com.arsdigita.persistence.FilterFactory;
import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.Session;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.toolbox.ui.DataQueryBuilder;
import com.arsdigita.toolbox.ui.DataTable;
import com.arsdigita.ui.admin.Admin;
import com.arsdigita.web.Application;
import com.arsdigita.web.Web;
import com.arsdigita.xml.Element;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.Component;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Iterator;
import org.apache.log4j.Logger;
/**
* A pane that contains details to soon to be expired content.
*
* @version $Id: ContentSoonExpiredPane.java 775 2005-09-12 14:54:17Z fabrice $
*/
public class ContentSoonExpiredPane extends SimpleContainer {
private static final Logger log = Logger.getLogger(ContentSoonExpiredPane.class);
private DataTable dataTable;
public ContentSoonExpiredPane() {
add(getDataTable());
}
public final void generateXML(final PageState state, final Element parent) {
if (!isVisible(state)) {
return;
}
SecurityManager sm = CMS.getContext().getSecurityManager();
User user = Web.getWebContext().getUser();
DataTable dt = getDataTable();
DataQuery dq = dt.getDataQuery(state);
dq.addFilter(getViewFilter(dq, user));
dt.generateXML(state, parent);
}
private static Filter getViewFilter(DataQuery query, User user) {
PrivilegeDescriptor privilege = new PrivilegeDescriptor(SecurityConstants.CMS_READ_ITEM);
FilterFactory ff = query.getFilterFactory();
OID partyOID = user.getOID();
return PermissionService.getFilterQuery(ff, "objectId", privilege, partyOID);
}
protected DataTable getDataTable() {
if (dataTable == null) {
dataTable = new DataTable(new ContentSoonExpiredQueryBuilder());
dataTable.addColumn(GlobalizationUtil.globalize("cms.ui.cse.authorName").localize()
.toString(),
"authorName", true);
dataTable.addColumn(GlobalizationUtil.globalize("cms.ui.cse.itemName").localize()
.toString(),
"objectId", true, new ItemTitleCellRender());
dataTable
.addColumn(GlobalizationUtil.globalize("cms.ui.cse.view").localize().toString(),
"objectId", false, new ItemViewLinkCellRender());
dataTable
.addColumn(GlobalizationUtil.globalize("cms.ui.cse.edit").localize().toString(),
"objectId", false, new ItemEditLinkCellRender());
dataTable.addColumn(GlobalizationUtil.globalize("cms.ui.cse.endDateTime").localize()
.toString(),
"endDateTime", true);
dataTable.setEmptyView(new Label(GlobalizationUtil.globalize("cms.ui.cse.none")));
}
return dataTable;
}
private static boolean hasSiteWideAdmin(User user) {
Application adminApp = Admin.getInstance();
if (adminApp == null) {
return false;
}
PermissionDescriptor admin = new PermissionDescriptor(PrivilegeDescriptor.ADMIN, adminApp,
user);
return PermissionService.checkPermission(admin);
}
private static GlobalizedMessage gz(final String key) {
return GlobalizationUtil.globalize(key);
}
private static String lz(final String key) {
return (String) gz(key).localize();
}
private class ContentSoonExpiredQueryBuilder implements DataQueryBuilder {
public String getKeyColumn() {
return "objectId";
}
public DataQuery makeDataQuery(DataTable t, PageState s) {
Session ses = SessionManager.getSession();
DataQuery query = ses.retrieveQuery(
"com.arsdigita.cms.getContentItemExpiredBeforeInSection");
int months = ContentSection.getConfig().getSoonExpiredMonths();
int days = ContentSection.getConfig().getSoonExpiredDays();
Calendar now = Calendar.getInstance();
now.add(Calendar.DAY_OF_YEAR, days);
now.add(Calendar.MONTH, months);
query.setParameter("endDateTime", now.getTime());
ContentSection section = CMS.getContext().getContentSection();
query.setParameter("sectionId", section.getID());
return query;
}
public void lock() {
}
public boolean isLocked() {
return false;
}
}
private class ItemTitleCellRender implements TableCellRenderer {
private ThreadLocal threadLocal;
public ItemTitleCellRender() {
threadLocal = new ThreadLocal() {
protected Object initialValue() {
return new Label("");
}
};
}
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column) {
BigDecimal id = (BigDecimal) key;
Label l = (Label) threadLocal.get();
l.setLabel(ContentSoonExpiredPane.getItemFromIdString(id.toString()).getDisplayName());
return l;
}
}
private class ItemEditLinkCellRender implements TableCellRenderer {
private ThreadLocal threadLocal;
public ItemEditLinkCellRender() {
threadLocal = new ThreadLocal() {
protected Object initialValue() {
return new Link(new Label(), "");
}
};
}
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column) {
boolean canEdit = false;
BigDecimal id = (BigDecimal) key;
User user = Web.getWebContext().getUser();
ContentItem ci = getItemFromIdString(id.toString());
Iterator permissions = PermissionService
.getImpliedPrivileges(ci.getOID(), user.getOID());
while (permissions.hasNext()) {
PrivilegeDescriptor permission = (PrivilegeDescriptor) permissions.next();
if (permission.equals(PrivilegeDescriptor.ADMIN) || permission.equals(
PrivilegeDescriptor.EDIT)) {
canEdit = true;
break;
}
}
if (!canEdit) {
return new Label("");
}
Link l = (Link) threadLocal.get();
// l.setTarget(ContentItemPage.getRelativeItemURL(ContentSoonExpiredPane.getItemDraft(id.toString()), ContentItemPage.AUTHORING_TAB));
l.setTarget(ContentItemPage.getItemURL(ContentSoonExpiredPane.getItemFromIdString(id
.toString()), ContentItemPage.AUTHORING_TAB));
((Label) l.getChild()).setLabel(GlobalizationUtil.globalize("cms.ui.cse.editLink"));
return l;
}
}
private class ItemViewLinkCellRender implements TableCellRenderer {
private ThreadLocal threadLocal;
public ItemViewLinkCellRender() {
threadLocal = new ThreadLocal() {
protected Object initialValue() {
return new Link(new Label(), "");
}
};
}
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column) {
BigDecimal id = (BigDecimal) key;
Link l = (Link) threadLocal.get();
ContentItem item = getItemFromIdString(id.toString());
String url = ".jsp";
while (item.getParent() != null) {
if (item.getParent() instanceof ContentItem) {
item = (ContentItem) item.getParent();
if (!"/".equals(item.getName())) {
url = "/" + item.getName() + url;
} else {
break;
}
}
}
ContentSection section = CMS.getContext().getContentSection();
l.setTarget("/" + section.getName() + url);
((Label) l.getChild()).setLabel(GlobalizationUtil.globalize("cms.ui.cse.viewLink"));
return l;
}
}
private static ContentItem getItemFromIdString(String idString) {
return new ContentItem(new OID(ContentItem.class.getName(), Integer.parseInt(idString)));
}
private static BigDecimal getItemDraft(String idString) {
ContentItem item = getItemFromIdString(idString);
return item.getDraftVersion().getID();
}
}

View File

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

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.cms.Folder;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.db.Sequences;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.SessionManager;
import org.apache.log4j.Logger;
import java.math.BigDecimal;
public class FolderCreator extends FolderForm {
private static Logger s_log =
Logger.getLogger(FolderCreator.class.getName());
public FolderCreator(String name, FolderSelectionModel parent) {
super(name, parent);
}
public void init(FormSectionEvent e) throws FormProcessException {
PageState state = e.getPageState();
ItemSelectionModel m = getItemSelectionModel();
// Create a new item_id and set it as the key
try {
m.setSelectedKey(state, Sequences.getNextValue());
} catch (java.sql.SQLException ex) {
s_log.error("Error retrieving sequence.nextval", ex);
throw new FormProcessException(ex);
}
}
public void process(FormSectionEvent e) throws FormProcessException {
PageState s = e.getPageState();
FormData data = e.getFormData();
ItemSelectionModel m = getItemSelectionModel();
BigDecimal id = (BigDecimal) m.getSelectedKey(s);
Folder parent = getCurrentFolder(s);
Folder child = null;
try {
child = new Folder(id);
} catch (DataObjectNotFoundException ex) {
child = new Folder(SessionManager.getSession().create
(new OID(Folder.BASE_DATA_OBJECT_TYPE, id)));
}
updateFolder(child, parent, (String)data.get(NAME), (String)data.get(TITLE));
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.cms.Folder;
/**
* Implements functionality for renaming a folder. Most code taken from FolderCreator. Need to refactor out base
* functionality of FolderEditor & Creator.
*
* @author Jon Orris (jorris@arsdigita.com)
*
* @version $Revision: #9 $ $DateTime: 2004/08/17 23:15:09 $
* @version $Id: FolderEditor.java 287 2005-02-22 00:29:02Z sskracic $
*/
public class FolderEditor extends FolderForm {
public FolderEditor(String name, FolderSelectionModel folder) {
super(name, folder);
}
/**
* Initialize the form with name & label of folder being edited.
*/
public void init(FormSectionEvent e) throws FormProcessException {
PageState s = e.getPageState();
FormData data = e.getFormData();
Folder folder = getCurrentFolder(s);
data.put(NAME, folder.getName());
data.put(TITLE, folder.getLabel());
}
public void process(FormSectionEvent e) throws FormProcessException {
PageState s = e.getPageState();
FormData data = e.getFormData();
Folder folder = getCurrentFolder(s);
updateFolder(folder, (String)data.get(NAME), (String)data.get(TITLE));
}
}

View File

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

View File

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

View File

@ -0,0 +1,204 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.tree.TreeModelBuilder;
import com.arsdigita.bebop.tree.TreeNode;
import com.arsdigita.cms.CMS;
import org.librecms.contentsection.ContentSection;
import com.arsdigita.util.LockableImpl;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Iterator;
import org.apache.log4j.Logger;
/**
* A {@link com.arsdigita.bebop.tree.TreeModelBuilder} that produces trees
* containing the folder structure underneath a root folder. The root
* folder can be changed by overriding {@link #getRoot getRoot}.
*
* @author <a href="mailto:tri@arsdigita.com">Tri Tran</a>
* @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a>
*
* @version $Id: FolderTreeModelBuilder.java 2183 2011-06-20 00:57:18Z pboy $
*/
public class FolderTreeModelBuilder extends LockableImpl
implements TreeModelBuilder {
private static final Logger s_log = Logger.getLogger(FolderTreeModelBuilder.class);
/**
* Make a tree model that lists the hierarchy of folders underneath the
* folder returned by {@link #getRoot getRoot}.
*
* @param t the tree in which the model is used
* @param s represents the current request
* @return a tree model that lists the hierarchy of folders underneath the
* folder returnedby {@link #getRoot getRoot}.
*/
@Override
public com.arsdigita.bebop.tree.TreeModel makeModel(final Tree t,
PageState s) {
return new DataQueryTreeModel(getRoot(s).getID(),
"com.arsdigita.cms.getRootFolder",
"com.arsdigita.cms.getSubFolders") {
@Override
public Iterator getChildren(TreeNode node, PageState data) {
String nodeKey = node.getKey().toString();
// Always expand root node
if (nodeKey.equals(getRoot(data).getKey().toString()) && t.isCollapsed(nodeKey, data)) {
t.expand(nodeKey, data);
}
if (t.isCollapsed(nodeKey, data)) {
return Collections.EMPTY_LIST.iterator();
}
Party party = Kernel.getContext().getParty();
OID partyOID = null;
if (party == null) {
partyOID = new OID(User.BASE_DATA_OBJECT_TYPE,
PermissionManager.VIRTUAL_PUBLIC_ID);
} else {
partyOID = party.getOID();
}
UniversalPermissionDescriptor universalPermission =
new UniversalPermissionDescriptor(SecurityManager.CMS_PREVIEW_ITEM_DESCRIPTOR, partyOID);
if (PermissionService.checkPermission(universalPermission)) {
// the person is an admin so we just pass in the
// standard, non filtered query
return getDataQueryTreeIterator(
(DataQueryTreeNode) node,
"com.arsdigita.cms.getSubFolders");
} else {
// now we need to set the parameters
return new NewFolderBrowserIterator(
(DataQueryTreeNode) node,
partyOID);
}
}
};
}
/**
* Retrn the root folder for the tree model in the current
* request.
* @param s represents the current request
* @return the root folder for the tree
* @post return != null
*/
protected Folder getRoot(PageState s)
throws IllegalStateException {
ContentSection sec = CMS.getContext().getContentSection();
return sec.getRootFolder();
}
private class NewFolderBrowserIterator implements Iterator {
private DataQuery m_nodes;
public NewFolderBrowserIterator(DataQueryTreeNode node, OID partyOID) {
BigDecimal userID = (BigDecimal) partyOID.get("id");
String sql = ""
+ "\n select f.folder_id as id,"
+ "\n f.label as name,"
+ "\n count(sub.item_id) as nchild"
+ "\n from cms_folders f,"
+ "\n cms_items i"
+ "\n left join"
+ "\n (select i2.item_id, f2.label as name, i2.parent_id"
+ "\n from cms_folders f2,"
+ "\n cms_items i2"
+ "\n where f2.folder_id = i2.item_id) sub"
+ "\n on (sub.parent_id = i.item_id"
+ "\n and"
+ "\n exists (select 1"
+ "\n from dnm_object_1_granted_context dogc,"
+ "\n dnm_granted_context dgc,"
+ "\n dnm_permissions dp,"
+ "\n dnm_group_membership dgm"
+ "\n where dogc.pd_object_id = sub.item_id"
+ "\n and dogc.pd_context_id = dgc.pd_object_id"
+ "\n and dgc.pd_context_id = dp.pd_object_id"
+ "\n and dp.pd_grantee_id = dgm.pd_group_id"
+ "\n and dgm.pd_member_id in (-200," + userID + ",-202)"
+ "\n and dp." + TREE_DESCRIPTOR.getColumnName() + " = '1'"
+ "\n ) )"
+ "\n where i.parent_id = " + node.getID()
+ "\n and f.folder_id = i.item_id"
+ "\n and exists ("
+ "\n select 1 as permission_p"
+ "\n from dnm_object_1_granted_context dogc,"
+ "\n dnm_granted_context dgc,"
+ "\n dnm_permissions dp,"
+ "\n dnm_group_membership dgm"
+ "\n where dogc.pd_context_id = dgc.pd_object_id"
+ "\n and dgc.pd_context_id = dp.pd_object_id"
+ "\n and dgm.pd_member_id in (-200," + userID + ",-202)"
+ "\n and dp.pd_grantee_id = dgm.pd_group_id"
+ "\n and dogc.pd_object_id = f.folder_id"
+ "\n and dp." + TREE_DESCRIPTOR.getColumnName() + " = '1' )"
+ "\n group by f.label, f.folder_id"
+ "\n order by lower(f.label)";
if (s_log.isDebugEnabled()) {
s_log.debug("Custom SQL: \n" + sql);
}
m_nodes = new GenericDataQuery(
SessionManager.getSession(),
sql,
new String[]{"id", "name", "nchild"});
}
@Override
public Object next() {
BigDecimal id = new BigDecimal(0);
try {
// this appears to be the only portable way to dig numbers out
// of the result set
id = new BigDecimal(m_nodes.get("id").toString());
} catch (NumberFormatException nfe) {
}
String name = m_nodes.get("name").toString();
BigDecimal count = new BigDecimal(0);
try {
count = new BigDecimal(m_nodes.get("nchild").toString());
} catch (NumberFormatException nfe) {
}
return new DataQueryTreeNode(id, name, count.intValue() > 0);
}
@Override
public void remove() {
throw new UnsupportedOperationException("cannot remove nodes via iterator");
}
@Override
public boolean hasNext() {
return m_nodes.next();
}
}
}

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.folder;
import com.arsdigita.bebop.List;
import com.arsdigita.bebop.PageState;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ItemCollection;
import com.arsdigita.cms.ItemSelectionModel;
import com.arsdigita.util.LockableImpl;
/**
* Produce a list of the items starting from the selected item's root down
* to the item itself.
*
* @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a>
* @version $Id: ItemPath.java 1940 2009-05-29 07:15:05Z terry $
*/
public class ItemPath extends List {
public ItemPath(ItemSelectionModel folderSel) {
super(new ListModelBuilder(folderSel));
setAttribute("type", "item-path");
setSelectionModel(folderSel);
}
public static class ListModel
implements com.arsdigita.bebop.list.ListModel {
ItemCollection m_coll;
public ListModel(ContentItem i) {
m_coll = i.getPathInfo(true);
}
public boolean next() {
return m_coll.next();
}
public Object getElement() {
return m_coll.getName();
}
public String getKey() {
return m_coll.getID().toString();
}
}
public static class ListModelBuilder extends LockableImpl
implements com.arsdigita.bebop.list.ListModelBuilder {
ItemSelectionModel m_itemSel;
public ListModelBuilder(ItemSelectionModel itemSel) {
m_itemSel = itemSel;
}
public com.arsdigita.bebop.list.ListModel makeModel(List l, final PageState s) {
return new ListModel((ContentItem) m_itemSel.getSelectedObject(s));
}
}
}

View File

@ -0,0 +1,110 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.lifecycle;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.lifecycle.LifecycleDefinition;
import com.arsdigita.cms.ui.BaseAdminPane;
import com.arsdigita.cms.ui.BaseDeleteForm;
import com.arsdigita.cms.ui.FormSecurityListener;
import org.apache.log4j.Logger;
import java.math.BigDecimal;
/**
* <p>This class contains the split pane for the lifecycle administration
* interface.</p>
*
* @author Michael Pih
* @author Jack Chung
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id: LifecycleAdminPane.java 1942 2009-05-29 07:53:23Z terry $
*/
public class LifecycleAdminPane extends BaseAdminPane {
private static Logger s_log = Logger.getLogger(LifecycleAdminPane.class);
private final SingleSelectionModel m_model;
private final LifecycleDefinitionRequestLocal m_definition;
public LifecycleAdminPane() {
super(new Label(gz("cms.ui.lifecycles")),
new LifecycleListModelBuilder());
m_model = getSelectionModel();
m_definition = new SelectionRequestLocal();
// XXX secvis
//add(new LifecycleAdminContainer(m_addLink));
setAdd(gz("cms.ui.lifecycle.add"),
new LifecycleAddForm(m_model));
setEdit(gz("cms.ui.lifecycle.edit"),
new LifecycleEditForm(m_definition));
setDelete(gz("cms.ui.lifecycle.delete"), new DeleteForm());
setIntroPane(new Label(gz("cms.ui.lifecycle.intro")));
setItemPane(new LifecycleItemPane(m_definition,
getEditLink(),
getDeleteLink()));
addAction(new LifecycleAdminContainer(getAddLink()));
}
private class SelectionRequestLocal
extends LifecycleDefinitionRequestLocal {
protected final Object initialValue(final PageState state) {
final String id = m_model.getSelectedKey(state).toString();
return new LifecycleDefinition(new BigDecimal(id));
}
}
private final class DeleteForm extends BaseDeleteForm {
DeleteForm() {
super(new Label(gz("cms.ui.lifecycle.delete_prompt")));
addSubmissionListener
(new FormSecurityListener(SecurityManager.LIFECYCLE_ADMIN));
}
public final void process(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
final ContentSection section =
CMS.getContext().getContentSection();
final LifecycleDefinition definition =
m_definition.getLifecycleDefinition(state);
section.removeLifecycleDefinition(definition);
section.save();
definition.delete();
m_model.clearSelection(state);
}
}
}

View File

@ -0,0 +1,208 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.role;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.List;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.list.ListModel;
import com.arsdigita.bebop.list.ListModelBuilder;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.ui.BaseAdminPane;
import com.arsdigita.cms.ui.BaseDeleteForm;
import com.arsdigita.cms.ui.VisibilityComponent;
import com.arsdigita.kernel.Role;
import com.arsdigita.toolbox.ui.ActionGroup;
import com.arsdigita.toolbox.ui.Section;
import com.arsdigita.util.LockableImpl;
import org.apache.log4j.Logger;
import java.math.BigDecimal;
/**
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id: RoleAdminPane.java 287 2005-02-22 00:29:02Z sskracic $
*/
public class RoleAdminPane extends BaseAdminPane {
private static final Logger s_log = Logger.getLogger(RoleAdminPane.class);
private final SingleSelectionModel m_model;
private final RoleRequestLocal m_role;
private final List m_staff;
private final List m_viewers;
public RoleAdminPane() {
m_model = new ParameterSingleSelectionModel
(new StringParameter(List.SELECTED));
setSelectionModel(m_model);
m_model.addChangeListener(new SelectionListener());
m_role = new SelectionRequestLocal();
m_staff = new List(new StaffListModelBuilder());
m_staff.setSelectionModel(m_model);
m_viewers = new List(new ViewerListModelBuilder());
m_viewers.setSelectionModel(m_model);
final SimpleContainer left = new SimpleContainer();
setLeft(left);
final StaffSection staff = new StaffSection();
left.add(staff);
final ViewerSection viewers = new ViewerSection();
left.add(viewers);
// XXX there need to be two edit forms with different boolean
// args. this is broken
setEdit(gz("cms.ui.role.edit"), new RoleEditForm(m_role, false));
setDelete(gz("cms.ui.role.delete"), new DeleteForm());
setIntroPane(new Label(gz("cms.ui.role.intro")));
setItemPane(new BaseRoleItemPane(m_model, m_role,
getEditLink(), getDeleteLink()));
}
private class StaffSection extends Section {
StaffSection() {
setHeading(gz("cms.ui.role.staff"));
final ActionGroup group = new ActionGroup();
setBody(group);
group.setSubject(m_staff);
final ActionLink link = new ActionLink
(new Label(gz("cms.ui.role.staff.add")));
group.addAction(new VisibilityComponent(link, STAFF_ADMIN),
ActionGroup.ADD);
final RoleAddForm form = new RoleAddForm(m_model, false);
getBody().add(form);
getBody().connect(link, form);
}
}
private class ViewerSection extends Section {
ViewerSection() {
setHeading(gz("cms.ui.role.viewers"));
final ActionGroup group = new ActionGroup();
setBody(group);
group.setSubject(m_viewers);
final ActionLink link = new ActionLink
(new Label(gz("cms.ui.role.viewer.add")));
group.addAction(new VisibilityComponent(link, STAFF_ADMIN),
ActionGroup.ADD);
final RoleAddForm form = new RoleAddForm(m_model, true);
getBody().add(form);
getBody().connect(link, form);
}
}
private class SelectionListener implements ChangeListener {
public final void stateChanged(final ChangeEvent e) {
s_log.debug("Selection state changed; I may change " +
"the body's visible pane");
final PageState state = e.getPageState();
getBody().reset(state);
if (m_model.isSelected(state)) {
s_log.debug("The selection model is selected; displaying " +
"the item pane");
getBody().push(state, getItemPane());
}
}
}
private class SelectionRequestLocal extends RoleRequestLocal {
protected final Object initialValue(final PageState state) {
final String id = m_model.getSelectedKey(state).toString();
return new Role(new BigDecimal(id));
}
}
private static class StaffListModelBuilder extends LockableImpl
implements ListModelBuilder {
public StaffListModelBuilder() {
super();
}
public final ListModel makeModel(final List list,
final PageState state) {
final ContentSection section =
CMS.getContext().getContentSection();
return new RoleListModel
(section.getStaffGroup().getOrderedRoles());
}
}
private static class ViewerListModelBuilder extends LockableImpl
implements ListModelBuilder {
public final ListModel makeModel(final List list,
final PageState state) {
final ContentSection section =
CMS.getContext().getContentSection();
return new RoleListModel
(section.getViewersGroup().getOrderedRoles());
}
}
private class DeleteForm extends BaseDeleteForm {
DeleteForm() {
super(gz("cms.ui.role.delete_prompt"));
addSecurityListener(STAFF_ADMIN);
}
public final void process(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
m_role.getRole(state).delete();
m_model.clearSelection(state);
}
}
}

View File

@ -0,0 +1,292 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.cms.ui.type;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.GridPanel;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSubmissionListener;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.ContentType;
import com.arsdigita.cms.ContentTypeCollection;
import com.arsdigita.cms.SectionTemplateMapping;
import com.arsdigita.cms.ui.BaseAdminPane;
import com.arsdigita.cms.ui.BaseDeleteForm;
import com.arsdigita.cms.ui.ContentSectionPage;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.domain.DomainCollection;
import com.arsdigita.persistence.DataCollection;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.kernel.ui.ACSObjectSelectionModel;
import com.arsdigita.toolbox.ui.ActionGroup;
import com.arsdigita.toolbox.ui.Section;
import com.arsdigita.toolbox.ui.Cancellable;
import org.apache.log4j.Logger;
import java.math.BigDecimal;
/**
* This class contains the split pane for the ContentType
* administration interface.
*
* @author Jack Chung
* @author Michael Pih
* @author Stanislav Freidin
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id: ContentTypeAdminPane.java 1942 2009-05-29 07:53:23Z terry $
*/
public final class ContentTypeAdminPane extends BaseAdminPane {
private static final Logger s_log = Logger.getLogger(ContentTypeAdminPane.class);
private final ACSObjectSelectionModel m_model;
private final ContentTypeRequestLocal m_type;
/**
* Constructs an admin pane. It is containing
* (a)
* a list of available content types in a
* given content section and adds a link to make additional content types
* available (out of a list of installed, but available in a given content
* section).
*/
public ContentTypeAdminPane() {
//
super(new Label(gz("cms.ui.types")),
new ContentTypeListModelBuilder() ); //list with all Types avail.
m_model = new ACSObjectSelectionModel(getSelectionModel());
m_type = new SelectionRequestLocal();
ActionLink addTypeLink = new ActionLink(new Label(gz("cms.ui.type.add")));
AddTypeContainer addTypeContainer = new AddTypeContainer();
getBody().add(addTypeContainer);
getBody().connect(addTypeLink, addTypeContainer);
addTypeLink.addActionListener(addTypeContainer);
setEdit(new ActionLink(new Label(gz("cms.ui.type.edit"))),
new EditType(m_model));
setDelete(new ActionLink(new Label(gz("cms.ui.type.delete"))),
new DeleteForm());
setIntroPane(new Label(gz("cms.ui.type.intro")));
setItemPane(new ContentTypeItemPane(m_model,
m_type,
getEditLink(),
getDeleteLink()));
addAction(new TypeSecurityContainer(addTypeLink), ActionGroup.ADD);
}
@Override
public void register(Page p) {
super.register(p);
p.addActionListener(new ActionListener() {
/**
*
* @param e
*/
@Override
public void actionPerformed(ActionEvent e) {
final PageState state = e.getPageState();
ContentType contentType = (ContentType) m_model.getSelectedObject(state);
ContentSection section = CMS.getContext().getContentSection();
if (contentType == null) {
final String template = state.getRequest()
.getParameter(ContentSectionPage
.SET_TEMPLATE);
if (template != null) {
DataCollection da = SessionManager.getSession().retrieve(SectionTemplateMapping.BASE_DATA_OBJECT_TYPE);
DomainCollection c = new DomainCollection(da);
c.addEqualsFilter(SectionTemplateMapping.SECTION + "." + ACSObject.ID,
section.getID());
c.addEqualsFilter(SectionTemplateMapping.TEMPLATE + "." + ACSObject.ID,
new BigDecimal(template));
c.addOrder(SectionTemplateMapping.CONTENT_TYPE + "." + ContentType.LABEL);
if (c.next()) {
SectionTemplateMapping mapping =
(SectionTemplateMapping) c.getDomainObject();
contentType = mapping.getContentType();
}
c.close();
}
if (contentType == null) {
ContentTypeCollection contentTypes = section.getContentTypes();
contentTypes.addOrder("label asc");
try {
if (contentTypes.next()) {
contentType = contentTypes.getContentType();
}
} finally {
contentTypes.close();
}
}
if (contentType != null) {
m_model.setSelectedObject(state, contentType);
getBody().push(state, getItemPane());
}
}
}
});
}
/**
*
*/
private class AddTypeContainer extends GridPanel implements ActionListener,
FormProcessListener {
private Label m_noTypesAvailable =
new Label(gz("cms.ui.type.select.none"));
private SelectType m_selectType;
private CreateType m_createType;
/**
*
*/
AddTypeContainer() {
super(1);
Section selectSection = new Section();
selectSection.setHeading(new Label(gz("cms.ui.type.select")));
add(selectSection);
GridPanel container = new GridPanel(1);
container.add(m_noTypesAvailable);
m_selectType = new SelectType();
m_selectType.addSubmissionListener(new CancelListener(m_selectType));
m_selectType.addProcessListener(this);
container.add(m_selectType);
selectSection.setBody(container);
Section addSection = new Section() {
@Override
public final boolean isVisible(final PageState state) {
return super.isVisible(state)
&& !ContentSection.getConfig().getHideUDCTUI();
}
};
addSection.setHeading(new Label(gz("cms.ui.type.define")));
m_createType = new CreateType(m_model);
m_createType.addSubmissionListener(new CancelListener(m_createType));
m_createType.addProcessListener(this);
addSection.setBody(m_createType);
add(addSection);
}
/**
*
* @param e
*/
@Override
public void actionPerformed(ActionEvent e) {
PageState s = e.getPageState();
ContentSection section = CMS.getContext().getContentSection();
ContentTypeCollection contentTypes =
section.getNotAssociatedContentTypes();
boolean hasAvailableTypes = !contentTypes.isEmpty();
m_selectType.setVisible(s, hasAvailableTypes);
m_noTypesAvailable.setVisible(s, !hasAvailableTypes);
}
public final void process(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
resetPane(state);
}
}
/**
* This class is essentially a copy of the CancelListener inside of
* ModalPanel. We could not use the one in ModalPanel because it was
* protected
*/
private final class CancelListener implements FormSubmissionListener {
Cancellable m_form;
CancelListener(Cancellable form) {
m_form = form;
}
@Override
public void submitted(FormSectionEvent event)
throws FormProcessException {
PageState state = event.getPageState();
if (m_form.isCancelled(state)) {
getBody().pop(state);
throw new FormProcessException(GlobalizationUtil.globalize(
"cms.ui.type.cancelled"));
}
}
} // end private class
private void resetPane(PageState state) {
getBody().reset(state);
if (getSelectionModel().isSelected(state)) {
s_log.debug("The selection model is selected; displaying "
+ "the item pane");
getBody().push(state, getItemPane());
}
}
private class SelectionRequestLocal extends ContentTypeRequestLocal {
protected final Object initialValue(final PageState state) {
ContentType contentType = (ContentType) m_model.getSelectedObject(state);
return contentType;
}
}
private class DeleteForm extends BaseDeleteForm {
DeleteForm() {
super(new Label(gz("cms.ui.type.delete_prompt")));
addSubmissionListener(new TypeSecurityListener());
}
public final void process(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
final ContentSection section =
CMS.getContext().getContentSection();
section.removeContentType(m_type.getContentType(state));
section.save();
getSelectionModel().clearSelection(state);
}
}
}

View File

@ -0,0 +1,89 @@
/*
* 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.workflow;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.ui.BaseAdminPane;
import com.arsdigita.cms.ui.BaseDeleteForm;
import com.arsdigita.cms.ui.VisibilityComponent;
import com.arsdigita.workflow.simple.WorkflowTemplate;
import org.apache.log4j.Logger;
import java.math.BigDecimal;
/**
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id: WorkflowAdminPane.java 287 2005-02-22 00:29:02Z sskracic $
*/
public final class WorkflowAdminPane extends BaseAdminPane {
private static final Logger s_log = Logger.getLogger
(WorkflowAdminPane.class);
private final WorkflowRequestLocal m_workflow;
public WorkflowAdminPane() {
super(gz("cms.ui.workflows"), new WorkflowListModelBuilder());
m_workflow = new SelectionRequestLocal();
setAdd(gz("cms.ui.workflow.add"),
new WorkflowAddForm(getSelectionModel()));
setEdit(gz("cms.ui.workflow.edit"), new WorkflowEditForm(m_workflow));
setDelete(gz("cms.ui.workflow.delete"), new DeleteForm());
setIntroPane(new Label(gz("cms.ui.workflow.intro")));
setItemPane(new WorkflowItemPane(m_workflow,
getEditLink(),
getDeleteLink()));
addAction(new VisibilityComponent(getAddLink(),
SecurityManager.WORKFLOW_ADMIN));
}
private class DeleteForm extends BaseDeleteForm {
DeleteForm() {
super(gz("cms.ui.workflow.delete_prompt"));
addSecurityListener(SecurityManager.WORKFLOW_ADMIN);
}
public final void process(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
m_workflow.getWorkflow(state).delete();
getSelectionModel().clearSelection(state);
}
}
private class SelectionRequestLocal extends WorkflowRequestLocal {
protected final Object initialValue(final PageState state) {
final String id = getSelectionModel().getSelectedKey
(state).toString();
return new WorkflowTemplate(new BigDecimal(id));
}
}
}

View File

@ -29,6 +29,7 @@ public class CmsConstants {
public static final String DB_SCHEMA = "CCM_CMS"; public static final String DB_SCHEMA = "CCM_CMS";
public static final String CMS_BUNDLE = "org.librecms.CmsResources"; public static final String CMS_BUNDLE = "org.librecms.CmsResources";
public static final String CMS_FOLDER_BUNDLE = "com.arsdigita.cms.ui.folder.CMSFolderResources";
public static final String CONTENT_CENTER_APP_TYPE = "com.arsdigita.cms.ContentCenter"; public static final String CONTENT_CENTER_APP_TYPE = "com.arsdigita.cms.ContentCenter";
public static final String CONTENT_CENTER_URL = "/content-center/"; public static final String CONTENT_CENTER_URL = "/content-center/";
@ -40,6 +41,9 @@ public class CmsConstants {
= "/templates/servlet/content-section/*"; = "/templates/servlet/content-section/*";
public static final String CONTENT_SECTION_DESC_BUNDLE public static final String CONTENT_SECTION_DESC_BUNDLE
= "org.librecms.contentsection.ContentSectionResources"; = "org.librecms.contentsection.ContentSectionResources";
public static final String CONTENT_SECTION_PAGE = "/admin";
public static final String CONTENT_SECTION_ITEM_PAGE = "/item";
public static final String CATEGORIZATION_TYPE_FOLDER = "folder"; public static final String CATEGORIZATION_TYPE_FOLDER = "folder";

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.librecms.contentsection;
import org.libreccm.core.AbstractEntityRepository;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class ContentTypeRepository
extends AbstractEntityRepository<Long, ContentType>{
@Override
public Class<ContentType> getEntityClass() {
return ContentType.class;
}
@Override
public boolean isNew(final ContentType type) {
return type.getObjectId() == 0;
}
}

View File

@ -0,0 +1,79 @@
COMMENT.00=BUTTONS/LINKS/LABELS
cms.ui.folder.edit_selection=What to do with checked items
cms.ui.folder.save=Save
cms.ui.folder.cancel=Cancel
cms.ui.folder.edit=Edit
cms.ui.folder.delete=Delete
cms.ui.folder.move=Move {0} items from {1} to {2}.
cms.ui.folder.copy=Copy {0} items from {1}
cms.ui.folder.go=Go
cms.ui.folder.name=Name
cms.ui.folder.type=Type
cms.ui.folder.creation_date=Creation Date
cms.ui.folder.last_modified=Last Modified
cms.ui.folder.action=Action
cms.ui.folder.title=Title
cms.ui.folder.index=Index
cms.ui.folder.preview=Preview
cms.ui.folder.lock=Lock
cms.ui.folder.unlock=Unlock
cms.ui.folder.external_lock=External lock
cms.ui.folder.left=Left
cms.ui.folder.right=Right
cms.ui.folder.items=item(s)
cms.ui.folder.from=from
cms.ui.folder.to=to
cms.ui.folder.no_items=No Items
cms.ui.folder.no_image=No image
cms.ui.folder.hide_metadata=Hide metadata
cms.ui.folder.show_metadata=Show metadata
cms.ui.folder.edit_subject_classes=Edit subject classes
cms.ui.folder.add_paragraph=Add a paragraph
cms.ui.folder.edit_in_applet=Edit In EoPro
cms.ui.folder.edit_in_browser=Edit In Browser
cms.ui.folder.edit_current_folder=Edit Current Folder
cms.ui.folder.preview_current_folder=Preview Current Folder
cms.ui.folder.contents_for=Contents&nbsp;for&nbsp;
cms.ui.folder.choose_target_folder=Choose target folder
cms.ui.foldr.new_wcms_doc=New WCMS Documents
COMMENT.05=INPUTS
cms.ui.folder.left=Left
cms.ui.folder.right=Right
COMMENT.10=FOLDER METADATA
cms.ui.folder.headline=Headline
cms.ui.folder.heading=Heading
cms.ui.folder.body=Body
cms.ui.folder.add_image=Add an Image
cms.ui.folder.replace_image=Replace this Image
cms.ui.folder.align=Align
cms.ui.folder.add_download=Add a Download
cms.ui.folder.alt=Alt
cms.ui.folder.caption=Caption
cms.ui.folder.remove_asset_link=Remove
COMMENT.20=ERROR MESSAGES
cms.ui.folder.column_index_not_in_table_model=Column index not in table model:
cms.ui.folder.cannot_find_root_folder=Cannot find a root folder.
cms.ui.folder.must_select_item=You must select at least one item to move/copy
cms.ui.folder.no_source_items_specified=No source items specified.
cms.ui.folder.need_select_target_folder=You need to select a folder to which the items should be copied/moved.
cms.ui.folder.not_within_same_folder=Cannot move/copy items within the same folder.
cms.ui.folder.no_permission=You do not have permission to create, copy, or move items.
cms.ui.folder.item_already_exists=There is already an item in the target folder named: {0}
cms.ui.folder.item_is_live= {0} is live; you must unpublish it before moving it.
cms.ui.folder.no_permission_for_item=You do not have permission to delete or move {0}.
cms.ui.folder.no_such_item=Item ID supplied does not match an existing Content Item.
cms.ui.folder.filter.all=All
cms.ui.folder.filter=Filter for work
cms.ui.folder.filter_do=Filter
cms.ui.folder.languages=Languages
cms.ui.folder.delete_confirmation=Permanently delete this item?
cms.ui.folder.additionalInfo=Info
cms.ui.folder.move.action=Move
cms.ui.folder.copy.action=Copy
cms.ui.folder.publish.action=(Re-)publish
cms.ui.folder.unpublish.action=Unpublish

View File

@ -0,0 +1,79 @@
COMMENT.00=BUTTONS/LINKS/LABELS
cms.ui.folder.save=Speichern
cms.ui.folder.cancel=Abbrechen
cms.ui.folder.edit=Editieren
cms.ui.folder.delete=L\u00f6schen
cms.ui.folder.move=Verschiebe {0} Dokumente von {1} nach {2}.
cms.ui.folder.copy=Kopiere {0} Dokumente von {1} nach
cms.ui.folder.go=Los
cms.ui.folder.name=Name
cms.ui.folder.type=Typ
cms.ui.folder.action=Aktion
cms.ui.folder.title=Titel
cms.ui.folder.preview=Voransicht
cms.ui.folder.lock=Sperren
cms.ui.folder.unlock=Entsperren
cms.ui.folder.external_lock=Externe Sperrung
cms.ui.folder.left=Links
cms.ui.folder.right=Rechts
cms.ui.folder.items=Eintrag/Eintr\u00e4ge
cms.ui.folder.from=von
cms.ui.folder.to=an
cms.ui.folder.no_items=Keine Eintr\u00e4ge
cms.ui.folder.no_image=Kein Bild
cms.ui.folder.hide_metadata=Metadaten verbergen
cms.ui.folder.show_metadata=Zeige die Metadaten
cms.ui.folder.edit_subject_classes=Themenklassen editieren
cms.ui.folder.add_paragraph=Abschnitt hinzuf\u00fcgen
cms.ui.folder.edit_in_applet=In EoPro editieren
cms.ui.folder.edit_in_browser=Im Browser editieren
cms.ui.folder.edit_current_folder=Bearbeiten des aktuellen Verzeichnisses
cms.ui.folder.preview_current_folder=Vorschau des aktuellen Verzeichnisses
cms.ui.folder.contents_for=Inhalt f\u00fcr
cms.ui.folder.choose_target_folder=Zielverzeichnis ausw\u00e4hlen
cms.ui.foldr.new_wcms_doc=Neue WCMS Documente
COMMENT.05=INPUTS
cms.ui.folder.left=Links
cms.ui.folder.right=Rechts
COMMENT.10=FOLDER METADATA
cms.ui.folder.headline=Titelzeile
cms.ui.folder.heading=\u00dcberschrift
cms.ui.folder.body=Hauptbereich
cms.ui.folder.add_image=Bild hinzuf\u00fcgen
cms.ui.folder.replace_image=Ersetze dieses Bild
cms.ui.folder.align=Ausrichten
cms.ui.folder.add_download=Download hinzuf\u00fcgen
cms.ui.folder.alt=Alt
cms.ui.folder.caption=\u00dcberschrift
COMMENT.20=ERROR MESSAGES
cms.ui.folder.column_index_not_in_table_model=Spaltenindex befindet sich nicht im Datenbankmodell:
cms.ui.folder.cannot_find_root_folder=Oberster Ordner kann nicht gefunden werden.
cms.ui.folder.must_select_item=Es mu\u00df mindestens ein Eintrag zum Verschieben/Kopieren ausgew\u00e4hlt werden
cms.ui.folder.no_source_items_specified=Es wurden keine Ursprungseintr\u00e4ge gew\u00e4hlt
cms.ui.folder.need_select_target_folder=Es mu\u00df ein Ordner ausgew\u00e4hlt werden, in den die Eintr\u00e4ge verschoben oder kopiert werden sollen.
cms.ui.folder.not_within_same_folder=Kopieren/Verschieben im gleichen Ordner nicht m\u00f6glich
cms.ui.folder.no_permission=Sie haben nicht die Berechtigung Eintr\u00e4ge zu erzeugen, zu kopieren oder zu verschieben.
cms.ui.folder.item_already_exists=Es gibt schon einen Eintrag im Zielordner mit Namen: {0}
cms.ui.folder.item_is_live={0} ist ver\u00f6ffentlicht. Sie m\u00fcssen ihn zum Verschieben depublizieren.
cms.ui.folder.no_permission_for_item=Sie haben nicht die Berechtigung {0} zum L\u00f6schen oder Verschieben.
cms.ui.folder.no_such_item=Die verwendete Eintrags-ID pa\u00dft zu keinem Eintrag.
cms.ui.folder.remove_asset_link=Entfernen
cms.ui.folder.filter.all=Alle
cms.ui.folder.filter=Nach Begriff filtern
cms.ui.folder.filter_do=Filtern
cms.ui.folder.languages=Sprachen
cms.ui.folder.delete_confirmation=Wollen Sie dieses Content-Item l\u00f6schen?
cms.ui.folder.edit_selection=Ausgew\u00e4hlte Items
cms.ui.folder.creation_date=Erstellungsdatum
cms.ui.folder.last_modified=Letzte \u00c4nderung
cms.ui.folder.index=Index
cms.ui.folder.additionalInfo=Info
cms.ui.folder.move.action=Verschieben
cms.ui.folder.copy.action=Kopieren
cms.ui.folder.publish.action=(Re-)Publizieren
cms.ui.folder.unpublish.action=Depublizieren

View File

@ -0,0 +1,74 @@
COMMENT.00=BOUTONS/LIENS/LIBELLE
cms.ui.folder.save=Sauver
cms.ui.folder.cancel=Annuler
cms.ui.folder.edit=Modifier
cms.ui.folder.delete=Effacer
cms.ui.folder.move=
cms.ui.folder.copy=
cms.ui.folder.go=Go
cms.ui.folder.name=Nom
cms.ui.folder.type=Type
cms.ui.folder.action=Action
cms.ui.folder.title=Titre
cms.ui.folder.index=Index
cms.ui.folder.preview=Pr\u00e9-visualisation
cms.ui.folder.lock=Verrouiller
cms.ui.folder.unlock=D\u00e9-v\u00e9rrouiller
cms.ui.folder.external_lock=Verrou externe
cms.ui.folder.left=Gauche
cms.ui.folder.right=Droite
cms.ui.folder.items=\u00e9l\u00e9ment(s)
cms.ui.folder.from=de
cms.ui.folder.to=\u00e0
cms.ui.folder.no_items=Pas d'\u00e9l\u00e9ments
cms.ui.folder.no_image=Pas d'image
cms.ui.folder.hide_metadata=Cacher les m\u00e9ta-donn\u00e9es
cms.ui.folder.show_metadata=Montrer les m\u00e9ta-donn\u00e9es
cms.ui.folder.edit_subject_classes=Modifier les classes objet
cms.ui.folder.add_paragraph=Ajouter un paragraphe
cms.ui.folder.edit_in_applet=Modifier dans EoPro
cms.ui.folder.edit_in_browser=Modifier dans un navigateur
cms.ui.folder.edit_current_folder=Modifier le dossier courant
cms.ui.folder.preview_current_folder=Pr\u00e9-visualiser le dossier courant
cms.ui.folder.contents_for=Contenu&nbsp;de&nbsp;
cms.ui.folder.choose_target_folder=Choisir le dossier de destination
cms.ui.foldr.new_wcms_doc=Nouveau document WCMS
COMMENT.05=ENTREES
cms.ui.folder.left=Gauche
cms.ui.folder.right=Droite
COMMENT.10=DOSSIER DES META DONNEES
cms.ui.folder.headline=Ent\u00eate
cms.ui.folder.heading=Chapeau
cms.ui.folder.body=Corps
cms.ui.folder.add_image=Ajouter une image
cms.ui.folder.replace_image=Remplacer cette image
cms.ui.folder.align=Aligner
cms.ui.folder.add_download=Ajouter un t\u00e9l\u00e9chargement
cms.ui.folder.alt=Alt
cms.ui.folder.caption=L\u00e9gende
cms.ui.folder.remove_asset_link=Retirer
COMMENT.20=MESSAGES D'ERREURS
cms.ui.folder.column_index_not_in_table_model=Index de la colonne absent du mod\u00e8le de table:
cms.ui.folder.cannot_find_root_folder=Impossible de trouver le dossier racine.
cms.ui.folder.must_select_item=Vous devez s\u00e9lectionner au moins \u00e9l\u00e9ment pour le d\u00e9placer ou le copier
cms.ui.folder.no_source_items_specified=Pas d'\u00e9l\u00e9ment source sp\u00e9cifi\u00e9.
cms.ui.folder.need_select_target_folder=Vous devez s\u00e9lectionner un dossier dans lequel les \u00e9l\u00e9ments seront d\u00e9plac\u00e9s ou copi\u00e9s.
cms.ui.folder.not_within_same_folder=Impossible de d\u00e9placer ou de copier des \u00e9l\u00e9ments \u00e0 l'int\u00e9rieur d'un m\u00eame dossier.
cms.ui.folder.no_permission=Vous n'avez pas l'autorisation de cr\u00e9er, de copier, ou de d\u00e9placer des \u00e9l\u00e9ments.
cms.ui.folder.item_already_exists=Il y a d\u00e9j\u00e0 un \u00e9l\u00e9ment dans le dossier destination appel\u00e9: {0}
cms.ui.folder.item_is_live={0} est en ligne ; Vous devez le d\u00e9-publier avant de le d\u00e9placer.
cms.ui.folder.no_permission_for_item=Vous n'avez pas l'autorisation de supprimer ou de d\u00e9placer {0}.
cms.ui.folder.no_such_item=L'identifiant fourni pour l'\u00e9l\u00e9ment ne correspond pas \u00e0 un contenu existant.
cms.ui.folder.filter.all=
cms.ui.folder.languages=
cms.ui.folder.delete_confirmation=
cms.ui.folder.additionalInfo=
cms.ui.folder.move.action=
cms.ui.folder.copy.action=
cms.ui.folder.publish.action=
cms.ui.folder.unpublish.action=

View File

@ -0,0 +1,487 @@
/*
* 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.kernel.ui;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.RequestLocal;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.parameters.ParameterModel;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.util.Assert;
import com.arsdigita.util.UncheckedWrapperException;
import java.math.BigDecimal;
import java.lang.reflect.Constructor;
import javax.servlet.ServletException;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.CcmObject;
import org.libreccm.core.CcmObjectRepository;
/**
* Loads a subclass of an ACSObject from the database.
* By default, uses a BigDecimal state parameter in order to
* store and retrieve the item id.
*
* <p>
* The <code>getSelectedKey(PageState state)</code> method will return the
* BigDecimal id of the currently selected object. This method
* will return the id even if the object with this id does not
* actually exist.
*
* <p>
* The <code>getSelectedObject(PageState state)</code> method will return the
* object whose id is <code>getSelectedKey(PageState state)</code>. If the
* object does not actually exist, the method will return null
*
* <p>
* Thus, it is possible to implement the following pattern:
* <blockquote><pre><code>class MyComponent extends SimpleComponent {
* ACSObjectSelectionModel m_model;
*
* public MyComponent() {
* super();
* m_model = new ACSObjectSelectionModel("item_id");
* }
*
* public void register(Page p) {
* super.register(p);
* p.addComponentStateParam(this, p.getStateParameter());
* }
*
* public void doSomethingUseful(PageState s) {
* if (m_model.isSelected(s)) {
* CusomACSObject obj = (CustomACSObject)m_model.getSelectedObject(state);
* // Do something with obj..
* }
* }
*}</code></pre></blockquote>
*
* Naturally, the <code>ACSObjectSelectionModel</code> could also be passed
* in as a parameter in the <code>MyComponent</code> constructor. In this
* case, it should be up to the parent of <code>MyComponent</code> to
* register the model's state parameter.
* <p>
* <b>Advanced Usage</b>: The <code>ACSObjectSelectionModel</code>
* is actually just a wrapper for a {@link SingleSelectionModel}
* which maintains the currently selected object's ID as a
* {@link BigDecimal}. By default, a new
* {@link ParameterSingleSelectionModel} is wrapped in this way;
* however, any {@link SingleSelectionModel} may be wrapped.
* Thus, it becomes possible to use the <code>ACSObjectSelectionModel</code>
* even if the currently selected ID is not stored in a state parameter.
* <p>
* <b>Persistence Details:</b> The default constructor of
* <code>ACSObjectSelectionModel</code> will attempt to use the
* {@link DomainObjectFactory} to automatically instantiate the correct Java
* subclass of {@link ACSObject}. However, it is also possible to use an
* alternate constructor in order to force the <code>ACSObjectSelectionModel</code>
* to manually instantiate the objects:
*
* <blockquote><pre><code>
* ACSObjectSelectionModel model =
* new ACSObjectSelectionModel("com.arsdigita.cms.Article",
* "com.arsdigita.cms.Article", "item_id");
* </code></pre></blockquote>
*
* In this case, the model will attempt to use reflection to instantiate the
* correct subclass of <code>ACSObject</code>. In addition, the supplementary
* constructor makes it possible to create new objects in the database
* using the {@link #createACSObject(BigDecimal)} method.
*
* @see com.arsdigita.bebop.SingleSelectionModel
* @see com.arsdigita.bebop.ParameterSingleSelectionModel
*
* @author Stanislav Freidin
* @version $Id$
*/
public class ACSObjectSelectionModel implements SingleSelectionModel {
private static final Logger s_log =
Logger.getLogger(ACSObjectSelectionModel.class);
private RequestLocal m_loaded;
private Class m_javaClass;
private Constructor m_constructor;
private String m_objectType;
private SingleSelectionModel m_model;
/**
* Construct a new <code>ACSObjectSelectionModel</code>.
* This model will produce instances of <code>ACSObject</code>
* by automatically instantiating the correct Java subclass using
* the {@link DomainObjectFactory}.
*
* @param parameter The state parameter which should be used to store
* the object ID
*/
public ACSObjectSelectionModel(BigDecimalParameter parameter) {
this(null, null, parameter);
}
/**
* Construct a new <code>ACSObjectSelectionModel</code>.
* This model will produce instances of <code>ACSObject</code>
* by automatically instantiating the correct Java subclass using
* the {@link DomainObjectFactory}.
*
* @param parameterName The name of the state parameter which will
* be used to store the object ID.
*/
public ACSObjectSelectionModel(String parameterName) {
this(null, null, new BigDecimalParameter(parameterName));
}
/**
* Construct a new <code>ACSObjectSelectionModel</code>.
* This model will produce instances of <code>ACSObject</code>
* by automatically instantiating the correct Java subclass using
* the {@link DomainObjectFactory}.
*
* @param model The {@link SingleSelectionModel} which will supply
* a {@link BigDecimal} ID of the currently selected object
*/
public ACSObjectSelectionModel(SingleSelectionModel model) {
this(null, null, model);
}
/**
* Construct a new <code>ACSObjectSelectionModel</code>
*
* @param javaClass The name of the Java class which represents
* the object. Must be a subclass of {@link ACSObject}. In
* addition, the class must have a constructor with a single
* {@link OID} parameter.
* @param objectType The name of the persistence metadata object type
* which represents the ACS object. In practice, will often be
* the same as the javaClass.
* @param parameterName The name of the state parameter which will
* be used to store the object ID.
*/
public ACSObjectSelectionModel( String javaClass,
String objectType,
String parameterName ) {
this(javaClass, objectType, new BigDecimalParameter(parameterName));
}
/**
* Construct a new <code>ACSObjectSelectionModel</code>
*
* @param javaClass The name of the Java class which represents
* the object. Must be a subclass of {@link ACSObject}. In
* addition, the class must have a constructor with a single
* {@link OID} parameter.
* @param objectType The name of the persistence metadata object type
* which represents the ACS object. In practice, will often be
* the same as the javaClass.
* @param parameter The state parameter which should be used to store
* the object ID
*/
public ACSObjectSelectionModel( String javaClass,
String objectType,
BigDecimalParameter parameter ) {
this(javaClass, objectType,
new ParameterSingleSelectionModel(parameter));
}
/**
* Construct a new <code>ACSObjectSelectionModel</code>
*
* @param javaClass The name of the Java class which represents
* the object. Must be a subclass of {@link ACSObject}. In
* addition, the class must have a constructor with a single
* {@link OID} parameter.
* @param objectType The name of the persistence metadata object type
* which represents the ACS object. In practice, will often be
* the same as the javaClass.
* @param model The {@link SingleSelectionModel} which will supply
* a {@link BigDecimal} ID of the currently selected object
*/
public ACSObjectSelectionModel( String javaClass,
String objectType,
SingleSelectionModel model ) {
m_loaded = new RequestLocal() {
protected Object initialValue(PageState state) {
return Boolean.FALSE;
}
};
if (javaClass != null) {
// Cache the Class object and the constructor for further use
try {
m_javaClass = Class.forName(javaClass);
m_constructor = m_javaClass.getConstructor();
} catch (Exception e) {
throw new UncheckedWrapperException( "Problem loading class "
+ javaClass, e );
}
}
m_objectType = objectType;
m_model = model;
}
/**
* Set the ID of the current object. The next time
* {@link #getSelectedObject(PageState)} is called, the object
* with the specified ID will be loaded from the database.
*
* @param state The page state
* @param key A {@link BigDecimal} primary key for the object,
* or a String representation of a BigDecimal, such as "42".
*/
public void setSelectedKey(PageState state, Object key) {
//BigDecimal newKey = convertToBigDecimal(key);
m_loaded.set(state, Boolean.FALSE);
m_model.setSelectedKey(state, key);
}
/**
* Return the object which was selected and loaded from the database,
* using the values supplied in the page state. May return <code>null</code>
* if <code>isSelected(state) == false</code>, or if the object was not found.
*
* @param state The page state
* @return The currently selected domain object, or null if no object is
* selected.
*/
public CcmObject getSelectedObject(PageState state) {
Long id = convertToLong(getSelectedKey(state));
if (id == null) {
return null;
}
return loadACSObject(state, id);
}
/**
* Load the selected object for the first time. Child classes
* may choose to override this method in order to load the object
* in nonstandard ways. The default implementation merely
* instantiates an {@link ACSObject} whose ID is the passed-in key.
*
* @param state the current page state
* @param key the currently selected key; guaranteed to be non-null
* @return the object identified by the specified key
* @pre key != null
*/
protected CcmObject loadACSObject(PageState state, Object key) {
CcmObject item = null;
// Cheesy back-and-forth conversion to ensure that
// the result will be a BigDecimal, not a String or
// something else. Should go away when ListModel.getKey is
// changed to return an Object.
Long id = convertToLong(key);
return CdiUtil.createCdiUtil().findBean(CcmObjectRepository.class).findById(id);
}
/**
* Select the specified object.
*
* @param state The page state
* @param object The content item to set
*/
public void setSelectedObject(PageState state, CcmObject object) {
CcmObject item = object;
if (item == null) {
m_loaded.set(state, Boolean.FALSE);
m_model.setSelectedKey(state, null);
} else {
m_loaded.set(state, Boolean.TRUE);
m_model.setSelectedKey(state, item.getObjectId());
}
}
/**
* Determine if the attempt to load the selected object has
* been made yet. Child classes may use this method to
* perform request-local initialization.
*
* @param state the page state
* @return true if the attempt to load the selected object has
* already been made, false otherwise
*/
public boolean isInitialized(PageState state) {
return ((Boolean)m_loaded.get(state)).booleanValue();
}
/**
* A utility function which creates a new object with the given ID.
* Uses reflection to create the instance of the class supplied
* in the constructor to this <code>ACSObjectSelectionModel</code>.
* If no classname was supplied in the constructor, an assertion
* failure will occur.
*
* @param id The id of the new item - this is ignored and the object
* will have a different id
* @return The newly created item
* @post return != null
* @deprecated This ignores the ID since ACSObject.setID is a no-op
*/
public CcmObject createACSObject(Long id) throws ServletException {
return createACSObject();
}
/**
* A utility function which creates a new object with the given ID.
* Uses reflection to create the instance of the class supplied
* in the constructor to this <code>ACSObjectSelectionModel</code>.
* If no classname was supplied in the constructor, an assertion
* failure will occur.
*
* @param id The id of the new item
* @return The newly created item
* @post return != null
*/
public CcmObject createACSObject() throws ServletException {
Assert.exists(m_javaClass, Class.class);
try {
CcmObject item = (CcmObject)m_javaClass.newInstance();
return item;
} catch (InstantiationException e) {
throw new ServletException(e);
} catch (IllegalAccessException e) {
throw new ServletException(e);
}
}
/**
* @return the Class of the content items which are produced
* by this model
*/
public Class getJavaClass() {
return m_javaClass;
}
/**
* @return The name of the object type of the
* content items which are produced by this model
*/
public String getObjectType() {
return m_objectType;
}
/**
* @return the underlying {@link SingleSelectionModel} which
* maintains the ID of the selected object
*/
public SingleSelectionModel getSingleSelectionModel() {
return m_model;
}
////////////////////////
//
// Passthrough methods
/**
* Return <code>true</code> if there is a selected object.
*
* @param state represents the state of the current request
* @return <code>true</code> if there is a selected component.
*/
public boolean isSelected(PageState state) {
return m_model.isSelected(state);
}
/**
* Return the key that identifies the selected object.
*
* @param state the current page state
* @return the {@link BigDecimal} ID of the currently selected
* object, or null if no object is selected.
* @post return instanceof BigDecimal
*
*/
public Object getSelectedKey(PageState state) {
Object key = m_model.getSelectedKey(state);
return key;
}
/**
* Clear the selection.
*
* @param state the current page state.
* @post ! isSelected(state)
* @post ! isInitialized(state)
*/
public void clearSelection(PageState state) {
m_model.clearSelection(state);
m_loaded.set(state, Boolean.FALSE);
}
/**
* Add a change listener to the model. The listener's
* <code>stateChanged</code> is called whenever the selected key changes.
*
* @param l a listener to notify when the selected key changes
*/
public void addChangeListener(ChangeListener l) {
m_model.addChangeListener(l);
}
/**
* Remove a change listener from the model.
*
* @param l the listener to remove.
*/
public void removeChangeListener(ChangeListener l) {
m_model.removeChangeListener(l);
}
/**
* Return the state parameter which will be used to keep track
* of the currently selected key. Most likely, the parameter will
* be a {@link BigDecimalParameter}.
*
* @return The state parameter which should be used to keep
* track of the ID of the currently selected object, or null
* if the ID is computed in some other way
* @see SingleSelectionModel#getStateParameter()
*/
public ParameterModel getStateParameter() {
return m_model.getStateParameter();
}
private static Long convertToLong(Object value) {
Long newValue = null;
if ( value instanceof Long ) {
newValue = (Long) value;
} else if ( value != null ) {
newValue = Long.parseLong(value.toString());
}
return newValue;
}
}

View File

@ -21,17 +21,23 @@ package org.libreccm.ui.admin;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.libreccm.security.Shiro; import org.libreccm.security.Shiro;
import org.libreccm.security.User; import org.libreccm.security.User;
import java.io.Serializable;
/** /**
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@RequestScoped
@Named @Named
public class UserContextController { @RequestScoped
public class UserContextController implements Serializable {
private static final long serialVersionUID = 2046117182808198398L;
@Inject @Inject
private Shiro shiro; private Shiro shiro;
@ -42,14 +48,14 @@ public class UserContextController {
public boolean isLoggedIn() { public boolean isLoggedIn() {
return subject.isAuthenticated(); return subject.isAuthenticated();
} }
public String getCurrentUserName() { public String getCurrentUserName() {
final User user = shiro.getUser(); final User user = shiro.getUser();
if (user == null) { if (user == null) {
return ""; return "";
} else { } else {
return String.format("%s %s", return String.format("%s %s",
user.getGivenName(), user.getGivenName(),
user.getFamilyName()); user.getFamilyName());
} }

View File

@ -18,55 +18,105 @@
*/ */
package org.libreccm.ui.admin.usersgroupsroles; package org.libreccm.ui.admin.usersgroupsroles;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.security.Permission;
import org.libreccm.security.Role; import org.libreccm.security.Role;
import org.libreccm.security.RoleMembership;
import org.libreccm.security.RoleRepository; import org.libreccm.security.RoleRepository;
import org.primefaces.model.LazyDataModel; import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder; import org.primefaces.model.SortOrder;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.enterprise.context.RequestScoped; import java.util.Set;
import javax.faces.view.ViewScoped;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.transaction.Transactional;
/** /**
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@RequestScoped
@Named @Named
public class RolesController { @ViewScoped
public class RolesController implements Serializable {
private static final long serialVersionUID = 9092665507680111584L;
private static final Logger LOGGER = LogManager.getLogger(
RolesController.class);
@Inject @Inject
private RoleRepository roleRepo; private RoleRepository roleRepo;
private final LazyDataModel<Role> tableModel; private final LazyDataModel<Role> tableModel;
private Role selectedRole; private Role selectedRole;
private String selectedRoleName;
public RolesController() { public RolesController() {
LOGGER.debug("Intializing RolesController and creating table model...");
tableModel = new RolesTableModel(); tableModel = new RolesTableModel();
} }
public LazyDataModel<Role> getTableModel() { public LazyDataModel<Role> getTableModel() {
LOGGER.debug("getTableModel invoked...");
return tableModel; return tableModel;
} }
public List<Role> getRoles() { public List<Role> getRoles() {
LOGGER.debug("getRoles invoked...");
return roleRepo.findAll(); return roleRepo.findAll();
} }
public Role getSelectedRole() { public Role getSelectedRole() {
LOGGER.debug("getSelectedRole invoked...");
return selectedRole; return selectedRole;
} }
public void setSelectedRole(final Role selectedRole) { public void setSelectedRole(final Role selectedRole) {
LOGGER.debug("Setting selected role to \"{}\"...", selectedRole);
this.selectedRole = selectedRole; this.selectedRole = selectedRole;
selectedRoleName = selectedRole.getName();
} }
public String getSelectedRoleName() {
return selectedRoleName;
}
public void setSelectedRoleName(final String name) {
selectedRoleName = name;
}
@Transactional(Transactional.TxType.REQUIRED)
public Set<RoleMembership> getSelectedRoleMemberships() {
final Role role = roleRepo.findById(selectedRole.getRoleId());
return role.getMemberships();
}
@Transactional(Transactional.TxType.REQUIRED)
public List<Permission> getSelectedRolePermissions() {
final Role role = roleRepo.findById(selectedRole.getRoleId(),
Role.ENTITY_GRPAH_WITH_PERMISSIONS);
return role.getPermissions();
}
public void renameSelectedRole() {
selectedRole.setName(selectedRoleName);
roleRepo.save(selectedRole);
}
public void renameSelectedRoleCancel() {
selectedRoleName = selectedRole.getName();
}
private class RolesTableModel extends LazyDataModel<Role> { private class RolesTableModel extends LazyDataModel<Role> {
private static final long serialVersionUID = 8878060757439667086L; private static final long serialVersionUID = 8878060757439667086L;

View File

@ -14,6 +14,7 @@
</h:head> </h:head>
<h:body> <h:body>
<f:metadata> <f:metadata>
<f:event listener="#{authorizationListener.isPermitted}" <f:event listener="#{authorizationListener.isPermitted}"
type="preRenderView" /> type="preRenderView" />
@ -29,9 +30,6 @@
library="admin-jsf" library="admin-jsf"
name="libreccm.png" /> name="libreccm.png" />
<!--<img alt=""
id="logo"
src="/themes/libreccm-default/images/libreccm.png" />-->
</div> </div>
<h:form id="user-widget"> <h:form id="user-widget">
@ -62,8 +60,6 @@
<h:outputText value="Groups Placeholder" /> <h:outputText value="Groups Placeholder" />
</p:tab> </p:tab>
<p:tab title="Roles"> <p:tab title="Roles">
<!--<h:outputText value="Roles Placeholder" />-->
<!--<p:panel header="#{texts['ui.admin.tab.users_groups_roles.title']}">-->
<h:form id="rolesForm"> <h:form id="rolesForm">
<p:dataTable id="rolesTable" <p:dataTable id="rolesTable"
lazy="true" lazy="true"
@ -71,6 +67,7 @@
rows="20" rows="20"
rowsPerPageTemplate="20,50" rowsPerPageTemplate="20,50"
scrollable="true" scrollable="true"
tableStyle="table-layout: auto;"
value="#{rolesController.tableModel}" value="#{rolesController.tableModel}"
var="role"> var="role">
<f:facet name="header"> <f:facet name="header">
@ -82,16 +79,20 @@
id="role-name"> id="role-name">
<h:outputText value="#{role.name}" /> <h:outputText value="#{role.name}" />
</p:column> </p:column>
<p:column> <p:column style="text-align: center">
<p:commandButton icon="ui-icon-wrench" <p:commandButton icon="ui-icon-wrench"
iconPos="center"
oncomplete="PF('roleDialog').show()" oncomplete="PF('roleDialog').show()"
title="Edit" title="Edit"
action="#{rolesController.setSelectedRole(role)}" update=":admin-tabs:user-groups-roles-tabs:rolesForm:roleDetails">
> <f:setPropertyActionListener value="#{role}"
<!-- --> target="#{rolesController.selectedRole}" />
<!-- update="selectedRoleName" --> </p:commandButton>
<!--<f:setPropertyActionListener value="{role}" </p:column>
target="{rolesController.selectedRole}" />--> <p:column style="text-align: center">
<p:commandButton icon="ui-icon-closethick"
iconPos="center"
title="Delete">
</p:commandButton> </p:commandButton>
</p:column> </p:column>
</p:dataTable> </p:dataTable>
@ -100,15 +101,52 @@
widgetVar="roleDialog" widgetVar="roleDialog"
modal="true" modal="true"
showEffect="fade" showEffect="fade"
hideEffect="fade"> hideEffect="fade"
<p:outputPanel rendered="#{rolesController.selectedRole != null}"> style="font-size: 1.2em;">
<h:outputText id="selectedRoleName" <p:outputPanel id="roleDetails">
rendered="#{rolesController.selectedRole != null}" <p:tabView dynamic="true"
value="#{rolesController.selectedRole.name}" /> id="rolesDetailTab">
<p:tab title="#{texts['ui.admin.tab.users_groups_roles.role_details']}">
<p:inputText
id="selectedRoleName"
value="#{rolesController.selectedRoleName}" />
<div>
<p:commandButton action="#{rolesController.renameSelectedRole()}"
oncomplete="PF('roleDialog').hide()"
update=":admin-tabs:user-groups-roles-tabs:rolesForm:rolesTable"
value="#{texts['ui.admin.tab.users_groups_roles.role_details.save']}"/>
<p:commandButton action="#{rolesController.renameSelectedRoleCancel()}"
oncomplete="PF('roleDialog').hide()"
value="#{texts['ui.admin.tab.users_groups_roles.role_details.cancel']}"/>
</div>
<!-- <h:outputText id="selectedRoleName"
value="#{rolesController.selectedRole.name}" />-->
</p:tab>
<p:tab title="#{texts['ui.admin.tab.users_groups_roles.role_members']}">
<p:dataTable value="#{rolesController.selectedRoleMemberships}"
var="membership">
<p:column headerText="Name">
<h:outputText value="#{membership.member.name}"/>
</p:column>
</p:dataTable>
</p:tab>
<p:tab title="#{texts['ui.admin.tab.users_groups_roles.role_permissions']}">
<p:dataTable tableStyle="table-layout: auto;"
value="#{rolesController.selectedRolePermissions}"
var="permission">
<p:column headerText="Privilege">
<h:outputText value="#{permission.grantedPrivilege}" />
</p:column>
<p:column headerText="On object">
<h:outputText rendered="#{permission.object != null}"
value="#{permission.object.displayName}" />
</p:column>
</p:dataTable>
</p:tab>
</p:tabView>
</p:outputPanel> </p:outputPanel>
</p:dialog> </p:dialog>
</h:form> </h:form>
<!--</p:panel>-->
</p:tab> </p:tab>
</p:tabView> </p:tabView>

View File

@ -547,3 +547,8 @@ ui.admin.applications.instance_table.heading=Instances
ui.admin.applications.new_instance.primary_url=Primary URL ui.admin.applications.new_instance.primary_url=Primary URL
ui.admin.applications.new_instance.primary_url.error.not_empty=The primary URL of an application instance can't be empty. ui.admin.applications.new_instance.primary_url.error.not_empty=The primary URL of an application instance can't be empty.
ui.admin.tab.users_groups_roles.edit=Edit role ui.admin.tab.users_groups_roles.edit=Edit role
ui.admin.tab.users_groups_roles.role_details=Details
ui.admin.tab.users_groups_roles.role_members=Members
ui.admin.tab.users_groups_roles.role_permissions=Permissions
ui.admin.tab.users_groups_roles.role_details.save=Save
ui.admin.tab.users_groups_roles.role_details.cancel=Cancel

View File

@ -551,3 +551,8 @@ ui.admin.applications.instance_table.heading=Instanzen
ui.admin.applications.new_instance.primary_url=Prim\u00e4re URL ui.admin.applications.new_instance.primary_url=Prim\u00e4re URL
ui.admin.applications.new_instance.primary_url.error.not_empty=Die prim\u00e4re URL einer Applikations-Instanz kann nicht leer sein. ui.admin.applications.new_instance.primary_url.error.not_empty=Die prim\u00e4re URL einer Applikations-Instanz kann nicht leer sein.
ui.admin.tab.users_groups_roles.edit=Rolle bearbeiten ui.admin.tab.users_groups_roles.edit=Rolle bearbeiten
ui.admin.tab.users_groups_roles.role_details=Details
ui.admin.tab.users_groups_roles.role_members=Mitglieder
ui.admin.tab.users_groups_roles.role_permissions=Berechtigungen
ui.admin.tab.users_groups_roles.role_details.save=Speichern
ui.admin.tab.users_groups_roles.role_details.cancel=Abbrechen

View File

@ -544,3 +544,8 @@ ui.admin.applications.instance_table.heading=Instances
ui.admin.applications.new_instance.primary_url=Primary URL ui.admin.applications.new_instance.primary_url=Primary URL
ui.admin.applications.new_instance.primary_url.error.not_empty=The primary URL of an application instance can't be empty. ui.admin.applications.new_instance.primary_url.error.not_empty=The primary URL of an application instance can't be empty.
ui.admin.tab.users_groups_roles.edit=Edit role ui.admin.tab.users_groups_roles.edit=Edit role
ui.admin.tab.users_groups_roles.role_details=Details\t
ui.admin.tab.users_groups_roles.role_members=Members
ui.admin.tab.users_groups_roles.role_permissions=Permissions
ui.admin.tab.users_groups_roles.role_details.save=Save
ui.admin.tab.users_groups_roles.role_details.cancel=Cancel

View File

@ -535,3 +535,8 @@ ui.admin.applications.instance_table.heading=Instances
ui.admin.applications.new_instance.primary_url=Primary URL ui.admin.applications.new_instance.primary_url=Primary URL
ui.admin.applications.new_instance.primary_url.error.not_empty=The primary URL of an application instance can't be empty. ui.admin.applications.new_instance.primary_url.error.not_empty=The primary URL of an application instance can't be empty.
ui.admin.tab.users_groups_roles.edit=Edit role ui.admin.tab.users_groups_roles.edit=Edit role
ui.admin.tab.users_groups_roles.role_details=Details
ui.admin.tab.users_groups_roles.role_members=Members
ui.admin.tab.users_groups_roles.role_permissions=Permissions
ui.admin.tab.users_groups_roles.role_details.save=Save
ui.admin.tab.users_groups_roles.role_details.cancel=Cancel