Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#28896 Create Factory method to find categories in all levels #29021

Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package com.dotmarketing.portlets.categories.business;

import java.util.Collection;
import java.util.List;

import com.dotcms.util.PaginationUtil;
import com.dotcms.util.pagination.OrderDirection;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.portlets.categories.model.Category;
import com.liferay.portal.model.User;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.QueryParam;

/**
*
Expand Down Expand Up @@ -273,5 +280,68 @@ public abstract class CategoryFactory {
* @throws DotDataException
*/
abstract protected List<Category> getAllChildren(Categorizable parent) throws DotDataException;

/**
* Return a {@link Category} Collection looking through the entire category tree starting from a specified inode.
* This means the search will begin from the specified inode category and then proceed recursively through its children.
*
* @param searchCriteria Search Criteria
*
* @return List of Category filtered
*/
public abstract Collection<Category> findAll(final CategorySearchCriteria searchCriteria) throws DotDataException;

/**
* Represents Search Criteria for {@link Category} searching, you cans set the follow:
*
* - filter: Value used to filter the Category by, returning only Categories that contain this value in their key, name, or variable name.
* - inode: Entry point on the Category tree to start the searching.
* - orderBy: Field name to order the Category
* - direction: Order by direction, it can be 'ASC' or 'DESC'
*/
public static class CategorySearchCriteria {
final String inode;
freddyDOTCMS marked this conversation as resolved.
Show resolved Hide resolved
final String filter;
final String orderBy;
final OrderDirection direction;

private CategorySearchCriteria (final Builder builder) {
this.inode = builder.inode;
this.filter = builder.filter;
this.orderBy = builder.orderBy;
this.direction = builder.direction;
}

public static class Builder {
private String inode;
private String filter;
private String orderBy = "category_name";
private OrderDirection direction = OrderDirection.ASC;

public Builder inode(String inode) {
this.inode = inode;
return this;
}

public Builder filter(String filter) {
this.filter = filter;
return this;
}

public Builder orderBy(String orderBy) {
this.orderBy = orderBy;
return this;
}

public Builder direction(OrderDirection direction) {
this.direction = direction;
return this;
}

public CategorySearchCriteria build() {
return new CategorySearchCriteria(this);
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,16 @@
import com.dotmarketing.util.Logger;
import com.dotmarketing.util.UtilMethods;
import com.dotmarketing.util.VelocityUtil;
import com.liferay.util.StringPool;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
*
Expand Down Expand Up @@ -165,15 +164,7 @@ protected List<Category> findAll() throws DotDataException {
.loadObjectResults();

List<Category> categories = convertForCategories(result);
for(final Category category : categories) {
//Updating the cache since we are already loading all the categories
if(catCache.get(category.getInode()) == null)
try {
catCache.put(category);
} catch (DotCacheException e) {
throw new DotDataException(e.getMessage(), e);
}
}
updateCache(categories);
return categories;
}

Expand Down Expand Up @@ -843,4 +834,72 @@ protected String suggestVelocityVarName(final String categoryVelVarName) throws
throw new DotDataException("Unable to suggest a variable name. Got to:" + var);
}

/**
* Default Implementation for {@link CategoryFactory#findAll(CategorySearchCriteria)}
* @param searchCriteria Search Criteria
*
* @return
* @throws DotDataException
*/
public List<Category> findAll(final CategorySearchCriteria searchCriteria)
throws DotDataException {

if (!UtilMethods.isSet(searchCriteria.inode) && !UtilMethods.isSet(searchCriteria.filter)) {
return findAll();
}

final String query = getFindAllSQLQuery(searchCriteria);

final DotConnect dc = new DotConnect().setSQL(query);

if (UtilMethods.isSet(searchCriteria.inode) ) {
dc.addObject(searchCriteria.inode);
}

if (UtilMethods.isSet(searchCriteria.filter) ) {
dc.addObject("%" + searchCriteria.filter.toLowerCase() + "%");
dc.addObject("%" + searchCriteria.filter.toLowerCase() + "%");
dc.addObject("%" + searchCriteria.filter.toLowerCase() + "%");
}

final List<Category> categories = convertForCategories(UtilMethods.isSet(searchCriteria.inode) ?
dc.loadObjectResults().stream()
.filter(map -> !map.get("inode").equals(searchCriteria.inode))
.collect(Collectors.toList()) : dc.loadObjectResults());

updateCache(categories);
return categories;
}

private static String getFindAllSQLQuery(CategorySearchCriteria searchCriteria) {
final String queryTemplate = "WITH RECURSIVE CategoryHierarchy AS ( " +
"SELECT c.* FROM Category c %s " +
"UNION ALL " +
"SELECT c.* FROM Category c JOIN tree t ON c.inode = t.child JOIN CategoryHierarchy ch ON t.parent = ch.inode " +
") " +
"SELECT * FROM CategoryHierarchy %s ORDER BY %s %s";

final String rootCategoryFilter = UtilMethods.isSet(searchCriteria.inode) ? "WHERE c.inode = ?" : StringPool.BLANK;

final String filterCategories = UtilMethods.isSet(searchCriteria.filter) ?
"WHERE LOWER(category_name) LIKE ? OR " +
"LOWER(category_key) LIKE ? OR " +
"LOWER(category_velocity_var_name) LIKE ?" : StringPool.BLANK;

final String query = String.format(queryTemplate, rootCategoryFilter, filterCategories, searchCriteria.orderBy,
searchCriteria.direction.toString());
return query;
}

private void updateCache(List<Category> categories) throws DotDataException {
for(final Category category : categories) {
if(catCache.get(category.getInode()) == null)
try {
catCache.put(category);
} catch (DotCacheException e) {
throw new DotDataException(e.getMessage(), e);
}
}
}

}
Loading
Loading