AbstractFilter.java
package org.dynamoframework.filter;
/*-
* #%L
* Dynamo Framework
* %%
* Copyright (C) 2014 - 2024 Open Circle Solutions
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.dynamoframework.filter.Compare.*;
import org.springframework.beans.PropertyAccessorFactory;
import java.util.Collection;
import java.util.List;
/**
* Abstract base class for filters
*
* @author bas.rutten
*/
public abstract class AbstractFilter implements Filter {
/**
* @return the filter, wrapped in an And filter
*/
public And and() {
if (this instanceof And) {
return (And) this;
}
return new And(this);
}
/**
* Wraps the provided filters in an And filter
*
* @param filters the filter to combine
* @return the provided filters, wrapped in an And filter
*/
public And and(Collection<Filter> filters) {
And result;
if (this instanceof And) {
result = (And) this;
result.getFilters().addAll(filters);
} else {
result = new And(this).and(filters);
}
return result;
}
/**
* Wraps the provided filters in an And filter
*
* @param filters the filters
* @return the provided filters, wrapped in an And filter
*/
public And and(Filter... filters) {
return and(List.of(filters));
}
/**
* Constructs a "between" filter for the provided property
*
* @param propertyId the property
* @param startValue the start value (inclusive)
* @param endValue the end value (inclusive)
* @return the constructed filter
*/
public AbstractJunctionFilter between(String propertyId, Comparable<?> startValue, Comparable<?> endValue) {
return newJunction(new Between(propertyId, startValue, endValue));
}
/**
* Get the value of a property of the given bean by use of optimized reflection
* by Spring.
*
* @param bean The bean
* @param propertyName The name of the property to get
* @return The property value
*/
protected Object getProperty(Object bean, String propertyName) {
if (bean == null || propertyName == null) {
return null;
}
return PropertyAccessorFactory.forBeanPropertyAccess(bean).getPropertyValue(propertyName);
}
/**
* Constructs a "greater than" filter for a property
*
* @param propertyId the property
* @param value the value to compare to
* @return the constructed filter
*/
public AbstractJunctionFilter greater(String propertyId, Object value) {
return newJunction(new Greater(propertyId, value));
}
/**
* Constructs a "greater or equals" filter for a property
*
* @param propertyId the property
* @param value the value to compare to
* @return the constructed filter
*/
public AbstractJunctionFilter greaterOrEqual(String propertyId, Object value) {
return newJunction(new GreaterOrEqual(propertyId, value));
}
/**
* Constructs an "equals" filter for a property
*
* @param propertyId the property
* @param value the value to compare to
* @return the constructed filter
*/
public AbstractJunctionFilter isEqual(String propertyId, Object value) {
return newJunction(new Equal(propertyId, value));
}
/**
* Constructs an "isNull" filter for a property
*
* @param propertyId the property
* @return the constructed filter
*/
public AbstractJunctionFilter isNull(String propertyId) {
return newJunction(new IsNull(propertyId));
}
/**
* Constructs a "less than" filter for a property
*
* @param propertyId the property
* @param value the property value
* @return the constructed filter
*/
public AbstractJunctionFilter less(String propertyId, Object value) {
return newJunction(new Less(propertyId, value));
}
/**
* Constructs a "less or equal" filter for a property
*
* @param propertyId the property
* @param value the property value
* @return the constructed filter
*/
public AbstractJunctionFilter lessOrEqual(String propertyId, Object value) {
return newJunction(new LessOrEqual(propertyId, value));
}
/**
* Constructs a case-sensitive "like" filter
*
* @param propertyId the property
* @param value the property value
* @return the constructed filter
*/
public AbstractJunctionFilter like(String propertyId, String value) {
return newJunction(new Like(propertyId, value, true));
}
/**
* Constructs a "like" filter for string comparison
*
* @param propertyId the property
* @param value the property value
* @param caseSensitive whether the search is case-insensitive
* @return the constructed filter
*/
public AbstractJunctionFilter like(String propertyId, String value, boolean caseSensitive) {
return newJunction(new Like(propertyId, value, caseSensitive));
}
/**
* Constructs a "like" filter (case insensitive) for string comparison
*
* @param propertyId the property
* @param value the property value
* @return the constructed filter
*/
public AbstractJunctionFilter likeIgnoreCase(String propertyId, String value) {
return newJunction(new Like(propertyId, value, false));
}
private AbstractJunctionFilter newJunction(Filter... filters) {
if (this instanceof Or) {
return or(filters);
}
// Default use And junction
return and(filters);
}
/**
* Constructs a filter that is the negation of the provided filter
*
* @param filter the filter to negate
* @return the constructed filter
*/
public AbstractJunctionFilter not(Filter filter) {
return newJunction(new Not(filter));
}
/**
* Wraps the current filter in an Or filter (if not already present)
*
* @return the current filter
*/
public Or or() {
if (this instanceof Or) {
// Do nothing
return (Or) this;
}
// Else create Or add current
return new Or(this);
}
/**
* Wraps the provided filters in a logical OR
*
* @param filters the filter to wrap
* @return the filters wrapped in a logical or
*/
public Or or(Collection<Filter> filters) {
Or result;
if (this instanceof Or) {
result = (Or) this;
result.getFilters().addAll(filters);
} else {
result = new Or(this).or(filters);
}
return result;
}
/**
* Wraps the provided filters in a logical OR
*
* @param filters the filter to wrap
* @return the filters wrapped in a logical or
*/
public Or or(Filter... filters) {
return or(List.of(filters));
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}