From 5de1dcf43fc0b392c649dab322a7a0a1e936139a Mon Sep 17 00:00:00 2001 From: jensp Date: Wed, 18 Oct 2017 09:32:17 +0000 Subject: [PATCH] CCM NG: Several components for the page model git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5056 8810af33-2d31-482b-a856-94f89814c4df --- ... AbstractContentItemComponentBuilder.java} | 199 +++++++++--------- .../pagemodel/CategorizedItemComponent.java | 42 ++++ .../CategorizedItemComponentBuilder.java | 127 +++++++++++ .../pagemodel/CategoryTreeComponent.java | 97 +++++++++ .../CategoryTreeComponentBuilder.java | 190 +++++++++++++++++ ...ingItem.java => ContentItemComponent.java} | 19 +- .../pagemodel/FixedContentItemComponent.java | 96 +++++++++ .../FixedContentItemComponentBuilder.java | 63 ++++++ .../pagemodel/GreetingItemComponent.java | 46 ++++ .../GreetingItemComponentBuilder.java | 105 +++++++++ 10 files changed, 876 insertions(+), 108 deletions(-) rename ccm-cms/src/main/java/org/librecms/pagemodel/{GreetingItemBuilder.java => AbstractContentItemComponentBuilder.java} (54%) create mode 100644 ccm-cms/src/main/java/org/librecms/pagemodel/CategorizedItemComponent.java create mode 100644 ccm-cms/src/main/java/org/librecms/pagemodel/CategorizedItemComponentBuilder.java create mode 100644 ccm-cms/src/main/java/org/librecms/pagemodel/CategoryTreeComponent.java create mode 100644 ccm-cms/src/main/java/org/librecms/pagemodel/CategoryTreeComponentBuilder.java rename ccm-cms/src/main/java/org/librecms/pagemodel/{GreetingItem.java => ContentItemComponent.java} (88%) create mode 100644 ccm-cms/src/main/java/org/librecms/pagemodel/FixedContentItemComponent.java create mode 100644 ccm-cms/src/main/java/org/librecms/pagemodel/FixedContentItemComponentBuilder.java create mode 100644 ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemComponent.java create mode 100644 ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemComponentBuilder.java diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemBuilder.java b/ccm-cms/src/main/java/org/librecms/pagemodel/AbstractContentItemComponentBuilder.java similarity index 54% rename from ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemBuilder.java rename to ccm-cms/src/main/java/org/librecms/pagemodel/AbstractContentItemComponentBuilder.java index b90b41e42..6c6663ef9 100644 --- a/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemBuilder.java +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/AbstractContentItemComponentBuilder.java @@ -18,19 +18,19 @@ */ package org.librecms.pagemodel; -import org.libreccm.categorization.Category; +import com.arsdigita.kernel.KernelConfig; + import org.libreccm.categorization.CategoryManager; import org.libreccm.categorization.CategoryRepository; -import org.libreccm.core.CcmObject; +import org.libreccm.configuration.ConfigurationManager; import org.libreccm.core.UnexpectedErrorException; -import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.l10n.LocalizedString; import org.libreccm.pagemodel.ComponentBuilder; -import org.libreccm.pagemodel.ComponentModelType; +import org.libreccm.pagemodel.ComponentModel; import org.libreccm.security.PermissionChecker; import org.librecms.contentsection.ContentItem; import org.librecms.contentsection.ContentItemL10NManager; import org.librecms.contentsection.ContentItemManager; -import org.librecms.contentsection.ContentItemRepository; import org.librecms.contentsection.privileges.ItemPrivileges; import java.beans.BeanInfo; @@ -39,14 +39,14 @@ import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; -import java.util.Optional; -import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.transaction.Transactional; import javax.ws.rs.NotFoundException; @@ -58,119 +58,93 @@ import static org.librecms.pages.PagesConstants.*; /** * * @author Jens Pelzetter + * @param */ -@RequestScoped -@ComponentModelType(componentModel = GreetingItem.class) -public class GreetingItemBuilder implements ComponentBuilder { +public abstract class AbstractContentItemComponentBuilder + implements ComponentBuilder { @Inject - private GlobalizationHelper globalizationHelper; - - @Inject - private CategoryRepository categoryRepo; + private ConfigurationManager confManager; @Inject private ContentItemL10NManager iteml10nManager; - @Inject - private CategoryManager categoryManager; - @Inject private ContentItemManager itemManager; - @Inject - private ContentItemRepository itemRepo; - @Inject private PermissionChecker permissionChecker; + protected abstract ContentItem getContentItem( + T componentModel, final Map parameters); + @Transactional(Transactional.TxType.REQUIRED) @Override public Map buildComponent( - final GreetingItem componentModel, + final T componentModel, final Map 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\""); - } + final ContentItem contentItem = getContentItem(componentModel, + parameters); - 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())); - } + if (Boolean.TRUE.equals(parameters.get("showDraftItem"))) { - 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 ContentItem draftItem = itemManager + .getDraftVersion(contentItem, contentItem.getClass()); - final Optional indexObj = categoryManager - .getIndexObject(category); + if (permissionChecker.isPermitted(ItemPrivileges.PREVIEW, draftItem)) { + final Map result = generateItem(componentModel, + parameters, + draftItem); + result.put("showDraftItem", Boolean.TRUE); - if (indexObj.isPresent()) { - - 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); - } + return result; } else { - throw new NotFoundException(String - .format("The index object %s of category %s is not a " - + "ContentItem.", - Objects.toString(indexObj), - Objects.toString(category))); + throw new WebApplicationException( + "You are not permitted to view the draft version of this item.", + Response.Status.UNAUTHORIZED); } + } else { - throw new NotFoundException(String - .format("The category %s does not have a index item.", - Objects.toString(category))); + + final ContentItem liveItem = itemManager + .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 generateGreetingItem( - final GreetingItem componentModel, + protected Map generateItem( + final T componentModel, final Map parameters, final ContentItem item) { - final String language = (String) parameters.get(PARAMETER_LANGUAGE); - - if (iteml10nManager.hasLanguage(item, new Locale(language))) { + final Locale language; + if (parameters.containsKey("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; try { beanInfo = Introspector.getBeanInfo(item.getClass()); @@ -184,7 +158,11 @@ public class GreetingItemBuilder implements ComponentBuilder { final Map result = new HashMap<>(); for (final PropertyDescriptor propertyDescriptor : properties) { - renderProperty(propertyDescriptor, componentModel, item, result); + renderProperty(propertyDescriptor, + componentModel, + language, + item, + result); } return result; @@ -193,10 +171,11 @@ public class GreetingItemBuilder implements ComponentBuilder { } } - private void renderProperty(final PropertyDescriptor propertyDescriptor, - final GreetingItem componentModel, - final ContentItem item, - final Map result) { + protected void renderProperty(final PropertyDescriptor propertyDescriptor, + final T componentModel, + final Locale language, + final ContentItem item, + final Map result) { final String propertyName = propertyDescriptor.getName(); if (componentModel.getExcludedPropertyPaths().contains(propertyName)) { @@ -207,26 +186,50 @@ public class GreetingItemBuilder implements ComponentBuilder { if (Collection.class.isAssignableFrom(propertyDescriptor .getPropertyType())) { - final Map associated; + final Collection collection; try { - associated = generateAssociatedObject(readMethod.invoke(item)); + collection = (Collection) readMethod.invoke(item); } catch (IllegalAccessException | InvocationTargetException ex) { - throw new UnsupportedOperationException(ex); + throw new UnexpectedErrorException(ex); } - result.put(propertyName, associated); + + final List> associatedObjs = new ArrayList<>(); + for (final Object obj : collection) { + associatedObjs.add(generateAssociatedObject(obj)); + } + + result.put(propertyName, associatedObjs); } else if (isValueType(propertyDescriptor.getPropertyType())) { try { result.put(propertyName, readMethod.invoke(item)); } catch (IllegalAccessException | InvocationTargetException 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 { - //ToDo + final Map associatedObj; + try { + associatedObj + = generateAssociatedObject(readMethod.invoke(item)); + } catch (IllegalAccessException | InvocationTargetException ex) { + throw new UnexpectedErrorException(ex); + } + result.put(propertyName, associatedObj); } } - private Map generateAssociatedObject(final Object obj) { + protected Map generateAssociatedObject(final Object obj) { final BeanInfo beanInfo; try { @@ -247,7 +250,7 @@ public class GreetingItemBuilder implements ComponentBuilder { result.put(propertyDescriptor.getName(), readMethod.invoke(obj)); } catch (IllegalAccessException - | InvocationTargetException ex) { + | InvocationTargetException ex) { throw new UnexpectedErrorException(ex); } } @@ -256,7 +259,7 @@ public class GreetingItemBuilder implements ComponentBuilder { return result; } - private boolean isValueType(final Class typeToTest) { + protected boolean isValueType(final Class typeToTest) { final Class[] types = new Class[]{ Boolean.class, Boolean.TYPE, diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/CategorizedItemComponent.java b/ccm-cms/src/main/java/org/librecms/pagemodel/CategorizedItemComponent.java new file mode 100644 index 000000000..9017dfb3c --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/CategorizedItemComponent.java @@ -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 Jens Pelzetter + */ +@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; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/CategorizedItemComponentBuilder.java b/ccm-cms/src/main/java/org/librecms/pagemodel/CategorizedItemComponentBuilder.java new file mode 100644 index 000000000..650ef40aa --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/CategorizedItemComponentBuilder.java @@ -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 Jens Pelzetter + */ +@RequestScoped +@ComponentModelType(componentModel = CategorizedItemComponent.class) +public class CategorizedItemComponentBuilder + extends AbstractContentItemComponentBuilder { + + @Inject + private CategoryRepository categoryRepo; + + @Inject + private EntityManager entityManager; + + @Override + protected ContentItem getContentItem( + final CategorizedItemComponent componentModel, + final Map 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 criteriaQuery = builder + .createQuery(ContentItem.class); + + final Root from = criteriaQuery.from(ContentItem.class); + final Join join = from + .join("categories"); + + final TypedQuery 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))); + } + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/CategoryTreeComponent.java b/ccm-cms/src/main/java/org/librecms/pagemodel/CategoryTreeComponent.java new file mode 100644 index 000000000..b45af1bf3 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/CategoryTreeComponent.java @@ -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 Jens Pelzetter + */ +@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)); + + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/CategoryTreeComponentBuilder.java b/ccm-cms/src/main/java/org/librecms/pagemodel/CategoryTreeComponentBuilder.java new file mode 100644 index 000000000..bf73ec24f --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/CategoryTreeComponentBuilder.java @@ -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 Jens Pelzetter + */ +@RequestScoped +@ComponentModelType(componentModel = CategoryTreeComponent.class) +public class CategoryTreeComponentBuilder + implements ComponentBuilder { + + @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 buildComponent( + final CategoryTreeComponent componentModel, + final Map 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 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> 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> subCategories = category + .getSubCategories() + .stream() + .map(current -> generateCategory(current, language)) + .collect(Collectors.toList()); + result.put("subCategories", subCategories); + } + return result; + } + + protected Map generateCategory(final Category category, + final Locale language) { + + final Map 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 generateCategoryWithTree( + final Category category, + final Category selectedCategory, + final Locale language) { + + final Map 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> 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()); + } + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItem.java b/ccm-cms/src/main/java/org/librecms/pagemodel/ContentItemComponent.java similarity index 88% rename from ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItem.java rename to ccm-cms/src/main/java/org/librecms/pagemodel/ContentItemComponent.java index 2698538ed..21e53b75e 100644 --- a/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItem.java +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/ContentItemComponent.java @@ -18,7 +18,6 @@ */ package org.librecms.pagemodel; -import org.libreccm.categorization.Category; import org.libreccm.pagemodel.ComponentModel; import org.libreccm.pagemodel.PageModel; @@ -36,16 +35,16 @@ import javax.persistence.Table; import static org.librecms.CmsConstants.*; /** - * A {@link PageModel} component model for displaying the Greeting/Index item of - * a {@link Category}. + * Basic {@link PageModel} component for displaying a content item. This class + * is not indented for direct use. The subclasses should be used instead. * * @author Jens Pelzetter */ @Entity -@Table(name = "GREETING_ITEMS", schema = DB_SCHEMA) -public class GreetingItem extends ComponentModel { +@Table(name = "CONTENT_ITEM_COMPONENTS", schema = DB_SCHEMA) +public class ContentItemComponent extends ComponentModel { - private static final long serialVersionUID = -5509783666595294223L; + private static final long serialVersionUID = 4904530823926147281L; @ElementCollection @CollectionTable(name = "GREETING_ITEM_INCLUDED_PATHS", @@ -63,7 +62,7 @@ public class GreetingItem extends ComponentModel { }) private Set excludedProperties; - public GreetingItem() { + public ContentItemComponent() { includedPropertyPaths = new HashSet<>(); excludedProperties = new HashSet<>(); } @@ -121,10 +120,10 @@ public class GreetingItem extends ComponentModel { if (!super.equals(obj)) { return false; } - if (!(obj instanceof GreetingItem)) { + if (!(obj instanceof ContentItemComponent)) { return false; } - final GreetingItem other = (GreetingItem) obj; + final ContentItemComponent other = (ContentItemComponent) obj; if (!other.canEqual(this)) { return false; } @@ -139,7 +138,7 @@ public class GreetingItem extends ComponentModel { @Override public boolean canEqual(final Object obj) { - return obj instanceof GreetingItem; + return obj instanceof ContentItemComponent; } @Override diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/FixedContentItemComponent.java b/ccm-cms/src/main/java/org/librecms/pagemodel/FixedContentItemComponent.java new file mode 100644 index 000000000..ed7d30b6a --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/FixedContentItemComponent.java @@ -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 Jens Pelzetter + */ +@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)); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/FixedContentItemComponentBuilder.java b/ccm-cms/src/main/java/org/librecms/pagemodel/FixedContentItemComponentBuilder.java new file mode 100644 index 000000000..20e36852f --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/FixedContentItemComponentBuilder.java @@ -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 Jens Pelzetter + */ +@RequestScoped +@ComponentModelType(componentModel = FixedContentItemComponent.class) +public class FixedContentItemComponentBuilder + extends AbstractContentItemComponentBuilder { + + @Inject + private ContentItemRepository itemRepo; + + @Override + protected ContentItem getContentItem( + final FixedContentItemComponent componentModel, + final Map 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()))); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemComponent.java b/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemComponent.java new file mode 100644 index 000000000..cca1aa670 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemComponent.java @@ -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 Jens Pelzetter + */ +@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; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemComponentBuilder.java b/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemComponentBuilder.java new file mode 100644 index 000000000..8f1aa99af --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemComponentBuilder.java @@ -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 Jens Pelzetter + */ +@RequestScoped +@ComponentModelType(componentModel = GreetingItemComponent.class) +public class GreetingItemComponentBuilder + extends AbstractContentItemComponentBuilder { + + @Inject + private CategoryRepository categoryRepo; + + @Inject + private CategoryManager categoryManager; + + @Override + protected ContentItem getContentItem( + final GreetingItemComponent componentModel, + final Map 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 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))); + } + } + +}