Does the functions like filter/top are implemented in the framework?
Does the functions like filter/top are implemented in the framework? I cannot make them work with the sample.
If you look at the current example we have both implemented a $top and $filter operation, for sure not all of them but at least a sort of getting started point.
In the current example if you run this out of the box you can fire the following queries with $filter and $top.
Example $top query: http://localhost:8080/example.svc/Persons?$top=1
$filter query: http://localhost:8080/example.svc/Persons?$filter=firstName eq 'Darkwing'
The implementation for the $top and $filter is in this example in the StrategyBuilder that is used to filter the in memory dataset. Here a link to the class in question: https://github.com/sdl/odata-example/blob/master/example-datasource/src/main/java/com/sdl/odata/example/datasource/StrategyBuilder.java
You can see in the buildFromOperation method that we check what type the incoming query operation is
This is used for the $top operation:
...if (operation instanceof LimitOperation) {
buildFromLimit((LimitOperation) operation);
}...
This is the actual code that limits the returned dataset:
private void buildFromLimit(LimitOperation operation) throws ODataException {
this.limit = operation.getCount();
LOG.debug("Limit has been set to: {}", limit);
buildFromOperation(operation.getSource());
}
This limit can be used to limit your dataset, we do this in the place where the actual in memory result set is returned, we simply limit the amount of items in the collection there.
This is used for a $filter operation that does a simple compare:
...if (operation instanceof CriteriaFilterOperation) {
buildFromFilter((CriteriaFilterOperation)operation);
}...
Here is the actual code that does a $filter compare operation the ('$filter=firstName eq 'Darkwing') part:
private void buildFromFilter(CriteriaFilterOperation criteriaFilterOperation) {
Criteria criteria = criteriaFilterOperation.getCriteria();
if(criteria instanceof ComparisonCriteria) {
ComparisonCriteria comparisonCriteria = (ComparisonCriteria) criteria;
//For now we only support here property key/value comparisons, just to keep the example simple
if(comparisonCriteria.getLeft() instanceof PropertyCriteriaValue
&& comparisonCriteria.getRight() instanceof LiteralCriteriaValue) {
PropertyCriteriaValue propertyCriteriaValue = (PropertyCriteriaValue) comparisonCriteria.getLeft();
LiteralCriteriaValue literalCriteriaValue = (LiteralCriteriaValue) comparisonCriteria.getRight();
Predicate<Person> p = person -> {
Object fieldValue = getPersonField(person, propertyCriteriaValue.getPropertyName());
Object queryValue = literalCriteriaValue.getValue();
LOG.debug("Comparing equality on value: {} to queried value: {}", fieldValue, queryValue);
return fieldValue != null && fieldValue.equals(literalCriteriaValue.getValue());
};
predicates.add(p);
}
}
}
I hope this helps you along?
Thanks for your information.
I found that the implementation here is incomplete.
private void buildFromFilter(CriteriaFilterOperation criteriaFilterOperation) {
it can only handle eq, and i cannot handle the operation like gt, lt.
And it can only handle the string value, and not for BigDecimal.
Are there an existing StrategyBuilder that the user can extend easily and all those operations can be supported out of the box, without the user to write so many code?
It is possible to handle GreaterThan operation:
if(criteria instanceof ComparisonCriteria) {
ComparisonCriteria comparisonCriteria = (ComparisonCriteria) criteria;
ComparisonOperator operator = comparisonCriteria.getOperator();
if(operator instanceof GtOperator$) {
LOG.info("Greater then operator");
}
Can you expand on the BigDecimal not working? Perhaps you can paste the query you want to have working and I can think with you?
I totally agree on a more out of the box StrategyBuilder / datasource, it is still on my todo list to get to that, just having lack of time to get to it.