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"
|
<Logger name="org.libreccm.security.Shiro"
|
||||||
level="debug">
|
level="debug">
|
||||||
</Logger>
|
</Logger>
|
||||||
|
<Logger name="org.librecms.contentsection.ContentSectionSetup"
|
||||||
|
level="debug">
|
||||||
|
</Logger>
|
||||||
</Loggers>
|
</Loggers>
|
||||||
</Configuration>
|
</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>
|
||||||
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
|
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
|
||||||
</listener>
|
</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>
|
</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.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
@ -136,7 +135,7 @@ public class ContentCenterServlet extends BaseApplicationServlet {
|
||||||
/* Check user and privilegies */
|
/* Check user and privilegies */
|
||||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
||||||
if (shiro.getSubject().isAuthenticated()) {
|
if (!shiro.getSubject().isAuthenticated()) {
|
||||||
throw new LoginSignal(sreq); // send to login page
|
throw new LoginSignal(sreq); // send to login page
|
||||||
}
|
}
|
||||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||||
|
|
@ -178,7 +177,7 @@ public class ContentCenterServlet extends BaseApplicationServlet {
|
||||||
// DispatcherHelper.sendRedirect(sresp, originalUrl + "/");
|
// DispatcherHelper.sendRedirect(sresp, originalUrl + "/");
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
final Page page = (Page) pages.get(pathInfo);
|
final Page page = pages.get(pathInfo);
|
||||||
if (page != null) {
|
if (page != null) {
|
||||||
|
|
||||||
// Check user access.
|
// Check user access.
|
||||||
|
|
@ -274,7 +273,7 @@ public class ContentCenterServlet extends BaseApplicationServlet {
|
||||||
)
|
)
|
||||||
throws ServletException {
|
throws ServletException {
|
||||||
|
|
||||||
if (CdiUtil.createCdiUtil().findBean(Shiro.class).getSubject()
|
if (!CdiUtil.createCdiUtil().findBean(Shiro.class).getSubject()
|
||||||
.isAuthenticated()) {
|
.isAuthenticated()) {
|
||||||
throw new LoginSignal(request);
|
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_viewAllLink;
|
||||||
// private ActionLink m_viewShortLink;
|
// private ActionLink m_viewShortLink;
|
||||||
private Paginator m_paginator;
|
private Paginator m_paginator;
|
||||||
private ActionLink m_viewLockLink, m_viewUnlockLink, m_viewAllLockLink;
|
private ActionLink m_viewLockLink;
|
||||||
private Label m_viewLockLabel, m_viewUnlockLabel, m_viewAllLockLabel;
|
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_sortDirectionParam;
|
||||||
private StringParameter m_sortTypeParam;
|
private StringParameter m_sortTypeParam;
|
||||||
private StringParameter m_lockFilterParam;
|
private StringParameter m_lockFilterParam;
|
||||||
|
|
@ -103,7 +107,7 @@ public class TasksPanel extends CMSContainer {
|
||||||
private Label m_selectorLabel;
|
private Label m_selectorLabel;
|
||||||
//ToDo
|
//ToDo
|
||||||
// private CreationSelector m_selector;
|
// private CreationSelector m_selector;
|
||||||
// private ContentSectionContainer m_sections;
|
private ContentSectionContainer m_sections;
|
||||||
// ToDo End
|
// ToDo End
|
||||||
private CcmObjectSelectionModel m_sectionSel;
|
private CcmObjectSelectionModel m_sectionSel;
|
||||||
private CcmObjectSelectionModel m_typeSel;
|
private CcmObjectSelectionModel m_typeSel;
|
||||||
|
|
@ -134,7 +138,8 @@ public class TasksPanel extends CMSContainer {
|
||||||
* @pre maxRows != null
|
* @pre maxRows != null
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public TasksPanel(int maxRows, CcmObjectSelectionModel typeModel,
|
public TasksPanel(int maxRows,
|
||||||
|
CcmObjectSelectionModel typeModel,
|
||||||
CcmObjectSelectionModel sectionModel) {
|
CcmObjectSelectionModel sectionModel) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
|
@ -192,14 +197,13 @@ public class TasksPanel extends CMSContainer {
|
||||||
// m_selector = new CreationSelector(m_typeSel, m_folderSel);
|
// m_selector = new CreationSelector(m_typeSel, m_folderSel);
|
||||||
// m_creationPane.add(m_selector);
|
// m_creationPane.add(m_selector);
|
||||||
//ToDo End
|
//ToDo End
|
||||||
|
|
||||||
m_creationPane.setClassAttr("itemCreationPane");
|
m_creationPane.setClassAttr("itemCreationPane");
|
||||||
add(m_creationPane);
|
add(m_creationPane);
|
||||||
|
|
||||||
// The section list UIx
|
// The section list UIx
|
||||||
//ToDo
|
//ToDo
|
||||||
// m_sections = new ContentSectionContainer(m_typeSel, m_sectionSel);
|
m_sections = new ContentSectionContainer(m_typeSel, m_sectionSel);
|
||||||
// add(m_sections);
|
add(m_sections);
|
||||||
//ToDo End
|
//ToDo End
|
||||||
// When a new type is selected, show the creation UI.
|
// When a new type is selected, show the creation UI.
|
||||||
// When the selection is cleared, return to section list
|
// When the selection is cleared, return to section list
|
||||||
|
|
@ -444,8 +448,6 @@ public class TasksPanel extends CMSContainer {
|
||||||
// query.addEqualsFilter("isLocked", "f");
|
// query.addEqualsFilter("isLocked", "f");
|
||||||
// } // else show all
|
// } // else show all
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
// private static class RootFolderSelectionModel
|
// private static class RootFolderSelectionModel
|
||||||
// extends FolderSelectionModel {
|
// extends FolderSelectionModel {
|
||||||
//
|
//
|
||||||
|
|
@ -474,7 +476,6 @@ public class TasksPanel extends CMSContainer {
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
//ToDo End
|
//ToDo End
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -512,9 +513,8 @@ public class TasksPanel extends CMSContainer {
|
||||||
//
|
//
|
||||||
// return query;
|
// return query;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public int size(PageState ps) {
|
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() {
|
private RequestLocal m_taskCount = new RequestLocal() {
|
||||||
|
|
@ -523,7 +523,7 @@ public class TasksPanel extends CMSContainer {
|
||||||
public Object initialValue(PageState state) {
|
public Object initialValue(PageState state) {
|
||||||
// DataQuery query = makeQuery(state);
|
// DataQuery query = makeQuery(state);
|
||||||
// return new Long(query.size());
|
// return new Long(query.size());
|
||||||
return null;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -536,7 +536,6 @@ return null;
|
||||||
exportAttributes(content);
|
exportAttributes(content);
|
||||||
|
|
||||||
// DataQuery query = makeQuery(state);
|
// DataQuery query = makeQuery(state);
|
||||||
|
|
||||||
String lockFilterType = getLockFilterType(state);
|
String lockFilterType = getLockFilterType(state);
|
||||||
content.addAttribute("lockFilterType", lockFilterType);
|
content.addAttribute("lockFilterType", lockFilterType);
|
||||||
|
|
||||||
|
|
@ -705,6 +704,7 @@ return null;
|
||||||
// link.generateXML(state, content);
|
// link.generateXML(state, content);
|
||||||
// state.clearControlEvent();
|
// state.clearControlEvent();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -776,5 +776,4 @@ return null;
|
||||||
// return PermissionService.getFilterQuery(factory, "itemID", privilege,
|
// return PermissionService.getFilterQuery(factory, "itemID", privilege,
|
||||||
// partyOID);
|
// partyOID);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms;
|
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.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.libreccm.core.CoreConstants;
|
import org.libreccm.core.CoreConstants;
|
||||||
|
|
@ -14,6 +18,7 @@ import org.libreccm.modules.RequiredModule;
|
||||||
import org.libreccm.modules.ShutdownEvent;
|
import org.libreccm.modules.ShutdownEvent;
|
||||||
import org.libreccm.modules.UnInstallEvent;
|
import org.libreccm.modules.UnInstallEvent;
|
||||||
import org.libreccm.web.ApplicationType;
|
import org.libreccm.web.ApplicationType;
|
||||||
|
import org.libreccm.web.CcmApplication;
|
||||||
import org.librecms.contentsection.ContentSection;
|
import org.librecms.contentsection.ContentSection;
|
||||||
import org.librecms.contentsection.ContentSectionCreator;
|
import org.librecms.contentsection.ContentSectionCreator;
|
||||||
import org.librecms.contentsection.ContentSectionSetup;
|
import org.librecms.contentsection.ContentSectionSetup;
|
||||||
|
|
@ -29,6 +34,13 @@ import java.util.Properties;
|
||||||
@RequiredModule(module = org.libreccm.core.CcmCore.class)
|
@RequiredModule(module = org.libreccm.core.CcmCore.class)
|
||||||
},
|
},
|
||||||
applicationTypes = {
|
applicationTypes = {
|
||||||
|
@ApplicationType(
|
||||||
|
name = CmsConstants.CONTENT_CENTER_APP_TYPE,
|
||||||
|
applicationClass = CcmApplication.class,
|
||||||
|
descBundle = CmsConstants.CONTENT_CENTER_DESC_BUNDLE,
|
||||||
|
creator = ContentCenterAppCreator.class,
|
||||||
|
servlet = ContentCenterServlet.class
|
||||||
|
),
|
||||||
@ApplicationType(
|
@ApplicationType(
|
||||||
name = CmsConstants.CONTENT_SECTION_APP_TYPE,
|
name = CmsConstants.CONTENT_SECTION_APP_TYPE,
|
||||||
applicationClass = ContentSection.class,
|
applicationClass = ContentSection.class,
|
||||||
|
|
@ -66,6 +78,12 @@ public class Cms implements CcmModule {
|
||||||
ex);
|
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(
|
final ContentSectionSetup contentSectionSetup = new ContentSectionSetup(
|
||||||
event);
|
event);
|
||||||
contentSectionSetup.setup();
|
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_APP_TYPE = "com.arsdigita.cms.ContentCenter";
|
||||||
public static final String CONTENT_CENTER_URL = "/content-center/";
|
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
|
public static final String CONTENT_SECTION_APP_TYPE
|
||||||
= "org.librecms.contentsection.ContentSection";
|
= "org.librecms.contentsection.ContentSection";
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,14 @@
|
||||||
package org.librecms.contentsection;
|
package org.librecms.contentsection;
|
||||||
|
|
||||||
import org.libreccm.categorization.Category;
|
import org.libreccm.categorization.Category;
|
||||||
|
import org.libreccm.workflow.WorkflowTemplate;
|
||||||
|
import org.librecms.lifecycle.LifecycleDefinition;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -32,10 +35,88 @@ import javax.enterprise.context.RequestScoped;
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class ContentItemManager {
|
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) {
|
public void move(final ContentItem item, final Category targetFolder) {
|
||||||
throw new UnsupportedOperationException();
|
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) {
|
public void copy(final ContentItem item, final Category targetFolder) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
@ -65,6 +146,7 @@ public class ContentItemManager {
|
||||||
* Determines if a content item has a live version.
|
* Determines if a content item has a live version.
|
||||||
*
|
*
|
||||||
* @param item The item
|
* @param item The item
|
||||||
|
*
|
||||||
* @return {@code true} if the content item has a live version,
|
* @return {@code true} if the content item has a live version,
|
||||||
* {@code false} if not.
|
* {@code false} if not.
|
||||||
*/
|
*/
|
||||||
|
|
@ -75,10 +157,14 @@ public class ContentItemManager {
|
||||||
/**
|
/**
|
||||||
* Retrieves the live version of the provided content item if any.
|
* Retrieves the live version of the provided content item if any.
|
||||||
*
|
*
|
||||||
* @param <T>
|
* @param <T> Type of the content item.
|
||||||
* @param item
|
* @param item The item of which the live version should be retrieved.
|
||||||
* @param type
|
* @param type Type of the content item.
|
||||||
* @return
|
*
|
||||||
|
* @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(
|
public <T extends ContentItem> Optional<T> getLiveVersion(
|
||||||
final ContentItem item,
|
final ContentItem item,
|
||||||
|
|
@ -86,11 +172,37 @@ public class ContentItemManager {
|
||||||
throw new UnsupportedOperationException();
|
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();
|
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();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,17 +24,19 @@ import org.libreccm.core.CcmObject;
|
||||||
import org.libreccm.core.CcmObjectRepository;
|
import org.libreccm.core.CcmObjectRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Repository for content items.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class ContentItemRepository
|
public class ContentItemRepository
|
||||||
extends AbstractAuditedEntityRepository<Long, ContentItem>{
|
extends AbstractAuditedEntityRepository<Long, ContentItem> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private CcmObjectRepository ccmObjectRepo;
|
private CcmObjectRepository ccmObjectRepo;
|
||||||
|
|
@ -54,20 +56,47 @@ public class ContentItemRepository
|
||||||
return ccmObjectRepo.isNew(item);
|
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);
|
final CcmObject result = ccmObjectRepo.findObjectById(itemId);
|
||||||
if (result instanceof ContentItem) {
|
if (result instanceof ContentItem) {
|
||||||
return (ContentItem) result;
|
return Optional.of((ContentItem) result);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends ContentItem> T findById(final long itemId,
|
/**
|
||||||
|
* 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) {
|
final Class<T> type) {
|
||||||
throw new UnsupportedOperationException();
|
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) {
|
public ContentItem findByUuid(final String uuid) {
|
||||||
final CcmObject result = ccmObjectRepo.findObjectByUuid(uuid);
|
final CcmObject result = ccmObjectRepo.findObjectByUuid(uuid);
|
||||||
if (result instanceof ContentItem) {
|
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,
|
public <T extends ContentItem> T findByUuid(final String uuid,
|
||||||
final Class<T> type) {
|
final Class<T> type) {
|
||||||
throw new UnsupportedOperationException();
|
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) {
|
public <T extends ContentItem> List<T> findByType(final Class<T> type) {
|
||||||
throw new UnsupportedOperationException();
|
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) {
|
public List<ContentItem> findByFolder(final Category folder) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import org.libreccm.security.Role;
|
||||||
import org.libreccm.web.AbstractCcmApplicationSetup;
|
import org.libreccm.web.AbstractCcmApplicationSetup;
|
||||||
import org.librecms.CmsConstants;
|
import org.librecms.CmsConstants;
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static org.librecms.CmsConstants.*;
|
import static org.librecms.CmsConstants.*;
|
||||||
|
|
@ -54,8 +53,13 @@ public class ContentSectionSetup extends AbstractCcmApplicationSetup {
|
||||||
if (getIntegrationProps().containsKey(INITIAL_CONTENT_SECTIONS)) {
|
if (getIntegrationProps().containsKey(INITIAL_CONTENT_SECTIONS)) {
|
||||||
sectionNames = getIntegrationProps().getProperty(
|
sectionNames = getIntegrationProps().getProperty(
|
||||||
INITIAL_CONTENT_SECTIONS);
|
INITIAL_CONTENT_SECTIONS);
|
||||||
|
LOGGER.info(
|
||||||
|
"Found names for initial content sections in integration "
|
||||||
|
+ "properties: {}", sectionNames);
|
||||||
} else {
|
} else {
|
||||||
sectionNames = "info";
|
sectionNames = "info";
|
||||||
|
LOGGER.info("No initial content sections definied integration "
|
||||||
|
+ "properties, using default: {}", sectionNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final String contentSectionName : sectionNames.split(",")) {
|
for (final String contentSectionName : sectionNames.split(",")) {
|
||||||
|
|
@ -64,13 +68,27 @@ public class ContentSectionSetup extends AbstractCcmApplicationSetup {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createContentSection(final String sectionName) {
|
private void createContentSection(final String sectionName) {
|
||||||
|
LOGGER.debug("Creating content section with section name \"{}\"...",
|
||||||
|
sectionName);
|
||||||
final ContentSection section = new ContentSection();
|
final ContentSection section = new ContentSection();
|
||||||
section.setUuid(UUID.randomUUID().toString());
|
section.setUuid(UUID.randomUUID().toString());
|
||||||
section.setApplicationType(CmsConstants.CONTENT_SECTION_APP_TYPE);
|
section.setApplicationType(CmsConstants.CONTENT_SECTION_APP_TYPE);
|
||||||
section.setPrimaryUrl(sectionName);
|
section.setPrimaryUrl(String.format("/%s/", sectionName));
|
||||||
section.setDisplayName(sectionName);
|
section.setDisplayName(sectionName);
|
||||||
section.setLabel(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();
|
final Category rootFolder = new Category();
|
||||||
rootFolder.setUuid(UUID.randomUUID().toString());
|
rootFolder.setUuid(UUID.randomUUID().toString());
|
||||||
rootFolder.setUniqueId(rootFolder.getUuid());
|
rootFolder.setUniqueId(rootFolder.getUuid());
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ import static org.librecms.CmsConstants.*;
|
||||||
|
|
||||||
import org.libreccm.core.CcmObject;
|
import org.libreccm.core.CcmObject;
|
||||||
import org.libreccm.l10n.LocalizedString;
|
import org.libreccm.l10n.LocalizedString;
|
||||||
import org.libreccm.workflow.Workflow;
|
import org.libreccm.workflow.WorkflowTemplate;
|
||||||
import org.librecms.lifecycle.Lifecycle;
|
import org.librecms.lifecycle.LifecycleDefinition;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -98,11 +98,11 @@ public class ContentType extends CcmObject implements Serializable {
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "DEFAULT_LIFECYCLE_ID")
|
@JoinColumn(name = "DEFAULT_LIFECYCLE_ID")
|
||||||
private Lifecycle defaultLifecycle;
|
private LifecycleDefinition defaultLifecycle;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "DEFAULT_WORKFLOW")
|
@JoinColumn(name = "DEFAULT_WORKFLOW")
|
||||||
private Workflow defaultWorkflow;
|
private WorkflowTemplate defaultWorkflow;
|
||||||
|
|
||||||
public String getContentItemClass() {
|
public String getContentItemClass() {
|
||||||
return contentItemClass;
|
return contentItemClass;
|
||||||
|
|
@ -160,19 +160,19 @@ public class ContentType extends CcmObject implements Serializable {
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Lifecycle getDefaultLifecycle() {
|
public LifecycleDefinition getDefaultLifecycle() {
|
||||||
return defaultLifecycle;
|
return defaultLifecycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setDefaultLifecycle(final Lifecycle defaultLifecycle) {
|
protected void setDefaultLifecycle(final LifecycleDefinition defaultLifecycle) {
|
||||||
this.defaultLifecycle = defaultLifecycle;
|
this.defaultLifecycle = defaultLifecycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Workflow getDefaultWorkflow() {
|
public WorkflowTemplate getDefaultWorkflow() {
|
||||||
return defaultWorkflow;
|
return defaultWorkflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setDefaultWorkflow(final Workflow defaultWorkflow) {
|
protected void setDefaultWorkflow(final WorkflowTemplate defaultWorkflow) {
|
||||||
this.defaultWorkflow = 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.testutils.EqualsVerifier;
|
||||||
import org.libreccm.web.CcmApplication;
|
import org.libreccm.web.CcmApplication;
|
||||||
import org.libreccm.workflow.Workflow;
|
import org.libreccm.workflow.Workflow;
|
||||||
|
import org.libreccm.workflow.WorkflowTemplate;
|
||||||
import org.librecms.lifecycle.Lifecycle;
|
import org.librecms.lifecycle.Lifecycle;
|
||||||
|
import org.librecms.lifecycle.LifecycleDefinition;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
@ -137,17 +139,17 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
||||||
final Resource resource2 = new Resource();
|
final Resource resource2 = new Resource();
|
||||||
resource2.setDisplayName("Resource 2");
|
resource2.setDisplayName("Resource 2");
|
||||||
|
|
||||||
final Lifecycle lifecycle1 = new Lifecycle();
|
final LifecycleDefinition lifecycleDef1 = new LifecycleDefinition();
|
||||||
lifecycle1.setFinished(true);
|
lifecycleDef1.setDefinitionId(-100);
|
||||||
|
|
||||||
final Lifecycle lifecycle2 = new Lifecycle();
|
final LifecycleDefinition lifecycleDef2 = new LifecycleDefinition();
|
||||||
lifecycle2.setFinished(false);
|
lifecycleDef2.setDefinitionId(-110);
|
||||||
|
|
||||||
final Workflow workflow1 = new Workflow();
|
final WorkflowTemplate workflowTemplate1 = new WorkflowTemplate();
|
||||||
workflow1.setWorkflowId(-100);
|
workflowTemplate1.setWorkflowId(-200);
|
||||||
|
|
||||||
final Workflow workflow2 = new Workflow();
|
final WorkflowTemplate workflowTemplate2 = new WorkflowTemplate();
|
||||||
workflow2.setWorkflowId(-200);
|
workflowTemplate2.setWorkflowId(-210);
|
||||||
|
|
||||||
verifier
|
verifier
|
||||||
.withPrefabValues(ContentItem.class, item1, item2)
|
.withPrefabValues(ContentItem.class, item1, item2)
|
||||||
|
|
@ -161,8 +163,12 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
||||||
.withPrefabValues(CcmApplication.class, application1, application2)
|
.withPrefabValues(CcmApplication.class, application1, application2)
|
||||||
.withPrefabValues(Domain.class, domain1, domain2)
|
.withPrefabValues(Domain.class, domain1, domain2)
|
||||||
.withPrefabValues(Resource.class, resource1, resource2)
|
.withPrefabValues(Resource.class, resource1, resource2)
|
||||||
.withPrefabValues(Lifecycle.class, lifecycle1, lifecycle2)
|
.withPrefabValues(LifecycleDefinition.class,
|
||||||
.withPrefabValues(Workflow.class, workflow1, workflow2);
|
lifecycleDef1,
|
||||||
|
lifecycleDef2)
|
||||||
|
.withPrefabValues(WorkflowTemplate.class,
|
||||||
|
workflowTemplate1,
|
||||||
|
workflowTemplate2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,11 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.primefaces</groupId>
|
||||||
|
<artifactId>primefaces</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Export Import Libraries -->
|
<!-- Export Import Libraries -->
|
||||||
|
|
||||||
<dependency>
|
<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];
|
m_typeURI = servletAnnotation.urlPatterns()[0];
|
||||||
}
|
}
|
||||||
} else {
|
} 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: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 <K> Primary key of the entity.
|
||||||
* @param <T> Type 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);
|
public abstract K getEntityId(final T entity);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public T retrieveRevisionOfEntity(final T entity, final Number revision) {
|
public T retrieveRevisionOfEntity(final T entity, final Number revision) {
|
||||||
final AuditQuery query = auditReader.createQuery()
|
final AuditQuery query = auditReader.createQuery()
|
||||||
.forEntitiesAtRevision(getEntityClass(), revision);
|
.forEntitiesAtRevision(getEntityClass(), revision);
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ import javax.persistence.EntityManager;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
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.CcmModule;
|
||||||
import org.libreccm.modules.InitEvent;
|
import org.libreccm.modules.InitEvent;
|
||||||
|
|
@ -60,7 +62,12 @@ import org.libreccm.web.ApplicationType;
|
||||||
descBundle = "com.arsdigita.ui.admin.AdminResources",
|
descBundle = "com.arsdigita.ui.admin.AdminResources",
|
||||||
singleton = true,
|
singleton = true,
|
||||||
creator = AdminApplicationCreator.class,
|
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 = {
|
configurations = {
|
||||||
com.arsdigita.bebop.BebopConfig.class,
|
com.arsdigita.bebop.BebopConfig.class,
|
||||||
com.arsdigita.dispatcher.DispatcherConfig.class,
|
com.arsdigita.dispatcher.DispatcherConfig.class,
|
||||||
|
|
@ -94,6 +101,11 @@ public class CcmCore implements CcmModule {
|
||||||
= new AdminApplicationSetup(event);
|
= new AdminApplicationSetup(event);
|
||||||
adminSetup.setup();
|
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...");
|
LOGGER.info("Setting up login application...");
|
||||||
final LoginApplicationSetup loginSetup
|
final LoginApplicationSetup loginSetup
|
||||||
= new LoginApplicationSetup(event);
|
= 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,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.librecms;
|
package org.libreccm.ui.admin;
|
||||||
|
|
||||||
import org.librecms.contentsection.ContentItem;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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>
|
* @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>
|
||||||
|
|
||||||
|
|
||||||
6
pom.xml
6
pom.xml
|
|
@ -291,6 +291,12 @@
|
||||||
<version>1.2.5</version>
|
<version>1.2.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- PrimeFaces for JSF prototype -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.primefaces</groupId>
|
||||||
|
<artifactId>primefaces</artifactId>
|
||||||
|
<version>6.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
*********************
|
*********************
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue