362 lines
16 KiB
Java
362 lines
16 KiB
Java
/*
|
|
* Copyright (C) 2016 LibreCCM Foundation.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301 USA
|
|
*/
|
|
package org.librecms.contentsection;
|
|
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
import org.libreccm.core.UnexpectedErrorException;
|
|
import org.libreccm.modules.InstallEvent;
|
|
import org.libreccm.security.Role;
|
|
import org.libreccm.web.AbstractCcmApplicationSetup;
|
|
import org.librecms.CmsConstants;
|
|
|
|
import java.util.UUID;
|
|
|
|
import static org.librecms.contentsection.ContentSection.*;
|
|
|
|
import org.librecms.contentsection.privileges.AdminPrivileges;
|
|
import org.librecms.contentsection.privileges.AssetPrivileges;
|
|
import org.librecms.contentsection.privileges.ItemPrivileges;
|
|
import org.librecms.contenttypes.Article;
|
|
import org.librecms.contenttypes.Event;
|
|
import org.librecms.contenttypes.MultiPartArticle;
|
|
import org.librecms.contenttypes.News;
|
|
import org.librecms.dispatcher.MultilingualItemResolver;
|
|
|
|
import java.util.Arrays;
|
|
import org.librecms.contentsection.privileges.TypePrivileges;
|
|
|
|
/**
|
|
*
|
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
|
*/
|
|
public class ContentSectionSetup extends AbstractCcmApplicationSetup {
|
|
|
|
private static final Logger LOGGER = LogManager.getLogger(
|
|
ContentSectionSetup.class);
|
|
|
|
private static final String INITIAL_CONTENT_SECTIONS
|
|
= "org.librecms.initial_content_sections";
|
|
private static final String DEFAULT_ITEM_RESOLVER
|
|
= "org.librecms.default_item_resolver";
|
|
private static final String[] DEFAULT_TYPES = new String[]{
|
|
Article.class.getName(),
|
|
Event.class.getName(),
|
|
MultiPartArticle.class.getName(),
|
|
News.class.getName()};
|
|
|
|
public ContentSectionSetup(final InstallEvent event) {
|
|
super(event);
|
|
}
|
|
|
|
@Override
|
|
public void setup() {
|
|
final String sectionNames;
|
|
if (getIntegrationProps().containsKey(INITIAL_CONTENT_SECTIONS)) {
|
|
sectionNames = getIntegrationProps().getProperty(
|
|
INITIAL_CONTENT_SECTIONS);
|
|
LOGGER.info(
|
|
"Found names for initial content sections in integration "
|
|
+ "properties: {}", sectionNames);
|
|
} else {
|
|
sectionNames = "info";
|
|
LOGGER.info("No initial content sections definied integration "
|
|
+ "properties, using default: {}", sectionNames);
|
|
}
|
|
|
|
for (final String contentSectionName : sectionNames.split(",")) {
|
|
createContentSection(contentSectionName);
|
|
}
|
|
}
|
|
|
|
private void createContentSection(final String sectionName) {
|
|
LOGGER.debug("Creating content section with section name \"{}\"...",
|
|
sectionName);
|
|
final ContentSection section = new ContentSection();
|
|
section.setUuid(UUID.randomUUID().toString());
|
|
section.setApplicationType(CmsConstants.CONTENT_SECTION_APP_TYPE);
|
|
section.setPrimaryUrl(String.format("/%s/", sectionName));
|
|
section.setDisplayName(sectionName);
|
|
section.setLabel(sectionName);
|
|
|
|
if (getIntegrationProps().getProperty(DEFAULT_ITEM_RESOLVER) == null
|
|
|| getIntegrationProps().getProperty(DEFAULT_ITEM_RESOLVER)
|
|
.trim().isEmpty()) {
|
|
section.setItemResolverClass(getIntegrationProps().getProperty(
|
|
DEFAULT_ITEM_RESOLVER));
|
|
} else {
|
|
section.setItemResolverClass(MultilingualItemResolver.class
|
|
.getName());
|
|
}
|
|
|
|
LOGGER.debug("New content section properties: "
|
|
+ "uuid = {}; "
|
|
+ "applicationType = \"{}\"; "
|
|
+ "primaryUrl = \"{}\"; "
|
|
+ "displayName = \"{}\"; "
|
|
+ "label = \"{}\"",
|
|
section.getUuid(),
|
|
section.getApplicationType(),
|
|
section.getPrimaryUrl(),
|
|
section.getDisplayName(),
|
|
section.getLabel());
|
|
|
|
final Folder rootFolder = new Folder();
|
|
rootFolder.setUuid(UUID.randomUUID().toString());
|
|
rootFolder.setUniqueId(rootFolder.getUuid());
|
|
rootFolder.setName(String.format("%s_" + ROOT, sectionName));
|
|
rootFolder.setType(FolderType.DOCUMENTS_FOLDER);
|
|
rootFolder.setSection(section);
|
|
|
|
final Folder rootAssetFolder = new Folder();
|
|
rootAssetFolder.setName(String.format("%s_" + ASSETS, sectionName));
|
|
rootAssetFolder.setUuid(UUID.randomUUID().toString());
|
|
rootAssetFolder.setUniqueId(rootAssetFolder.getUuid());
|
|
rootAssetFolder.setType(FolderType.ASSETS_FOLDER);
|
|
rootAssetFolder.setSection(section);
|
|
|
|
section.setRootDocumentFolder(rootFolder);
|
|
section.setRootAssetsFolder(rootAssetFolder);
|
|
|
|
getEntityManager().persist(section);
|
|
getEntityManager().persist(rootFolder);
|
|
getEntityManager().persist(rootAssetFolder);
|
|
|
|
LOGGER.debug(
|
|
"Creating default roles and permissions for content section "
|
|
+ "'{}'...",
|
|
sectionName);
|
|
final Role alertRecipient = createRole(String.format(
|
|
"%s_" + ALERT_RECIPIENT, sectionName));
|
|
final Role author = createRole(String.format("%s_" + AUTHOR,
|
|
sectionName));
|
|
final Role editor = createRole(String.format("%s_" + EDITOR,
|
|
sectionName));
|
|
final Role manager = createRole(String.format("%s_" + MANAGER,
|
|
sectionName));
|
|
final Role publisher = createRole(String.format("%s_" + PUBLISHER,
|
|
sectionName));
|
|
final Role contentReader = createRole(String.format(
|
|
"%s_" + CONTENT_READER, sectionName));
|
|
|
|
grantPermissions(author,
|
|
rootFolder,
|
|
ItemPrivileges.CATEGORIZE,
|
|
ItemPrivileges.CREATE_NEW,
|
|
ItemPrivileges.EDIT,
|
|
ItemPrivileges.VIEW_PUBLISHED,
|
|
ItemPrivileges.PREVIEW);
|
|
|
|
grantPermissions(author,
|
|
rootAssetFolder,
|
|
AssetPrivileges.USE,
|
|
AssetPrivileges.CREATE_NEW,
|
|
AssetPrivileges.EDIT,
|
|
AssetPrivileges.VIEW,
|
|
AssetPrivileges.DELETE);
|
|
|
|
grantPermissions(editor,
|
|
rootFolder,
|
|
ItemPrivileges.CATEGORIZE,
|
|
ItemPrivileges.CREATE_NEW,
|
|
ItemPrivileges.EDIT,
|
|
ItemPrivileges.APPROVE,
|
|
ItemPrivileges.DELETE,
|
|
ItemPrivileges.VIEW_PUBLISHED,
|
|
ItemPrivileges.PREVIEW);
|
|
|
|
grantPermissions(editor,
|
|
rootAssetFolder,
|
|
AssetPrivileges.USE,
|
|
AssetPrivileges.CREATE_NEW,
|
|
AssetPrivileges.EDIT,
|
|
AssetPrivileges.VIEW,
|
|
AssetPrivileges.DELETE);
|
|
|
|
grantPermissions(manager,
|
|
section,
|
|
AdminPrivileges.ADMINISTER_ROLES,
|
|
AdminPrivileges.ADMINISTER_WORKFLOW,
|
|
AdminPrivileges.ADMINISTER_LIFECYLES,
|
|
AdminPrivileges.ADMINISTER_CATEGORIES,
|
|
AdminPrivileges.ADMINISTER_CONTENT_TYPES);
|
|
|
|
grantPermissions(manager,
|
|
rootFolder,
|
|
ItemPrivileges.ADMINISTER,
|
|
ItemPrivileges.CATEGORIZE,
|
|
ItemPrivileges.CREATE_NEW,
|
|
ItemPrivileges.EDIT,
|
|
ItemPrivileges.APPROVE,
|
|
ItemPrivileges.PUBLISH,
|
|
ItemPrivileges.DELETE,
|
|
ItemPrivileges.VIEW_PUBLISHED,
|
|
ItemPrivileges.PREVIEW);
|
|
|
|
grantPermissions(manager,
|
|
rootAssetFolder,
|
|
AssetPrivileges.USE,
|
|
AssetPrivileges.CREATE_NEW,
|
|
AssetPrivileges.EDIT,
|
|
AssetPrivileges.VIEW,
|
|
AssetPrivileges.DELETE);
|
|
|
|
grantPermissions(publisher,
|
|
rootFolder,
|
|
ItemPrivileges.CATEGORIZE,
|
|
ItemPrivileges.CREATE_NEW,
|
|
ItemPrivileges.EDIT,
|
|
ItemPrivileges.APPROVE,
|
|
ItemPrivileges.PUBLISH,
|
|
ItemPrivileges.DELETE,
|
|
ItemPrivileges.VIEW_PUBLISHED,
|
|
ItemPrivileges.PREVIEW);
|
|
|
|
grantPermissions(publisher,
|
|
rootAssetFolder,
|
|
AssetPrivileges.USE,
|
|
AssetPrivileges.CREATE_NEW,
|
|
AssetPrivileges.EDIT,
|
|
AssetPrivileges.VIEW,
|
|
AssetPrivileges.DELETE);
|
|
|
|
grantPermissions(contentReader,
|
|
rootFolder,
|
|
ItemPrivileges.VIEW_PUBLISHED);
|
|
|
|
grantPermissions(contentReader,
|
|
rootAssetFolder,
|
|
AssetPrivileges.VIEW);
|
|
|
|
getEntityManager().persist(alertRecipient);
|
|
getEntityManager().persist(author);
|
|
getEntityManager().persist(editor);
|
|
getEntityManager().persist(manager);
|
|
getEntityManager().persist(publisher);
|
|
getEntityManager().persist(contentReader);
|
|
|
|
section.addRole(alertRecipient);
|
|
section.addRole(author);
|
|
section.addRole(editor);
|
|
section.addRole(manager);
|
|
section.addRole(publisher);
|
|
section.addRole(contentReader);
|
|
|
|
LOGGER.debug("Setting ItemResolver for content section '{}'...",
|
|
sectionName);
|
|
final String itemResolverClassName;
|
|
if (getIntegrationProps().containsKey(String.format("%s.item_resolver",
|
|
sectionName))) {
|
|
|
|
itemResolverClassName = getIntegrationProps().getProperty(
|
|
String.format("%s.item_resolver",
|
|
sectionName));
|
|
LOGGER.debug("integration.properties contains setting for the item "
|
|
+ "resolver of content section '{}'. Using "
|
|
+ "item resolver '{}'.",
|
|
sectionName, itemResolverClassName);
|
|
} else if (getIntegrationProps().containsKey("default_item_resolver")) {
|
|
itemResolverClassName = getIntegrationProps().getProperty(
|
|
"default_item_resolver_name");
|
|
LOGGER.debug("integration.properties contains setting for the "
|
|
+ "default item resolver. Using item "
|
|
+ "resolver '{}'.",
|
|
itemResolverClassName);
|
|
} else {
|
|
itemResolverClassName = MultilingualItemResolver.class.getName();
|
|
LOGGER.debug("integration.properties contains *no* setting for item "
|
|
+ "resolver. Using default item resolver '{}'.",
|
|
itemResolverClassName);
|
|
}
|
|
section.setItemResolverClass(itemResolverClassName);
|
|
|
|
LOGGER.debug("Adding default content types to content section '{}'...",
|
|
sectionName);
|
|
final String[] types;
|
|
if (getIntegrationProps().containsKey(String.format("%s.content_types",
|
|
sectionName))) {
|
|
final String typesStr = getIntegrationProps().getProperty(String
|
|
.format("%s.content_types", sectionName));
|
|
LOGGER.debug("integration.properties contains setting for content "
|
|
+ "types of section '{}': {}",
|
|
sectionName,
|
|
typesStr);
|
|
types = typesStr.split(",");
|
|
} else if (getIntegrationProps().containsKey("default_content_types")) {
|
|
final String typesStr = getIntegrationProps().getProperty(
|
|
"default_content_types");
|
|
LOGGER.debug("integration.properties contains setting for default "
|
|
+ "content types for all sections: {}",
|
|
typesStr);
|
|
types = typesStr.split(",");
|
|
} else {
|
|
LOGGER.debug("integration.properties contains not settings for "
|
|
+ "default content types. Using internal default: {}",
|
|
String.join(", ", DEFAULT_TYPES));
|
|
types = DEFAULT_TYPES;
|
|
}
|
|
Arrays.stream(types).forEach(type -> addContentTypeToSection(section,
|
|
type,
|
|
author,
|
|
editor,
|
|
manager));
|
|
|
|
getEntityManager().merge(section);
|
|
}
|
|
|
|
private void addContentTypeToSection(final ContentSection section,
|
|
final String contentType,
|
|
final Role... roles) {
|
|
final String typeClassName = contentType.trim();
|
|
LOGGER.debug("Adding content type '{}' to content section '{}'...",
|
|
contentType,
|
|
section.getPrimaryUrl());
|
|
final Class<?> clazz;
|
|
try {
|
|
clazz = Class.forName(typeClassName);
|
|
} catch (ClassNotFoundException ex) {
|
|
throw new UnexpectedErrorException(String.format(
|
|
"No class for content type '%s'.", typeClassName));
|
|
}
|
|
|
|
if (ContentItem.class.isAssignableFrom(clazz)) {
|
|
LOGGER.warn("'{}' is not is assignable from '{}'!",
|
|
ContentItem.class.getName(),
|
|
clazz.getName());
|
|
final ContentType type = new ContentType();
|
|
type.setContentSection(section);
|
|
type.setUuid(UUID.randomUUID().toString());
|
|
type.setContentItemClass(clazz.getName());
|
|
getEntityManager().persist(type);
|
|
section.addContentType(type);
|
|
|
|
Arrays.stream(roles)
|
|
.forEach(role -> grantPermission(role,
|
|
TypePrivileges.USE_TYPE,
|
|
type));
|
|
} else {
|
|
throw new UnexpectedErrorException(String.format(
|
|
"The class '%s' is not a sub class of '%s'.",
|
|
clazz.getName(),
|
|
ContentItem.class.getName()));
|
|
}
|
|
}
|
|
|
|
}
|