- EqualsAndHashCode test for classes org.librecms.contenttypes (not all of them yet)
- Some work on the ContentSectionManager, including documentation



git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4289 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2016-09-08 11:00:35 +00:00
parent 36defa4cb7
commit 448199806e
4 changed files with 222 additions and 51 deletions

View File

@ -42,6 +42,7 @@ import javax.inject.Inject;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import org.librecms.CmsConstants;
import org.librecms.lifecycle.LifecycleDefinition; import org.librecms.lifecycle.LifecycleDefinition;
@ -77,7 +78,8 @@ public class ContentSectionManager {
private ConfigurationManager confManager; private ConfigurationManager confManager;
/** /**
* Creates a new content section including the default roles. * Creates a new content section including the default roles. This operation
* requries {@code admin} privileges.
* *
* @param name The name of the new content section. * @param name The name of the new content section.
* *
@ -89,11 +91,11 @@ public class ContentSectionManager {
public ContentSection createContentSection(final String name) { public ContentSection createContentSection(final String name) {
if (name == null || name.isEmpty()) { if (name == null || name.isEmpty()) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The name of a ContentSection can't be blank."); "The name of a ContentSection can't be blank.");
} }
final KernelConfig kernelConfig = confManager.findConfiguration( final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class); KernelConfig.class);
final Locale defautLocale = kernelConfig.getDefaultLocale(); final Locale defautLocale = kernelConfig.getDefaultLocale();
final ContentSection section = new ContentSection(); final ContentSection section = new ContentSection();
@ -180,7 +182,7 @@ public class ContentSectionManager {
* Renames a content section and all roles associated with it (roles * Renames a content section and all roles associated with it (roles
* starting with the name of the content section). Note that you have to * starting with the name of the content section). Note that you have to
* rename the localised titles of the content section and the root folders * rename the localised titles of the content section and the root folders
* manually * manually. This operation requires {@code admin} privileges.
* *
* @param section The section to rename. * @param section The section to rename.
* *
@ -211,12 +213,24 @@ public class ContentSectionManager {
} }
} }
/**
* Adds new role to a content section. the new role will not have any
* members, they have to be added separatly. This operation requires
* {@link CmsConstants#PRIVILEGE_ADMINISTER_ROLES} for the provided content
* section.
*
* @param section The {@link ContentSection} to which the role is added.
* @param roleName The name of the new role.
* @param privileges The privileges of the new role.
*/
@AuthorizationRequired @AuthorizationRequired
@RequiresPrivilege(CoreConstants.ADMIN_PRIVILEGE)
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void addRoleToContentSection(final ContentSection section, public void addRoleToContentSection(
final String roleName, @RequiresPrivilege(PRIVILEGE_ADMINISTER_ROLES)
final String... privileges) { final ContentSection section,
final String roleName,
final String... privileges) {
final Role role = new Role(); final Role role = new Role();
role.setName(String.join("_", section.getLabel(), roleName)); role.setName(String.join("_", section.getLabel(), roleName));
roleRepo.save(role); roleRepo.save(role);
@ -226,20 +240,52 @@ public class ContentSectionManager {
permissionManager.grantPrivilege(privilege, role, rootFolder); permissionManager.grantPrivilege(privilege, role, rootFolder);
} }
// section.addRole(role);
// sectionRepo.save(section);
addRoleToContentSection(role, section);
}
/**
* Associates an existing role to with a content section. This will not
* grant any permissions for the content section to the role. This operation
* requires {@link CmsConstants#PRIVILEGE_ADMINISTER_ROLES} for the provided
* content section.
*
* @param role The role to add.
* @param section The section the role is associated with.
*/
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public void addRoleToContentSection(
final Role role,
@RequiresPrivilege(PRIVILEGE_ADMINISTER_ROLES)
final ContentSection section) {
section.addRole(role); section.addRole(role);
sectionRepo.save(section); sectionRepo.save(section);
} }
/**
* Removes a role from a content section and deletes all permissions of the
* role which are associated with the content section. The role itself is
* <strong>not</strong> deleted because the role is maybe is used in other
* places. This operation requires
* {@link CmsConstants#PRIVILEGE_ADMINISTER_ROLES} for the provided content
* section.
*
* @param contentSection The section from which the role is removed.
* @param role The role to remove from the content section.
*/
@AuthorizationRequired @AuthorizationRequired
@RequiresPrivilege(CoreConstants.ADMIN_PRIVILEGE)
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void removeRoleFromContentSection( public void removeRoleFromContentSection(
final ContentSection contentSection, @RequiresPrivilege(PRIVILEGE_ADMINISTER_ROLES)
final Role role) { final ContentSection contentSection,
final Role role) {
if (contentSection == null) { if (contentSection == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Can't remove role from ContentSection null"); "Can't remove role from ContentSection null");
} }
if (role == null) { if (role == null) {
@ -250,8 +296,8 @@ public class ContentSectionManager {
sectionRepo.save(contentSection); sectionRepo.save(contentSection);
final TypedQuery<Permission> query = entityManager final TypedQuery<Permission> query = entityManager
.createNamedQuery("ContentSection.findPermissions", .createNamedQuery("ContentSection.findPermissions",
Permission.class); Permission.class);
query.setParameter("section", contentSection); query.setParameter("section", contentSection);
query.setParameter("rootDocumentsFolder", query.setParameter("rootDocumentsFolder",
contentSection.getRootDocumentsFolder()); contentSection.getRootDocumentsFolder());
@ -261,64 +307,133 @@ public class ContentSectionManager {
permissions.forEach(p -> entityManager.remove(p)); permissions.forEach(p -> entityManager.remove(p));
} }
/**
* Associates a content type with a content section making the type
* available for use in the content section. This operation requires
* {@link CmsConstants#PRIVILEGE_ADMINISTER_CONTENT_TYPES} for the provided
* content section.
*
* @param type The {@link ContentItem} class representing the type to add.
* @param section The section to which to type is added.
*/
@AuthorizationRequired @AuthorizationRequired
@RequiresPrivilege(CoreConstants.ADMIN_PRIVILEGE)
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void addTypeToSection(final ContentType type, public void addTypeToSection(
final ContentSection section) { final Class<? extends ContentItem> type,
@RequiresPrivilege(PRIVILEGE_ADMINISTER_CONTENT_TYPES)
final ContentSection section) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/**
* Removes a content type from a content section. After this it is not
* possible to create new items of this type in the content section.
* Existing items are left untouched. This operation requires
* {@link CmsConstants#PRIVILEGE_ADMINISTER_CONTENT_TYPES} for the provided
* content section.
*
* @param type The type to remove.
* @param section The section from which the type is removed.
*/
@AuthorizationRequired @AuthorizationRequired
@RequiresPrivilege(CoreConstants.ADMIN_PRIVILEGE)
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void removeTypeFromSection(final ContentType type, public void removeTypeFromSection(
final ContentSection section) { final ContentType type,
@RequiresPrivilege(PRIVILEGE_ADMINISTER_CONTENT_TYPES)
final ContentSection section) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/**
* Adds a lifecycle definition to a content section. This operation requires
* {@link CmsConstants#PRIVILEGE_ADMINISTER_LIFECYLES} for the provided
* content section.
*
* @param definition The lifecycle definition to add.
* @param section The section to which the definition is added.
*/
@AuthorizationRequired @AuthorizationRequired
@RequiresPrivilege(CoreConstants.ADMIN_PRIVILEGE)
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void addLifecycleDefinitionToContentSection( public void addLifecycleDefinitionToContentSection(
final LifecycleDefinition definition, final LifecycleDefinition definition,
final ContentSection section) { @RequiresPrivilege(PRIVILEGE_ADMINISTER_LIFECYLES)
throw new UnsupportedOperationException(); final ContentSection section) {
section.addLifecycleDefinition(definition);
sectionRepo.save(section);
} }
/**
* Removes a lifecycle definition from a content section. This operation
* requires {@link CmsConstants#PRIVILEGE_ADMINISTER_LIFECYLES} for the
* provided content section.
*
* @param definition The definition to remove.
* @param section The section from which the definition is removed.
*/
@AuthorizationRequired @AuthorizationRequired
@RequiresPrivilege(CoreConstants.ADMIN_PRIVILEGE)
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void removeLifecycleDefinitionFromContentSection( public void removeLifecycleDefinitionFromContentSection(
final LifecycleDefinition definition, final LifecycleDefinition definition,
final ContentSection contentSection) { @RequiresPrivilege(PRIVILEGE_ADMINISTER_LIFECYLES)
throw new UnsupportedOperationException(); final ContentSection section) {
section.removeLifecycleDefinition(definition);
sectionRepo.save(section);
} }
/**
* Adds a workflow template to a content section. This operation requires
* {@link CmsConstants#PRIVILEGE_ADMINISTER_WORKFLOW} for the provided
* content section.
*
* @param template The template to add.
* @param section The content section to which the template is added.
*/
@AuthorizationRequired @AuthorizationRequired
@RequiresPrivilege(CoreConstants.ADMIN_PRIVILEGE)
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void addWorkflowTemplateToContentSection( public void addWorkflowTemplateToContentSection(
final WorkflowTemplate definition, final WorkflowTemplate template,
final ContentSection section) { @RequiresPrivilege(PRIVILEGE_ADMINISTER_WORKFLOW)
throw new UnsupportedOperationException(); final ContentSection section) {
section.addWorkflowTemplate(template);
sectionRepo.save(section);
} }
/**
* Removes a workflow template from a content section. This operation
* requires {@link CmsConstants#PRIVILEGE_ADMINISTER_WORKFLOW} for the
* provided content section.
*
* @param template The template to remove.
* @param section The section from which the template is removed.
*/
@AuthorizationRequired @AuthorizationRequired
@RequiresPrivilege(CoreConstants.ADMIN_PRIVILEGE)
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void removeWorkflowTemplateFromContentSection( public void removeWorkflowTemplateFromContentSection(
final LifecycleDefinition definition, final WorkflowTemplate template,
final ContentSection contentSection) { @RequiresPrivilege(PRIVILEGE_ADMINISTER_WORKFLOW)
throw new UnsupportedOperationException(); final ContentSection section) {
section.removeWorkflowTemplate(template);
sectionRepo.save(section);
} }
/**
* Retrieves the {@link ItemResolver} for the provided content section.
*
* @param section The section for which the {@link ItemResolver} is
* retrieved.
* @return The {@link ItemResolver} for the provided content section.
*/
public ItemResolver getItemResolver(final ContentSection section) { public ItemResolver getItemResolver(final ContentSection section) {
try { try {
final Class<ItemResolver> itemResolverClazz final Class<ItemResolver> itemResolverClazz
= (Class<ItemResolver>) Class. = (Class<ItemResolver>) Class.
forName(section.getItemResolverClass()); forName(section.getItemResolverClass());
return itemResolverClazz.newInstance(); return itemResolverClazz.newInstance();
} catch (ClassNotFoundException | } catch (ClassNotFoundException |
IllegalAccessException | IllegalAccessException |

View File

@ -27,14 +27,14 @@ import java.util.Objects;
/** /**
* Encapsulates the informations about an authoring kit. * Encapsulates the informations about an authoring kit.
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
public class AuthoringKitInfo { public class AuthoringKitInfo {
/** /**
* The create component (the form used to collect the mandatory data for * The create component (the form used to collect the mandatory data for the
* the content type). * content type).
*/ */
private Class<? extends ItemCreateForm> createComponent; private Class<? extends ItemCreateForm> createComponent;
@ -52,17 +52,21 @@ public class AuthoringKitInfo {
} }
public void setCreateComponent( public void setCreateComponent(
final Class<? extends ItemCreateForm> createComponent) { final Class<? extends ItemCreateForm> createComponent) {
this.createComponent = createComponent; this.createComponent = createComponent;
} }
public List<AuthoringStepInfo> getAuthoringSteps() { public List<AuthoringStepInfo> getAuthoringSteps() {
return Collections.unmodifiableList(authoringSteps); if (authoringSteps == null) {
return null;
} else {
return Collections.unmodifiableList(authoringSteps);
}
} }
protected void setAuthoringSteps( protected void setAuthoringSteps(
final List<AuthoringStepInfo> authoringSteps) { final List<AuthoringStepInfo> authoringSteps) {
this.authoringSteps = authoringSteps; this.authoringSteps = authoringSteps;
} }
@ -97,10 +101,10 @@ public class AuthoringKitInfo {
if (!other.canEqual(this)) { if (!other.canEqual(this)) {
return false; return false;
} }
if (!Objects.equals(this.createComponent, other.getCreateComponent())) { if (!Objects.equals(createComponent, other.getCreateComponent())) {
return false; return false;
} }
return Objects.equals(this.authoringSteps, other.getAuthoringSteps()); return Objects.equals(authoringSteps, other.getAuthoringSteps());
} }
public boolean canEqual(final Object obj) { public boolean canEqual(final Object obj) {
@ -114,9 +118,9 @@ public class AuthoringKitInfo {
public String toString(final String data) { public String toString(final String data) {
return String.format("%s{ " return String.format("%s{ "
+ "createComponent = \"%s\", " + "createComponent = \"%s\", "
+ "authoringSteps = { %s }%s" + "authoringSteps = { %s }%s"
+ " }", + " }",
super.toString(), super.toString(),
Objects.toString(createComponent), Objects.toString(createComponent),
Objects.toString(authoringSteps), Objects.toString(authoringSteps),

View File

@ -30,9 +30,7 @@ import org.libreccm.security.User;
import org.libreccm.tests.categories.UnitTest; 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.WorkflowTemplate; import org.libreccm.workflow.WorkflowTemplate;
import org.librecms.lifecycle.Lifecycle;
import org.librecms.lifecycle.LifecycleDefinition; import org.librecms.lifecycle.LifecycleDefinition;
import java.util.Arrays; import java.util.Arrays;

View File

@ -0,0 +1,54 @@
/*
* 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.contenttypes;
import java.util.Arrays;
import java.util.Collection;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.libreccm.tests.categories.UnitTest;
import org.libreccm.testutils.EqualsVerifier;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RunWith(Parameterized.class)
@org.junit.experimental.categories.Category(UnitTest.class)
public class EqualsAndHashCodeTest extends EqualsVerifier {
@Parameterized.Parameters(name = "{0}")
public static Collection<Class<?>> data() {
return Arrays.asList(new Class<?>[]{
AuthoringKitInfo.class,
AuthoringStepInfo.class,
ContentTypeInfo.class
});
}
public EqualsAndHashCodeTest(final Class<?> clazz) {
super(clazz);
}
@Override
protected void addPrefabValues(
final nl.jqno.equalsverifier.EqualsVerifier<?> verifier) {
}
}