- Added some more JavaDoc
- Replaced return values in CcmObjectRepository with Optional for methods which not return a value


git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4234 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2016-08-30 12:55:35 +00:00
parent 38c421efd7
commit 94fc4dcded
4 changed files with 218 additions and 176 deletions

View File

@ -63,6 +63,7 @@ import javax.persistence.TypedQuery;
import javax.transaction.Transactional; import javax.transaction.Transactional;
/** /**
* Manager class providing several methods to manipulate {@link ContentItem}s.
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@ -70,7 +71,7 @@ import javax.transaction.Transactional;
public class ContentItemManager { public class ContentItemManager {
private static final Logger LOGGER = LogManager.getLogger( private static final Logger LOGGER = LogManager.getLogger(
ContentItemManager.class); ContentItemManager.class);
@Inject @Inject
private EntityManager entityManager; private EntityManager entityManager;
@ -104,29 +105,29 @@ public class ContentItemManager {
* {@link ContentSection#rootDocumentsFolder} of the provided content * {@link ContentSection#rootDocumentsFolder} of the provided content
* section. Otherwise an {@link IllegalArgumentException} is thrown. * section. Otherwise an {@link IllegalArgumentException} is thrown.
* *
* @param <T> The type of the content item. * @param <T> The type of the content item.
* @param name The name (URL stub) of the new 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 section The content section in which the item is generated.
* @param folder The folder in which in the item is stored. * @param folder The folder in which in the item is stored.
* @param type The type of the new content item. * @param type The type of the new content item.
* *
* @return The new content item. * @return The new content item.
*/ */
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public <T extends ContentItem> T createContentItem( public <T extends ContentItem> T createContentItem(
final String name, final String name,
final ContentSection section, final ContentSection section,
final Category folder, final Category folder,
final Class<T> type) { final Class<T> type) {
final Optional<ContentType> contentType = typeRepo final Optional<ContentType> contentType = typeRepo
.findByContentSectionAndClass(section, type); .findByContentSectionAndClass(section, type);
if (!contentType.isPresent()) { if (!contentType.isPresent()) {
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"ContentSection \"%s\" has no content type for \"%s\".", "ContentSection \"%s\" has no content type for \"%s\".",
section.getLabel(), section.getLabel(),
type.getName())); type.getName()));
} }
return createContentItem(name, return createContentItem(name,
@ -149,54 +150,53 @@ public class ContentItemManager {
* {@link WorkflowTemplate} must be defined in the provided content section. * {@link WorkflowTemplate} must be defined in the provided content section.
* Otherwise an {@link IllegalArgumentException} is thrown. * Otherwise an {@link IllegalArgumentException} is thrown.
* *
* @param <T> The type of the content item. * @param <T> The type of the content item.
* @param name The name (URL stub) of the new content item. * @param name The name (URL stub) of the new content item.
* @param section The content section in which the item is * @param section The content section in which the item is generated.
* generated. * @param folder The folder in which in the item is stored.
* @param folder The folder in which in the item is stored.
* @param workflowTemplate * @param workflowTemplate
* @param lifecycleDefinition * @param lifecycleDefinition
* @param type The type of the new content item. * @param type The type of the new content item.
* *
* @return The new content item. * @return The new content item.
*/ */
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public <T extends ContentItem> T createContentItem( public <T extends ContentItem> T createContentItem(
final String name, final String name,
final ContentSection section, final ContentSection section,
final Category folder, final Category folder,
final WorkflowTemplate workflowTemplate, final WorkflowTemplate workflowTemplate,
final LifecycleDefinition lifecycleDefinition, final LifecycleDefinition lifecycleDefinition,
final Class<T> type) { final Class<T> type) {
final Optional<ContentType> contentType = typeRepo final Optional<ContentType> contentType = typeRepo
.findByContentSectionAndClass(section, type); .findByContentSectionAndClass(section, type);
if (!contentType.isPresent()) { if (!contentType.isPresent()) {
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"ContentSection \"%s\" has no content type for \"%s\".", "ContentSection \"%s\" has no content type for \"%s\".",
section.getLabel(), section.getLabel(),
type.getName())); type.getName()));
} }
final Lifecycle lifecycle = lifecycleManager.createLifecycle( final Lifecycle lifecycle = lifecycleManager.createLifecycle(
lifecycleDefinition); lifecycleDefinition);
final Workflow workflow = workflowManager.createWorkflow( final Workflow workflow = workflowManager.createWorkflow(
workflowTemplate); workflowTemplate);
final T item; final T item;
try { try {
item = type.newInstance(); item = type.newInstance();
} catch (InstantiationException | IllegalAccessException ex) { } catch (InstantiationException | IllegalAccessException ex) {
LOGGER.error("Failed to create new content item of type \"{}\" " LOGGER.error("Failed to create new content item of type \"{}\" "
+ "in content section \"{}\".", + "in content section \"{}\".",
type.getName(), type.getName(),
section.getLabel()); section.getLabel());
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
final KernelConfig kernelConfig = confManager.findConfiguration( final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class); KernelConfig.class);
item.setDisplayName(name); item.setDisplayName(name);
item.getName().addValue(new Locale(kernelConfig.getDefaultLanguage()), item.getName().addValue(new Locale(kernelConfig.getDefaultLanguage()),
@ -216,7 +216,7 @@ public class ContentItemManager {
* only moves the draft version of the item. The live version is moved after * only moves the draft version of the item. The live version is moved after
* a the item is republished. * a the item is republished.
* *
* @param item The item to move. * @param item The item to move.
* @param targetFolder The folder to which the item is moved. * @param targetFolder The folder to which the item is moved.
*/ */
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
@ -241,23 +241,23 @@ public class ContentItemManager {
* Creates an copy of the draft version of the item in the provided * Creates an copy of the draft version of the item in the provided
* {@code targetFolder}. * {@code targetFolder}.
* *
* @param item The item to copy. * @param item The item to copy.
* @param targetFolder The folder in which the copy is created. If the * @param targetFolder The folder in which the copy is created. If the
* target folder is the same folder as the folder of the * target folder is the same folder as the folder of the original item an
* original item an index is appended to the name of the * index is appended to the name of the item.
* item.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void copy(final ContentItem item, final Category targetFolder) { public void copy(final ContentItem item, final Category targetFolder) {
final Optional<ContentType> contentType = typeRepo final Optional<ContentType> contentType = typeRepo
.findByContentSectionAndClass( .findByContentSectionAndClass(
item.getContentType().getContentSection(), item.getClass()); item.getContentType().getContentSection(), item.
getClass());
if (!contentType.isPresent()) { if (!contentType.isPresent()) {
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"ContentSection \"%s\" has no content type for \"%s\".", "ContentSection \"%s\" has no content type for \"%s\".",
item.getContentType().getContentSection(), item.getContentType().getContentSection(),
item.getClass().getName())); item.getClass().getName()));
} }
final ContentItem draftItem = getDraftVersion(item, item.getClass()); final ContentItem draftItem = getDraftVersion(item, item.getClass());
@ -272,30 +272,30 @@ public class ContentItemManager {
copy.setContentType(contentType.get()); copy.setContentType(contentType.get());
final Lifecycle lifecycle = lifecycleManager.createLifecycle( final Lifecycle lifecycle = lifecycleManager.createLifecycle(
contentType.get().getDefaultLifecycle()); contentType.get().getDefaultLifecycle());
final Workflow workflow = workflowManager.createWorkflow(contentType final Workflow workflow = workflowManager.createWorkflow(contentType
.get().getDefaultWorkflow()); .get().getDefaultWorkflow());
copy.setLifecycle(lifecycle); copy.setLifecycle(lifecycle);
copy.setWorkflow(workflow); copy.setWorkflow(workflow);
draftItem.getCategories().forEach(categorization -> categoryManager draftItem.getCategories().forEach(categorization -> categoryManager
.addObjectToCategory(copy, categorization.getCategory())); .addObjectToCategory(copy, categorization.getCategory()));
final Optional<Category> itemFolder = getItemFolder(draftItem); final Optional<Category> itemFolder = getItemFolder(draftItem);
if (itemFolder.isPresent()) { if (itemFolder.isPresent()) {
try { try {
categoryManager.removeObjectFromCategory( categoryManager.removeObjectFromCategory(
copy, getItemFolder(draftItem).get()); copy, getItemFolder(draftItem).get());
} catch (ObjectNotAssignedToCategoryException ex) { } catch (ObjectNotAssignedToCategoryException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
} }
categoryManager.addObjectToCategory( categoryManager.addObjectToCategory(
copy, copy,
targetFolder, targetFolder,
CmsConstants.CATEGORIZATION_TYPE_FOLDER); CmsConstants.CATEGORIZATION_TYPE_FOLDER);
// !!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!
// ToDo copy Attachments // ToDo copy Attachments
@ -310,7 +310,7 @@ public class ContentItemManager {
} }
for (final PropertyDescriptor propertyDescriptor : beanInfo for (final PropertyDescriptor propertyDescriptor : beanInfo
.getPropertyDescriptors()) { .getPropertyDescriptors()) {
if (propertyIsExcluded(propertyDescriptor.getName())) { if (propertyIsExcluded(propertyDescriptor.getName())) {
continue; continue;
} }
@ -332,9 +332,10 @@ public class ContentItemManager {
} }
source.getAvailableLocales().forEach( source.getAvailableLocales().forEach(
locale -> target.addValue(locale, source.getValue(locale))); locale -> target.addValue(locale, source.
getValue(locale)));
} else if (propType != null } else if (propType != null
&& propType.isAssignableFrom(ContentItem.class)) { && propType.isAssignableFrom(ContentItem.class)) {
final ContentItem linkedItem; final ContentItem linkedItem;
try { try {
@ -346,7 +347,7 @@ public class ContentItemManager {
} }
final ContentItem linkedDraftItem = getDraftVersion( final ContentItem linkedDraftItem = getDraftVersion(
linkedItem, linkedItem.getClass()); linkedItem, linkedItem.getClass());
try { try {
writeMethod.invoke(copy, linkedDraftItem); writeMethod.invoke(copy, linkedDraftItem);
@ -356,7 +357,7 @@ public class ContentItemManager {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
} else if (propType != null } else if (propType != null
&& propType.isAssignableFrom(List.class)) { && propType.isAssignableFrom(List.class)) {
final List<Object> source; final List<Object> source;
final List<Object> target; final List<Object> target;
try { try {
@ -370,7 +371,7 @@ public class ContentItemManager {
target.addAll(source); target.addAll(source);
} else if (propType != null } else if (propType != null
&& propType.isAssignableFrom(Map.class)) { && propType.isAssignableFrom(Map.class)) {
final Map<Object, Object> source; final Map<Object, Object> source;
final Map<Object, Object> target; final Map<Object, Object> target;
@ -385,7 +386,7 @@ public class ContentItemManager {
source.forEach((key, value) -> target.put(key, value)); source.forEach((key, value) -> target.put(key, value));
} else if (propType != null } else if (propType != null
&& propType.isAssignableFrom(Set.class)) { && propType.isAssignableFrom(Set.class)) {
final Set<Object> source; final Set<Object> source;
final Set<Object> target; final Set<Object> target;
@ -459,7 +460,7 @@ public class ContentItemManager {
liveItem.setWorkflow(draftItem.getWorkflow()); liveItem.setWorkflow(draftItem.getWorkflow());
draftItem.getCategories().forEach(categorization -> categoryManager draftItem.getCategories().forEach(categorization -> categoryManager
.addObjectToCategory(item, categorization.getCategory())); .addObjectToCategory(item, categorization.getCategory()));
liveItem.setUuid(draftItem.getUuid()); liveItem.setUuid(draftItem.getUuid());
@ -476,7 +477,7 @@ public class ContentItemManager {
} }
for (final PropertyDescriptor propertyDescriptor : beanInfo for (final PropertyDescriptor propertyDescriptor : beanInfo
.getPropertyDescriptors()) { .getPropertyDescriptors()) {
if (propertyIsExcluded(propertyDescriptor.getName())) { if (propertyIsExcluded(propertyDescriptor.getName())) {
continue; continue;
@ -499,9 +500,10 @@ public class ContentItemManager {
} }
source.getAvailableLocales().forEach( source.getAvailableLocales().forEach(
locale -> target.addValue(locale, source.getValue(locale))); locale -> target.addValue(locale, source.
getValue(locale)));
} else if (propType != null } else if (propType != null
&& propType.isAssignableFrom(ContentItem.class)) { && propType.isAssignableFrom(ContentItem.class)) {
final ContentItem linkedItem; final ContentItem linkedItem;
try { try {
linkedItem = (ContentItem) readMethod.invoke(draftItem); linkedItem = (ContentItem) readMethod.invoke(draftItem);
@ -512,13 +514,13 @@ public class ContentItemManager {
} }
final ContentItem linkedDraftItem = getDraftVersion( final ContentItem linkedDraftItem = getDraftVersion(
linkedItem, linkedItem.getClass()); linkedItem, linkedItem.getClass());
if (isLive(linkedDraftItem)) { if (isLive(linkedDraftItem)) {
try { try {
final Optional<ContentItem> linkedLiveItem final Optional<ContentItem> linkedLiveItem
= getLiveVersion( = getLiveVersion(
linkedDraftItem, ContentItem.class); linkedDraftItem, ContentItem.class);
writeMethod.invoke(liveItem, linkedLiveItem); writeMethod.invoke(liveItem, linkedLiveItem);
} catch (IllegalAccessException | } catch (IllegalAccessException |
IllegalArgumentException | IllegalArgumentException |
@ -527,7 +529,7 @@ public class ContentItemManager {
} }
} }
} else if (propType != null } else if (propType != null
&& propType.isAssignableFrom(List.class)) { && propType.isAssignableFrom(List.class)) {
final List<Object> source; final List<Object> source;
final List<Object> target; final List<Object> target;
try { try {
@ -541,7 +543,7 @@ public class ContentItemManager {
target.addAll(source); target.addAll(source);
} else if (propType != null } else if (propType != null
&& propType.isAssignableFrom(Map.class)) { && propType.isAssignableFrom(Map.class)) {
final Map<Object, Object> source; final Map<Object, Object> source;
final Map<Object, Object> target; final Map<Object, Object> target;
@ -556,7 +558,7 @@ public class ContentItemManager {
source.forEach((key, value) -> target.put(key, value)); source.forEach((key, value) -> target.put(key, value));
} else if (propType != null } else if (propType != null
&& propType.isAssignableFrom(Set.class)) { && propType.isAssignableFrom(Set.class)) {
final Set<Object> source; final Set<Object> source;
final Set<Object> target; final Set<Object> target;
@ -587,7 +589,8 @@ public class ContentItemManager {
} }
/** /**
* Unpublishes a content item by deleting its live version if any. * Unpublishes a content item by deleting its live version if there is a
* live version.
* *
* @param item * @param item
*/ */
@ -595,7 +598,7 @@ public class ContentItemManager {
public void unpublish(final ContentItem item public void unpublish(final ContentItem item
) { ) {
final Optional<ContentItem> liveItem = getLiveVersion( final Optional<ContentItem> liveItem = getLiveVersion(
item, ContentItem.class); item, ContentItem.class);
if (liveItem.isPresent()) { if (liveItem.isPresent()) {
entityManager.remove(liveItem); entityManager.remove(liveItem);
@ -609,11 +612,11 @@ public class ContentItemManager {
* @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.
*/ */
public boolean isLive(final ContentItem item) { public boolean isLive(final ContentItem item) {
final TypedQuery<Boolean> query = entityManager.createNamedQuery( final TypedQuery<Boolean> query = entityManager.createNamedQuery(
"ContentItem.hasLiveVersion", Boolean.class); "ContentItem.hasLiveVersion", Boolean.class);
query.setParameter("uuid", item.getUuid()); query.setParameter("uuid", item.getUuid());
return query.getSingleResult(); return query.getSingleResult();
@ -622,24 +625,24 @@ 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> Type of the content item. * @param <T> Type of the content item.
* @param item The item of which the live version should be retrieved. * @param item The item of which the live version should be retrieved.
* @param type Type of the content item. * @param type Type of the content item.
* *
* @return The live version of an item. If the item provided is already the * @return The live version of an item. If the item provided is already the
* live version the provided item is returned, otherwise the live * live version the provided item is returned, otherwise the live version is
* version is returned. If there is no live version an empty * returned. If there is no live version an empty {@link Optional} is
* {@link Optional} is returned. * returned.
*/ */
public <T extends ContentItem> Optional<T> getLiveVersion( public <T extends ContentItem> Optional<T> getLiveVersion(
final ContentItem item, final ContentItem item,
final Class<T> type) { final Class<T> type) {
if (isLive(item)) { if (isLive(item)) {
final TypedQuery<T> query = entityManager.createNamedQuery( final TypedQuery<T> query = entityManager.createNamedQuery(
"ContentItem.findLiveVersion", type); "ContentItem.findLiveVersion", type);
query.setParameter("uuid", item.getUuid()); query.setParameter("uuid", item.getUuid());
return Optional.of(query.getSingleResult()); return Optional.of(query.getSingleResult());
} else { } else {
return Optional.empty(); return Optional.empty();
@ -649,38 +652,38 @@ public class ContentItemManager {
/** /**
* Retrieves the pending versions of an item if there are any. * Retrieves the pending versions of an item if there are any.
* *
* @param <T> Type of the content item to retrieve. * @param <T> Type of the content item to retrieve.
* @param item The item of which the pending versions are retrieved. * @param item The item of which the pending versions are retrieved.
* @param type Type of the content item to retrieve. * @param type Type of the content item to retrieve.
* *
* @return A list of the pending versions of the item. * @return A list of the pending versions of the item.
*/ */
public <T extends ContentItem> List<T> getPendingVersions( public <T extends ContentItem> List<T> getPendingVersions(
final ContentItem item, final ContentItem item,
final Class<T> type) { final Class<T> type) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/** /**
* Retrieves the draft version * Retrieves the draft version
* *
* @param <T> Type of the item. * @param <T> Type of the item.
* @param item The item of which the draft version is retrieved. * @param item The item of which the draft version is retrieved.
* @param type Type of the item. * @param type Type of the item.
* *
* @return The draft version of the provided content item. If the provided * @return The draft version of the provided content item. If the provided
* item is the draft version the provided item is simply returned. * item is the draft version the provided item is simply returned. Otherwise
* Otherwise the draft version is retrieved from the database and is * the draft version is retrieved from the database and is returned. Each
* returned. Each content item has a draft version (otherwise * content item has a draft version (otherwise something is seriously wrong
* something is seriously wrong with the database) this method will * with the database) this method will
* <b>never</b> return {@code null}. * <b>never</b> return {@code null}.
*/ */
public <T extends ContentItem> T getDraftVersion(final ContentItem item, public <T extends ContentItem> T getDraftVersion(final ContentItem item,
final Class<T> type) { final Class<T> type) {
final TypedQuery<T> query = entityManager.createNamedQuery( final TypedQuery<T> query = entityManager.createNamedQuery(
"ContentItem.findDraftVersion", type); "ContentItem.findDraftVersion", type);
query.setParameter("uuid", item.getUuid()); query.setParameter("uuid", item.getUuid());
return query.getSingleResult(); return query.getSingleResult();
} }
@ -717,9 +720,9 @@ public class ContentItemManager {
* {@code info}, the path including the content section would be * {@code info}, the path including the content section would be
* {@code info:/research/computer-science/artificial-intelligence/neural-nets}. * {@code info:/research/computer-science/artificial-intelligence/neural-nets}.
* *
* @param item The item whose path is generated. * @param item The item whose path is generated.
* @param withContentSection Wether to include the content section into the * @param withContentSection Wether to include the content section into the
* path. * path.
* *
* @return The path of the content item * @return The path of the content item
* *
@ -728,9 +731,9 @@ public class ContentItemManager {
public String getItemPath(final ContentItem item, public String getItemPath(final ContentItem item,
final boolean withContentSection) { final boolean withContentSection) {
final List<Categorization> result = item.getCategories().stream(). final List<Categorization> result = item.getCategories().stream().
filter(categorization -> CmsConstants.CATEGORIZATION_TYPE_FOLDER. filter(categorization -> CmsConstants.CATEGORIZATION_TYPE_FOLDER.
equals(categorization.getType())) equals(categorization.getType()))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (result.isEmpty()) { if (result.isEmpty()) {
return item.getDisplayName(); return item.getDisplayName();
@ -751,9 +754,9 @@ public class ContentItemManager {
if (withContentSection) { if (withContentSection) {
final String sectionName = item.getContentType(). final String sectionName = item.getContentType().
getContentSection().getDisplayName(); getContentSection().getDisplayName();
return String.format( return String.format(
"%s/%s", sectionName, path); "%s/%s", sectionName, path);
} else { } else {
return String.format("/%s", path); return String.format("/%s", path);
} }
@ -769,9 +772,9 @@ public class ContentItemManager {
*/ */
public List<Category> getItemFolders(final ContentItem item) { public List<Category> getItemFolders(final ContentItem item) {
final List<Categorization> result = item.getCategories().stream(). final List<Categorization> result = item.getCategories().stream().
filter(categorization -> CmsConstants.CATEGORIZATION_TYPE_FOLDER. filter(categorization -> CmsConstants.CATEGORIZATION_TYPE_FOLDER.
equals(categorization.getType())) equals(categorization.getType()))
.collect(Collectors.toList()); .collect(Collectors.toList());
final List<Category> folders = new ArrayList<>(); final List<Category> folders = new ArrayList<>();
if (!result.isEmpty()) { if (!result.isEmpty()) {
@ -797,13 +800,13 @@ public class ContentItemManager {
* @param item The item * @param item The item
* *
* @return An {@link Optional} containing the folder of the item if the item * @return An {@link Optional} containing the folder of the item if the item
* is part of a folder. * is part of a folder.
*/ */
public Optional<Category> getItemFolder(final ContentItem item) { public Optional<Category> getItemFolder(final ContentItem item) {
final List<Categorization> result = item.getCategories().stream(). final List<Categorization> result = item.getCategories().stream().
filter(categorization -> CmsConstants.CATEGORIZATION_TYPE_FOLDER. filter(categorization -> CmsConstants.CATEGORIZATION_TYPE_FOLDER.
equals(categorization.getType())) equals(categorization.getType()))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (result.size() > 0) { if (result.size() > 0) {
return Optional.of(result.get(0).getCategory()); return Optional.of(result.get(0).getCategory());

View File

@ -23,15 +23,12 @@ import org.libreccm.categorization.Category;
import org.libreccm.core.CcmObject; import org.libreccm.core.CcmObject;
import org.libreccm.core.CcmObjectRepository; import org.libreccm.core.CcmObjectRepository;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.inject.Inject; import javax.inject.Inject;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import jdk.nashorn.internal.objects.NativeArray;
/** /**
* Repository for content items. * Repository for content items.
@ -69,9 +66,9 @@ public class ContentItemRepository
* nothing if there is such content item. * nothing if there is such content item.
*/ */
public Optional<ContentItem> findById(final long itemId) { public Optional<ContentItem> findById(final long itemId) {
final CcmObject result = ccmObjectRepo.findObjectById(itemId); final Optional<CcmObject> result = ccmObjectRepo.findObjectById(itemId);
if (result instanceof ContentItem) { if (result.isPresent() && result.get() instanceof ContentItem) {
return Optional.of((ContentItem) result); return Optional.of((ContentItem) result.get());
} else { } else {
return Optional.empty(); return Optional.empty();
} }
@ -107,12 +104,12 @@ public class ContentItemRepository
* @return The content item identified by the provided {@code uuid} or * @return The content item identified by the provided {@code uuid} or
* nothing if there is such content item. * nothing if there is such content item.
*/ */
public ContentItem findByUuid(final String uuid) { public Optional<ContentItem> findByUuid(final String uuid) {
final CcmObject result = ccmObjectRepo.findObjectByUuid(uuid); final Optional<CcmObject> result = ccmObjectRepo.findObjectByUuid(uuid);
if (result instanceof ContentItem) { if (result.isPresent() && result.get() instanceof ContentItem) {
return (ContentItem) result; return Optional.of((ContentItem) result.get());
} else { } else {
return null; return Optional.empty();
} }
} }
@ -131,10 +128,11 @@ public class ContentItemRepository
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends ContentItem> Optional<T> findByUuid(final String uuid, public <T extends ContentItem> Optional<T> findByUuid(final String uuid,
final Class<T> type) { final Class<T> type) {
final CcmObject result = ccmObjectRepo.findObjectByUuid(uuid); final Optional<CcmObject> result = ccmObjectRepo.findObjectByUuid(uuid);
if (result.getClass().isAssignableFrom(type)) { if (result.isPresent()
return Optional.of((T) result); && result.get().getClass().isAssignableFrom(type)) {
return Optional.of((T) result.get());
} else { } else {
return Optional.empty(); return Optional.empty();
} }
@ -166,21 +164,34 @@ public class ContentItemRepository
*/ */
public List<ContentItem> findByFolder(final Category folder) { public List<ContentItem> findByFolder(final Category folder) {
final TypedQuery<ContentItem> query = getEntityManager() final TypedQuery<ContentItem> query = getEntityManager()
.createNamedQuery("ContentItem.findByFolder", .createNamedQuery("ContentItem.findByFolder",
ContentItem.class); ContentItem.class);
query.setParameter("folder", folder); query.setParameter("folder", folder);
return query.getResultList(); return query.getResultList();
} }
/**
* Counts the items in a folder/category.
*
* @param folder The folder/category
* @return The number of content items in the category/folder.
*/
public long countItemsInFolder(final Category folder) { public long countItemsInFolder(final Category folder) {
final TypedQuery<Long> query = getEntityManager() final TypedQuery<Long> query = getEntityManager()
.createNamedQuery("ContentItem.countItemsInFolder", Long.class); .createNamedQuery("ContentItem.countItemsInFolder", Long.class);
query.setParameter("folder", folder); query.setParameter("folder", folder);
return query.getSingleResult(); return query.getSingleResult();
} }
/**
* Counts the number of items with a specific name in a folder/category.
*
* @param folder
* @param name
* @return
*/
public long countByNameInFolder(final Category folder, final String name) { public long countByNameInFolder(final Category folder, final String name) {
final TypedQuery<Long> query = getEntityManager().createNamedQuery( final TypedQuery<Long> query = getEntityManager().createNamedQuery(
"ContentItem.countByNameInFolder", Long.class); "ContentItem.countByNameInFolder", Long.class);
@ -190,6 +201,15 @@ public class ContentItemRepository
return query.getSingleResult(); return query.getSingleResult();
} }
/**
* Retrieves all items in a specific folder where
* {@link CcmObject#displayName} of the item starts with the provided
* pattern.
*
* @param folder The folder/category whose items are filtered.
* @param name The name pattern to use.
* @return A list with all items in the folder matching the provided filter.
*/
public List<ContentItem> filterByFolderAndName(final Category folder, public List<ContentItem> filterByFolderAndName(final Category folder,
final String name) { final String name) {
final TypedQuery<ContentItem> query = getEntityManager() final TypedQuery<ContentItem> query = getEntityManager()
@ -201,6 +221,15 @@ public class ContentItemRepository
return query.getResultList(); return query.getResultList();
} }
/**
* Counts a items in a specfic folder whose {@link CcmObject#displayName}
* starts with the provided pattern.
*
* @param folder The folder/category to use.
* @param name The name pattern to use.
* @return The number of items in the folder/category which match the
* provided pattern.
*/
public long countFilterByFolderAndName(final Category folder, public long countFilterByFolderAndName(final Category folder,
final String name) { final String name) {
final TypedQuery<Long> query = getEntityManager() final TypedQuery<Long> query = getEntityManager()

View File

@ -27,6 +27,7 @@ import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SaveCancelSection; import com.arsdigita.bebop.SaveCancelSection;
import com.arsdigita.bebop.form.TextField; import com.arsdigita.bebop.form.TextField;
import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.globalization.GlobalizedMessage;
import java.util.Optional;
import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.CcmObject; import org.libreccm.core.CcmObject;
@ -55,14 +56,14 @@ class RolePermissionsForm extends Form {
private final SaveCancelSection saveCancelSection; private final SaveCancelSection saveCancelSection;
public RolePermissionsForm( public RolePermissionsForm(
final RoleAdmin roleAdmin, final RoleAdmin roleAdmin,
final ParameterSingleSelectionModel<String> selectedRoleId) { final ParameterSingleSelectionModel<String> selectedRoleId) {
super("rolePermissionsForm"); super("rolePermissionsForm");
final ActionLink backToRole = new ActionLink(new GlobalizedMessage( final ActionLink backToRole = new ActionLink(new GlobalizedMessage(
"ui.admin.group_details.add_permission.back", "ui.admin.group_details.add_permission.back",
ADMIN_BUNDLE)); ADMIN_BUNDLE));
backToRole.addActionListener(e -> { backToRole.addActionListener(e -> {
roleAdmin.showRolePermissionsPanel(e.getPageState()); roleAdmin.showRolePermissionsPanel(e.getPageState());
}); });
@ -75,112 +76,113 @@ class RolePermissionsForm extends Form {
final Label target = (Label) e.getTarget(); final Label target = (Label) e.getTarget();
final RoleRepository roleRepository = CdiUtil.createCdiUtil() final RoleRepository roleRepository = CdiUtil.createCdiUtil()
.findBean(RoleRepository.class); .findBean(RoleRepository.class);
final Role role = roleRepository.findById(Long.parseLong( final Role role = roleRepository.findById(Long.parseLong(
selectedRoleId.getSelectedKey(state))); selectedRoleId.getSelectedKey(state)));
target.setLabel(new GlobalizedMessage( target.setLabel(new GlobalizedMessage(
"ui.admin.role_details.add_permission.heading", "ui.admin.role_details.add_permission.heading",
ADMIN_BUNDLE, ADMIN_BUNDLE,
new String[]{role.getName()})); new String[]{role.getName()}));
}); });
add(heading); add(heading);
objectId = new TextField(OBJECT_ID); objectId = new TextField(OBJECT_ID);
objectId.setLabel(new GlobalizedMessage( objectId.setLabel(new GlobalizedMessage(
"ui.admin.role_details.add_permission.object_id.label", "ui.admin.role_details.add_permission.object_id.label",
ADMIN_BUNDLE)); ADMIN_BUNDLE));
objectId.setHint(new GlobalizedMessage( objectId.setHint(new GlobalizedMessage(
"ui.admin.role_details.add_permission.object_id.hint", "ui.admin.role_details.add_permission.object_id.hint",
ADMIN_BUNDLE ADMIN_BUNDLE
)); ));
add(objectId); add(objectId);
privilege = new TextField(PRIVILEGE); privilege = new TextField(PRIVILEGE);
privilege.setLabel(new GlobalizedMessage( privilege.setLabel(new GlobalizedMessage(
"ui.admin.role_details.add_permission.privilege.label", "ui.admin.role_details.add_permission.privilege.label",
ADMIN_BUNDLE)); ADMIN_BUNDLE));
privilege.setHint(new GlobalizedMessage( privilege.setHint(new GlobalizedMessage(
"ui.admin.role_details.add_permission.privilege.hint", "ui.admin.role_details.add_permission.privilege.hint",
ADMIN_BUNDLE ADMIN_BUNDLE
)); ));
add(privilege); add(privilege);
saveCancelSection = new SaveCancelSection(); saveCancelSection = new SaveCancelSection();
add(saveCancelSection); add(saveCancelSection);
addValidationListener(e -> { addValidationListener(event -> {
final PageState state = e.getPageState(); final PageState state = event.getPageState();
if (saveCancelSection.getSaveButton().isSelected(state)) { if (saveCancelSection.getSaveButton().isSelected(state)) {
final FormData data = e.getFormData(); final FormData data = event.getFormData();
final String privilegeData = data.getString(PRIVILEGE); final String privilegeData = data.getString(PRIVILEGE);
if (privilegeData == null || privilegeData.isEmpty()) { if (privilegeData == null || privilegeData.isEmpty()) {
data.addError(PRIVILEGE, new GlobalizedMessage( data.addError(PRIVILEGE, new GlobalizedMessage(
"ui.admin.role_details.add_permission." "ui.admin.role_details.add_permission."
+ "privilege.error.notempty", + "privilege.error.notempty",
ADMIN_BUNDLE)); ADMIN_BUNDLE));
} }
final String objectIdData = data.getString(OBJECT_ID); final String objectIdData = data.getString(OBJECT_ID);
if (objectIdData != null && !objectIdData.isEmpty()) { if (objectIdData != null && !objectIdData.isEmpty()) {
final CcmObjectRepository objectRepository = CdiUtil final CcmObjectRepository objectRepository = CdiUtil
.createCdiUtil().findBean(CcmObjectRepository.class); .createCdiUtil().findBean(CcmObjectRepository.class);
try { try {
Long.parseLong(objectIdData); Long.parseLong(objectIdData);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
data.addError( data.addError(
OBJECT_ID, OBJECT_ID,
new GlobalizedMessage( new GlobalizedMessage(
"ui.admin.role_details.add_permission.object_id" "ui.admin.role_details.add_permission.object_id"
+ ".error.nan", + ".error.nan",
ADMIN_BUNDLE)); ADMIN_BUNDLE));
return; return;
} }
final CcmObject object = objectRepository.findObjectById( final Optional<CcmObject> object = objectRepository.
Long.parseLong(objectIdData)); findObjectById(
if (object == null) { Long.parseLong(objectIdData));
if (!object.isPresent()) {
data.addError( data.addError(
OBJECT_ID, OBJECT_ID,
new GlobalizedMessage( new GlobalizedMessage(
"ui.admin.role_details.add_permission.object_id" "ui.admin.role_details.add_permission.object_id"
+ ".error.no_object", + ".error.no_object",
ADMIN_BUNDLE)); ADMIN_BUNDLE));
} }
} }
} }
}); });
addProcessListener(e -> { addProcessListener(event -> {
final PageState state = e.getPageState(); final PageState state = event.getPageState();
if (saveCancelSection.getSaveButton().isSelected(state)) { if (saveCancelSection.getSaveButton().isSelected(state)) {
final FormData data = e.getFormData(); final FormData data = event.getFormData();
final String privilegeData = data.getString(PRIVILEGE); final String privilegeData = data.getString(PRIVILEGE);
final String objectIdData = data.getString(OBJECT_ID); final String objectIdData = data.getString(OBJECT_ID);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final RoleRepository roleRepository = cdiUtil.findBean( final RoleRepository roleRepository = cdiUtil.findBean(
RoleRepository.class); RoleRepository.class);
final Role role = roleRepository.findById(Long.parseLong( final Role role = roleRepository.findById(Long.parseLong(
selectedRoleId.getSelectedKey(state))); selectedRoleId.getSelectedKey(state)));
final PermissionManager permissionManager = cdiUtil.findBean( final PermissionManager permissionManager = cdiUtil.findBean(
PermissionManager.class); PermissionManager.class);
if (objectIdData == null || objectIdData.isEmpty()) { if (objectIdData == null || objectIdData.isEmpty()) {
permissionManager.grantPrivilege(privilegeData, role); permissionManager.grantPrivilege(privilegeData, role);
} else { } else {
final CcmObjectRepository objectRepository = cdiUtil final CcmObjectRepository objectRepository = cdiUtil
.findBean(CcmObjectRepository.class); .findBean(CcmObjectRepository.class);
final CcmObject object = objectRepository.findObjectById( final Optional<CcmObject> object = objectRepository
Long.parseLong(objectIdData)); .findObjectById(Long.parseLong(objectIdData));
permissionManager.grantPrivilege(privilegeData, permissionManager.grantPrivilege(privilegeData,
role, role,
object); object.get());
} }
} }

View File

@ -18,6 +18,8 @@
*/ */
package org.libreccm.core; package org.libreccm.core;
import java.util.Optional;
import static org.libreccm.core.CoreConstants.*; import static org.libreccm.core.CoreConstants.*;
import java.util.UUID; import java.util.UUID;
@ -47,7 +49,7 @@ public class CcmObjectRepository extends AbstractEntityRepository<Long, CcmObjec
if (ACCESS_DENIED.equals(entity.getDisplayName())) { if (ACCESS_DENIED.equals(entity.getDisplayName())) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Can't save the Access Denied object."); "Can't save the Access Denied object.");
} }
return entity.getObjectId() == 0; return entity.getObjectId() == 0;
@ -58,27 +60,33 @@ public class CcmObjectRepository extends AbstractEntityRepository<Long, CcmObjec
entity.setUuid(UUID.randomUUID().toString()); entity.setUuid(UUID.randomUUID().toString());
} }
public CcmObject findObjectById(final long objectId) { /**
* Finds a {@link CcmObject} by its id.
*
@param objectId The id of the item to find.
* @return
*/
public Optional<CcmObject> findObjectById(final long objectId) {
final TypedQuery<CcmObject> query = getEntityManager().createNamedQuery( final TypedQuery<CcmObject> query = getEntityManager().createNamedQuery(
"CcmObject.findById", CcmObject.class); "CcmObject.findById", CcmObject.class);
query.setParameter("id", objectId); query.setParameter("id", objectId);
try { try {
return query.getSingleResult(); return Optional.of(query.getSingleResult());
} catch (NoResultException ex) { } catch (NoResultException ex) {
return null; return Optional.empty();
} }
} }
public CcmObject findObjectByUuid(final String uuid) { public Optional<CcmObject> findObjectByUuid(final String uuid) {
final TypedQuery<CcmObject> query = getEntityManager().createNamedQuery( final TypedQuery<CcmObject> query = getEntityManager().createNamedQuery(
"CcmObject.findByUuid", CcmObject.class); "CcmObject.findByUuid", CcmObject.class);
query.setParameter("uuid", uuid); query.setParameter("uuid", uuid);
try { try {
return query.getSingleResult(); return Optional.of(query.getSingleResult());
} catch (NoResultException ex) { } catch (NoResultException ex) {
return null; return Optional.empty();
} }
} }