com.github.restup.query.ResourceQueryDefaults Maven / Gradle / Ivy
package com.github.restup.query;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import com.github.restup.path.ResourcePath;
import com.github.restup.query.criteria.ListCriteria;
import com.github.restup.query.criteria.ResourcePathFilter;
import com.github.restup.query.criteria.ResourcePathFilter.Operator;
import com.github.restup.query.criteria.ResourceQueryCriteria;
import com.github.restup.registry.Resource;
/**
*
* Provides defaults for queries. For example, may define
*
*
* - Fields required for some internal logic, but not requested in sparse field request
* - Filters applied by default for some access control or hiding inactive data by default
* - Default sort criteria.
*
*
* This is a mutable object, which may be the argument of multiple filter methods setting values as
* needed.
*
*
* @author abuttaro
*/
public class ResourceQueryDefaults {
private final Resource, ?> resource;
private final ResourceQueryStatement requestedQuery;
private List requiredFields;
// query criteria
private List criteria;
// sorting
private List sort;
public ResourceQueryDefaults(Resource, ?> resource, ResourceQueryStatement requestedQuery) {
this.resource = resource;
this.requestedQuery = requestedQuery;
}
/**
* null safe convenience method
*
* @param defaults source of criteria
* @return true if default criteria is not null, false otherwise
*/
public static boolean hasCriteria(ResourceQueryDefaults defaults) {
return defaults != null && defaults.getCriteria() != null;
}
private boolean isPresentInRequest(ResourcePathFilter> criteria) {
if (criteria != null && requestedQuery != null) {
for (ResourceQueryCriteria c : requestedQuery.getRequestedCriteria()) {
if (filterPathEquals(c, criteria)) {
return true;
}
}
}
return false;
}
private boolean filterPathEquals(ResourceQueryCriteria a, ResourcePathFilter> b) {
if (a instanceof ResourcePathFilter) {
ResourcePathFilter> aa = (ResourcePathFilter>) a;
if (Objects.equals(b.getPath(), aa.getPath())) {
return true;
}
} else if (a instanceof ListCriteria) {
for (ResourceQueryCriteria q : ((ListCriteria) a).getCriteria()) {
if (filterPathEquals(q, b)) {
return true;
}
}
}
return false;
}
/**
* Add a field that is required for handling the request. A Repository may implement query
* projection, retrieving only requested fields. If a field not requested is required for handling
* the request, it must also be added to the query for projection.
*
* @param beanPaths required
*/
public void addRequiredFields(String... beanPaths) {
this.requiredFields = addPaths(requiredFields, beanPaths);
}
public void addRequired(ResourcePath path) {
this.requiredFields = addPath(requiredFields, path);
}
private List addPaths(List target, String[] beanPaths) {
List result = target;
if (result == null) {
result = new ArrayList();
}
for (String beanPath : beanPaths) {
result.add(ResourcePath.path(resource, beanPath));
}
return result;
}
private List addPath(List target, ResourcePath path) {
List result = target;
if (result == null) {
result = new ArrayList();
}
result.add(path);
return result;
}
/**
* Add a filter that must always be applied. For example, a filter that restricts data available to
* the requestor that may not be passed in the request, but defaulted from an authenticated context.
* @param queryCriteria to add
*/
public void addCriteria(ResourceQueryCriteria queryCriteria) {
if (queryCriteria != null) {
if (criteria == null) {
criteria = new ArrayList();
}
criteria.add(queryCriteria);
}
}
public void addCriteria(String beanPath, Object value) {
addCriteria(new ResourcePathFilter