CCM NG:
- Content Center Application now works again. - JavaDoc for ContentItemRepository and ContentItemManager - A prototype/test for using JSF/PrimeFaces instead of Bebop for the Backend UI (will may be removed later) git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4211 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
a704ef72a6
commit
23f682b16d
|
|
@ -45,5 +45,8 @@
|
|||
<Logger name="org.libreccm.security.Shiro"
|
||||
level="debug">
|
||||
</Logger>
|
||||
<Logger name="org.librecms.contentsection.ContentSectionSetup"
|
||||
level="debug">
|
||||
</Logger>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0"?>
|
||||
<faces-config version="2.2"
|
||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
|
||||
</faces-config>
|
||||
|
|
@ -26,4 +26,20 @@
|
|||
<listener>
|
||||
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<url-pattern>*.xhtml</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<context-param>
|
||||
<param-name>javax.faces.PROJECT_STAGE</param-name>
|
||||
<param-value>Development</param-value>
|
||||
</context-param>
|
||||
</web-app>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html">
|
||||
|
||||
<head>
|
||||
<title>
|
||||
JSF Test INDEX
|
||||
</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h:outputText value="JSF TEST INDEX"/>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 com.arsdigita.cms;
|
||||
|
||||
import org.libreccm.web.ApplicationCreator;
|
||||
import org.libreccm.web.ApplicationRepository;
|
||||
import org.libreccm.web.ApplicationType;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
import org.librecms.CmsConstants;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
public class ContentCenterAppCreator implements ApplicationCreator<CcmApplication> {
|
||||
|
||||
@Inject
|
||||
private ApplicationRepository appRepository;
|
||||
|
||||
@Override
|
||||
public CcmApplication createInstance(final String primaryUrl,
|
||||
final ApplicationType type) {
|
||||
if (!CmsConstants.CONTENT_CENTER_URL.equals(primaryUrl)) {
|
||||
throw new IllegalArgumentException(
|
||||
"ContentCenter is a singleton application which is mounted at "
|
||||
+ "/content-center/");
|
||||
}
|
||||
|
||||
return appRepository.retrieveApplicationForPath(primaryUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -48,7 +48,6 @@ import org.librecms.contentsection.ContentSectionRepository;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -136,8 +135,8 @@ public class ContentCenterServlet extends BaseApplicationServlet {
|
|||
/* Check user and privilegies */
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
||||
if (shiro.getSubject().isAuthenticated()) {
|
||||
throw new LoginSignal(sreq); // send to login page
|
||||
if (!shiro.getSubject().isAuthenticated()) {
|
||||
throw new LoginSignal(sreq); // send to login page
|
||||
}
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
|
|
@ -178,7 +177,7 @@ public class ContentCenterServlet extends BaseApplicationServlet {
|
|||
// DispatcherHelper.sendRedirect(sresp, originalUrl + "/");
|
||||
// return;
|
||||
// }
|
||||
final Page page = (Page) pages.get(pathInfo);
|
||||
final Page page = pages.get(pathInfo);
|
||||
if (page != null) {
|
||||
|
||||
// Check user access.
|
||||
|
|
@ -274,7 +273,7 @@ public class ContentCenterServlet extends BaseApplicationServlet {
|
|||
)
|
||||
throws ServletException {
|
||||
|
||||
if (CdiUtil.createCdiUtil().findBean(Shiro.class).getSubject()
|
||||
if (!CdiUtil.createCdiUtil().findBean(Shiro.class).getSubject()
|
||||
.isAuthenticated()) {
|
||||
throw new LoginSignal(request);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 com.arsdigita.cms;
|
||||
|
||||
import org.libreccm.modules.InstallEvent;
|
||||
import org.libreccm.web.AbstractCcmApplicationSetup;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
import org.librecms.CmsConstants;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class ContentCenterSetup extends AbstractCcmApplicationSetup {
|
||||
|
||||
public ContentCenterSetup(final InstallEvent event) {
|
||||
super(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
final CcmApplication contentCenter = new CcmApplication();
|
||||
contentCenter.setUuid(UUID.randomUUID().toString());
|
||||
contentCenter.setApplicationType(CmsConstants.CONTENT_CENTER_APP_TYPE);
|
||||
contentCenter.setPrimaryUrl(CmsConstants.CONTENT_CENTER_URL);
|
||||
|
||||
getEntityManager().persist(contentCenter);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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.Form;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.Resettable;
|
||||
import com.arsdigita.bebop.SimpleContainer;
|
||||
|
||||
import com.arsdigita.search.QuerySpecification;
|
||||
import com.arsdigita.search.ui.QueryGenerator;
|
||||
|
||||
/**
|
||||
* A wrapper around the {@link ItemSearchSection} which embedds
|
||||
* the form section in a form.
|
||||
*
|
||||
* @author Stanislav Freidin (sfreidin@arsdigita.com)
|
||||
* @version $Id: ItemSearch.java 1940 2009-05-29 07:15:05Z terry $
|
||||
*/
|
||||
public class ItemSearch extends Form implements Resettable, QueryGenerator {
|
||||
|
||||
private static final org.apache.log4j.Logger s_log =
|
||||
org.apache.log4j.Logger.getLogger(ItemSearch.class);
|
||||
public static final String SINGLE_TYPE_PARAM = ItemSearchSection.SINGLE_TYPE_PARAM;
|
||||
private ItemSearchSection m_section;
|
||||
|
||||
/**
|
||||
* Construct a new <code>ItemSearch</code> component
|
||||
* Default to limit the search to current content section
|
||||
*
|
||||
* @param context the context for the retrieved items. Should be
|
||||
* {@link ContentItem#DRAFT} or {@link ContentItem#LIVE}
|
||||
*/
|
||||
public ItemSearch(String context) {
|
||||
this(context, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new <code>ItemSearch</code> component
|
||||
*
|
||||
* @param context the context for the retrieved items. Should be
|
||||
* {@link ContentItem#DRAFT} or {@link ContentItem#LIVE}
|
||||
* @param limitToContentSection limit the search to the current content section
|
||||
*/
|
||||
public ItemSearch(String context, boolean limitToContentSection) {
|
||||
super("itemSearch", new SimpleContainer());
|
||||
//setMethod("GET");
|
||||
m_section = createSearchSection(context, limitToContentSection);
|
||||
add(m_section);
|
||||
}
|
||||
|
||||
protected ItemSearchSection createSearchSection(String context, boolean limitToContentSection) {
|
||||
return new ItemSearchSection(context, limitToContentSection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasQuery(PageState state) {
|
||||
return m_section.hasQuery(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuerySpecification getQuerySpecification(PageState state) {
|
||||
return m_section.getQuerySpecification(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(PageState state) {
|
||||
m_section.reset(state);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
package com.arsdigita.cms.ui.authoring;
|
||||
|
||||
import com.arsdigita.bebop.BoxPanel;
|
||||
import com.arsdigita.bebop.Form;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.event.PrintEvent;
|
||||
import com.arsdigita.bebop.event.PrintListener;
|
||||
import com.arsdigita.bebop.form.Option;
|
||||
import com.arsdigita.bebop.form.OptionGroup;
|
||||
import com.arsdigita.bebop.form.SingleSelect;
|
||||
import com.arsdigita.bebop.form.Submit;
|
||||
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
||||
import com.arsdigita.cms.ui.ItemSearch;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.ui.admin.GlobalizationUtil;
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
import com.arsdigita.xml.Element;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.libreccm.security.Party;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentType;
|
||||
|
||||
import java.awt.image.Kernel;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A form element which displays a select box of all content types available
|
||||
* under the given content section, and forwards to the item creation UI when
|
||||
* the user selects a content type to instantiate.
|
||||
*
|
||||
* @author Stanislav Freidin (sfreidin@arsdigtia.com)
|
||||
* @version $Revision: #12 $ $DateTime: 2004/08/17 23:15:09 $
|
||||
* @version $Id: NewItemForm.java 2161 2011-02-02 00:16:13Z pboy $
|
||||
*/
|
||||
public abstract class NewItemForm extends Form {
|
||||
|
||||
/**
|
||||
* Internal logger instance to faciliate debugging. Enable logging output by
|
||||
* editing /WEB-INF/conf/log4j.properties int hte runtime environment and
|
||||
* set com.arsdigita.cms.ui.authoring.NewItemForm=DEBUG by uncommenting or
|
||||
* adding the line.
|
||||
*/
|
||||
private static final Logger s_log = Logger.getLogger(NewItemForm.class);
|
||||
|
||||
private final SingleSelect m_typeWidget;
|
||||
private final Submit m_submit;
|
||||
private final Label m_emptyLabel;
|
||||
private final Label m_createLabel;
|
||||
public static final String TYPE_ID = "tid";
|
||||
|
||||
public NewItemForm(String name) {
|
||||
this(name, BoxPanel.HORIZONTAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new NewItemForm. It sets a vertical BoxPanel as the component
|
||||
* container.
|
||||
*
|
||||
* @param name the name attribute of the form.
|
||||
*/
|
||||
public NewItemForm(String name, int orientation) {
|
||||
|
||||
super(name, new BoxPanel(BoxPanel.VERTICAL));
|
||||
setIdAttr("new_item_form");
|
||||
|
||||
//BoxPanel panel = new BoxPanel(BoxPanel.HORIZONTAL);
|
||||
BoxPanel panel = new BoxPanel(orientation);
|
||||
panel.setWidth("2%");
|
||||
panel.setBorder(0);
|
||||
|
||||
// create and add an "empty" component
|
||||
m_emptyLabel = new Label(new GlobalizedMessage(
|
||||
"cms.ui.authoring.no_types_registered", CmsConstants.CMS_BUNDLE),
|
||||
false);
|
||||
m_emptyLabel.setIdAttr("empty_label");
|
||||
panel.add(m_emptyLabel);
|
||||
|
||||
m_createLabel = new Label(new GlobalizedMessage(
|
||||
"cms.ui.authoring.create_new", CmsConstants.CMS_BUNDLE),
|
||||
false);
|
||||
m_createLabel.setIdAttr("create_label");
|
||||
panel.add(m_createLabel);
|
||||
|
||||
m_typeWidget = new SingleSelect(new BigDecimalParameter(TYPE_ID),
|
||||
OptionGroup.SortMode.ALPHABETICAL_ASCENDING);
|
||||
try {
|
||||
m_typeWidget.addPrintListener(new PrintListener() {
|
||||
|
||||
// Read the content section's content types and add them as options
|
||||
@Override
|
||||
public void prepare(PrintEvent e) {
|
||||
OptionGroup o = (OptionGroup) e.getTarget();
|
||||
o.clearOptions();
|
||||
PageState state = e.getPageState();
|
||||
|
||||
// gather the content types of this section into a list
|
||||
ContentSection section = getContentSection(state);
|
||||
ContentType parentType = null;
|
||||
List<ContentType> typesCollection = null;
|
||||
BigDecimal singleTypeID = (BigDecimal) state.getValue(
|
||||
new BigDecimalParameter(
|
||||
ItemSearch.SINGLE_TYPE_PARAM));
|
||||
|
||||
if (singleTypeID != null) {
|
||||
try {
|
||||
parentType = new ContentType(singleTypeID);
|
||||
} catch (DataObjectNotFoundException ex) {
|
||||
parentType = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (parentType == null) {
|
||||
typesCollection = section.getCreatableContentTypes();
|
||||
} else {
|
||||
typesCollection = section.getDescendantsOfContentType(
|
||||
parentType);
|
||||
}
|
||||
|
||||
typesCollection.addOrder(ContentType.LABEL);
|
||||
|
||||
if (!typesCollection.isEmpty()) {
|
||||
// Add content types
|
||||
while (typesCollection.next()) {
|
||||
boolean list = true;
|
||||
ContentType type = typesCollection.getContentType();
|
||||
if (PermissionService
|
||||
.getDirectGrantedPermissions(type.getOID())
|
||||
.size() > 0) {
|
||||
// chris gilbert - allow restriction of some types
|
||||
// to certain users/groups. No interface to do
|
||||
// this, but group could be created and permission
|
||||
// granted in a content type loader
|
||||
//
|
||||
// can't permission filter the collection because
|
||||
// most types will have no permissions granted.
|
||||
// This approach involves a small overhead getting
|
||||
// the count of granted permissions for each type
|
||||
// (mitigated by only checking DIRECT permissions)
|
||||
|
||||
Party party = Kernel.getContext().getParty();
|
||||
if (party == null) {
|
||||
party = Kernel.getPublicUser();
|
||||
}
|
||||
PermissionDescriptor create
|
||||
= new PermissionDescriptor(
|
||||
PrivilegeDescriptor
|
||||
.get(SecurityManager.CMS_NEW_ITEM),
|
||||
type,
|
||||
party);
|
||||
list = PermissionService.checkPermission(create);
|
||||
|
||||
}
|
||||
if (list) {
|
||||
// o.addOption(new Option(type.getID().toString(), type.getName()));
|
||||
o.addOption(new Option(type.getID().toString(),
|
||||
new Label(type.getLabel())));
|
||||
}
|
||||
|
||||
}
|
||||
typesCollection.reset();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
} catch (java.util.TooManyListenersException e) {
|
||||
throw new UncheckedWrapperException("Too many listeners: " + e
|
||||
.getMessage(), e);
|
||||
}
|
||||
|
||||
panel.add(m_typeWidget);
|
||||
|
||||
m_submit = new Submit("new", GlobalizationUtil.globalize(
|
||||
"cms.ui.authoring.go"));
|
||||
panel.add(m_submit);
|
||||
|
||||
add(panel);
|
||||
}
|
||||
|
||||
public abstract ContentSection getContentSection(PageState state);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param state
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public BigDecimal getTypeID(PageState state) {
|
||||
return (BigDecimal) m_typeWidget.getValue(state);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public final SingleSelect getTypeSelect() {
|
||||
return m_typeWidget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate XML - show/hide labels/widgets
|
||||
*
|
||||
* @param state
|
||||
* @param parent
|
||||
*/
|
||||
@Override
|
||||
public void generateXML(PageState state, Element parent) {
|
||||
|
||||
if (isVisible(state)) {
|
||||
ContentSection section = getContentSection(state);
|
||||
|
||||
ContentTypeCollection c = section.getCreatableContentTypes();
|
||||
boolean isEmpty = c.isEmpty();
|
||||
c.close();
|
||||
|
||||
m_createLabel.setVisible(state, !isEmpty);
|
||||
m_typeWidget.setVisible(state, !isEmpty);
|
||||
m_submit.setVisible(state, !isEmpty);
|
||||
m_emptyLabel.setVisible(state, isEmpty);
|
||||
|
||||
super.generateXML(state, parent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,649 @@
|
|||
/*
|
||||
* 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.contentcenter;
|
||||
|
||||
import com.arsdigita.bebop.BoxPanel;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.arsdigita.bebop.Component;
|
||||
import com.arsdigita.bebop.Embedded;
|
||||
import com.arsdigita.bebop.FormProcessException;
|
||||
import com.arsdigita.bebop.Label;
|
||||
import com.arsdigita.bebop.Link;
|
||||
import com.arsdigita.bebop.Page;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.SingleSelectionModel;
|
||||
import com.arsdigita.bebop.Table;
|
||||
import com.arsdigita.bebop.event.FormProcessListener;
|
||||
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||
import com.arsdigita.bebop.event.FormSubmissionListener;
|
||||
import com.arsdigita.bebop.form.Hidden;
|
||||
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
||||
import com.arsdigita.bebop.table.TableCellRenderer;
|
||||
import com.arsdigita.bebop.table.TableColumn;
|
||||
import com.arsdigita.bebop.table.TableColumnModel;
|
||||
import com.arsdigita.bebop.table.TableModel;
|
||||
import com.arsdigita.bebop.table.TableModelBuilder;
|
||||
import com.arsdigita.cms.ui.CMSContainer;
|
||||
import com.arsdigita.ui.admin.GlobalizationUtil;
|
||||
import com.arsdigita.util.Assert;
|
||||
import com.arsdigita.util.LockableImpl;
|
||||
import com.arsdigita.web.Web;
|
||||
|
||||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
import org.libreccm.security.User;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentSectionConfig;
|
||||
import org.librecms.contentsection.ContentSectionRepository;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.mail.Folder;
|
||||
|
||||
/**
|
||||
* Displays all the content sections in table, with links to the admin (and in
|
||||
* legacy mode to legacy public pages as well). Also displays a form for each
|
||||
* content section to create an object of a given type (configurable). The list
|
||||
* of available types retrieved for each content section.
|
||||
*
|
||||
* <p>
|
||||
* This class is a container for two other components: a form and a table. The
|
||||
* form represents the drop down list of the content types available in a
|
||||
* particular content section. It is an extension of the
|
||||
* {@link com.arsdigita.cms.ui.authoring.NewItemForm}. The table displays each
|
||||
* content section in one row, along with the specified form. The same form is
|
||||
* reused in every row of the table.
|
||||
*
|
||||
* @author <a href="mailto:mbryzek@arsdigita.com">Michael Bryzek</a>
|
||||
* @version $Id: ContentSectionContainer.java 287 2005-02-22 00:29:02Z sskracic$
|
||||
*/
|
||||
public class ContentSectionContainer extends CMSContainer {
|
||||
|
||||
private static final String CONTENT_SECTION_CLASS = "contentSections";
|
||||
|
||||
private final ContentSectionTable m_table;
|
||||
private final FormContainer m_formContainer;
|
||||
private final SingleSelectionModel m_typeSel;
|
||||
private final SingleSelectionModel m_sectionSel;
|
||||
|
||||
/**
|
||||
* Constructs a new ContentSectionContainer which containts:
|
||||
*
|
||||
* <ul>
|
||||
* <li> SimpleContainer (to contain the form)
|
||||
* <ul>
|
||||
* <li> Form (for creating a new content item in each section)
|
||||
* </ul>
|
||||
* <li> Table (Displays all content sections)
|
||||
* </ul>
|
||||
*
|
||||
* @param typeSel passthrough to {@link NewItemForm}
|
||||
* @param sectionSel passthrough to {@link NewItemForm}
|
||||
*/
|
||||
public ContentSectionContainer(SingleSelectionModel typeSel,
|
||||
SingleSelectionModel sectionSel) {
|
||||
super();
|
||||
setClassAttr(CONTENT_SECTION_CLASS);
|
||||
|
||||
m_typeSel = typeSel;
|
||||
m_sectionSel = sectionSel;
|
||||
|
||||
m_formContainer = new FormContainer();
|
||||
add(m_formContainer);
|
||||
m_table = new ContentSectionTable();
|
||||
add(m_table);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param p
|
||||
*/
|
||||
@Override
|
||||
public void register(Page p) {
|
||||
super.register(p);
|
||||
p.setVisibleDefault(m_formContainer, false);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private class FormContainer extends CMSContainer {
|
||||
|
||||
// private final StaticNewItemForm m_form;
|
||||
private final BigDecimalParameter m_sectionIdParam;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
private FormContainer() {
|
||||
super();
|
||||
m_sectionIdParam = new BigDecimalParameter("sectionId");
|
||||
// m_form = new StaticNewItemForm(m_sectionIdParam);
|
||||
|
||||
// m_form.addSubmissionListener(new FormSubmissionListener() {
|
||||
//
|
||||
// /**
|
||||
// * Cancels the form if the user lacks the "create new items"
|
||||
// * privilege.
|
||||
// */
|
||||
// @Override
|
||||
// public void submitted(FormSectionEvent event)
|
||||
// throws FormProcessException {
|
||||
// PageState state = event.getPageState();
|
||||
// StaticNewItemForm form = (StaticNewItemForm) event
|
||||
// .getSource();
|
||||
//
|
||||
// ContentSection section = form.getContentSection(state);
|
||||
// final PermissionChecker permissionChecker = CdiUtil
|
||||
// .createCdiUtil().findBean(PermissionChecker.class);
|
||||
// Category folder = null;
|
||||
// //ToDo
|
||||
//// User user = Web.getWebContext().getUser();
|
||||
//// if (user != null) {
|
||||
//// folder = Folder.getUserHomeFolder(user, section);
|
||||
//// }
|
||||
//// if (folder == null) {
|
||||
//// folder = section.getRootFolder();
|
||||
//// }
|
||||
////ToDo End
|
||||
// folder = section.getRootDocumentsFolder();
|
||||
//
|
||||
// if (!permissionChecker.isPermitted(
|
||||
// CmsConstants.PRIVILEGE_ITEMS_CREATE_NEW, folder)) {
|
||||
// throw new FormProcessException(
|
||||
// (GlobalizationUtil.globalize(
|
||||
// "cms.ui.insufficient_privileges")));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// });
|
||||
//
|
||||
// m_form.addProcessListener(new FormProcessListener() {
|
||||
//
|
||||
// /**
|
||||
// * Process listener: redirects to the authoring kit to create a
|
||||
// * new item.
|
||||
// */
|
||||
// @Override
|
||||
// public void process(FormSectionEvent e) throws
|
||||
// FormProcessException {
|
||||
// StaticNewItemForm form = (StaticNewItemForm) e.getSource();
|
||||
// PageState state = e.getPageState();
|
||||
//
|
||||
// BigDecimal typeId = form.getTypeID(state);
|
||||
// if (typeId != null) {
|
||||
// Long sectionId = form.getContentSectionID(state);
|
||||
// m_sectionSel.setSelectedKey(state, sectionId);
|
||||
// m_typeSel.setSelectedKey(state, typeId);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// });
|
||||
//
|
||||
// add(m_form);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Page p) {
|
||||
super.register(p);
|
||||
p.addComponentStateParam(this, m_sectionIdParam);
|
||||
}
|
||||
|
||||
// public StaticNewItemForm getNewItemForm() {
|
||||
//// return m_form;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
// private static class StaticNewItemForm extends NewItemForm {
|
||||
//
|
||||
// private final Hidden m_sectionIDParamWidget;
|
||||
//
|
||||
// public StaticNewItemForm(BigDecimalParameter sectionParam) {
|
||||
// super("StaticNewItemForm", BoxPanel.VERTICAL);
|
||||
// setClassAttr("static-new-item-form");
|
||||
// m_sectionIDParamWidget = new Hidden(sectionParam);
|
||||
// add(m_sectionIDParamWidget);
|
||||
// setProcessInvisible(true);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Sets the id of the content section in this form. This ID is used to
|
||||
// * generate a list of available content types in the section.
|
||||
// *
|
||||
// * @param state The current page state.
|
||||
// * @param id The id of the ContentSection for which this form should
|
||||
// * display a list of content types
|
||||
// *
|
||||
// * @pre ( state != null && id != null )
|
||||
// */
|
||||
// public void setSectionId(PageState state, BigDecimal id) {
|
||||
// Assert.exists(id);
|
||||
// m_sectionIDParamWidget.setValue(state, id);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Retrieves the content section for this form given the specified page
|
||||
// * state. This method will return null if there is no content section.
|
||||
// *
|
||||
// * @param state The current page state.
|
||||
// *
|
||||
// * @return The current content section or null if the section does not
|
||||
// * exist
|
||||
// *
|
||||
// * @pre ( state != null )
|
||||
// */
|
||||
// @Override
|
||||
// public ContentSection getContentSection(PageState state) {
|
||||
// Long id = getContentSectionID(state);
|
||||
// Assert.exists(id);
|
||||
// ContentSection section;
|
||||
// section = CdiUtil.createCdiUtil().findBean(
|
||||
// ContentSectionRepository.class).findById(id);
|
||||
// return section;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Retrieves the ID of the content section for this form given the
|
||||
// * specified page state. This method will return null if no content
|
||||
// * section id has been set.
|
||||
// *
|
||||
// * @param state The current page state.
|
||||
// *
|
||||
// * @return The id of the content section or null if it has not been set.
|
||||
// *
|
||||
// * @pre ( state != null )
|
||||
// */
|
||||
// private Long getContentSectionID(PageState state) {
|
||||
// return (Long) Long.parseLong((String) m_sectionIDParamWidget
|
||||
// .getValue(state));
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* A table that displays all content sections, with links to their locations
|
||||
* and admin pages and a {@link NewItemForm} next to each section.
|
||||
*
|
||||
* @author <a href="mailto:mbryzek@arsdigita.com">Michael Bryzek</a>
|
||||
* @version $Revision$ $DateTime: 2004/08/17 23:15:09 $
|
||||
*
|
||||
*/
|
||||
private class ContentSectionTable extends Table {
|
||||
|
||||
// We will use a (symboloc) headerKey to match columns. Because the
|
||||
// number of columns depends on configuration for the llocation column,
|
||||
// the index varies and con not be used.
|
||||
private static final String COLUMN_SECTION = "Section";
|
||||
private static final String COLUMN_LOCATION = "Public Site";
|
||||
private static final String COLUMN_ACTION = "Action";
|
||||
|
||||
/**
|
||||
* Constructs a new ContentSectionTable, using a default table model
|
||||
* builder.
|
||||
*/
|
||||
private ContentSectionTable() {
|
||||
super();
|
||||
|
||||
// we must use symbolic keys (instead of symbolic column index as
|
||||
// usual) to identify a column because their number is dynamic
|
||||
// depending on configuration of the location column!
|
||||
Integer colNo = 0;
|
||||
|
||||
Label emptyView = new Label(GlobalizationUtil
|
||||
.globalize("cms.ui.contentcenter.section"));
|
||||
emptyView.setFontWeight(Label.ITALIC);
|
||||
setEmptyView(emptyView);
|
||||
|
||||
setClassAttr("dataTable");
|
||||
|
||||
// add columns to the table
|
||||
TableColumnModel columnModel = getColumnModel();
|
||||
|
||||
// prepare column headers
|
||||
Label sectionHead = new Label(GlobalizationUtil
|
||||
.globalize("cms.ui.contentcenter.section"));
|
||||
sectionHead.setHint(GlobalizationUtil
|
||||
.globalize("cms.ui.contentcenter.section_hint"));
|
||||
Label locationHead = new Label(GlobalizationUtil
|
||||
.globalize("cms.ui.contentcenter.location"));
|
||||
locationHead.setHint(GlobalizationUtil
|
||||
.globalize("cms.ui.contentcenter.location_hint"));
|
||||
Label actionHead = new Label(GlobalizationUtil
|
||||
.globalize("cms.ui.contentcenter.action"));
|
||||
actionHead.setHint(GlobalizationUtil
|
||||
.globalize("cms.ui.contentcenter.action_hint"));
|
||||
|
||||
//TableColumn contentSectionColumn = new TableColumn(colNo, COLUMN_SECTION);
|
||||
TableColumn contentSectionColumn = new TableColumn(
|
||||
colNo,
|
||||
sectionHead,
|
||||
COLUMN_SECTION);
|
||||
contentSectionColumn
|
||||
.setCellRenderer(new AdminURLTableCellRenderer());
|
||||
columnModel.add(contentSectionColumn);
|
||||
|
||||
TableColumn actionColumn = new TableColumn(
|
||||
colNo++,
|
||||
actionHead,
|
||||
COLUMN_ACTION);
|
||||
actionColumn.setCellRenderer(new ActionTableCellRenderer());
|
||||
columnModel.add(actionColumn);
|
||||
|
||||
setModelBuilder(new ContentSectionTableModelBuilder());
|
||||
}
|
||||
|
||||
/**
|
||||
* An ContentSections table model builder
|
||||
*
|
||||
* @author <a href="mailto:mbryzek@arsdigita.com">Michael Bryzek</a>
|
||||
*
|
||||
*/
|
||||
private class ContentSectionTableModelBuilder extends LockableImpl
|
||||
implements TableModelBuilder {
|
||||
|
||||
@Override
|
||||
public TableModel makeModel(Table table, PageState state) {
|
||||
table.getRowSelectionModel().clearSelection(state);
|
||||
return new ContentSectionTableModel((ContentSectionTable) table,
|
||||
state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* An ContentSections table model
|
||||
*
|
||||
* @author <a href="mailto:mbryzek@arsdigita.com">Michael Bryzek</a>
|
||||
*
|
||||
*/
|
||||
private class ContentSectionTableModel implements TableModel {
|
||||
|
||||
private final ContentSectionTable m_table;
|
||||
private final TableColumnModel m_columnModel;
|
||||
private final PageState m_state;
|
||||
private final List<ContentSection> m_contentSections;
|
||||
private ContentSection m_section;
|
||||
private int index = -1;
|
||||
|
||||
private ContentSectionTableModel(ContentSectionTable table,
|
||||
PageState state) {
|
||||
m_table = table;
|
||||
m_columnModel = table.getColumnModel();
|
||||
m_state = state;
|
||||
|
||||
// retrieve all Content Sections
|
||||
m_contentSections = getContentSectionCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collection of ContentSections to display in this table.
|
||||
* This implementation orders the content sections by
|
||||
* <code>lower(label)</code>. They are also already filtered for the
|
||||
* sections to which the current user has no access.
|
||||
*
|
||||
*/
|
||||
private List<ContentSection> getContentSectionCollection() {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
final List<ContentSection> allSections = cdiUtil.findBean(
|
||||
ContentSectionRepository.class).findAll();
|
||||
return allSections
|
||||
.stream()
|
||||
.filter(section -> permissionChecker
|
||||
.isPermitted(CmsConstants.PRIVILEGE_ITEMS_VIEW_PUBLISHED,
|
||||
section))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return m_columnModel.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nextRow() {
|
||||
index++;
|
||||
if (index < m_contentSections.size()) {
|
||||
m_section = m_contentSections.get(index);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* By default, we return null. For the section, location, and action
|
||||
* columns, we return the current Content Section if there is one.
|
||||
*
|
||||
* @param columnIndex The index of the current column
|
||||
*/
|
||||
@Override
|
||||
public Object getElementAt(int columnIndex) {
|
||||
if (m_columnModel == null || m_section == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
TableColumn tc = m_columnModel.get(columnIndex);
|
||||
String columnKey = (String) tc.getHeaderKey();
|
||||
|
||||
Object result = m_section;
|
||||
if (columnKey.equals(COLUMN_SECTION)
|
||||
|| columnKey.equals(COLUMN_LOCATION)
|
||||
|| columnKey.equals(
|
||||
COLUMN_ACTION)) {
|
||||
result = m_section;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getKeyAt(int columnIndex) {
|
||||
return m_section.getObjectId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the table associated with this table model.
|
||||
*
|
||||
*/
|
||||
protected Table getTable() {
|
||||
return m_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current page state
|
||||
*
|
||||
*/
|
||||
protected PageState getPageState() {
|
||||
return m_state;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hidden parameter in the form containers form to the id of
|
||||
* the current section. Then returns the form for display, but only if
|
||||
* the user has permission to create new items in the current section.
|
||||
*
|
||||
* @author <a href="mailto:mbryzek@arsdigita.com">Michael Bryzek</a>
|
||||
*
|
||||
*/
|
||||
private class ActionTableCellRenderer implements TableCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getComponent(Table table, PageState state,
|
||||
Object value,
|
||||
boolean isSelected, Object key,
|
||||
int row, int column) {
|
||||
ContentSection section = (ContentSection) value;
|
||||
Category folder = null;
|
||||
//ToDo
|
||||
// User user = Web.getWebContext().getUser();
|
||||
// if (user != null) {
|
||||
// folder = Folder.getUserHomeFolder(user, section);
|
||||
// }
|
||||
// if (folder == null) {
|
||||
// folder = section.getRootFolder();
|
||||
// }
|
||||
|
||||
folder = section.getRootDocumentsFolder();
|
||||
// If the user has no access, return an empty Label
|
||||
|
||||
//
|
||||
// SecurityManager sm = new SecurityManager(section);
|
||||
//
|
||||
// if (!sm.canAccess(state.getRequest(), SecurityManager.NEW_ITEM,
|
||||
// folder)
|
||||
// || !ContentSection.getConfig()
|
||||
// .getAllowContentCreateInSectionListing()) {
|
||||
// // return null; // produces NPE here but works somewhere else.
|
||||
// // It's a kind of a hack. Label is supposed not to accept
|
||||
// // not-gloabalized data. Usually aou will return null here
|
||||
// // and xmlgenerator takes care of it. Doesn't work here.
|
||||
// return new Embedded(
|
||||
// " - - ");
|
||||
// } else {
|
||||
// // set the value of the sectionIdParameter in the form
|
||||
// // to this section
|
||||
// m_formContainer.getNewItemForm().setSectionId(state, section
|
||||
// .getID());
|
||||
// return m_formContainer.getNewItemForm();
|
||||
// }
|
||||
//ToDo End
|
||||
return new Embedded(
|
||||
" - - ");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the correct URL to the public pages for a content section.
|
||||
*
|
||||
* @author <a href="mailto:mbryzek@arsdigita.com">Michael Bryzek</a>
|
||||
*
|
||||
*/
|
||||
public static class URLTableCellRenderer implements TableCellRenderer {
|
||||
|
||||
/**
|
||||
* The object passed in is the current content section. This returns a
|
||||
* Link whose name and target are the url to the public pages.
|
||||
*
|
||||
* @return Link whose name and target are the url to the public pages of
|
||||
* the current (passed in) content section or a Label if current
|
||||
* use does not habe acces priviledge for the content section
|
||||
*/
|
||||
@Override
|
||||
public Component getComponent(Table table,
|
||||
PageState state,
|
||||
Object value,
|
||||
boolean isSelected,
|
||||
Object key,
|
||||
int row,
|
||||
int column) {
|
||||
|
||||
/* cast to ContentSection for further processing */
|
||||
ContentSection section = (ContentSection) value;
|
||||
String name = section.getLabel();
|
||||
String path = section.getPrimaryUrl(); // from Application
|
||||
|
||||
// If the user has no access, return a Label instead of a Link
|
||||
// Kind of a hack because Label is supposed not to accept
|
||||
// "un-globalized" display data. Label had been abused here to
|
||||
// to display a DataValue
|
||||
return new Embedded("/" + name + "/", false);
|
||||
// return null; // produces NPE here
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the correct URL to the admin pages for a content section.
|
||||
*
|
||||
* @author <a href="mailto:mbryzek@arsdigita.com">Michael Bryzek</a>
|
||||
*
|
||||
*/
|
||||
public static class AdminURLTableCellRenderer extends URLTableCellRenderer {
|
||||
|
||||
/**
|
||||
* The object passed in is the current content section
|
||||
*
|
||||
* @param table
|
||||
* @param state
|
||||
* @param row
|
||||
* @param value
|
||||
* @param column
|
||||
* @param isSelected
|
||||
* @param key
|
||||
*
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public Component getComponent(Table table, PageState state, Object value,
|
||||
boolean isSelected, Object key,
|
||||
int row, int column) {
|
||||
ContentSection section = (ContentSection) value;
|
||||
|
||||
final PermissionChecker permissionChecker = CdiUtil.createCdiUtil()
|
||||
.findBean(PermissionChecker.class);
|
||||
|
||||
// If the user has no access, return a Label instead of a Link
|
||||
if (permissionChecker.isPermitted(
|
||||
CmsConstants.PRIVILEGE_ITEMS_EDIT,
|
||||
section.getRootDocumentsFolder())) {
|
||||
|
||||
return new Link(section.getLabel(),
|
||||
generateURL(section.getPrimaryUrl() + "/"));
|
||||
} else {
|
||||
//return new Label(section.getName(), false);
|
||||
// return null; // Produces a NPE although it shouldn't and
|
||||
// indeed doesn't elsewhere
|
||||
// Kind of a hack because Label is supposed not to accept
|
||||
// "un-globalized" display data. Label had been abused here to
|
||||
// to display a DataValue
|
||||
return new Embedded(section.getLabel(), false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the admin url for the specified prefix. Always returns
|
||||
* something that does not start with a forward slash.
|
||||
*
|
||||
* @param prefix The prefix of the URL
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected String generateURL(String prefix) {
|
||||
return prefix;// + PageLocations.SECTION_PAGE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -75,8 +75,12 @@ public class TasksPanel extends CMSContainer {
|
|||
// private ActionLink m_viewAllLink;
|
||||
// private ActionLink m_viewShortLink;
|
||||
private Paginator m_paginator;
|
||||
private ActionLink m_viewLockLink, m_viewUnlockLink, m_viewAllLockLink;
|
||||
private Label m_viewLockLabel, m_viewUnlockLabel, m_viewAllLockLabel;
|
||||
private ActionLink m_viewLockLink;
|
||||
private ActionLink m_viewUnlockLink;
|
||||
private ActionLink m_viewAllLockLink;
|
||||
private Label m_viewLockLabel;
|
||||
private Label m_viewUnlockLabel;
|
||||
private Label m_viewAllLockLabel;
|
||||
private StringParameter m_sortDirectionParam;
|
||||
private StringParameter m_sortTypeParam;
|
||||
private StringParameter m_lockFilterParam;
|
||||
|
|
@ -103,7 +107,7 @@ public class TasksPanel extends CMSContainer {
|
|||
private Label m_selectorLabel;
|
||||
//ToDo
|
||||
// private CreationSelector m_selector;
|
||||
// private ContentSectionContainer m_sections;
|
||||
private ContentSectionContainer m_sections;
|
||||
// ToDo End
|
||||
private CcmObjectSelectionModel m_sectionSel;
|
||||
private CcmObjectSelectionModel m_typeSel;
|
||||
|
|
@ -134,7 +138,8 @@ public class TasksPanel extends CMSContainer {
|
|||
* @pre maxRows != null
|
||||
*
|
||||
*/
|
||||
public TasksPanel(int maxRows, CcmObjectSelectionModel typeModel,
|
||||
public TasksPanel(int maxRows,
|
||||
CcmObjectSelectionModel typeModel,
|
||||
CcmObjectSelectionModel sectionModel) {
|
||||
super();
|
||||
|
||||
|
|
@ -192,14 +197,13 @@ public class TasksPanel extends CMSContainer {
|
|||
// m_selector = new CreationSelector(m_typeSel, m_folderSel);
|
||||
// m_creationPane.add(m_selector);
|
||||
//ToDo End
|
||||
|
||||
m_creationPane.setClassAttr("itemCreationPane");
|
||||
add(m_creationPane);
|
||||
|
||||
// The section list UIx
|
||||
//ToDo
|
||||
// m_sections = new ContentSectionContainer(m_typeSel, m_sectionSel);
|
||||
// add(m_sections);
|
||||
m_sections = new ContentSectionContainer(m_typeSel, m_sectionSel);
|
||||
add(m_sections);
|
||||
//ToDo End
|
||||
// When a new type is selected, show the creation UI.
|
||||
// When the selection is cleared, return to section list
|
||||
|
|
@ -444,8 +448,6 @@ public class TasksPanel extends CMSContainer {
|
|||
// query.addEqualsFilter("isLocked", "f");
|
||||
// } // else show all
|
||||
// }
|
||||
|
||||
|
||||
// private static class RootFolderSelectionModel
|
||||
// extends FolderSelectionModel {
|
||||
//
|
||||
|
|
@ -474,7 +476,6 @@ public class TasksPanel extends CMSContainer {
|
|||
//
|
||||
// }
|
||||
//ToDo End
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -512,9 +513,8 @@ public class TasksPanel extends CMSContainer {
|
|||
//
|
||||
// return query;
|
||||
// }
|
||||
|
||||
public int size(PageState ps) {
|
||||
return ((Long) m_taskCount.get(ps)).intValue();
|
||||
return ((Integer)m_taskCount.get(ps)).intValue();
|
||||
}
|
||||
|
||||
private RequestLocal m_taskCount = new RequestLocal() {
|
||||
|
|
@ -523,7 +523,7 @@ public class TasksPanel extends CMSContainer {
|
|||
public Object initialValue(PageState state) {
|
||||
// DataQuery query = makeQuery(state);
|
||||
// return new Long(query.size());
|
||||
return null;
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -536,7 +536,6 @@ return null;
|
|||
exportAttributes(content);
|
||||
|
||||
// DataQuery query = makeQuery(state);
|
||||
|
||||
String lockFilterType = getLockFilterType(state);
|
||||
content.addAttribute("lockFilterType", lockFilterType);
|
||||
|
||||
|
|
@ -664,18 +663,18 @@ return null;
|
|||
// String.valueOf(
|
||||
// ContentItemPage.AUTHORING_TAB));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// m_actionLabel.generateXML(state, content);
|
||||
String[][] sortableHeaders = {{SORT_TITLE,
|
||||
"cms.ui.workflow.task.item_title"},
|
||||
{SORT_ACTION, "cms.ui.action"},
|
||||
{SORT_DATE, "cms.ui.tasks_due_date"},
|
||||
{SORT_STATUS,
|
||||
"cms.ui.tasks_status_no_colon"},
|
||||
{SORT_USER,
|
||||
"cms.ui.workflow.task.locking_user"},
|
||||
{SORT_WORKFLOW, "cms.ui.workflow"}};
|
||||
// m_actionLabel.generateXML(state, content);
|
||||
String[][] sortableHeaders = {{SORT_TITLE,
|
||||
"cms.ui.workflow.task.item_title"},
|
||||
{SORT_ACTION, "cms.ui.action"},
|
||||
{SORT_DATE, "cms.ui.tasks_due_date"},
|
||||
{SORT_STATUS,
|
||||
"cms.ui.tasks_status_no_colon"},
|
||||
{SORT_USER,
|
||||
"cms.ui.workflow.task.locking_user"},
|
||||
{SORT_WORKFLOW, "cms.ui.workflow"}};
|
||||
// for (int i = 0; i < sortableHeaders.length; i++) {
|
||||
// String header = sortableHeaders[i][0];
|
||||
// String labelKey = sortableHeaders[i][1];
|
||||
|
|
@ -705,14 +704,15 @@ return null;
|
|||
// link.generateXML(state, content);
|
||||
// state.clearControlEvent();
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void respond(PageState state) throws ServletException {
|
||||
String key = state.getControlEventName();
|
||||
String value = state.getControlEventValue();
|
||||
if (TASK_ACTION.equals(key)) {
|
||||
BigDecimal itemID = new BigDecimal(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void respond(PageState state) throws ServletException {
|
||||
String key = state.getControlEventName();
|
||||
String value = state.getControlEventValue();
|
||||
if (TASK_ACTION.equals(key)) {
|
||||
BigDecimal itemID = new BigDecimal(value);
|
||||
//
|
||||
// try {
|
||||
// ContentItem item = new ContentItem(itemID);
|
||||
|
|
@ -751,7 +751,7 @@ return null;
|
|||
// throw new ServletException("Unknown content ID" + itemID);
|
||||
// }
|
||||
// } else
|
||||
if (SORT_UP.equals(key) || SORT_DOWN.equals(key)) {
|
||||
if (SORT_UP.equals(key) || SORT_DOWN.equals(key)) {
|
||||
state.setValue(m_sortTypeParam, value);
|
||||
if (SORT_DOWN.equals(key)) {
|
||||
state.setValue(m_sortDirectionParam, SORT_DOWN);
|
||||
|
|
@ -776,5 +776,4 @@ return null;
|
|||
// return PermissionService.getFilterQuery(factory, "itemID", privilege,
|
||||
// partyOID);
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@
|
|||
*/
|
||||
package org.librecms;
|
||||
|
||||
import com.arsdigita.cms.ContentCenterAppCreator;
|
||||
import com.arsdigita.cms.ContentCenterServlet;
|
||||
import com.arsdigita.cms.ContentCenterSetup;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.core.CoreConstants;
|
||||
|
|
@ -14,6 +18,7 @@ import org.libreccm.modules.RequiredModule;
|
|||
import org.libreccm.modules.ShutdownEvent;
|
||||
import org.libreccm.modules.UnInstallEvent;
|
||||
import org.libreccm.web.ApplicationType;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentSectionCreator;
|
||||
import org.librecms.contentsection.ContentSectionSetup;
|
||||
|
|
@ -29,6 +34,13 @@ import java.util.Properties;
|
|||
@RequiredModule(module = org.libreccm.core.CcmCore.class)
|
||||
},
|
||||
applicationTypes = {
|
||||
@ApplicationType(
|
||||
name = CmsConstants.CONTENT_CENTER_APP_TYPE,
|
||||
applicationClass = CcmApplication.class,
|
||||
descBundle = CmsConstants.CONTENT_CENTER_DESC_BUNDLE,
|
||||
creator = ContentCenterAppCreator.class,
|
||||
servlet = ContentCenterServlet.class
|
||||
),
|
||||
@ApplicationType(
|
||||
name = CmsConstants.CONTENT_SECTION_APP_TYPE,
|
||||
applicationClass = ContentSection.class,
|
||||
|
|
@ -66,6 +78,12 @@ public class Cms implements CcmModule {
|
|||
ex);
|
||||
}
|
||||
|
||||
LOGGER.info("Setting content center...");
|
||||
final ContentCenterSetup contentCenterSetup = new ContentCenterSetup(
|
||||
event);
|
||||
contentCenterSetup.setup();
|
||||
|
||||
LOGGER.info("Setting up content sections...");
|
||||
final ContentSectionSetup contentSectionSetup = new ContentSectionSetup(
|
||||
event);
|
||||
contentSectionSetup.setup();
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ public class CmsConstants {
|
|||
|
||||
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_DESC_BUNDLE = "org.librecms.contentcenter.ContentCenterResources";
|
||||
|
||||
public static final String CONTENT_SECTION_APP_TYPE
|
||||
= "org.librecms.contentsection.ContentSection";
|
||||
|
|
|
|||
|
|
@ -19,11 +19,14 @@
|
|||
package org.librecms.contentsection;
|
||||
|
||||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.workflow.WorkflowTemplate;
|
||||
import org.librecms.lifecycle.LifecycleDefinition;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -32,10 +35,88 @@ import javax.enterprise.context.RequestScoped;
|
|||
@RequestScoped
|
||||
public class ContentItemManager {
|
||||
|
||||
@Inject
|
||||
private ContentItemRepository contentItemRepo;
|
||||
|
||||
/**
|
||||
* Creates a new content item in the provided content section and folder
|
||||
* with the default lifecycle and workflow.
|
||||
*
|
||||
* The folder must be a subfolder of the
|
||||
* {@link ContentSection#rootDocumentsFolder} of the provided content
|
||||
* section. Otherwise an {@link IllegalArgumentException} is thrown.
|
||||
*
|
||||
* @param <T> The type of the content item.
|
||||
* @param name The name (URL stub) of the new content item.
|
||||
* @param section The content section in which the item is generated.
|
||||
* @param folder The folder in which in the item is stored.
|
||||
* @param type The type of the new content item.
|
||||
*
|
||||
* @return The new content item.
|
||||
*/
|
||||
public <T extends ContentItem> T createContentItem(
|
||||
final String name,
|
||||
final ContentSection section,
|
||||
final Category folder,
|
||||
final Class<T> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new content item in the provided content section and folder
|
||||
* with the provided lifecycle and workflow.
|
||||
*
|
||||
* The folder must be a subfolder of the
|
||||
* {@link ContentSection#rootDocumentsFolder} of the provided content
|
||||
* section. Otherwise an {@link IllegalArgumentException} is thrown.
|
||||
*
|
||||
* Likewise the provided {@link LifecycleDefinition} and
|
||||
* {@link WorkflowTemplate} must be defined in the provided content section.
|
||||
* Otherwise an {@link IllegalArgumentException} is thrown.
|
||||
*
|
||||
* @param <T> The type of the content item.
|
||||
* @param name The name (URL stub) of the new content item.
|
||||
* @param section The content section in which the item is
|
||||
* generated.
|
||||
* @param folder The folder in which in the item is stored.
|
||||
* @param workflowTemplate
|
||||
* @param lifecycleDefinition
|
||||
* @param type The type of the new content item.
|
||||
*
|
||||
* @return The new content item.
|
||||
*/
|
||||
public <T extends ContentItem> T createContentItem(
|
||||
final String name,
|
||||
final ContentSection section,
|
||||
final Category folder,
|
||||
final WorkflowTemplate workflowTemplate,
|
||||
final LifecycleDefinition lifecycleDefinition,
|
||||
final Class<T> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a content item to another folder in the same content section. This
|
||||
* only moves the draft version of the item. The live version is moved after
|
||||
* a the item is republished.
|
||||
*
|
||||
* @param item The item to move.
|
||||
* @param targetFolder The folder to which the item is moved.
|
||||
*/
|
||||
public void move(final ContentItem item, final Category targetFolder) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an copy of the draft version of the item in the provided
|
||||
* {@code targetFolder}.
|
||||
*
|
||||
* @param item The item to copy.
|
||||
* @param targetFolder The folder in which the copy is created. If the
|
||||
* target folder is the same folder as the folder of the
|
||||
* original item an index is appended to the name of the
|
||||
* item.
|
||||
*/
|
||||
public void copy(final ContentItem item, final Category targetFolder) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
|
@ -65,6 +146,7 @@ public class ContentItemManager {
|
|||
* Determines if a content item has a live version.
|
||||
*
|
||||
* @param item The item
|
||||
*
|
||||
* @return {@code true} if the content item has a live version,
|
||||
* {@code false} if not.
|
||||
*/
|
||||
|
|
@ -75,10 +157,14 @@ public class ContentItemManager {
|
|||
/**
|
||||
* Retrieves the live version of the provided content item if any.
|
||||
*
|
||||
* @param <T>
|
||||
* @param item
|
||||
* @param type
|
||||
* @return
|
||||
* @param <T> Type of the content item.
|
||||
* @param item The item of which the live version should be retrieved.
|
||||
* @param type Type of the content item.
|
||||
*
|
||||
* @return The live version of an item. If the item provided is already the
|
||||
* live version the provided item is returned, otherwise the live
|
||||
* version is returned. If there is no live version an empty
|
||||
* {@link Optional} is returned.
|
||||
*/
|
||||
public <T extends ContentItem> Optional<T> getLiveVersion(
|
||||
final ContentItem item,
|
||||
|
|
@ -86,11 +172,37 @@ public class ContentItemManager {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public <T extends ContentItem> List<T> getPendingVersions() {
|
||||
/**
|
||||
* Retrieves the pending versions of an item if there are any.
|
||||
*
|
||||
* @param <T> Type of the content item to retrieve.
|
||||
* @param item The item of which the pending versions are retrieved.
|
||||
* @param type Type of the content item to retrieve.
|
||||
*
|
||||
* @return A list of the pending versions of the item.
|
||||
*/
|
||||
public <T extends ContentItem> List<T> getPendingVersions(
|
||||
final ContentItem item,
|
||||
final Class<T> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public <T extends ContentItem> T getDraftVersion(final ContentItem item) {
|
||||
/**
|
||||
* Retrieves the draft version
|
||||
*
|
||||
* @param <T> Type of the item.
|
||||
* @param item The item of which the draft version is retrieved.
|
||||
* @param type Type of the item.
|
||||
*
|
||||
* @return The draft version of the provided content item. If the provided
|
||||
* item is the draft version the provided item is simply returned.
|
||||
* Otherwise the draft version is retrieved from the database and is
|
||||
* returned. Each content item has a draft version (otherwise
|
||||
* something is seriously wrong with the database) this method will
|
||||
* <b>never</b> return {@code null}.
|
||||
*/
|
||||
public <T extends ContentItem> T getDraftVersion(final ContentItem item,
|
||||
final Class<T> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,17 +24,19 @@ import org.libreccm.core.CcmObject;
|
|||
import org.libreccm.core.CcmObjectRepository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Repository for content items.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
public class ContentItemRepository
|
||||
extends AbstractAuditedEntityRepository<Long, ContentItem>{
|
||||
extends AbstractAuditedEntityRepository<Long, ContentItem> {
|
||||
|
||||
@Inject
|
||||
private CcmObjectRepository ccmObjectRepo;
|
||||
|
|
@ -54,20 +56,47 @@ public class ContentItemRepository
|
|||
return ccmObjectRepo.isNew(item);
|
||||
}
|
||||
|
||||
public ContentItem findById(final long itemId) {
|
||||
/**
|
||||
* Finds a content item by is id.
|
||||
*
|
||||
* @param itemId The id of item to retrieve.
|
||||
*
|
||||
* @return The content item identified by the provided {@code itemId} or
|
||||
* nothing if there is such content item.
|
||||
*/
|
||||
public Optional<ContentItem> findById(final long itemId) {
|
||||
final CcmObject result = ccmObjectRepo.findObjectById(itemId);
|
||||
if (result instanceof ContentItem) {
|
||||
return (ContentItem) result;
|
||||
return Optional.of((ContentItem) result);
|
||||
} else {
|
||||
return null;
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends ContentItem> T findById(final long itemId,
|
||||
final Class<T> type) {
|
||||
/**
|
||||
* Finds a content item by its ID and ensures that is a the requested type.
|
||||
*
|
||||
* @param <T> The type of the content item.
|
||||
* @param itemId The id of item to retrieve.
|
||||
* @param type The type of the content item.
|
||||
*
|
||||
* @return The content item identified by the provided id or an empty
|
||||
* {@link Optional} if there is no such item or if it is not of the
|
||||
* requested type.
|
||||
*/
|
||||
public <T extends ContentItem> Optional<T> findById(final long itemId,
|
||||
final Class<T> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a content item by is UUID.
|
||||
*
|
||||
* @param uuid The id of item to retrieve.
|
||||
*
|
||||
* @return The content item identified by the provided {@code uuid} or
|
||||
* nothing if there is such content item.
|
||||
*/
|
||||
public ContentItem findByUuid(final String uuid) {
|
||||
final CcmObject result = ccmObjectRepo.findObjectByUuid(uuid);
|
||||
if (result instanceof ContentItem) {
|
||||
|
|
@ -77,15 +106,39 @@ public class ContentItemRepository
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a content item by its UUID and ensures that is a the requested type.
|
||||
*
|
||||
* @param <T> The type of the content item.
|
||||
* @param uuid The UUID of item to retrieve.
|
||||
* @param type The type of the content item.
|
||||
*
|
||||
* @return The content item identified by the provided UUID or an empty
|
||||
* {@link Optional} if there is no such item or if it is not of the
|
||||
* requested type.
|
||||
*/
|
||||
public <T extends ContentItem> T findByUuid(final String uuid,
|
||||
final Class<T> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all content items of a specific type.
|
||||
*
|
||||
* @param <T> The type of the items.
|
||||
* @param type The type of the items.
|
||||
* @return A list of all content items of the requested type.
|
||||
*/
|
||||
public <T extends ContentItem> List<T> findByType(final Class<T> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all content items in the provided folder.
|
||||
*
|
||||
* @param folder The folder.
|
||||
* @return A list of all items in the provided folder.
|
||||
*/
|
||||
public List<ContentItem> findByFolder(final Category folder) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import org.libreccm.security.Role;
|
|||
import org.libreccm.web.AbstractCcmApplicationSetup;
|
||||
import org.librecms.CmsConstants;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.librecms.CmsConstants.*;
|
||||
|
|
@ -54,8 +53,13 @@ public class ContentSectionSetup extends AbstractCcmApplicationSetup {
|
|||
if (getIntegrationProps().containsKey(INITIAL_CONTENT_SECTIONS)) {
|
||||
sectionNames = getIntegrationProps().getProperty(
|
||||
INITIAL_CONTENT_SECTIONS);
|
||||
LOGGER.info(
|
||||
"Found names for initial content sections in integration "
|
||||
+ "properties: {}", sectionNames);
|
||||
} else {
|
||||
sectionNames = "info";
|
||||
LOGGER.info("No initial content sections definied integration "
|
||||
+ "properties, using default: {}", sectionNames);
|
||||
}
|
||||
|
||||
for (final String contentSectionName : sectionNames.split(",")) {
|
||||
|
|
@ -64,13 +68,27 @@ public class ContentSectionSetup extends AbstractCcmApplicationSetup {
|
|||
}
|
||||
|
||||
private void createContentSection(final String sectionName) {
|
||||
LOGGER.debug("Creating content section with section name \"{}\"...",
|
||||
sectionName);
|
||||
final ContentSection section = new ContentSection();
|
||||
section.setUuid(UUID.randomUUID().toString());
|
||||
section.setApplicationType(CmsConstants.CONTENT_SECTION_APP_TYPE);
|
||||
section.setPrimaryUrl(sectionName);
|
||||
section.setPrimaryUrl(String.format("/%s/", sectionName));
|
||||
section.setDisplayName(sectionName);
|
||||
section.setLabel(sectionName);
|
||||
|
||||
LOGGER.debug("New content section properties: "
|
||||
+ "uuid = {}; "
|
||||
+ "applicationType = \"{}\"; "
|
||||
+ "primaryUrl = \"{}\"; "
|
||||
+ "displayName = \"{}\"; "
|
||||
+ "label = \"{}\"",
|
||||
section.getUuid(),
|
||||
section.getApplicationType(),
|
||||
section.getPrimaryUrl(),
|
||||
section.getDisplayName(),
|
||||
section.getLabel());
|
||||
|
||||
final Category rootFolder = new Category();
|
||||
rootFolder.setUuid(UUID.randomUUID().toString());
|
||||
rootFolder.setUniqueId(rootFolder.getUuid());
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ import static org.librecms.CmsConstants.*;
|
|||
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.l10n.LocalizedString;
|
||||
import org.libreccm.workflow.Workflow;
|
||||
import org.librecms.lifecycle.Lifecycle;
|
||||
import org.libreccm.workflow.WorkflowTemplate;
|
||||
import org.librecms.lifecycle.LifecycleDefinition;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
|
@ -98,11 +98,11 @@ public class ContentType extends CcmObject implements Serializable {
|
|||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "DEFAULT_LIFECYCLE_ID")
|
||||
private Lifecycle defaultLifecycle;
|
||||
private LifecycleDefinition defaultLifecycle;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "DEFAULT_WORKFLOW")
|
||||
private Workflow defaultWorkflow;
|
||||
private WorkflowTemplate defaultWorkflow;
|
||||
|
||||
public String getContentItemClass() {
|
||||
return contentItemClass;
|
||||
|
|
@ -160,19 +160,19 @@ public class ContentType extends CcmObject implements Serializable {
|
|||
this.mode = mode;
|
||||
}
|
||||
|
||||
public Lifecycle getDefaultLifecycle() {
|
||||
public LifecycleDefinition getDefaultLifecycle() {
|
||||
return defaultLifecycle;
|
||||
}
|
||||
|
||||
protected void setDefaultLifecycle(final Lifecycle defaultLifecycle) {
|
||||
protected void setDefaultLifecycle(final LifecycleDefinition defaultLifecycle) {
|
||||
this.defaultLifecycle = defaultLifecycle;
|
||||
}
|
||||
|
||||
public Workflow getDefaultWorkflow() {
|
||||
public WorkflowTemplate getDefaultWorkflow() {
|
||||
return defaultWorkflow;
|
||||
}
|
||||
|
||||
protected void setDefaultWorkflow(final Workflow defaultWorkflow) {
|
||||
protected void setDefaultWorkflow(final WorkflowTemplate defaultWorkflow) {
|
||||
this.defaultWorkflow = defaultWorkflow;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
alter table CCM_CMS.CONTENT_TYPES
|
||||
drop constraint FKoqvcvktnvt4ncx5k6daqat4u8;
|
||||
|
||||
alter table CCM_CMS.CONTENT_TYPES
|
||||
drop constraint FKpgeccqsr50xwb268ypmfx0r66;
|
||||
|
||||
alter table CCM_CMS.CONTENT_TYPES
|
||||
add constraint FK8s83we1tuh9r3j57dyos69wfa
|
||||
foreign key (DEFAULT_LIFECYCLE_ID)
|
||||
references CCM_CMS.LIFECYLE_DEFINITIONS;
|
||||
|
||||
alter table CCM_CMS.CONTENT_TYPES
|
||||
add constraint FKhnu9oikw8rpf22lt5fmk41t7k
|
||||
foreign key (DEFAULT_WORKFLOW)
|
||||
references CCM_CORE.WORKFLOW_TEMPLATES;
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
alter table CCM_CMS.CONTENT_TYPES
|
||||
drop constraint FKoqvcvktnvt4ncx5k6daqat4u8;
|
||||
|
||||
alter table CCM_CMS.CONTENT_TYPES
|
||||
drop constraint FKpgeccqsr50xwb268ypmfx0r66;
|
||||
|
||||
alter table CCM_CMS.CONTENT_TYPES
|
||||
add constraint FK8s83we1tuh9r3j57dyos69wfa
|
||||
foreign key (DEFAULT_LIFECYCLE_ID)
|
||||
references CCM_CMS.LIFECYLE_DEFINITIONS;
|
||||
|
||||
alter table CCM_CMS.CONTENT_TYPES
|
||||
add constraint FKhnu9oikw8rpf22lt5fmk41t7k
|
||||
foreign key (DEFAULT_WORKFLOW)
|
||||
references CCM_CORE.WORKFLOW_TEMPLATES;
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
application_title=Content Center
|
||||
application_desc=Content Center application
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
application_title=Content Center
|
||||
application_desc=Content Center application
|
||||
|
|
@ -31,7 +31,9 @@ import org.libreccm.tests.categories.UnitTest;
|
|||
import org.libreccm.testutils.EqualsVerifier;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
import org.libreccm.workflow.Workflow;
|
||||
import org.libreccm.workflow.WorkflowTemplate;
|
||||
import org.librecms.lifecycle.Lifecycle;
|
||||
import org.librecms.lifecycle.LifecycleDefinition;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
|
@ -137,17 +139,17 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
|||
final Resource resource2 = new Resource();
|
||||
resource2.setDisplayName("Resource 2");
|
||||
|
||||
final Lifecycle lifecycle1 = new Lifecycle();
|
||||
lifecycle1.setFinished(true);
|
||||
final LifecycleDefinition lifecycleDef1 = new LifecycleDefinition();
|
||||
lifecycleDef1.setDefinitionId(-100);
|
||||
|
||||
final Lifecycle lifecycle2 = new Lifecycle();
|
||||
lifecycle2.setFinished(false);
|
||||
final LifecycleDefinition lifecycleDef2 = new LifecycleDefinition();
|
||||
lifecycleDef2.setDefinitionId(-110);
|
||||
|
||||
final Workflow workflow1 = new Workflow();
|
||||
workflow1.setWorkflowId(-100);
|
||||
final WorkflowTemplate workflowTemplate1 = new WorkflowTemplate();
|
||||
workflowTemplate1.setWorkflowId(-200);
|
||||
|
||||
final Workflow workflow2 = new Workflow();
|
||||
workflow2.setWorkflowId(-200);
|
||||
final WorkflowTemplate workflowTemplate2 = new WorkflowTemplate();
|
||||
workflowTemplate2.setWorkflowId(-210);
|
||||
|
||||
verifier
|
||||
.withPrefabValues(ContentItem.class, item1, item2)
|
||||
|
|
@ -161,8 +163,12 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
|||
.withPrefabValues(CcmApplication.class, application1, application2)
|
||||
.withPrefabValues(Domain.class, domain1, domain2)
|
||||
.withPrefabValues(Resource.class, resource1, resource2)
|
||||
.withPrefabValues(Lifecycle.class, lifecycle1, lifecycle2)
|
||||
.withPrefabValues(Workflow.class, workflow1, workflow2);
|
||||
.withPrefabValues(LifecycleDefinition.class,
|
||||
lifecycleDef1,
|
||||
lifecycleDef2)
|
||||
.withPrefabValues(WorkflowTemplate.class,
|
||||
workflowTemplate1,
|
||||
workflowTemplate2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -187,6 +187,11 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.primefaces</groupId>
|
||||
<artifactId>primefaces</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Export Import Libraries -->
|
||||
|
||||
<dependency>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Peter Boy, University of Bremen. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
package com.arsdigita.bebop;
|
||||
|
||||
import static com.arsdigita.bebop.Component.BEBOP_XML_NS;
|
||||
import com.arsdigita.bebop.event.PrintEvent;
|
||||
import com.arsdigita.bebop.event.PrintListener;
|
||||
import com.arsdigita.xml.Element;
|
||||
|
||||
/**
|
||||
* Injects arbitrary content as a String into the xml output. It is not for
|
||||
* any semantic type of data und it is not localizable. Specifically it is
|
||||
* meant for data as Javascript and alike.
|
||||
*
|
||||
* It generates some fixed string to be included in the XML output.
|
||||
*
|
||||
* It resembles the Label methods for String parameters and currently
|
||||
* generates the same XML attributes in order to avoid any need to modify the
|
||||
* themes.
|
||||
*
|
||||
* @author pb
|
||||
*/
|
||||
public class Embedded extends SimpleComponent {
|
||||
|
||||
private final String m_content;
|
||||
/** The setting for output escaping affects how markup in the
|
||||
* <code>content</code> is handled.
|
||||
* <UL><LI>If output escaping is in effect (true), <b>example</b>
|
||||
* will appear literally.</LI>
|
||||
* <LI>If output escaping is disabled, <b>example</b> appears as the
|
||||
* String "example" in bold (i.e. retaining the markup.</LI></UL>
|
||||
* Default is false. */
|
||||
private boolean m_escaping = false; // default for a primitive
|
||||
private PrintListener m_printListener;
|
||||
|
||||
/**
|
||||
* Default constructor creates a new <code>Embedded</code> with the empty
|
||||
* content.
|
||||
*
|
||||
* @param content
|
||||
*/
|
||||
public Embedded() {
|
||||
m_content = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor creates a new <code>Embedded</code> with the specified
|
||||
* (fixed) content.
|
||||
*
|
||||
* @param content
|
||||
*/
|
||||
public Embedded(String content) {
|
||||
m_content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor creates a new <code>Embedded</code> with the specified
|
||||
* content and output escaping turned on if <code>escaping</code> is
|
||||
* <code>true</code>.
|
||||
*
|
||||
* The setting for output escaping affects how markup in the
|
||||
* <code>content</code> is handled. For example: <UL><LI>If output escaping
|
||||
* is in effect, <b>content</b> will appear literally.</LI> <LI>If
|
||||
* output escaping is disabled, <b>content</b> appears as the String
|
||||
* "context" in bold.</LI></UL>
|
||||
*
|
||||
* @param content the content to inject into the output.
|
||||
* @param escaping <code>true</code> if output escaping will be in effect;
|
||||
* <code>false</code> if output escaping will be disabled
|
||||
*/
|
||||
public Embedded(String content, boolean escaping) {
|
||||
m_content = content;
|
||||
m_escaping = escaping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the (J)DOM fragment for a embedded.
|
||||
* <p><pre>
|
||||
* <bebop:link href="..." type="..." %bebopAttr;/>
|
||||
* </pre>
|
||||
*
|
||||
* @param state The current {@link PageState}.
|
||||
* @param parent The XML element to attach the XML to.
|
||||
*/
|
||||
@Override
|
||||
public void generateXML(PageState state, Element parent) {
|
||||
|
||||
if (!isVisible(state)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Embedded target = firePrintEvent(state);
|
||||
|
||||
Element content = parent.newChildElement("bebop:label", BEBOP_XML_NS);
|
||||
target.exportAttributes(content);
|
||||
|
||||
if (!target.m_escaping) {
|
||||
content.addAttribute("escape", "yes");
|
||||
} else {
|
||||
content.addAttribute("escape", "no");
|
||||
}
|
||||
|
||||
content.setText(m_content);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param state
|
||||
* @return
|
||||
*/
|
||||
protected Embedded firePrintEvent(PageState state) {
|
||||
Embedded e = this;
|
||||
|
||||
if (m_printListener != null) {
|
||||
try {
|
||||
e = (Embedded) this.clone();
|
||||
m_printListener.prepare(new PrintEvent(this, state, e));
|
||||
} catch (CloneNotSupportedException nse) {
|
||||
throw new RuntimeException(
|
||||
"Couldn't clone Embedded for PrintListener. "
|
||||
+ "This probably indicates a serious programming error: "
|
||||
+ nse.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -437,7 +437,7 @@ public class CCMDispatcherServlet extends BaseServlet {
|
|||
m_typeURI = servletAnnotation.urlPatterns()[0];
|
||||
}
|
||||
} else {
|
||||
m_typeURI = "";
|
||||
m_typeURI = appType.servletPath();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.libreccm.admin.ui;
|
||||
|
||||
import org.libreccm.web.ApplicationCreator;
|
||||
import org.libreccm.web.ApplicationRepository;
|
||||
import org.libreccm.web.ApplicationType;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
public class AdminJsfApplicationCreator implements ApplicationCreator<CcmApplication>{
|
||||
|
||||
@Inject
|
||||
private ApplicationRepository appRepo;
|
||||
|
||||
@Override
|
||||
public CcmApplication createInstance(final String primaryUrl,
|
||||
final ApplicationType type) {
|
||||
if ("org.libreccm.ui.admin.AdminFaces".equals(primaryUrl)) {
|
||||
throw new IllegalArgumentException(
|
||||
"CCM Admin Faces is a singleton application"
|
||||
+ "which is mounted at /admin-jsf");
|
||||
}
|
||||
|
||||
return appRepo.retrieveApplicationForPath(primaryUrl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.libreccm.admin.ui;
|
||||
|
||||
import org.libreccm.modules.InstallEvent;
|
||||
import org.libreccm.web.AbstractCcmApplicationSetup;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class AdminJsfApplicationSetup extends AbstractCcmApplicationSetup {
|
||||
|
||||
public static final String ADMIN_APP_NAME = "CcmAdminJsf";
|
||||
|
||||
public AdminJsfApplicationSetup(final InstallEvent event) {
|
||||
super(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
final CcmApplication admin = new CcmApplication();
|
||||
admin.setUuid(UUID.randomUUID().toString());
|
||||
admin.setApplicationType("org.libreccm.ui.admin.AdminFaces");
|
||||
admin.setPrimaryUrl("/admin-jsf/");
|
||||
|
||||
getEntityManager().persist(admin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ import java.util.List;
|
|||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a>
|
||||
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
|
||||
* @param <K> Primary key of the entity.
|
||||
* @param <T> Type of the entity
|
||||
*/
|
||||
|
|
@ -42,6 +42,7 @@ public abstract class AbstractAuditedEntityRepository<K, T>
|
|||
|
||||
public abstract K getEntityId(final T entity);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T retrieveRevisionOfEntity(final T entity, final Number revision) {
|
||||
final AuditQuery query = auditReader.createQuery()
|
||||
.forEntitiesAtRevision(getEntityClass(), revision);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ import javax.persistence.EntityManager;
|
|||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.admin.ui.AdminJsfApplicationCreator;
|
||||
import org.libreccm.admin.ui.AdminJsfApplicationSetup;
|
||||
|
||||
import org.libreccm.modules.CcmModule;
|
||||
import org.libreccm.modules.InitEvent;
|
||||
|
|
@ -60,7 +62,12 @@ import org.libreccm.web.ApplicationType;
|
|||
descBundle = "com.arsdigita.ui.admin.AdminResources",
|
||||
singleton = true,
|
||||
creator = AdminApplicationCreator.class,
|
||||
servlet = AdminServlet.class)},
|
||||
servlet = AdminServlet.class),
|
||||
@ApplicationType(name = "org.libreccm.ui.admin.AdminFaces",
|
||||
descBundle = "com.arsdigita.ui.admin.AdminResources",
|
||||
singleton = true,
|
||||
creator = AdminJsfApplicationCreator.class,
|
||||
servletPath = "/admin-jsf/admin.xhtml")},
|
||||
configurations = {
|
||||
com.arsdigita.bebop.BebopConfig.class,
|
||||
com.arsdigita.dispatcher.DispatcherConfig.class,
|
||||
|
|
@ -94,6 +101,11 @@ public class CcmCore implements CcmModule {
|
|||
= new AdminApplicationSetup(event);
|
||||
adminSetup.setup();
|
||||
|
||||
LOGGER.info("Setting up admin-jsf application (/ccm/admin-jsf/)...");
|
||||
final AdminJsfApplicationSetup adminJsfSetup
|
||||
= new AdminJsfApplicationSetup(event);
|
||||
adminJsfSetup.setup();
|
||||
|
||||
LOGGER.info("Setting up login application...");
|
||||
final LoginApplicationSetup loginSetup
|
||||
= new LoginApplicationSetup(event);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* 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.libreccm.ui.admin;
|
||||
|
||||
import com.arsdigita.web.BaseServlet;
|
||||
import com.arsdigita.web.CCMDispatcherServlet;
|
||||
import com.arsdigita.web.WebConfig;
|
||||
|
||||
import org.apache.commons.codec.EncoderException;
|
||||
import org.apache.commons.codec.net.URLCodec;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.ComponentSystemEvent;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.libreccm.configuration.ConfigurationManager;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
@Named
|
||||
public class AuthorizationListener {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(
|
||||
AuthorizationListener.class);
|
||||
|
||||
@Inject
|
||||
private Subject subject;
|
||||
|
||||
@Inject
|
||||
private HttpServletRequest request;
|
||||
|
||||
// @Inject
|
||||
// private HttpServletResponse response;
|
||||
@Inject
|
||||
private PermissionChecker permissionChecker;
|
||||
|
||||
@Inject
|
||||
private ConfigurationManager confManager;
|
||||
|
||||
public void isPermitted(final ComponentSystemEvent event) {
|
||||
if (!subject.isAuthenticated()) {
|
||||
redirectToLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
final String requiredPrivilege = (String) event.getComponent().
|
||||
getAttributes().get("requiredPrivilege");
|
||||
|
||||
if (!permissionChecker.isPermitted(requiredPrivilege)) {
|
||||
try {
|
||||
final FacesContext facesContext = FacesContext.
|
||||
getCurrentInstance();
|
||||
final ExternalContext externalContext = facesContext.
|
||||
getExternalContext();
|
||||
final HttpServletResponse response
|
||||
= (HttpServletResponse) externalContext
|
||||
.getResponse();
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Failed to send FORBIDDEN error to client.", ex);
|
||||
throw new RuntimeException(
|
||||
"Failed to send FORBIDDEN error to client", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void redirectToLogin() {
|
||||
try {
|
||||
final FacesContext facesContext = FacesContext.getCurrentInstance();
|
||||
final ExternalContext externalContext = facesContext.
|
||||
getExternalContext();
|
||||
final HttpServletResponse response
|
||||
= (HttpServletResponse) externalContext
|
||||
.getResponse();
|
||||
final WebConfig webConfig = confManager.findConfiguration(
|
||||
WebConfig.class);
|
||||
final URLCodec urlCodec = new URLCodec("utf-8");
|
||||
response.sendRedirect(new URI(String.format(
|
||||
"%s://%s:%d%s%s/register/?return_url=%s",
|
||||
request.getScheme(),
|
||||
request.getServerName(),
|
||||
request.getLocalPort(),
|
||||
CCMDispatcherServlet.getContextPath(),
|
||||
webConfig.getDispatcherServletPath(),
|
||||
urlCodec.encode(request.getAttribute(
|
||||
BaseServlet.REQUEST_URL_ATTRIBUTE).toString())))
|
||||
.toString());
|
||||
} catch (IOException |
|
||||
URISyntaxException |
|
||||
EncoderException ex) {
|
||||
LOGGER.error("Failed to redirect to login.", ex);
|
||||
throw new RuntimeException("Failed to redirect to login.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,18 +16,28 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms;
|
||||
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
package org.libreccm.ui.admin;
|
||||
|
||||
/**
|
||||
* Annotation providing several informations about a content type. A content
|
||||
* type is provided by a class extending the {@link ContentItem} class.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public @interface ContentType {
|
||||
public class ConfProperty {
|
||||
|
||||
//ToDo
|
||||
private final String name;
|
||||
private final String value;
|
||||
|
||||
public ConfProperty(final String name, final String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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.libreccm.ui.admin;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Named;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
@Named
|
||||
public class ConfigurationController {
|
||||
|
||||
public List<ConfProperty> getSystemInformation() {
|
||||
final Properties properties = new Properties();
|
||||
|
||||
try (final InputStream stream = getClass().getResourceAsStream(
|
||||
"systeminformation.properties")) {
|
||||
if (stream == null) {
|
||||
properties.put("version", "");
|
||||
properties.put("appname", "LibreCCM");
|
||||
properties.put("apphomepage", "http://www.libreccm.org");
|
||||
} else {
|
||||
properties.load(stream);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
final List<ConfProperty> sysInfo = new ArrayList<>();
|
||||
properties.stringPropertyNames().forEach(propName -> sysInfo.add(
|
||||
new ConfProperty(propName,
|
||||
properties.getProperty(propName))));
|
||||
return sysInfo;
|
||||
}
|
||||
|
||||
public List<ConfProperty> getJavaSystemProperties() {
|
||||
final Properties systemProperties = System.getProperties();
|
||||
final List<ConfProperty> javaSysProps = new ArrayList<>();
|
||||
systemProperties.stringPropertyNames().forEach(propName -> javaSysProps
|
||||
.add(new ConfProperty(propName, systemProperties.getProperty(
|
||||
propName))));
|
||||
return javaSysProps;
|
||||
}
|
||||
|
||||
public List<ConfProperty> getXmlConfig() {
|
||||
final List<ConfProperty> xmlProps = new ArrayList<>();
|
||||
|
||||
final ResourceBundle texts = ResourceBundle.getBundle(
|
||||
"com.arsdigita.ui.admin.AdminResources");
|
||||
|
||||
xmlProps.add(new ConfProperty(
|
||||
texts.getString("ui.admin.sysinfo.xml_transformer_factory"),
|
||||
TransformerFactory.newInstance().getClass().getName()));
|
||||
try {
|
||||
xmlProps.add(new ConfProperty(
|
||||
texts.getString("ui.admin.sysinfo.xml_transformer"),
|
||||
TransformerFactory.newInstance().newTransformer().getClass()
|
||||
.getName()));
|
||||
} catch (TransformerConfigurationException ex) {
|
||||
xmlProps.add(new ConfProperty(
|
||||
texts.getString("ui.admin.sysinfo.xml_transformer"), "???"));
|
||||
}
|
||||
|
||||
xmlProps.add(new ConfProperty(
|
||||
texts.getString("ui.admin.sysinfo.xml_document_builder_factory"),
|
||||
DocumentBuilderFactory.newInstance().getClass().getName()));
|
||||
|
||||
try {
|
||||
xmlProps.add(new ConfProperty(
|
||||
texts.getString("ui.admin.sysinfo.xml_document_builder"),
|
||||
DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
||||
.getClass().getName()));
|
||||
} catch (ParserConfigurationException ex) {
|
||||
xmlProps.add(new ConfProperty(
|
||||
texts.getString("ui.admin.sysinfo.xml_document_builder"),
|
||||
"???"));
|
||||
}
|
||||
|
||||
xmlProps.add(new ConfProperty(
|
||||
texts.getString("ui.admin.sysinfo.sax_parser_factory"),
|
||||
SAXParserFactory.newInstance().getClass().getName()));
|
||||
|
||||
try {
|
||||
xmlProps.add(new ConfProperty(
|
||||
texts.getString("ui.admin.sysinfo.sax_parser"),
|
||||
SAXParserFactory.newInstance().newSAXParser().getClass()
|
||||
.getName()));
|
||||
} catch (ParserConfigurationException | SAXException ex) {
|
||||
xmlProps.add(new ConfProperty(
|
||||
texts.getString("ui.admin.sysinfo.sax_parser"), "???"));
|
||||
}
|
||||
|
||||
return xmlProps;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.libreccm.ui.admin;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.libreccm.security.Shiro;
|
||||
import org.libreccm.security.User;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
@Named
|
||||
public class UserContextController {
|
||||
|
||||
@Inject
|
||||
private Shiro shiro;
|
||||
|
||||
@Inject
|
||||
private Subject subject;
|
||||
|
||||
public boolean isLoggedIn() {
|
||||
return subject.isAuthenticated();
|
||||
}
|
||||
|
||||
public String getCurrentUserName() {
|
||||
final User user = shiro.getUser();
|
||||
|
||||
if (user == null) {
|
||||
return "";
|
||||
} else {
|
||||
return String.format("%s %s",
|
||||
user.getGivenName(),
|
||||
user.getFamilyName());
|
||||
}
|
||||
}
|
||||
|
||||
public void changePassword() {
|
||||
|
||||
}
|
||||
|
||||
public void logout() {
|
||||
subject.logout();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core">
|
||||
|
||||
<f:loadBundle basename="com.arsdigita.ui.admin.AdminResources"
|
||||
var="texts" />
|
||||
|
||||
<h:head>
|
||||
<title>
|
||||
LibreCCM Admin
|
||||
</title>
|
||||
</h:head>
|
||||
|
||||
<h:body>
|
||||
<f:metadata>
|
||||
<f:event listener="#{authorizationListener.isPermitted}"
|
||||
type="preRenderView" />
|
||||
<f:attribute name="requiredPrivilege" value="admin" />
|
||||
</f:metadata>
|
||||
|
||||
<div id="header">
|
||||
<h:outputStylesheet library="admin-jsf" name="header.css" />
|
||||
|
||||
<div id="logo">
|
||||
<h:graphicImage alt=""
|
||||
height="70"
|
||||
|
||||
library="admin-jsf"
|
||||
name="libreccm.png" />
|
||||
<!--<img alt=""
|
||||
id="logo"
|
||||
src="/themes/libreccm-default/images/libreccm.png" />-->
|
||||
</div>
|
||||
|
||||
<h:form id="user-widget">
|
||||
<p:menuButton rendered="#{userContextController.loggedIn}"
|
||||
value="#{userContextController.currentUserName}">
|
||||
<p:menuitem action="#{userContextController.changePassword()}"
|
||||
icon="fa fa-edit"
|
||||
value="Change password" />
|
||||
<p:menuitem action="#{userContextController.logout()}"
|
||||
icon="fa fa-sign-out"
|
||||
value="Logout" />
|
||||
</p:menuButton>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<p:tabView id="admin-tabs" dynamic="true">
|
||||
<p:tab title="#{texts['ui.admin.tab.applications']}">
|
||||
<h:outputText value="Applications Placeholder" />
|
||||
</p:tab>
|
||||
<p:tab title="#{texts['ui.admin.tab.users_groups_roles.title']}">
|
||||
<p:tabView id="user-groups-roles-tabs" orientation="left">
|
||||
<p:tab title="Users">
|
||||
<h:outputText value="Users Placeholder" />
|
||||
</p:tab>
|
||||
<p:tab title="Groups">
|
||||
<h:outputText value="Groups Placeholder" />
|
||||
</p:tab>
|
||||
<p:tab title="Roles">
|
||||
<h:outputText value="Roles Placeholder" />
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
|
||||
</p:tab>
|
||||
<p:tab title="#{texts['ui.admin.tab.categories.title']}">
|
||||
<h:outputText value="Categories Placeholder" />
|
||||
</p:tab>
|
||||
<p:tab title="#{texts['ui.admin.tab.configuration.title']}">
|
||||
<h:outputText value="Configuration Placeholder" />
|
||||
</p:tab>
|
||||
<p:tab title="#{texts['ui.admin.tab.workflows.title']}">
|
||||
<h:outputText value="Workflows Placeholder" />
|
||||
</p:tab>
|
||||
<p:tab title="#{texts['ui.admin.tab.sysinfo.title']}">
|
||||
<p:dataTable value="#{configurationController.systemInformation}"
|
||||
var="prop">
|
||||
<f:facet name="header">
|
||||
<h:outputText value="#{texts['ui.admin.sysinfo.appinfo']}" />
|
||||
</f:facet>
|
||||
<p:column>
|
||||
<h:outputText value="#{prop.name}" />
|
||||
</p:column>
|
||||
<p:column>
|
||||
<h:outputText value="#{prop.value}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<p:dataTable value="#{configurationController.javaSystemProperties}"
|
||||
var="prop">
|
||||
<f:facet name="header">
|
||||
<h:outputText value="#{texts['ui.admin.sysinfo.java_system_properties']}" />
|
||||
</f:facet>
|
||||
<p:column>
|
||||
<h:outputText value="#{prop.name}" />
|
||||
</p:column>
|
||||
<p:column>
|
||||
<h:outputText value="#{prop.value}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
|
||||
<p:dataTable value="#{configurationController.xmlConfig}"
|
||||
var="prop">
|
||||
<f:facet name="header">
|
||||
<h:outputText value="#{texts['ui.admin.sysinfo.xml_config']}" />
|
||||
</f:facet>
|
||||
<p:column>
|
||||
<h:outputText value="#{prop.name}" />
|
||||
</p:column>
|
||||
<p:column>
|
||||
<h:outputText value="#{prop.value}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
<h:outputText value="Systeminformation Placeholder" />
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
|
||||
|
||||
<h:outputText value="LibreCCM Admin Faces Placeholder" />
|
||||
</h:body>
|
||||
|
||||
</html>
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div#header {
|
||||
background-color: #56a1bd;
|
||||
|
||||
background-image: -moz-linear-gradient(top, #56a1bd 5%, #024C68 95%);
|
||||
background-image: -webkit-linear-gradient(top, #56a1bd 5%, #024C68 95%);
|
||||
background-image: linear-gradient(top, #56a1bd 5%, #024C68 95%);
|
||||
|
||||
display: flex;
|
||||
|
||||
height: 70px;
|
||||
|
||||
padding: 0 10px;
|
||||
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#logo, #user-widget {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#user-widget {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.ui-widget, .ui-widget .ui-widget {
|
||||
font-size: 90% !important;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
|
|
@ -0,0 +1,16 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html">
|
||||
|
||||
<head>
|
||||
<title>
|
||||
JSF Test
|
||||
</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h:outputText value="JSF TEST ccm-core:/resources/"/>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html">
|
||||
|
||||
<head>
|
||||
<title>
|
||||
JSF Test
|
||||
</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h:outputText value="JSF TEST"/>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue