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: 0327c3a0d4
pull/2/head
jensp 2018-01-11 13:24:45 +00:00
parent 774a96cfd9
commit 66bfeb1d3b
1 changed files with 126 additions and 29 deletions

View File

@ -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;
@ -292,41 +300,70 @@ public class FolderBrowserController {
final int firstResult,
final int maxResults) {
final List<Folder> subFolders = findSubFolders(folder,
final List<CcmObject> objects = findObjectsInFolder(folder,
filterTerm,
orderBy,
orderDirection,
firstResult,
maxResults);
final List<FolderBrowserTableRow> subFolderRows = subFolders
LOGGER.debug("Found {} objects for folder \"{}\".",
objects.size(),
folder.getDisplayName());
final List<FolderBrowserTableRow> rows = objects
.stream()
.map(subFolder -> buildRow(subFolder))
.map(object -> buildRow(object))
.collect(Collectors.toList());
return rows;
// final List<Folder> subFolders = findSubFolders(folder,
// filterTerm,
// orderBy,
// orderDirection,
// firstResult,
// maxResults);
// final List<FolderBrowserTableRow> 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<ContentItem> items = findItemsInFolder(folder,
filterTerm,
orderBy,
orderDirection,
firstItem,
maxItems);
final List<FolderBrowserTableRow> itemRows = items.stream()
.map(item -> buildRow(item))
.collect(Collectors.toList());
final List<FolderBrowserTableRow> 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<ContentItem> items = findItemsInFolder(folder,
// filterTerm,
// orderBy,
// orderDirection,
// firstItem,
// maxItems);
// final List<FolderBrowserTableRow> itemRows = items.stream()
// .map(item -> buildRow(item))
// .collect(Collectors.toList());
//
// final List<FolderBrowserTableRow> 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<CcmObject> 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<CcmObject> criteriaQuery = builder
.createQuery(CcmObject.class);
final Root<CcmObject> from = criteriaQuery.from(CcmObject.class);
criteriaQuery.select(from);
final Subquery<Folder> folderCriteriaQuery = criteriaQuery
.subquery(Folder.class);
final Root<Folder> 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<ContentItem> itemCriteriaQuery = criteriaQuery
.subquery(ContentItem.class);
final Root<ContentItem> fromItem = itemCriteriaQuery
.from(ContentItem.class);
itemCriteriaQuery.select(fromItem);
final Join<ContentItem, Categorization> 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<CcmObject> 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