CCM NG: Several components for the page model

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5056 8810af33-2d31-482b-a856-94f89814c4df
jensp 2017-10-18 09:32:17 +00:00
parent 952ef32587
commit 5de1dcf43f
10 changed files with 876 additions and 108 deletions

View File

@ -18,19 +18,19 @@
*/ */
package org.librecms.pagemodel; package org.librecms.pagemodel;
import org.libreccm.categorization.Category; import com.arsdigita.kernel.KernelConfig;
import org.libreccm.categorization.CategoryManager; import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.CategoryRepository; import org.libreccm.categorization.CategoryRepository;
import org.libreccm.core.CcmObject; import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.core.UnexpectedErrorException; import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.l10n.GlobalizationHelper; import org.libreccm.l10n.LocalizedString;
import org.libreccm.pagemodel.ComponentBuilder; import org.libreccm.pagemodel.ComponentBuilder;
import org.libreccm.pagemodel.ComponentModelType; import org.libreccm.pagemodel.ComponentModel;
import org.libreccm.security.PermissionChecker; import org.libreccm.security.PermissionChecker;
import org.librecms.contentsection.ContentItem; import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemL10NManager; import org.librecms.contentsection.ContentItemL10NManager;
import org.librecms.contentsection.ContentItemManager; import org.librecms.contentsection.ContentItemManager;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.privileges.ItemPrivileges; import org.librecms.contentsection.privileges.ItemPrivileges;
import java.beans.BeanInfo; import java.beans.BeanInfo;
@ -39,14 +39,14 @@ import java.beans.Introspector;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject; import javax.inject.Inject;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import javax.ws.rs.NotFoundException; import javax.ws.rs.NotFoundException;
@ -58,119 +58,93 @@ import static org.librecms.pages.PagesConstants.*;
/** /**
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @param <T>
*/ */
@RequestScoped public abstract class AbstractContentItemComponentBuilder<T extends ContentItemComponent>
@ComponentModelType(componentModel = GreetingItem.class) implements ComponentBuilder<T> {
public class GreetingItemBuilder implements ComponentBuilder<GreetingItem> {
@Inject @Inject
private GlobalizationHelper globalizationHelper; private ConfigurationManager confManager;
@Inject
private CategoryRepository categoryRepo;
@Inject @Inject
private ContentItemL10NManager iteml10nManager; private ContentItemL10NManager iteml10nManager;
@Inject
private CategoryManager categoryManager;
@Inject @Inject
private ContentItemManager itemManager; private ContentItemManager itemManager;
@Inject
private ContentItemRepository itemRepo;
@Inject @Inject
private PermissionChecker permissionChecker; private PermissionChecker permissionChecker;
protected abstract ContentItem getContentItem(
T componentModel, final Map<String, Object> parameters);
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
@Override @Override
public Map<String, Object> buildComponent( public Map<String, Object> buildComponent(
final GreetingItem componentModel, final T componentModel,
final Map<String, Object> parameters) { final Map<String, Object> parameters) {
Objects.requireNonNull(componentModel); Objects.requireNonNull(componentModel);
Objects.requireNonNull(parameters); Objects.requireNonNull(parameters);
if (!parameters.containsKey(PARAMETER_CATEGORY)) { final ContentItem contentItem = getContentItem(componentModel,
throw new IllegalArgumentException("The parameters map passed to " parameters);
+ "this GreetingItem component does not include the parameter "
+ "\"category\"");
}
if (!(parameters.get(PARAMETER_CATEGORY) instanceof Category)) { if (Boolean.TRUE.equals(parameters.get("showDraftItem"))) {
throw new IllegalArgumentException(String
.format("The parameters map passed to "
+ "this GreetingItem component contains the parameter "
+ "\"category\", but the parameter is not of type"
+ "\"%s\" but of type \"%s\".",
Category.class.getName(),
parameters.get(PARAMETER_CATEGORY).getClass().getName()));
}
final Category category = categoryRepo final ContentItem draftItem = itemManager
.findById(((CcmObject) parameters.get(PARAMETER_CATEGORY)) .getDraftVersion(contentItem, contentItem.getClass());
.getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No category with ID %d in the database.",
((CcmObject) parameters.get(PARAMETER_CATEGORY)).getObjectId())));
final Optional<CcmObject> indexObj = categoryManager if (permissionChecker.isPermitted(ItemPrivileges.PREVIEW, draftItem)) {
.getIndexObject(category); final Map<String, Object> result = generateItem(componentModel,
parameters,
draftItem);
result.put("showDraftItem", Boolean.TRUE);
if (indexObj.isPresent()) { return result;
if (indexObj.get() instanceof ContentItem) {
final ContentItem indexItem;
if (itemManager.isLive((ContentItem) indexObj.get())) {
indexItem = itemManager
.getLiveVersion((ContentItem) indexObj.get(),
ContentItem.class)
.get();
} else {
throw new NotFoundException(String
.format(
"The index item %s of category %s does not have "
+ "a live version.",
Objects.toString(indexObj),
Objects.toString(category)));
}
if (permissionChecker.isPermitted(ItemPrivileges.VIEW_PUBLISHED,
indexItem)) {
return generateGreetingItem(componentModel,
parameters,
indexItem);
} else {
throw new WebApplicationException(
"You are not permitted to view the view version of this item.",
Response.Status.UNAUTHORIZED);
}
} else { } else {
throw new NotFoundException(String throw new WebApplicationException(
.format("The index object %s of category %s is not a " "You are not permitted to view the draft version of this item.",
+ "ContentItem.", Response.Status.UNAUTHORIZED);
Objects.toString(indexObj),
Objects.toString(category)));
} }
} else { } else {
throw new NotFoundException(String
.format("The category %s does not have a index item.", final ContentItem liveItem = itemManager
Objects.toString(category))); .getLiveVersion(contentItem, contentItem.getClass())
.orElseThrow(() -> new NotFoundException(
"This content item does not "
+ "have a live version."));
if (permissionChecker.isPermitted(ItemPrivileges.VIEW_PUBLISHED,
liveItem)) {
return generateItem(componentModel,
parameters,
liveItem);
} else {
throw new WebApplicationException(
"You are not permitted to view the live version of "
+ "this item.",
Response.Status.UNAUTHORIZED);
}
} }
} }
private Map<String, Object> generateGreetingItem( protected Map<String, Object> generateItem(
final GreetingItem componentModel, final T componentModel,
final Map<String, Object> parameters, final Map<String, Object> parameters,
final ContentItem item) { final ContentItem item) {
final String language = (String) parameters.get(PARAMETER_LANGUAGE); final Locale language;
if (parameters.containsKey("language")) {
if (iteml10nManager.hasLanguage(item, new Locale(language))) { language = new Locale((String) parameters.get(PARAMETER_LANGUAGE));
} else {
final KernelConfig kernelConfig = confManager
.findConfiguration(KernelConfig.class);
language = kernelConfig.getDefaultLocale();
}
if (iteml10nManager.hasLanguage(item, language)) {
final BeanInfo beanInfo; final BeanInfo beanInfo;
try { try {
beanInfo = Introspector.getBeanInfo(item.getClass()); beanInfo = Introspector.getBeanInfo(item.getClass());
@ -184,7 +158,11 @@ public class GreetingItemBuilder implements ComponentBuilder<GreetingItem> {
final Map<String, Object> result = new HashMap<>(); final Map<String, Object> result = new HashMap<>();
for (final PropertyDescriptor propertyDescriptor : properties) { for (final PropertyDescriptor propertyDescriptor : properties) {
renderProperty(propertyDescriptor, componentModel, item, result); renderProperty(propertyDescriptor,
componentModel,
language,
item,
result);
} }
return result; return result;
@ -193,10 +171,11 @@ public class GreetingItemBuilder implements ComponentBuilder<GreetingItem> {
} }
} }
private void renderProperty(final PropertyDescriptor propertyDescriptor, protected void renderProperty(final PropertyDescriptor propertyDescriptor,
final GreetingItem componentModel, final T componentModel,
final ContentItem item, final Locale language,
final Map<String, Object> result) { final ContentItem item,
final Map<String, Object> result) {
final String propertyName = propertyDescriptor.getName(); final String propertyName = propertyDescriptor.getName();
if (componentModel.getExcludedPropertyPaths().contains(propertyName)) { if (componentModel.getExcludedPropertyPaths().contains(propertyName)) {
@ -207,26 +186,50 @@ public class GreetingItemBuilder implements ComponentBuilder<GreetingItem> {
if (Collection.class.isAssignableFrom(propertyDescriptor if (Collection.class.isAssignableFrom(propertyDescriptor
.getPropertyType())) { .getPropertyType())) {
final Map<String, Object> associated; final Collection<?> collection;
try { try {
associated = generateAssociatedObject(readMethod.invoke(item)); collection = (Collection<?>) readMethod.invoke(item);
} catch (IllegalAccessException | InvocationTargetException ex) { } catch (IllegalAccessException | InvocationTargetException ex) {
throw new UnsupportedOperationException(ex); throw new UnexpectedErrorException(ex);
} }
result.put(propertyName, associated);
final List<Map<String, Object>> associatedObjs = new ArrayList<>();
for (final Object obj : collection) {
associatedObjs.add(generateAssociatedObject(obj));
}
result.put(propertyName, associatedObjs);
} else if (isValueType(propertyDescriptor.getPropertyType())) { } else if (isValueType(propertyDescriptor.getPropertyType())) {
try { try {
result.put(propertyName, readMethod.invoke(item)); result.put(propertyName, readMethod.invoke(item));
} catch (IllegalAccessException | InvocationTargetException ex) { } catch (IllegalAccessException | InvocationTargetException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }
} else if (LocalizedString.class.isAssignableFrom(propertyDescriptor
.getPropertyType())) {
final LocalizedString localizedString;
try {
localizedString = (LocalizedString) readMethod.invoke(item);
} catch (IllegalAccessException | InvocationTargetException ex) {
throw new UnexpectedErrorException(ex);
}
result.put(propertyName, localizedString.getValue(language));
} else { } else {
//ToDo final Map<String, Object> associatedObj;
try {
associatedObj
= generateAssociatedObject(readMethod.invoke(item));
} catch (IllegalAccessException | InvocationTargetException ex) {
throw new UnexpectedErrorException(ex);
}
result.put(propertyName, associatedObj);
} }
} }
private Map<String, Object> generateAssociatedObject(final Object obj) { protected Map<String, Object> generateAssociatedObject(final Object obj) {
final BeanInfo beanInfo; final BeanInfo beanInfo;
try { try {
@ -247,7 +250,7 @@ public class GreetingItemBuilder implements ComponentBuilder<GreetingItem> {
result.put(propertyDescriptor.getName(), result.put(propertyDescriptor.getName(),
readMethod.invoke(obj)); readMethod.invoke(obj));
} catch (IllegalAccessException } catch (IllegalAccessException
| InvocationTargetException ex) { | InvocationTargetException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }
} }
@ -256,7 +259,7 @@ public class GreetingItemBuilder implements ComponentBuilder<GreetingItem> {
return result; return result;
} }
private boolean isValueType(final Class<?> typeToTest) { protected boolean isValueType(final Class<?> typeToTest) {
final Class<?>[] types = new Class<?>[]{ final Class<?>[] types = new Class<?>[]{
Boolean.class, Boolean.class,
Boolean.TYPE, Boolean.TYPE,

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2017 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.pagemodel;
import javax.persistence.Entity;
import javax.persistence.Table;
import static org.librecms.CmsConstants.*;
/**
* A component for showing a content item which is assigned to a category.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "CATEGORIZED_ITEM_COMPONENT", schema = DB_SCHEMA)
public class CategorizedItemComponent extends ContentItemComponent {
private static final long serialVersionUID = 6366311513244770272L;
@Override
public boolean canEqual(final Object obj) {
return obj instanceof CategorizedItemComponent;
}
}

View File

@ -0,0 +1,127 @@
/*
* Copyright (C) 2017 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.pagemodel;
import org.libreccm.categorization.Categorization;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.core.CcmObject;
import org.libreccm.pagemodel.ComponentModelType;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemVersion;
import java.util.Map;
import java.util.Objects;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;
import javax.ws.rs.NotFoundException;
import static org.librecms.pages.PagesConstants.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@ComponentModelType(componentModel = CategorizedItemComponent.class)
public class CategorizedItemComponentBuilder
extends AbstractContentItemComponentBuilder<CategorizedItemComponent> {
@Inject
private CategoryRepository categoryRepo;
@Inject
private EntityManager entityManager;
@Override
protected ContentItem getContentItem(
final CategorizedItemComponent componentModel,
final Map<String, Object> parameters) {
Objects.requireNonNull(componentModel);
Objects.requireNonNull(parameters);
if (!parameters.containsKey(PARAMETER_CATEGORY)) {
throw new IllegalArgumentException(String
.format("The parameters map passed to this component does "
+ "not include the parameter \"%s\"",
PARAMETER_CATEGORY));
}
if (!parameters.containsKey(PARAMETER_ITEMNAME)) {
throw new IllegalArgumentException(String
.format("The parameters map passed to this component does "
+ "not include the parameter \"%s\"",
PARAMETER_ITEMNAME));
}
if (!(parameters.get(PARAMETER_CATEGORY) instanceof Category)) {
throw new IllegalArgumentException(String
.format("The parameters map passed to this GreetingItem "
+ "component contains the parameter \"category\", but the "
+ "parameter is not of type \"%s\" but of type \"%s\".",
Category.class.getName(),
parameters.get(PARAMETER_CATEGORY).getClass().getName()));
}
final Category category = categoryRepo
.findById(((CcmObject) parameters.get(PARAMETER_CATEGORY))
.getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No category with ID %d in the database.",
((CcmObject) parameters.get(PARAMETER_CATEGORY)).getObjectId())));
final String itemName = (String) parameters.get(PARAMETER_ITEMNAME);
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<ContentItem> criteriaQuery = builder
.createQuery(ContentItem.class);
final Root<ContentItem> from = criteriaQuery.from(ContentItem.class);
final Join<ContentItem, Categorization> join = from
.join("categories");
final TypedQuery<ContentItem> query = entityManager
.createQuery(criteriaQuery
.select(from)
.where(builder.and(
builder.equal(from.get("displayName"), itemName),
builder.equal(from.get("version"), ContentItemVersion.DRAFT),
builder.equal(join.get("category"), category)
)));
try {
return query.getSingleResult();
} catch (NoResultException ex) {
throw new NotFoundException(String
.format("No ContentItem with name \"%s\" in Category \"%s\".",
itemName,
Objects.toString(category)));
}
}
}

View File

@ -0,0 +1,97 @@
/*
* Copyright (C) 2017 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.pagemodel;
import org.libreccm.pagemodel.ComponentModel;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import static org.librecms.CmsConstants.*;
/**
* A component which shows the category tree. Depending on the parameters set
* either the complete category tree is shown or the sub tree of the current
* category.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "CATEGORY_TREE_COMPONENTS", schema = DB_SCHEMA)
public class CategoryTreeComponent extends ComponentModel {
private static final long serialVersionUID = 9142791033478189003L;
@Column(name = "SHOW_FULL_TREE")
private boolean showFullTree;
public boolean isShowFullTree() {
return showFullTree;
}
public void setShowFullTree(final boolean showFullTree) {
this.showFullTree = showFullTree;
}
@Override
public int hashCode() {
int hash = super.hashCode();
hash = 61 * hash + (showFullTree ? 1 : 0);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof CategoryTreeComponent)) {
return false;
}
final CategoryTreeComponent other = (CategoryTreeComponent) obj;
if (!other.canEqual(this)) {
return false;
}
return showFullTree == other.isShowFullTree();
}
@Override
public boolean canEqual(final Object obj) {
return obj instanceof CategoryTreeComponent;
}
@Override
public String toString(final String data) {
return super.toString(String.format(", showFullTree = %b%s",
showFullTree,
data));
}
}

View File

@ -0,0 +1,190 @@
/*
* Copyright (C) 2017 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.pagemodel;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.categorization.DomainRepository;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.core.CcmObject;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.pagemodel.ComponentBuilder;
import org.libreccm.pagemodel.ComponentModelType;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import static org.librecms.pages.PagesConstants.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@ComponentModelType(componentModel = CategoryTreeComponent.class)
public class CategoryTreeComponentBuilder
implements ComponentBuilder<CategoryTreeComponent> {
@Inject
private DomainRepository domainRepo;
@Inject
private CategoryManager categoryManager;
@Inject
private CategoryRepository categoryRepo;
@Inject
private ConfigurationManager confManager;
@Inject
private GlobalizationHelper globalizationHelper;
@Transactional(Transactional.TxType.REQUIRED)
@Override
public Map<String, Object> buildComponent(
final CategoryTreeComponent componentModel,
final Map<String, Object> parameters) {
Objects.requireNonNull(componentModel);
Objects.requireNonNull(parameters);
if (!parameters.containsKey(PARAMETER_CATEGORY)) {
throw new IllegalArgumentException(
"The parameters map passed to this GreetingItem component does "
+ "not include the parameter \"category\"");
}
if (!(parameters.get(PARAMETER_CATEGORY) instanceof Category)) {
throw new IllegalArgumentException(String
.format("The parameters map passed to this GreetingItem "
+ "component contains the parameter \"category\", but the "
+ "parameter is not of type \"%s\" but of type \"%s\".",
Category.class.getName(),
parameters.get(PARAMETER_CATEGORY).getClass().getName()));
}
final Category category = categoryRepo
.findById(((CcmObject) parameters.get(PARAMETER_CATEGORY))
.getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No category with ID %d in the database.",
((CcmObject) parameters.get(PARAMETER_CATEGORY)).getObjectId())));
final Locale language;
if (parameters.containsKey(PARAMETER_LANGUAGE)) {
language = new Locale((String) parameters.get(PARAMETER_LANGUAGE));
} else {
final KernelConfig kernelConfig = confManager
.findConfiguration(KernelConfig.class);
language = kernelConfig.getDefaultLocale();
}
final Map<String, Object> result = new HashMap<>();
if (componentModel.isShowFullTree()) {
final Category rootCategory = findRootCategory(category);
result.put("categoryName", rootCategory.getName());
result.put("categoryPath",
categoryManager.getCategoryPath(rootCategory));
result.put("categoryTitle",
rootCategory.getTitle().getValue(language));
result.put("selected", rootCategory.equals(category));
final List<Map<String, Object>> subCategories = rootCategory
.getSubCategories()
.stream()
.map(current -> generateCategoryWithTree(current,
category,
language))
.collect(Collectors.toList());
result.put("subCategories", subCategories);
} else {
result.put("categoryName", category.getName());
result.put("categoryPath",
categoryManager.getCategoryPath(category));
result.put("categoryTitle", category.getTitle().getValue(language));
final List<Map<String, Object>> subCategories = category
.getSubCategories()
.stream()
.map(current -> generateCategory(current, language))
.collect(Collectors.toList());
result.put("subCategories", subCategories);
}
return result;
}
protected Map<String, Object> generateCategory(final Category category,
final Locale language) {
final Map<String, Object> result = new HashMap<>();
result.put("categoryName", category.getName());
result.put("categoryPath", categoryManager.getCategoryPath(category));
result.put("categoryTitle", category.getTitle().getValue(language));
return result;
}
protected Map<String, Object> generateCategoryWithTree(
final Category category,
final Category selectedCategory,
final Locale language) {
final Map<String, Object> result = new HashMap<>();
result.put("categoryName", category.getName());
result.put("categoryPath", categoryManager.getCategoryPath(category));
result.put("categoryTitle", category.getTitle().getValue(language));
result.put("selected", selectedCategory.equals(category));
if (!category.getSubCategories().isEmpty()) {
final List<Map<String, Object>> subCategories = category
.getSubCategories()
.stream()
.map(current -> generateCategoryWithTree(current,
selectedCategory,
language))
.collect(Collectors.toList());
result.put("subCategories", subCategories);
}
return result;
}
protected Category findRootCategory(final Category category) {
if (category.getParentCategory() == null) {
return category;
} else {
return findRootCategory(category.getParentCategory());
}
}
}

View File

@ -18,7 +18,6 @@
*/ */
package org.librecms.pagemodel; package org.librecms.pagemodel;
import org.libreccm.categorization.Category;
import org.libreccm.pagemodel.ComponentModel; import org.libreccm.pagemodel.ComponentModel;
import org.libreccm.pagemodel.PageModel; import org.libreccm.pagemodel.PageModel;
@ -36,16 +35,16 @@ import javax.persistence.Table;
import static org.librecms.CmsConstants.*; import static org.librecms.CmsConstants.*;
/** /**
* A {@link PageModel} component model for displaying the Greeting/Index item of * Basic {@link PageModel} component for displaying a content item. This class
* a {@link Category}. * is not indented for direct use. The subclasses should be used instead.
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@Entity @Entity
@Table(name = "GREETING_ITEMS", schema = DB_SCHEMA) @Table(name = "CONTENT_ITEM_COMPONENTS", schema = DB_SCHEMA)
public class GreetingItem extends ComponentModel { public class ContentItemComponent extends ComponentModel {
private static final long serialVersionUID = -5509783666595294223L; private static final long serialVersionUID = 4904530823926147281L;
@ElementCollection @ElementCollection
@CollectionTable(name = "GREETING_ITEM_INCLUDED_PATHS", @CollectionTable(name = "GREETING_ITEM_INCLUDED_PATHS",
@ -63,7 +62,7 @@ public class GreetingItem extends ComponentModel {
}) })
private Set<String> excludedProperties; private Set<String> excludedProperties;
public GreetingItem() { public ContentItemComponent() {
includedPropertyPaths = new HashSet<>(); includedPropertyPaths = new HashSet<>();
excludedProperties = new HashSet<>(); excludedProperties = new HashSet<>();
} }
@ -121,10 +120,10 @@ public class GreetingItem extends ComponentModel {
if (!super.equals(obj)) { if (!super.equals(obj)) {
return false; return false;
} }
if (!(obj instanceof GreetingItem)) { if (!(obj instanceof ContentItemComponent)) {
return false; return false;
} }
final GreetingItem other = (GreetingItem) obj; final ContentItemComponent other = (ContentItemComponent) obj;
if (!other.canEqual(this)) { if (!other.canEqual(this)) {
return false; return false;
} }
@ -139,7 +138,7 @@ public class GreetingItem extends ComponentModel {
@Override @Override
public boolean canEqual(final Object obj) { public boolean canEqual(final Object obj) {
return obj instanceof GreetingItem; return obj instanceof ContentItemComponent;
} }
@Override @Override

View File

@ -0,0 +1,96 @@
/*
* Copyright (C) 2017 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.pagemodel;
import org.librecms.contentsection.ContentItem;
import java.util.Objects;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import static org.librecms.CmsConstants.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "FIXED_CONTENT_ITEM_COMPONENT", schema = DB_SCHEMA)
public class FixedContentItemComponent extends ContentItemComponent {
private static final long serialVersionUID = -4518031021801472455L;
@OneToOne
@JoinColumn(name = "CONTENT_ITEM_ID")
private ContentItem contentItem;
public ContentItem getContentItem() {
return contentItem;
}
public void setContentItem(final ContentItem contentItem) {
this.contentItem = contentItem;
}
@Override
public int hashCode() {
int hash = super.hashCode();
hash = 41 * hash + Objects.hashCode(contentItem);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof FixedContentItemComponent)) {
return false;
}
final FixedContentItemComponent other = (FixedContentItemComponent) obj;
if (!other.canEqual(this)) {
return false;
}
return Objects.equals(contentItem, other.getContentItem());
}
@Override
public boolean canEqual(final Object obj) {
return obj instanceof FixedContentItemComponent;
}
@Override
public String toString(final String data) {
return super.toString(String.format(", contentItem = %s%s",
Objects.toString(contentItem),
data));
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2017 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.pagemodel;
import org.libreccm.pagemodel.ComponentModelType;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemRepository;
import java.util.Map;
import java.util.Objects;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.ws.rs.NotFoundException;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@ComponentModelType(componentModel = FixedContentItemComponent.class)
public class FixedContentItemComponentBuilder
extends AbstractContentItemComponentBuilder<FixedContentItemComponent> {
@Inject
private ContentItemRepository itemRepo;
@Override
protected ContentItem getContentItem(
final FixedContentItemComponent componentModel,
final Map<String, Object> parameters) {
Objects.requireNonNull(componentModel);
Objects.requireNonNull(parameters);
if (componentModel.getContentItem() == null) {
throw new NotFoundException("No ContentItem configured.");
}
return itemRepo
.findById(componentModel.getContentItem().getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String
.format("No ContentItem with ID %d in the database.",
componentModel.getContentItem().getObjectId())));
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2017 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.pagemodel;
import org.libreccm.categorization.Category;
import org.libreccm.pagemodel.PageModel;
import javax.persistence.Entity;
import javax.persistence.Table;
import static org.librecms.CmsConstants.*;
/**
* A {@link PageModel} component model for displaying the Greeting/Index item of
* a {@link Category}.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "GREETING_ITEM_COMPONENTS", schema = DB_SCHEMA)
public class GreetingItemComponent extends ContentItemComponent {
private static final long serialVersionUID = 592400386436077481L;
@Override
public boolean canEqual(final Object obj) {
return obj instanceof GreetingItemComponent;
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2017 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.pagemodel;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.core.CcmObject;
import org.libreccm.pagemodel.ComponentModelType;
import org.librecms.contentsection.ContentItem;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.ws.rs.NotFoundException;
import static org.librecms.pages.PagesConstants.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@ComponentModelType(componentModel = GreetingItemComponent.class)
public class GreetingItemComponentBuilder
extends AbstractContentItemComponentBuilder<GreetingItemComponent> {
@Inject
private CategoryRepository categoryRepo;
@Inject
private CategoryManager categoryManager;
@Override
protected ContentItem getContentItem(
final GreetingItemComponent componentModel,
final Map<String, Object> parameters) {
Objects.requireNonNull(componentModel);
Objects.requireNonNull(parameters);
if (!parameters.containsKey(PARAMETER_CATEGORY)) {
throw new IllegalArgumentException(
"The parameters map passed to this GreetingItem component does "
+ "not include the parameter \"category\"");
}
if (!(parameters.get(PARAMETER_CATEGORY) instanceof Category)) {
throw new IllegalArgumentException(String
.format("The parameters map passed to this GreetingItem "
+ "component contains the parameter \"category\", but the "
+ "parameter is not of type \"%s\" but of type \"%s\".",
Category.class.getName(),
parameters.get(PARAMETER_CATEGORY).getClass().getName()));
}
final Category category = categoryRepo
.findById(((CcmObject) parameters.get(PARAMETER_CATEGORY))
.getObjectId())
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No category with ID %d in the database.",
((CcmObject) parameters.get(PARAMETER_CATEGORY)).getObjectId())));
final Optional<CcmObject> indexObj = categoryManager
.getIndexObject(category);
if (indexObj.isPresent()) {
if (indexObj.get() instanceof ContentItem) {
return (ContentItem) indexObj.get();
} else {
throw new NotFoundException(String
.format(
"The index item %s of category %s does not have "
+ "a live version.",
Objects.toString(indexObj),
Objects.toString(category)));
}
} else {
throw new NotFoundException(String
.format("The category %s does not have a index item.",
Objects.toString(category)));
}
}
}