From 66bfeb1d3b65b26eb3f3ec241aa0349a3de96928 Mon Sep 17 00:00:00 2001 From: jensp Date: Thu, 11 Jan 2018 13:24:45 +0000 Subject: [PATCH] CCM NG: Optimized queries for FolderBrowser git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5191 8810af33-2d31-482b-a856-94f89814c4df Former-commit-id: 0327c3a0d4cf1a33b1f56257731f73170c4aef4e --- .../ui/folder/FolderBrowserController.java | 155 ++++++++++++++---- 1 file changed, 126 insertions(+), 29 deletions(-) diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserController.java index d15777232..a746e4c83 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserController.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserController.java @@ -20,6 +20,8 @@ package com.arsdigita.cms.ui.folder; import com.arsdigita.kernel.KernelConfig; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.libreccm.categorization.Categorization; import org.libreccm.categorization.CategoryManager; import org.libreccm.configuration.ConfigurationManager; @@ -60,8 +62,11 @@ import javax.transaction.Transactional; import javax.persistence.TypedQuery; import javax.persistence.criteria.Order; import javax.persistence.criteria.Path; + import org.librecms.contentsection.FolderManager; +import javax.persistence.criteria.Subquery; + import static org.librecms.CmsConstants.*; /** @@ -75,6 +80,9 @@ import static org.librecms.CmsConstants.*; @RequestScoped public class FolderBrowserController { + private static final Logger LOGGER = LogManager + .getLogger(FolderBrowserController.class); + @Inject private EntityManager entityManager; @@ -291,42 +299,71 @@ public class FolderBrowserController { final String orderDirection, final int firstResult, final int maxResults) { - - final List subFolders = findSubFolders(folder, - filterTerm, - orderBy, - orderDirection, - firstResult, - maxResults); - final List subFolderRows = subFolders - .stream() - .map(subFolder -> buildRow(subFolder)) - .collect(Collectors.toList()); + final List objects = findObjectsInFolder(folder, + filterTerm, + orderBy, + orderDirection, + firstResult, + maxResults); + LOGGER.debug("Found {} objects for folder \"{}\".", + objects.size(), + folder.getDisplayName()); + + final List rows = objects + .stream() + .map(object -> buildRow(object)) + .collect(Collectors.toList()); + + return rows; + +// final List subFolders = findSubFolders(folder, +// filterTerm, +// orderBy, +// orderDirection, +// firstResult, +// maxResults); +// final List subFolderRows = subFolders +// .stream() +// .map(subFolder -> buildRow(subFolder)) +// .collect(Collectors.toList()); +// // if (subFolders.size() >= maxResults) { // return subFolderRows; // } else { - final int maxItems = maxResults - subFolders.size(); - final int firstItem = firstResult - subFolders.size(); - - final List items = findItemsInFolder(folder, - filterTerm, - orderBy, - orderDirection, - firstItem, - maxItems); - final List itemRows = items.stream() - .map(item -> buildRow(item)) - .collect(Collectors.toList()); - - final List rows = new ArrayList<>(); - rows.addAll(subFolderRows); - rows.addAll(itemRows); - - return rows; +// final int maxItems = maxResults - subFolders.size(); +// final int firstItem = firstResult - subFolders.size(); +// +// final List items = findItemsInFolder(folder, +// filterTerm, +// orderBy, +// orderDirection, +// firstItem, +// maxItems); +// final List itemRows = items.stream() +// .map(item -> buildRow(item)) +// .collect(Collectors.toList()); +// +// final List rows = new ArrayList<>(); +// rows.addAll(subFolderRows); +// rows.addAll(itemRows); +// +// return rows; // } } + private FolderBrowserTableRow buildRow(final CcmObject object) { + + if (object instanceof Folder) { + return buildRow((Folder) object); + } else if(object instanceof ContentItem) { + return buildRow((ContentItem) object); + } else{ + throw new IllegalArgumentException( + "Only Folders and ContentItems are supported."); + } + } + /** * Helper method for building a {@link FolderBrowserTableRow} from a * {@link Folder}. @@ -440,6 +477,66 @@ public class FolderBrowserController { } } + private List findObjectsInFolder(final Folder folder, + final String filterTerm, + final String orderBy, + final String orderDirection, + final int firstResult, + final int maxResults) { + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + + final CriteriaQuery criteriaQuery = builder + .createQuery(CcmObject.class); + final Root from = criteriaQuery.from(CcmObject.class); + criteriaQuery.select(from); + + final Subquery folderCriteriaQuery = criteriaQuery + .subquery(Folder.class); + final Root fromFolder = folderCriteriaQuery.from(Folder.class); + folderCriteriaQuery.select(fromFolder); + folderCriteriaQuery.where( + builder.and( + builder.equal(fromFolder.get("parentCategory"), folder), + builder.like(builder.lower(fromFolder.get("name")), + filterTerm))); + + final Subquery itemCriteriaQuery = criteriaQuery + .subquery(ContentItem.class); + final Root fromItem = itemCriteriaQuery + .from(ContentItem.class); + itemCriteriaQuery.select(fromItem); + final Join itemCategoryJoin = fromItem + .join("categories"); + itemCriteriaQuery.where(builder + .and( + builder.equal(itemCategoryJoin.get("category"), folder), + builder.equal(itemCategoryJoin.get("type"), + CmsConstants.CATEGORIZATION_TYPE_FOLDER), + builder.equal(fromItem.get("version"), + ContentItemVersion.DRAFT), + builder.like(builder.lower(fromItem.get("displayName")), + filterTerm))); + + criteriaQuery.where( + builder.or( + builder.in(from).value(folderCriteriaQuery), + builder.in(from).value(itemCriteriaQuery) + )); + + final TypedQuery query = entityManager + .createQuery(criteriaQuery); + + if (maxResults > 0) { + query.setMaxResults(maxResults); + } + if (firstResult > 0) { + query.setFirstResult(firstResult); + } + + return query.getResultList(); + } + /** * Retrieves all subfolders of a folder matching the provided filter term. * Because {@link Folder} does not have any of the fields despite the name