diff --git a/ccm-bundle-devel-wildfly/src/main/resources/themes/librecms-devel/templates/default.html.ftl b/ccm-bundle-devel-wildfly/src/main/resources/themes/librecms-devel/templates/default.html.ftl new file mode 100644 index 000000000..f9bf761f5 --- /dev/null +++ b/ccm-bundle-devel-wildfly/src/main/resources/themes/librecms-devel/templates/default.html.ftl @@ -0,0 +1,62 @@ + + + + LibreCCM Devel Theme + + +

LibreCCM Devel

+

Site Info

+
+
host
+
${CmsPagesSiteInfoModel.host}
+
domain
+
${CmsPagesSiteInfoModel.domain}
+
name
+
${CmsPagesSiteInfoModel.name}
+
Current category
+
${CmsPagesCategoryModel.category.name}
+
+

Category Tree

+ +

(Index) Item

+ <#if (CmsPagesCategoryModel.category.hasIndexItem)> +
+
Name
+
${CmsPagesCategorizedItemModel.name}
+
Title
+
${CmsPagesCategorizedItemModel.title}
+
Description
+
${CmsPagesCategorizedItemModel.description}
+
+ <#else> +

No (Index) Item

+ +

Item List

+ + + + +<#macro categoryTreeNode category> +
  • + ${category.name} + <#if (category.subCategories?size > 0)> + + +
  • + \ No newline at end of file diff --git a/ccm-cms/src/main/java/org/librecms/pages/PagesController.java b/ccm-cms/src/main/java/org/librecms/pages/PagesController.java index 146480517..35e515e58 100644 --- a/ccm-cms/src/main/java/org/librecms/pages/PagesController.java +++ b/ccm-cms/src/main/java/org/librecms/pages/PagesController.java @@ -195,7 +195,7 @@ public class PagesController { @Inject private PagePropertiesModel pagePropertiesModel; - + @Inject private PagesRepository pagesRepo; @@ -330,20 +330,45 @@ public class PagesController { @DefaultValue("") final String preview ) { - final Versions versions = generateFromPreviewParam(preview); - - globalizationHelper.setSelectedLocale(new Locale(language)); - - contentItemModel.setItemName(itemName); - contentItemModel.setItemVersion(versions.getContentItemVersion()); - - final String domain = uriInfo.getBaseUri().getHost(); - final Pages pages = getPages(domain); - final Category category = getCategory(domain, pages, "/"); - final Page page = pageManager.findPageForCategory(category); - pagePropertiesModel.setProperties(page.getProperties()); - return themesMvc.getMvcTemplate( - uriInfo, "pages", page.getDisplayName() +// final Versions versions = generateFromPreviewParam(preview); +// +// globalizationHelper.setSelectedLocale(new Locale(language)); +// +// contentItemModel.setItemName(itemName); +// contentItemModel.setItemVersion(versions.getContentItemVersion()); +// +// final String domain = uriInfo.getBaseUri().getHost(); +// final Pages pages = getPages(domain); +// final Site site = pages.getSite(); +// siteInfoModel.setAvailableLanguages( +// confManager +// .findConfiguration(KernelConfig.class) +// .getSupportedLanguages() +// .stream() +// .sorted() +// .collect(Collectors.toList()) +// ); +// siteInfoModel.setDomain(site.getDomainOfSite()); +// siteInfoModel.setHost(domain); +// siteInfoModel.setName( +// Optional +// .ofNullable(site.getDisplayName()) +// .orElse("") +// ); +// final Category category = getCategory(domain, pages, "/"); +// categoryModel.init(pages.getCategoryDomain(), category); +// final Page page = pageManager.findPageForCategory(category); +// pagePropertiesModel.setProperties(page.getProperties()); +// return themesMvc.getMvcTemplate( +// uriInfo, "pages", page.getDisplayName() +// ); + return getPageAsHtml( + uriInfo, + "/", + itemName, + language, + theme, + preview ); } @@ -439,15 +464,15 @@ public class PagesController { final String redirectTo; if (uriInfo.getPath().endsWith("/")) { redirectTo = String.format( - "%sindex.%s.html%s", - uriInfo.getPath(), + "%sindex.%s.html%s", + uriInfo.getPath(), language, buildQueryParamsStr(preview, theme) ); } else { final String itemPath = String.format( - "%s.%s.html%s", - itemName, + "%s.%s.html%s", + itemName, language, buildQueryParamsStr(preview, theme) ); @@ -492,13 +517,33 @@ public class PagesController { final String preview ) { final Versions versions = generateFromPreviewParam(preview); - + + globalizationHelper.setSelectedLocale(new Locale(language)); + contentItemModel.setItemName(itemName); + final ContentItemVersion version = versions.getContentItemVersion(); contentItemModel.setItemVersion(versions.getContentItemVersion()); final String domain = uriInfo.getBaseUri().getHost(); final Pages pages = getPages(domain); + final Site site = pages.getSite(); + siteInfoModel.setAvailableLanguages( + confManager + .findConfiguration(KernelConfig.class) + .getSupportedLanguages() + .stream() + .sorted() + .collect(Collectors.toList()) + ); + siteInfoModel.setDomain(site.getDomainOfSite()); + siteInfoModel.setHost(domain); + siteInfoModel.setName( + Optional + .ofNullable(site.getDisplayName()) + .orElse("") + ); final Category category = getCategory(domain, pages, pagePath); + categoryModel.init(pages.getCategoryDomain(), category, version); final Page page = pageManager.findPageForCategory(category); pagePropertiesModel.setProperties(page.getProperties()); return themesMvc.getMvcTemplate( @@ -506,6 +551,26 @@ public class PagesController { ); } + private void initSiteInfoModel( + final Site site, final String host + ) { + siteInfoModel.setAvailableLanguages( + confManager + .findConfiguration(KernelConfig.class) + .getSupportedLanguages() + .stream() + .sorted() + .collect(Collectors.toList()) + ); + siteInfoModel.setDomain(site.getDomainOfSite()); + siteInfoModel.setHost(host); + siteInfoModel.setName( + Optional + .ofNullable(site.getDisplayName()) + .orElse("") + ); + } + private Site getSite(final UriInfo uriInfo) { final String domain = Objects .requireNonNull(uriInfo) @@ -695,48 +760,6 @@ public class PagesController { } - private Page findPage( - final UriInfo uriInfo, final String pagePath, final String language - ) { - Objects.requireNonNull(uriInfo); - Objects.requireNonNull(pagePath); - - final Site site = getSite(uriInfo); - final String domain = uriInfo.getBaseUri().getHost(); - final Pages pages = getPages(domain); - - final Category category = getCategory(domain, pages, pagePath); - // disabled. Needs to be decided if the available languages of the - // index item or of the category are - // used to decide if a NotFoundException is thrown. -// if (!category.getTitle().hasValue(locale)) { -// throw new NotFoundException(); -// } - final Locale locale = new Locale(language); - globalizationHelper.setSelectedLocale(locale); - - final KernelConfig kernelConfig = confManager - .findConfiguration(KernelConfig.class); - - siteInfoModel.setAvailableLanguages( - kernelConfig - .getSupportedLanguages() - .stream() - .sorted() - .collect(Collectors.toList()) - ); - siteInfoModel.setDomain(site.getDomainOfSite()); - siteInfoModel.setHost(uriInfo.getBaseUri().getHost()); - siteInfoModel.setName(site.getDisplayName()); - - categoryModel.setCategory(category); - categoryModel.setCategoryPath( - categoryManager.getCategoryPath(category) - ); - - return pageManager.findPageForCategory(category); - } - /** * Parse the value of the {@code preview} query parameter. * diff --git a/ccm-cms/src/main/java/org/librecms/pages/models/CategoryData.java b/ccm-cms/src/main/java/org/librecms/pages/models/CategoryData.java new file mode 100644 index 000000000..0c7f533c4 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pages/models/CategoryData.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2021 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.pages.models; + +/** + * + * @author Jens Pelzetter + */ +public class CategoryData { + + private long categoryId; + + private String uuid; + + private String uniqueId; + + private String name; + + private String path; + + private String title; + + private String description; + + private boolean enabled; + + private boolean visible; + + private boolean abstractCategory; + + private boolean hasIndexItem; + + CategoryData() { + super(); + } + + public long getCategoryId() { + return categoryId; + } + + protected void setCategoryId(final long categoryId) { + this.categoryId = categoryId; + } + + public String getUuid() { + return uuid; + } + + protected void setUuid(final String uuid) { + this.uuid = uuid; + } + + public String getUniqueId() { + return uniqueId; + } + + protected void setUniqueId(final String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getName() { + return name; + } + + protected void setName(final String name) { + this.name = name; + } + + public String getTitle() { + return title; + } + + protected void setTitle(final String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + protected void setDescription(final String description) { + this.description = description; + } + + public boolean isEnabled() { + return enabled; + } + + protected void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isVisible() { + return visible; + } + + protected void setVisible(final boolean visible) { + this.visible = visible; + } + + public boolean isAbstractCategory() { + return abstractCategory; + } + + protected void setAbstractCategory(final boolean abstractCategory) { + this.abstractCategory = abstractCategory; + } + + public String getPath() { + return path; + } + + protected void setPath(final String path) { + this.path = path; + } + + public boolean getHasIndexItem() { + return hasIndexItem; + } + + protected void setHasIndexItem(final boolean hasIndexItem) { + this.hasIndexItem = hasIndexItem; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pages/models/CategoryDomainData.java b/ccm-cms/src/main/java/org/librecms/pages/models/CategoryDomainData.java new file mode 100644 index 000000000..c6beb0b08 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pages/models/CategoryDomainData.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2021 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.pages.models; + +import org.libreccm.categorization.Domain; + +/** + * Model for the current category system/domain. + * + * @see CategoryModel + * @see Domain + * + * @author Jens Pelzetter + */ +public class CategoryDomainData { + + private long domainId; + + private String uuid; + + private String domainKey; + + private String uri; + + private String title; + + private String description; + + CategoryDomainData() { + super(); + } + + public long getDomainId() { + return domainId; + } + + protected void setDomainId(final long domainId) { + this.domainId = domainId; + } + + public String getUuid() { + return uuid; + } + + protected void setUuid(final String uuid) { + this.uuid = uuid; + } + + public String getDomainKey() { + return domainKey; + } + + protected void setDomainKey(final String domainKey) { + this.domainKey = domainKey; + } + + public String getUri() { + return uri; + } + + protected void setUri(final String uri) { + this.uri = uri; + } + + public String getTitle() { + return title; + } + + protected void setTitle(final String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + protected void setDescription(final String description) { + this.description = description; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pages/models/CategoryModel.java b/ccm-cms/src/main/java/org/librecms/pages/models/CategoryModel.java index 2c2a526de..9d823b7f8 100644 --- a/ccm-cms/src/main/java/org/librecms/pages/models/CategoryModel.java +++ b/ccm-cms/src/main/java/org/librecms/pages/models/CategoryModel.java @@ -19,17 +19,26 @@ package org.librecms.pages.models; import org.libreccm.categorization.Category; -import org.librecms.pages.PagesController; +import org.libreccm.categorization.CategoryManager; +import org.libreccm.categorization.CategoryRepository; +import org.libreccm.categorization.Domain; +import org.libreccm.categorization.DomainRepository; +import org.libreccm.l10n.GlobalizationHelper; +import org.librecms.contentsection.ContentItemVersion; +import org.librecms.pages.PagesService; import java.io.Serializable; +import java.util.Comparator; +import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; import javax.inject.Named; +import javax.transaction.Transactional; /** * Model for MVC applications providing access to the current category. This - * model MUST be initalized by the calling application (for example - * {@link PagesController} with the current category. + * model MUST be initalized by the calling application using {@link #init(org.libreccm.categorization.Domain, org.libreccm.categorization.Category)). * * @author Jens Pelzetter */ @@ -39,25 +48,140 @@ public class CategoryModel implements Serializable { private static final long serialVersionUID = 1L; - private Category category; - - private String categoryPath; + @Inject + private CategoryManager categoryManager; - public Category getCategory() { + @Inject + private DomainRepository domainRepository; + + @Inject + private GlobalizationHelper globalizationHelper; + + @Inject + private PagesService pagesService; + + private CategoryDomainData domain; + + private CategoryData category; + + /** + * Controllers must call this method to initalize the this model. + * + * @param domain The current category domain. + * @param category The current category. + * @param version + */ + @Transactional(Transactional.TxType.REQUIRED) + public void init( + final Domain domain, + final Category category, + final ContentItemVersion version + ) { + this.domain = new CategoryDomainData(); + this.domain.setDescription( + globalizationHelper.getValueFromLocalizedString( + domain.getDescription() + ) + ); + this.domain.setDomainId(domain.getObjectId()); + this.domain.setDomainKey(domain.getDomainKey()); + this.domain.setTitle( + globalizationHelper.getValueFromLocalizedString( + domain.getTitle() + ) + ); + this.domain.setUri(domain.getUri()); + this.domain.setUuid(domain.getUuid()); + + this.category = new CategoryData(); + this.category.setAbstractCategory(category.isAbstractCategory()); + this.category.setDescription( + globalizationHelper.getValueFromLocalizedString( + category.getDescription() + )); + this.category.setEnabled(category.isEnabled()); + this.category.setCategoryId(category.getObjectId()); + this.category.setName(category.getName()); + this.category.setPath(categoryManager.getCategoryPath(category)); + this.category.setTitle( + globalizationHelper.getValueFromLocalizedString( + category.getTitle() + )); + this.category.setUniqueId(category.getUniqueId()); + this.category.setUuid(category.getUuid()); + this.category.setVisible(category.isVisible()); + this.category.setHasIndexItem( + //pagesService.findIndexItem(category, version).isPresent() + categoryManager.hasIndexObject(category) + ); + } + + public CategoryDomainData getDomain() { + return domain; + } + + public CategoryData getCategory() { return category; } - public void setCategory(final Category category) { - this.category = category; + @Transactional(Transactional.TxType.REQUIRED) + public CategoryTreeNode getCategoryTree() { + final Domain currentDomain = domainRepository + .findById(domain.getDomainId()) + .orElseThrow( + () -> new RuntimeException( + String.format( + "The category domain with the ID %d was set as current " + + "category domain, but there is such domain in " + + "the database.", + domain.getDomainId() + ) + ) + ); + + return buildTreeNode(currentDomain.getRoot(), null); } - public String getCategoryPath() { - return categoryPath; + private CategoryTreeNode buildTreeNode( + final Category fromCategory, + final CategoryTreeNode parent + ) { + final CategoryTreeNode node = new CategoryTreeNode(); + node.setCategoryPath(categoryManager.getCategoryPath(fromCategory)); + node.setDescription( + globalizationHelper.getValueFromLocalizedString( + fromCategory.getDescription()) + ); + node.setName(fromCategory.getName()); + node.setSelected(fromCategory.getUuid().equals(category.getUuid())); + node.setParentCategory(parent); + node.setSubCategories( + fromCategory + .getSubCategories() + .stream() + .sorted(Comparator.comparing(Category::getCategoryOrder)) + .map(cat -> buildTreeNode(cat, node)) + .collect(Collectors.toList()) + ); + node.setTitle( + globalizationHelper.getValueFromLocalizedString( + fromCategory.getTitle() + ) + ); + node.setUuid(fromCategory.getUuid()); + + if (node.isSelected() && node.getParentCategory() != null) { + setSubCategoryCategorySelected(node.getParentCategory()); + } + + return node; } - public void setCategoryPath(final String categoryPath) { - this.categoryPath = categoryPath; + private void setSubCategoryCategorySelected(final CategoryTreeNode node) { + node.setSubCategorySelected(true); + if (node.getParentCategory() != null) { + setSubCategoryCategorySelected(node.getParentCategory()); + } } - } diff --git a/ccm-cms/src/main/java/org/librecms/pages/models/CategoryTreeNode.java b/ccm-cms/src/main/java/org/librecms/pages/models/CategoryTreeNode.java new file mode 100644 index 000000000..2ff2d6222 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/pages/models/CategoryTreeNode.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2021 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.pages.models; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * + * @author Jens Pelzetter + */ +public class CategoryTreeNode { + + private String uuid; + + private String name; + + private String title; + + private String description; + + private String categoryPath; + + private boolean selected; + + private boolean subCategorySelected; + + private CategoryTreeNode parentCategory; + + private List subCategories; + + public String getUuid() { + return uuid; + } + + protected void setUuid(final String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + protected void setName(final String name) { + this.name = name; + } + + public String getTitle() { + return title; + } + + protected void setTitle(final String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + protected void setDescription(final String description) { + this.description = description; + } + + public String getCategoryPath() { + return categoryPath; + } + + protected void setCategoryPath(final String categoryPath) { + this.categoryPath = categoryPath; + } + + public List getSubCategories() { + return Collections.unmodifiableList(subCategories); + } + + protected void setSubCategories( + final List subCategories + ) { + this.subCategories = new ArrayList<>(subCategories); + } + + public boolean isSelected() { + return selected; + } + + protected void setSelected(boolean selected) { + this.selected = selected; + } + + + public CategoryTreeNode getParentCategory() { + return parentCategory; + } + + protected void setParentCategory(final CategoryTreeNode parentCategory) { + this.parentCategory = parentCategory; + } + + public boolean isSubCategorySelected() { + return subCategorySelected; + } + + + protected void setSubCategorySelected(final boolean subCategorySelected) { + this.subCategorySelected = subCategorySelected; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/pages/models/ContentItemModel.java b/ccm-cms/src/main/java/org/librecms/pages/models/ContentItemModel.java index dc0021070..1a475683d 100644 --- a/ccm-cms/src/main/java/org/librecms/pages/models/ContentItemModel.java +++ b/ccm-cms/src/main/java/org/librecms/pages/models/ContentItemModel.java @@ -21,11 +21,11 @@ package org.librecms.pages.models; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.libreccm.categorization.CategoryManager; +import org.libreccm.categorization.CategoryRepository; import org.libreccm.l10n.GlobalizationHelper; import org.librecms.contentsection.AttachmentList; import org.librecms.contentsection.ContentItem; import org.librecms.contentsection.ContentItemVersion; -import org.librecms.pages.PagesRouter; import org.librecms.pages.PagesService; import java.time.ZoneId; @@ -59,6 +59,9 @@ public class ContentItemModel { @Inject private CategoryManager categoryManager; + + @Inject + private CategoryRepository categoryRepository; @Inject private CategoryModel categoryModel; @@ -217,11 +220,36 @@ public class ContentItemModel { private void retrieveContentItem() { if (itemName == null) { contentItem = pagesService.findIndexItem( - categoryModel.getCategory(), itemVersion + categoryRepository + .findById(categoryModel.getCategory().getCategoryId()) + .orElseThrow( + () -> new RuntimeException( + String.format( + "The category with the ID %d is set as current " + + "category, but not category with that ID " + + "can be found in the database.", + categoryModel.getCategory().getCategoryId() + ) + ) + ), + itemVersion ); } else { contentItem = pagesService.findCategorizedItem( - categoryModel.getCategory(), itemName, itemVersion + categoryRepository + .findById(categoryModel.getCategory().getCategoryId()) + .orElseThrow( + () -> new RuntimeException( + String.format( + "The category with the ID %d is set as current " + + "category, but not category with that ID " + + "can be found in the database.", + categoryModel.getCategory().getCategoryId() + ) + ) + ), + itemName, + itemVersion ); } } diff --git a/ccm-cms/src/main/java/org/librecms/pages/models/ItemListModel.java b/ccm-cms/src/main/java/org/librecms/pages/models/ItemListModel.java index 93f72829d..803739450 100644 --- a/ccm-cms/src/main/java/org/librecms/pages/models/ItemListModel.java +++ b/ccm-cms/src/main/java/org/librecms/pages/models/ItemListModel.java @@ -22,6 +22,7 @@ import com.arsdigita.kernel.KernelConfig; import org.libreccm.categorization.Categorization; import org.libreccm.categorization.Category; +import org.libreccm.categorization.CategoryRepository; import org.libreccm.configuration.ConfigurationManager; import org.libreccm.core.UnexpectedErrorException; import org.libreccm.l10n.GlobalizationHelper; @@ -54,6 +55,7 @@ import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Order; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import javax.transaction.Transactional; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; @@ -68,6 +70,9 @@ public class ItemListModel { @Inject private CategoryModel categoryModel; + @Inject + private CategoryRepository categoryRepository; + @Inject private ConfigurationManager confManager; @@ -111,7 +116,7 @@ public class ItemListModel { public ItemListModel() { descending = false; limitToType = ContentItem.class.getName(); - listOrder = List.of(ContentItem.class.getName()); + listOrder = List.of("displayName"); pageSize = 20; } @@ -155,11 +160,25 @@ public class ItemListModel { return getItems().size(); } + @Transactional(Transactional.TxType.REQUIRED) public List getItems() { if (itemList == null) { buildList( buildLimitToType(limitToType), - collectCategories(categoryModel.getCategory()), + collectCategories( + categoryRepository + .findById(categoryModel.getCategory().getCategoryId()) + .orElseThrow( + () -> new RuntimeException( + String.format( + "Category with ID %d was set as current " + + "category, but no category with " + + "that ID was found in the database.", + categoryModel.getCategory().getCategoryId() + ) + ) + ) + ), listOrder, pageSize ); @@ -205,7 +224,7 @@ public class ItemListModel { criteriaQuery.orderBy( listOrder .stream() - .map(order -> builderOrder(order, from, criteriaBuilder)) + .map(order -> buildOrder(order, from, criteriaBuilder)) .collect(Collectors.toList()) ); @@ -225,17 +244,15 @@ public class ItemListModel { } private List collectCategories(final Category category) { - - if (category.getSubCategories().isEmpty()) { - return Collections.emptyList(); - } else { - final List categories = new ArrayList<>(); + final List categories = new ArrayList<>(); + categories.add(category); + if (!category.getSubCategories().isEmpty()) { for (final Category subCategory : category.getSubCategories()) { categories.add(subCategory); categories.addAll(collectCategories(subCategory)); } - return categories; } + return categories; } private Class buildLimitToType( @@ -352,7 +369,7 @@ public class ItemListModel { return roles; } - private Order builderOrder( + private Order buildOrder( final String order, final Root from, final CriteriaBuilder criteriaBuilder