[Major] Implemented GenericSearch for internal use

This commit is contained in:
Robert von Burg 2018-03-14 09:04:07 +01:00
parent 9bd0d43f50
commit 50fbafde45
8 changed files with 224 additions and 78 deletions

View File

@ -1,7 +1,5 @@
package li.strolch.search;
import java.util.Date;
import li.strolch.model.StrolchRootElement;
import li.strolch.utils.collections.DateRange;
@ -10,46 +8,46 @@ public interface ExpressionBuilder {
Object extract(StrolchRootElement element);
default SearchExpression isEqualTo(Object right) {
return element -> PredicatesSupport.isEqualTo(right, false).matches(extract(element));
return element -> PredicatesSupport.isEqualTo(right).matches(extract(element));
}
default SearchExpression isNotEqualTo(Object right) {
return element -> PredicatesSupport.isEqualTo(right, false).not().matches(extract(element));
return element -> PredicatesSupport.isNotEqualTo(right).matches(extract(element));
}
default SearchExpression isEqualToIgnoreCase(Object right) {
return element -> PredicatesSupport.isEqualTo(right, true).matches(extract(element));
return element -> PredicatesSupport.isEqualToIgnoreCase(right).matches(extract(element));
}
default SearchExpression isNotEqualToIgnoreCase(Object right) {
return element -> PredicatesSupport.isEqualTo(right, true).not().matches(extract(element));
return element -> PredicatesSupport.isNotEqualToIgnoreCase(right).matches(extract(element));
}
default SearchExpression startsWith(Object right) {
return element -> PredicatesSupport.startsWith(right, false).matches(extract(element));
return element -> PredicatesSupport.startsWith(right).matches(extract(element));
}
default SearchExpression startsWithIgnoreCase(Object right) {
return element -> PredicatesSupport.startsWith(right, true).matches(extract(element));
return element -> PredicatesSupport.startsWithIgnoreCase(right).matches(extract(element));
}
default SearchExpression endsWith(Object right) {
return element -> PredicatesSupport.endsWith(right, false).matches(extract(element));
return element -> PredicatesSupport.endsWith(right).matches(extract(element));
}
default SearchExpression endsWithIgnoreCase(Object right) {
return element -> PredicatesSupport.endsWith(right, true).matches(extract(element));
return element -> PredicatesSupport.endsWithIgnoreCase(right).matches(extract(element));
}
default SearchExpression contains(Object right) {
return element -> PredicatesSupport.contains(right, false).matches(extract(element));
return element -> PredicatesSupport.contains(right).matches(extract(element));
}
default SearchExpression containsIgnoreCase(Object right) {
return element -> PredicatesSupport.contains(right, true).matches(extract(element));
return element -> PredicatesSupport.containsIgnoreCase(right).matches(extract(element));
}
default SearchExpression inRange(DateRange range) {
return element -> range.contains((Date) extract(element));
return element -> PredicatesSupport.inRange(range).matches(extract(element));
}
}

View File

@ -0,0 +1,78 @@
package li.strolch.search;
import li.strolch.model.Order;
import li.strolch.model.ParameterBag;
import li.strolch.model.StrolchElement;
import li.strolch.model.activity.Activity;
import li.strolch.model.parameter.Parameter;
public class ExpressionsSupport {
public static SearchExpression not(SearchExpression expression) {
return element -> !expression.matches(element);
}
public static ExpressionBuilder id() {
return StrolchElement::getId;
}
public static SearchExpression id(SearchPredicate predicate) {
return element -> predicate.matches(element.getId());
}
public static ExpressionBuilder name() {
return StrolchElement::getName;
}
public static SearchExpression name(SearchPredicate predicate) {
return element -> predicate.matches(element.getName());
}
public static ExpressionBuilder date() {
return element -> ((Order) element).getDate();
}
public static SearchExpression date(SearchPredicate predicate) {
return element -> predicate.matches(((Order) element).getDate());
}
public static ExpressionBuilder state() {
return element -> {
if (element instanceof Order)
return ((Order) element).getState();
if (element instanceof Activity)
return ((Activity) element).getState();
throw new IllegalArgumentException(element.getObjectType() + " does not have a state!");
};
}
public static SearchExpression state(SearchPredicate predicate) {
return element -> predicate.matches(state().extract(element));
}
public static ExpressionBuilder param(String bagId, String paramId) {
return element -> {
ParameterBag bag = element.getParameterBag(bagId);
if (bag == null)
return null;
Parameter<?> param = bag.getParameter(paramId);
return param == null ? null : param.getValue();
};
}
public static SearchExpression param(String bagId, String paramId, SearchPredicate predicate) {
return element -> predicate.matches(param(bagId, paramId).extract(element));
}
public static SearchExpression paramNull(String bagId, String paramId) {
return element -> {
ParameterBag bag = element.getParameterBag(bagId);
if (bag == null)
return true;
Parameter<?> param = bag.getParameter(paramId);
return param == null;
};
}
}

View File

@ -0,0 +1,34 @@
package li.strolch.search;
import li.strolch.model.StrolchRootElement;
public class GenericSearch<T extends StrolchRootElement> extends StrolchSearch<T> {
@Override
protected void define() {
// ignored
}
@SuppressWarnings("unchecked")
protected GenericSearch<T> resources(String... types) {
super.resources(types);
return this;
}
@SuppressWarnings("unchecked")
protected GenericSearch<T> orders(String... types) {
super.orders(types);
return this;
}
@SuppressWarnings("unchecked")
protected GenericSearch<T> activities(String... types) {
super.activities(types);
return this;
}
protected GenericSearch<T> where(SearchExpression expression) {
super.where(expression);
return this;
}
}

View File

@ -7,20 +7,44 @@ import li.strolch.utils.collections.DateRange;
public class PredicatesSupport {
public static SearchPredicate isEqualTo(Object right, boolean ignoreCase) {
return left -> ObjectHelper.equals(left, right, ignoreCase);
public static SearchPredicate isEqualTo(Object right) {
return left -> ObjectHelper.equals(left, right, false);
}
public static SearchPredicate startsWith(Object right, boolean ignoreCase) {
return left -> ObjectHelper.startsWith(left, right, ignoreCase);
public static SearchPredicate isEqualToIgnoreCase(Object right) {
return left -> ObjectHelper.equals(left, right, true);
}
public static SearchPredicate endsWith(Object right, boolean ignoreCase) {
return left -> ObjectHelper.endsWith(left, right, ignoreCase);
public static SearchPredicate isNotEqualTo(Object right) {
return left -> !ObjectHelper.equals(left, right, false);
}
public static SearchPredicate contains(Object right, boolean ignoreCase) {
return left -> ObjectHelper.contains(left, right, ignoreCase);
public static SearchPredicate isNotEqualToIgnoreCase(Object right) {
return left -> !ObjectHelper.equals(left, right, true);
}
public static SearchPredicate startsWith(Object right) {
return left -> ObjectHelper.startsWith(left, right, false);
}
public static SearchPredicate startsWithIgnoreCase(Object right) {
return left -> ObjectHelper.startsWith(left, right, true);
}
public static SearchPredicate endsWith(Object right) {
return left -> ObjectHelper.endsWith(left, right, false);
}
public static SearchPredicate endsWithIgnoreCase(Object right) {
return left -> ObjectHelper.endsWith(left, right, true);
}
public static SearchPredicate contains(Object right) {
return left -> ObjectHelper.contains(left, right, false);
}
public static SearchPredicate containsIgnoreCase(Object right) {
return left -> ObjectHelper.contains(left, right, true);
}
public static SearchPredicate inRange(DateRange range) {

View File

@ -1,11 +1,5 @@
package li.strolch.search;
import li.strolch.model.Order;
import li.strolch.model.ParameterBag;
import li.strolch.model.StrolchElement;
import li.strolch.model.activity.Activity;
import li.strolch.model.parameter.Parameter;
public interface SearchExpressions {
default SearchExpression not(SearchExpression expression) {
@ -13,66 +7,46 @@ public interface SearchExpressions {
}
default ExpressionBuilder id() {
return StrolchElement::getId;
return ExpressionsSupport.id();
}
default SearchExpression id(SearchPredicate predicate) {
return element -> predicate.matches(element.getId());
return ExpressionsSupport.id(predicate);
}
default ExpressionBuilder name() {
return StrolchElement::getName;
return ExpressionsSupport.name();
}
default SearchExpression name(SearchPredicate predicate) {
return element -> predicate.matches(element.getName());
return ExpressionsSupport.name(predicate);
}
default ExpressionBuilder date() {
return element -> ((Order) element).getDate();
return ExpressionsSupport.date();
}
default SearchExpression date(SearchPredicate predicate) {
return element -> predicate.matches(((Order) element).getDate());
return ExpressionsSupport.date(predicate);
}
default ExpressionBuilder state() {
return element -> {
if (element instanceof Order)
return ((Order) element).getState();
if (element instanceof Activity)
return ((Activity) element).getState();
throw new IllegalArgumentException(element.getObjectType() + " does not have a state!");
};
return ExpressionsSupport.state();
}
default SearchExpression state(SearchPredicate predicate) {
return element -> predicate.matches(state().extract(element));
return ExpressionsSupport.state(predicate);
}
default ExpressionBuilder param(String bagId, String paramId) {
return element -> {
ParameterBag bag = element.getParameterBag(bagId);
if (bag == null)
return null;
Parameter<?> param = bag.getParameter(paramId);
return param == null ? null : param.getValue();
};
return ExpressionsSupport.param(bagId, paramId);
}
default SearchExpression param(String bagId, String paramId, SearchPredicate predicate) {
return element -> predicate.matches(param(bagId, paramId).extract(element));
return ExpressionsSupport.param(bagId, paramId, predicate);
}
default SearchExpression paramNull(String bagId, String paramId) {
return element -> {
ParameterBag bag = element.getParameterBag(bagId);
if (bag == null)
return true;
Parameter<?> param = bag.getParameter(paramId);
return param == null;
};
return ExpressionsSupport.paramNull(bagId, paramId);
}
}

View File

@ -1,52 +1,50 @@
package li.strolch.search;
import java.util.Date;
import li.strolch.utils.collections.DateRange;
public interface SearchPredicates {
default SearchPredicate isEqualTo(Object right) {
return PredicatesSupport.isEqualTo(right, false);
return PredicatesSupport.isEqualTo(right);
}
default SearchPredicate isNotEqualTo(Object right) {
return PredicatesSupport.isEqualTo(right, false).not();
return PredicatesSupport.isNotEqualTo(right);
}
default SearchPredicate isEqualToIgnoreCase(Object right) {
return PredicatesSupport.isEqualTo(right, true);
return PredicatesSupport.isEqualToIgnoreCase(right);
}
default SearchPredicate isNotEqualToIgnoreCase(Object right) {
return PredicatesSupport.isEqualTo(right, true).not();
return PredicatesSupport.isNotEqualToIgnoreCase(right);
}
default SearchPredicate startsWith(Object right) {
return PredicatesSupport.startsWith(right, false);
return PredicatesSupport.startsWith(right);
}
default SearchPredicate startsWithIgnoreCase(Object right) {
return PredicatesSupport.startsWith(right, true);
return PredicatesSupport.startsWithIgnoreCase(right);
}
default SearchPredicate endsWith(Object right) {
return PredicatesSupport.endsWith(right, false);
return PredicatesSupport.endsWith(right);
}
default SearchPredicate endsWithIgnoreCase(Object right) {
return PredicatesSupport.endsWith(right, true);
return PredicatesSupport.endsWithIgnoreCase(right);
}
default SearchPredicate contains(Object right) {
return PredicatesSupport.contains(right, false);
return PredicatesSupport.contains(right);
}
default SearchPredicate containsIgnoreCase(Object right) {
return PredicatesSupport.contains(right, true);
return PredicatesSupport.containsIgnoreCase(right);
}
default SearchPredicate inRange(DateRange range) {
return left -> range.contains((Date) left);
return PredicatesSupport.inRange(range);
}
}

View File

@ -30,7 +30,7 @@ public abstract class StrolchSearch<T extends StrolchRootElement>
*
* @return this object for chaining
*/
public StrolchSearch internal() {
public StrolchSearch<T> internal() {
this.privilegeValue = StrolchModelConstants.INTERNAL;
return this;
}
@ -58,28 +58,28 @@ public abstract class StrolchSearch<T extends StrolchRootElement>
protected abstract void define();
@SuppressWarnings("unchecked")
protected StrolchSearch resources(String... types) {
protected StrolchSearch<T> resources(String... types) {
this.navigator = tx -> (Stream<T>) tx.streamResources(types);
return this;
}
@SuppressWarnings("unchecked")
protected StrolchSearch orders(String... types) {
protected StrolchSearch<T> orders(String... types) {
this.navigator = tx -> (Stream<T>) tx.streamOrders(types);
return this;
}
@SuppressWarnings("unchecked")
protected StrolchSearch activities(String... types) {
protected StrolchSearch<T> activities(String... types) {
this.navigator = tx -> (Stream<T>) tx.streamActivities(types);
return this;
}
protected StrolchSearch where(SearchExpression searchExpression) {
protected StrolchSearch<T> where(SearchExpression expression) {
if (this.expression == null)
this.expression = searchExpression;
this.expression = expression;
else
this.expression = this.expression.and(searchExpression);
this.expression = this.expression.and(expression);
return this;
}

View File

@ -4,6 +4,10 @@ import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static li.strolch.agent.api.StrolchAgent.getUniqueId;
import static li.strolch.model.ModelGenerator.*;
import static li.strolch.search.ExpressionsSupport.name;
import static li.strolch.search.ExpressionsSupport.param;
import static li.strolch.search.ExpressionsSupport.state;
import static li.strolch.search.PredicatesSupport.*;
import static org.junit.Assert.assertEquals;
import java.util.Date;
@ -194,6 +198,42 @@ public class StrolchSearchTest {
}
}
@Test
public void shouldSearchGeneric() {
StrolchRealm realm = runtimeMock.getAgent().getContainer().getRealm(cert);
try (StrolchTransaction tx = realm.openTx(cert, ParallelTests.class)) {
Map<String, State> states = new GenericSearch<Activity>() //
.activities() //
.where(state().isEqualTo(State.PLANNING) //
.and(name(isEqualTo("Activity")))) //
.search(tx) //
.toMap(Activity::getId, Activity::getState);
assertEquals(1, states.size());
}
}
@Test
public void shouldSearchGeneric1() {
StrolchRealm realm = runtimeMock.getAgent().getContainer().getRealm(cert);
try (StrolchTransaction tx = realm.openTx(cert, ParallelTests.class)) {
assertEquals(4, new GenericSearch<Resource>() //
.resources() //
.where(param(BAG_ID, PARAM_STRING_ID, contains("rol"))) //
.search(tx) //
.toList().size());
assertEquals(4, new GenericSearch<Resource>() //
.resources() //
.where(param(BAG_ID, PARAM_STRING_ID, startsWithIgnoreCase("STR"))) //
.search(tx) //
.toList().size());
}
}
public class BallSearch extends StrolchSearch<Resource> {
private String id;