CCM NG:
- 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
parent
790959901b
commit
76e5784e2e
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <jross@redhat.com>
|
||||||
|
* @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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 <dlutter@redhat.com>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 <jross@redhat.com>
|
||||||
|
* @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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 <xdmoon@redhat.com>
|
||||||
|
* @author Justin Ross <jross@redhat.com>
|
||||||
|
* @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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <jross@redhat.com>
|
||||||
|
* @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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <jross@redhat.com>
|
||||||
|
* @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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 <jross@redhat.com>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 <jross@redhat.com>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 <jross@redhat.com>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 <jross@redhat.com>
|
||||||
|
* @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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 for
|
||||||
|
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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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 de
|
||||||
|
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=
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue