[Fix] Fixed behavior of IsIn and Contains ReportFilters

This commit is contained in:
Robert von Burg 2018-08-30 13:08:59 +02:00
parent 901af241ac
commit 7677d27442
7 changed files with 103 additions and 57 deletions

View File

@ -13,8 +13,8 @@ public class GreaterThanReportFilter extends ReportFilterPolicy {
@Override
protected boolean filter(Object left, Object right, boolean negate) {
if (negate)
return ObjectHelper.compare(left, right, false) > 0;
else
return ObjectHelper.compare(right, left, false) > 0;
else
return ObjectHelper.compare(left, right, false) > 0;
}
}

View File

@ -1,6 +1,13 @@
package li.strolch.report.policy;
import static java.util.stream.Collectors.toList;
import java.util.Arrays;
import java.util.Date;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.model.StrolchValueType;
import li.strolch.model.parameter.Parameter;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.utils.ObjectHelper;
@ -10,6 +17,43 @@ public class IsInReportFilter extends ReportFilterPolicy {
super(container, tx);
}
@Override
public boolean filter(Object value) {
Object left;
if (value instanceof Date) {
if (this.right == null)
this.right = Arrays.stream(this.filterValue.split(",")).map(String::trim)
.map(this::parseFilterValueToDate).collect(toList());
left = value;
} else if (value instanceof Parameter) {
Parameter parameter = (Parameter) value;
if (this.right == null) {
StrolchValueType valueType = parameter.getValueType();
if (valueType == StrolchValueType.DATE)
this.right = Arrays.stream(this.filterValue.split(",")).map(String::trim)
.map(this::parseFilterValueToDate).collect(toList());
else
this.right = Arrays.stream(this.filterValue.split(",")).map(String::trim)
.map(valueType::parseValue).collect(toList());
}
left = parameter.getValue();
} else {
if (this.right == null)
this.right = Arrays.stream(this.filterValue.split(",")).map(String::trim).collect(toList());
left = value.toString();
}
return filter(left, this.right, this.negate);
}
@Override
protected boolean filter(Object left, Object right, boolean negate) {
if (negate)

View File

@ -13,8 +13,8 @@ public class LessThanReportFilter extends ReportFilterPolicy {
@Override
protected boolean filter(Object left, Object right, boolean negate) {
if (negate)
return ObjectHelper.compare(left, right, false) < 0;
else
return ObjectHelper.compare(right, left, false) < 0;
else
return ObjectHelper.compare(left, right, false) < 0;
}
}

View File

@ -21,7 +21,7 @@ public abstract class ReportFilterPolicy extends StrolchPolicy {
protected boolean negate;
protected String filterValue;
protected Object left;
protected Object right;
public boolean isNegate() {
return this.negate;
@ -35,14 +35,6 @@ public abstract class ReportFilterPolicy extends StrolchPolicy {
this.filterValue = filterValue;
}
public Object getLeft() {
return this.left;
}
public void setLeft(Object left) {
this.left = left;
}
public void init(String value) {
if (value.startsWith("!")) {
setNegate(true);
@ -54,38 +46,38 @@ public abstract class ReportFilterPolicy extends StrolchPolicy {
public boolean filter(Object value) {
Object right;
Object left;
if (value instanceof Date) {
if (this.left == null)
this.left = parseFilterValueToDate(this.filterValue);
if (this.right == null)
this.right = parseFilterValueToDate(this.filterValue);
right = value;
left = value;
} else if (value instanceof Parameter) {
Parameter parameter = (Parameter) value;
if (this.left == null) {
if (this.right == null) {
StrolchValueType valueType = parameter.getValueType();
if (valueType == StrolchValueType.DATE)
this.left = parseFilterValueToDate(this.filterValue);
this.right = parseFilterValueToDate(this.filterValue);
else
this.left = valueType.parseValue(this.filterValue);
this.right = valueType.parseValue(this.filterValue);
}
right = parameter.getValue();
left = parameter.getValue();
} else {
if (this.left == null)
this.left = this.filterValue;
if (this.right == null)
this.right = this.filterValue;
right = value.toString();
left = value.toString();
}
return filter(this.left, right, this.negate);
return filter(left, this.right, this.negate);
}
private Date parseFilterValueToDate(String filterValue) {
protected Date parseFilterValueToDate(String filterValue) {
DBC.INTERIM.assertNotEmpty("filterValue must not be empty for date comparisons!", filterValue);
if (!filterValue.startsWith("now"))

View File

@ -1,30 +1,26 @@
package li.strolch.report;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assert.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import li.strolch.model.StrolchElement;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.google.gson.JsonObject;
import li.strolch.model.StrolchElement;
import li.strolch.model.StrolchRootElement;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.model.Certificate;
import li.strolch.testbase.runtime.RuntimeMock;
import li.strolch.utils.collections.DateRange;
import li.strolch.utils.collections.MapOfSets;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class GenericReportTest {
@ -172,7 +168,7 @@ public class GenericReportTest {
.filter("Product", "product01") //
.dateRange(dateRange) //
.doReportAsJson() //
.collect(Collectors.toList());
.collect(toList());
assertTrue(result.isEmpty());
// expect 2 slots, as in date range
@ -182,7 +178,7 @@ public class GenericReportTest {
.filter("Product", "product01") //
.dateRange(dateRange) //
.doReportAsJson() //
.collect(Collectors.toList());
.collect(toList());
assertEquals(2, result.size());
}
}
@ -199,15 +195,14 @@ public class GenericReportTest {
// expect no orders as all not in date range
Report report = new Report(tx, "fromStockReport");
List<JsonObject> result = report.filter("Product", "product01").dateRange(dateRange).doReportAsJson()
.collect(Collectors.toList());
.collect(toList());
assertTrue(result.isEmpty());
// expect 2 orders, as in date range
to = new Date(LocalDate.of(2017, 3, 1).toEpochDay() * 86400000);
dateRange = new DateRange().from(from, true).to(to, false);
report = new Report(tx, "fromStockReport");
result = report.filter("Product", "product01").dateRange(dateRange).doReportAsJson()
.collect(Collectors.toList());
result = report.filter("Product", "product01").dateRange(dateRange).doReportAsJson().collect(toList());
assertEquals(2, result.size());
// expect 4 orders, as all in date range
@ -215,7 +210,7 @@ public class GenericReportTest {
dateRange = new DateRange().from(from, true).to(to, false);
report = new Report(tx, "fromStockReport");
result = report.filter("Product", "product01", "product02").dateRange(dateRange).doReportAsJson()
.collect(Collectors.toList());
.collect(toList());
assertEquals(4, result.size());
}
}
@ -228,16 +223,14 @@ public class GenericReportTest {
Report report = new Report(tx, "stockReport");
MapOfSets<String, StrolchRootElement> filterCriteria = report.generateFilterCriteria();
assertFalse(filterCriteria.containsSet("Location"));
assertFalse(filterCriteria.containsSet("Slot"));
assertThat(filterCriteria.getSet("Product").stream().map(StrolchElement::getId).collect(Collectors.toSet()),
containsInAnyOrder("product01", "product02"));
assertThat(
filterCriteria.getSet("Location").stream().map(StrolchElement::getId).collect(Collectors.toSet()),
containsInAnyOrder("location01", "location02"));
assertThat(filterCriteria.getSet("Storage").stream().map(StrolchElement::getId).collect(Collectors.toSet()),
containsInAnyOrder("storage01", "storage02"));
assertThat(filterCriteria.getSet("Section").stream().map(StrolchElement::getId).collect(Collectors.toSet()),
containsInAnyOrder("section001", "section002"));
assertFalse(filterCriteria.containsSet("Slot"));
}
}
@ -247,20 +240,24 @@ public class GenericReportTest {
try (StrolchTransaction tx = runtimeMock.openUserTx(certificate)) {
Report report = new Report(tx, "stockReport");
MapOfSets<String, StrolchRootElement> filterCriteria = report //
.filter("Product", "product01") //
MapOfSets<String, StrolchRootElement> filterCriteria = report.filter("Product", "product01")
.generateFilterCriteria();
// assert sequence of filter criteria is correct
List<String> types = new ArrayList<>(filterCriteria.keySet());
assertEquals(3, types.size());
assertEquals("Product", types.get(0));
assertEquals("Storage", types.get(1));
assertEquals("Section", types.get(2));
assertFalse(filterCriteria.containsSet("Location"));
assertFalse(filterCriteria.containsSet("Slot"));
assertThat(filterCriteria.getSet("Product").stream().map(StrolchElement::getId).collect(Collectors.toSet()),
containsInAnyOrder("product01"));
assertThat(
filterCriteria.getSet("Location").stream().map(StrolchElement::getId).collect(Collectors.toSet()),
containsInAnyOrder("location01", "location02"));
assertThat(filterCriteria.getSet("Storage").stream().map(StrolchElement::getId).collect(Collectors.toSet()),
containsInAnyOrder("storage01", "storage02"));
assertThat(filterCriteria.getSet("Section").stream().map(StrolchElement::getId).collect(Collectors.toSet()),
containsInAnyOrder("section001", "section002"));
assertFalse(filterCriteria.containsSet("Slot"));
}
}

View File

@ -1,6 +1,9 @@
<StrolchPolicies>
<PolicyType Type="ReportFilterPolicy" Api="li.strolch.report.policy.ReportFilterPolicy">
<Policy Key="Contains" Class="li.strolch.report.policy.ContainsReportFilter" />
<Policy Key="IsIn" Class="li.strolch.report.policy.IsInReportFilter" />
<Policy Key="GreaterThan" Class="li.strolch.report.policy.GreaterThanReportFilter" />
<Policy Key="GreaterThan" Class="li.strolch.report.policy.GreaterThanReportFilter" />
<Policy Key="LessThan" Class="li.strolch.report.policy.LessThanReportFilter" />
<Policy Key="Equals" Class="li.strolch.report.policy.EqualsReportFilter" />

View File

@ -15,6 +15,10 @@
<Parameter Id="quantity" Name="Quantity" Type="String" Interpretation="Resource-Ref" Uom="Slot" Value="Bags/parameters/quantity"/>
</ParameterBag>
<ParameterBag Id="stateFilter" Name="Filter" Type="Filter">
<Parameter Id="policy" Name="Filter Policy" Type="String" Interpretation="ReportFilterPolicy" Uom="key:IsIn" Value="valid, invalid"/>
<Parameter Id="fieldRef" Name="Field reference" Type="String" Interpretation="Resource-Ref" Uom="Slot" Value="Bags/parameters/state"/>
</ParameterBag>
<ParameterBag Id="quantityFilter" Name="Filter" Type="Filter">
<Parameter Id="policy" Name="Filter Policy" Type="String" Interpretation="ReportFilterPolicy" Uom="key:GreaterThan" Value="0.0"/>
<Parameter Id="fieldRef" Name="Field reference" Type="String" Interpretation="Resource-Ref" Uom="Slot" Value="Bags/parameters/quantity"/>
@ -37,10 +41,10 @@
</ParameterBag>
<ParameterBag Id="joins" Name="Joins" Type="Joins">
<Parameter Id="Product" Name="Product" Type="String" Interpretation="Resource-Ref" Uom="Product" Value="Slot"/>
<Parameter Id="Section" Name="Section" Type="String" Interpretation="Resource-Ref" Uom="Section" Value="Slot"/>
<Parameter Id="Storage" Name="Storage" Type="String" Interpretation="Resource-Ref" Uom="Storage" Value="Section"/>
<Parameter Id="Location" Name="Location" Type="String" Interpretation="Resource-Ref" Uom="Location" Value="Storage"/>
<Parameter Id="Product" Index="0" Name="Product" Type="String" Interpretation="Resource-Ref" Uom="Product" Value="Slot"/>
<Parameter Id="Section" Index="10" Name="Section" Type="String" Interpretation="Resource-Ref" Uom="Section" Value="Slot"/>
<Parameter Id="Storage" Index="5" Name="Storage" Type="String" Interpretation="Resource-Ref" Uom="Storage" Value="Section"/>
<Parameter Id="Location" Hidden="true" Name="Location" Type="String" Interpretation="Resource-Ref" Uom="Location" Value="Storage"/>
</ParameterBag>
<Policies>
@ -184,6 +188,7 @@
<ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
<Parameter Id="quantity" Name="Quantity" Type="Float" Value="20.0"/>
<Parameter Id="maxQuantity" Name="max. quantity of items" Type="Float" Value="40.0"/>
<Parameter Id="state" Name="State" Type="String" Value="valid"/>
</ParameterBag>
<ParameterBag Id="relations" Name="Relations" Type="Parameters">
<Parameter Id="parentSection" Name="Section" Type="String" Interpretation="Resource-Ref" Uom="Section" Value="section001"/>
@ -195,6 +200,7 @@
<ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
<Parameter Id="quantity" Name="Quantity" Type="Float" Value="18.0"/>
<Parameter Id="maxQuantity" Name="max. quantity of items" Type="Float" Value="20.0"/>
<Parameter Id="state" Name="State" Type="String" Value="valid"/>
</ParameterBag>
<ParameterBag Id="relations" Name="Relations" Type="Parameters">
<Parameter Id="parentSection" Name="Section" Type="String" Interpretation="Resource-Ref" Uom="Section" Value="section001"/>
@ -206,6 +212,7 @@
<ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
<Parameter Id="quantity" Name="Quantity" Type="Float" Value="11.0"/>
<Parameter Id="maxQuantity" Name="max. quantity of items" Type="Float" Value="40.0"/>
<Parameter Id="state" Name="State" Type="String" Value="valid"/>
</ParameterBag>
<ParameterBag Id="relations" Name="Relations" Type="Parameters">
<Parameter Id="parentSection" Name="Section" Type="String" Interpretation="Resource-Ref" Uom="Section" Value="section002"/>
@ -217,6 +224,7 @@
<ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
<Parameter Id="quantity" Name="Quantity" Type="Float" Value="16.0"/>
<Parameter Id="maxQuantity" Name="max. quantity of items" Type="Float" Value="20.0"/>
<Parameter Id="state" Name="State" Type="String" Value="valid"/>
</ParameterBag>
<ParameterBag Id="relations" Name="Relations" Type="Parameters">
<Parameter Id="parentSection" Name="Section" Type="String" Interpretation="Resource-Ref" Uom="Section" Value="section002"/>
@ -228,6 +236,7 @@
<ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
<Parameter Id="quantity" Name="Quantity" Type="Float" Value="0.0"/>
<Parameter Id="maxQuantity" Name="max. quantity of items" Type="Float" Value="20.0"/>
<Parameter Id="state" Name="State" Type="String" Value="valid"/>
</ParameterBag>
<ParameterBag Id="relations" Name="Relations" Type="Parameters">
<Parameter Id="parentSection" Name="Section" Type="String" Interpretation="Resource-Ref" Uom="Section" Value="section002"/>
@ -239,6 +248,7 @@
<ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
<Parameter Id="quantity" Name="Quantity" Type="Float" Value="22.0"/>
<Parameter Id="maxQuantity" Name="max. quantity of items" Type="Float" Value="20.0"/>
<Parameter Id="state" Name="State" Type="String" Value="valid"/>
</ParameterBag>
<ParameterBag Id="relations" Name="Relations" Type="Parameters">
<Parameter Id="parentSection" Name="Section" Type="String" Interpretation="Resource-Ref" Uom="Section" Value="section002"/>