From 8be9639e80adeb29c06f52fd1ec2505d8482429e Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Fri, 3 Jan 2020 17:02:16 +0200 Subject: [PATCH 01/53] Clarify doc --- client/src/main/proto/spine/client/filters.proto | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/main/proto/spine/client/filters.proto b/client/src/main/proto/spine/client/filters.proto index 63e98b7049f..881dff656b8 100644 --- a/client/src/main/proto/spine/client/filters.proto +++ b/client/src/main/proto/spine/client/filters.proto @@ -104,7 +104,9 @@ message Filter { // The path to the field to be matched. // - // For entities, the path contains the only entry being the name of entity column. + // If the filter is a query filter, this path should contain only top-level message fields that + // are marked with `(column)`. For subscriptions, any field can be specified including nested + // one. base.FieldPath field_path = 1 [(required) = true]; // The value to compare upon. From 766d8e11e3b2d1da30b922b2b33f26604a530dc3 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Fri, 3 Jan 2020 17:02:24 +0200 Subject: [PATCH 02/53] Fix a typo --- .../main/java/io/spine/server/stand/EntityUpdateHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/io/spine/server/stand/EntityUpdateHandler.java b/server/src/main/java/io/spine/server/stand/EntityUpdateHandler.java index b6cc65b3281..710bdf2e9b9 100644 --- a/server/src/main/java/io/spine/server/stand/EntityUpdateHandler.java +++ b/server/src/main/java/io/spine/server/stand/EntityUpdateHandler.java @@ -99,7 +99,7 @@ private static EntityStateChanged asEntityEvent(EventEnvelope event) { } /** - * Checks if the event message matches the subscription filters. + * Checks if the entity state matches the subscription filters. */ private boolean stateMatches(EntityState state) { TargetFilters filters = target().getFilters(); From 22203d65462e7a69954897f5ebb43aa45a0851f7 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Fri, 3 Jan 2020 17:04:18 +0200 Subject: [PATCH 03/53] Add usage of `EntityColumn` and `SubscribableField` to `Filters` tool --- .../main/java/io/spine/client/Filters.java | 77 ++++++++++++++++++- .../java/io/spine/client/FiltersTest.java | 21 +++++ 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index 13f4d153e98..0e56c273a76 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -24,11 +24,13 @@ import com.google.protobuf.Any; import com.google.protobuf.Timestamp; import io.spine.annotation.Internal; +import io.spine.base.EntityColumn; import io.spine.base.Field; import io.spine.base.FieldPath; +import io.spine.base.SubscribableField; import io.spine.client.CompositeFilter.CompositeOperator; -import io.spine.core.Version; import io.spine.core.Event; +import io.spine.core.Version; import java.util.Collection; import java.util.function.Predicate; @@ -80,6 +82,19 @@ public final class Filters { private Filters() { } + public static Filter eq(EntityColumn column, Object value) { + checkNotNull(column); + checkNotNull(value); + checkNotNull(value); + return createFilter(column, value, EQUAL); + } + + public static Filter eq(SubscribableField field, Object value) { + checkNotNull(field); + checkNotNull(value); + return createFilter(field, value, EQUAL); + } + /** * Creates new equality {@link Filter}. * @@ -95,6 +110,18 @@ public static Filter eq(String fieldPath, Object value) { return createFilter(fieldPath, value, EQUAL); } + public static Filter gt(EntityColumn column, Object value) { + checkNotNull(column); + checkNotNull(value); + return createFilter(column, value, GREATER_THAN); + } + + public static Filter gt(SubscribableField field, Object value) { + checkNotNull(field); + checkNotNull(value); + return createFilter(field, value, GREATER_THAN); + } + /** * Creates new "greater than" {@link Filter}. * @@ -113,6 +140,18 @@ public static Filter gt(String fieldPath, Object value) { return createFilter(fieldPath, value, GREATER_THAN); } + public static Filter lt(EntityColumn column, Object value) { + checkNotNull(column); + checkNotNull(value); + return createFilter(column, value, LESS_THAN); + } + + public static Filter lt(SubscribableField field, Object value) { + checkNotNull(field); + checkNotNull(value); + return createFilter(field, value, LESS_THAN); + } + /** * Creates new "less than" {@link Filter}. * @@ -131,6 +170,18 @@ public static Filter lt(String fieldPath, Object value) { return createFilter(fieldPath, value, LESS_THAN); } + public static Filter ge(EntityColumn column, Object value) { + checkNotNull(column); + checkNotNull(value); + return createFilter(column, value, GREATER_OR_EQUAL); + } + + public static Filter ge(SubscribableField field, Object value) { + checkNotNull(field); + checkNotNull(value); + return createFilter(field, value, GREATER_OR_EQUAL); + } + /** * Creates new "greater or equal" {@link Filter}. * @@ -149,6 +200,18 @@ public static Filter ge(String fieldPath, Object value) { return createFilter(fieldPath, value, GREATER_OR_EQUAL); } + public static Filter le(EntityColumn column, Object value) { + checkNotNull(column); + checkNotNull(value); + return createFilter(column, value, LESS_OR_EQUAL); + } + + public static Filter le(SubscribableField field, Object value) { + checkNotNull(field); + checkNotNull(value); + return createFilter(field, value, LESS_OR_EQUAL); + } + /** * Creates new "less or equal" {@link Filter}. * @@ -226,8 +289,20 @@ static CompositeFilter all(Collection filters) { return composeFilters(filters, ALL); } + private static Filter createFilter(EntityColumn column, Object value, Operator operator) { + return createFilter(column.value(), value, operator); + } + + private static Filter createFilter(SubscribableField field, Object value, Operator operator) { + return createFilter(field.getFieldPath(), value, operator); + } + private static Filter createFilter(String fieldPath, Object value, Operator operator) { FieldPath path = Field.parse(fieldPath).path(); + return createFilter(path, value, operator); + } + + private static Filter createFilter(FieldPath path, Object value, Operator operator) { Any wrappedValue = toAny(value); Filter filter = Filter .newBuilder() diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index 65883fc8ed3..6eb7691f970 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -25,9 +25,12 @@ import com.google.protobuf.ProtocolStringList; import com.google.protobuf.StringValue; import com.google.protobuf.Timestamp; +import io.spine.base.EntityColumn; +import io.spine.base.SubscribableField; import io.spine.client.Filter.Operator; import io.spine.core.Version; import io.spine.core.Versions; +import io.spine.test.client.TestEntity; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -80,6 +83,8 @@ void passNullToleranceCheck() { new NullPointerTester() .setDefault(Timestamp.class, Timestamp.getDefaultInstance()) .setDefault(Filter.class, Filter.getDefaultInstance()) + .setDefault(EntityColumn.class, TestEntity.Columns.firstField()) + .setDefault(SubscribableField.class, TestEntity.Fields.id()) .testAllPublicStaticMethods(Filters.class); } @@ -137,6 +142,22 @@ private void checkCreatesInstance(Filter filter, Operator operator) { } } + @Test + @DisplayName("create a filter for an entity column") + void createForEntityColumn() { + Filter eq = eq(TestEntity.Columns.firstField(), "some-value"); + System.out.println("Entity column filter"); + System.out.println(eq); + } + + @Test + @DisplayName("create a filter for a subscribable field") + void createForField() { + Filter eq = Filters.eq(TestEntity.Fields.name().value(), "some-name"); + System.out.println("Field filter"); + System.out.println(eq); + } + @Nested @DisplayName("create composite filter of type") class CreateCompositeFilterOfType { From fda46d88527fef21bf4b7a4c2bc2634240b138cb Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Wed, 8 Jan 2020 18:56:11 +0200 Subject: [PATCH 04/53] Introduce stricter typing for `where(...)` Now, using parameterized `EntityColumn` and `SubscribableField` types, the filters passed to `where(...)` will be forced to have the target type matching the filtered object. --- .../io/spine/client/CompositeQueryFilter.java | 46 +++++++++ .../client/CompositeSubscriptionFilter.java | 47 ++++++++++ .../main/java/io/spine/client/Filters.java | 93 ++++++++++++++----- .../java/io/spine/client/QueryFilter.java | 41 ++++++++ .../java/io/spine/client/QueryRequest.java | 19 ++++ .../io/spine/client/SubscribingRequest.java | 19 ++++ .../io/spine/client/SubscriptionFilter.java | 42 +++++++++ 7 files changed, 284 insertions(+), 23 deletions(-) create mode 100644 client/src/main/java/io/spine/client/CompositeQueryFilter.java create mode 100644 client/src/main/java/io/spine/client/CompositeSubscriptionFilter.java create mode 100644 client/src/main/java/io/spine/client/QueryFilter.java create mode 100644 client/src/main/java/io/spine/client/SubscriptionFilter.java diff --git a/client/src/main/java/io/spine/client/CompositeQueryFilter.java b/client/src/main/java/io/spine/client/CompositeQueryFilter.java new file mode 100644 index 00000000000..1937241e04d --- /dev/null +++ b/client/src/main/java/io/spine/client/CompositeQueryFilter.java @@ -0,0 +1,46 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.client; + +import io.spine.base.EntityState; +import io.spine.client.CompositeFilter.CompositeOperator; + +import java.util.Collection; +import java.util.List; + +import static io.spine.client.Filters.composeFilters; +import static java.util.stream.Collectors.toList; + +public final class CompositeQueryFilter { + + private final CompositeFilter filter; + + public CompositeQueryFilter(Collection> filters, CompositeOperator operator) { + List filterList = filters.stream() + .map(QueryFilter::wrappedFilter) + .collect(toList()); + this.filter = composeFilters(filterList, operator); + } + + public CompositeFilter filter() { + return filter; + } +} diff --git a/client/src/main/java/io/spine/client/CompositeSubscriptionFilter.java b/client/src/main/java/io/spine/client/CompositeSubscriptionFilter.java new file mode 100644 index 00000000000..32bd80faeb7 --- /dev/null +++ b/client/src/main/java/io/spine/client/CompositeSubscriptionFilter.java @@ -0,0 +1,47 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.client; + +import com.google.protobuf.Message; +import io.spine.client.CompositeFilter.CompositeOperator; + +import java.util.Collection; +import java.util.List; + +import static io.spine.client.Filters.composeFilters; +import static java.util.stream.Collectors.toList; + +public final class CompositeSubscriptionFilter { + + private final CompositeFilter filter; + + public CompositeSubscriptionFilter(Collection> filters, + CompositeOperator operator) { + List filterList = filters.stream() + .map(SubscriptionFilter::filter) + .collect(toList()); + this.filter = composeFilters(filterList, operator); + } + + public CompositeFilter filter() { + return filter; + } +} diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index 0e56c273a76..9a476a249fe 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -22,9 +22,11 @@ import com.google.common.primitives.Primitives; import com.google.protobuf.Any; +import com.google.protobuf.Message; import com.google.protobuf.Timestamp; import io.spine.annotation.Internal; import io.spine.base.EntityColumn; +import io.spine.base.EntityState; import io.spine.base.Field; import io.spine.base.FieldPath; import io.spine.base.SubscribableField; @@ -82,14 +84,14 @@ public final class Filters { private Filters() { } - public static Filter eq(EntityColumn column, Object value) { + public static QueryFilter eq(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); - checkNotNull(value); return createFilter(column, value, EQUAL); } - public static Filter eq(SubscribableField field, Object value) { + public static SubscriptionFilter + eq(SubscribableField field, Object value) { checkNotNull(field); checkNotNull(value); return createFilter(field, value, EQUAL); @@ -110,15 +112,18 @@ public static Filter eq(String fieldPath, Object value) { return createFilter(fieldPath, value, EQUAL); } - public static Filter gt(EntityColumn column, Object value) { + public static QueryFilter gt(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); return createFilter(column, value, GREATER_THAN); } - public static Filter gt(SubscribableField field, Object value) { + public static SubscriptionFilter + gt(SubscribableField field, Object value) { checkNotNull(field); checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); return createFilter(field, value, GREATER_THAN); } @@ -140,15 +145,18 @@ public static Filter gt(String fieldPath, Object value) { return createFilter(fieldPath, value, GREATER_THAN); } - public static Filter lt(EntityColumn column, Object value) { + public static QueryFilter lt(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); return createFilter(column, value, LESS_THAN); } - public static Filter lt(SubscribableField field, Object value) { + public static SubscriptionFilter + lt(SubscribableField field, Object value) { checkNotNull(field); checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); return createFilter(field, value, LESS_THAN); } @@ -170,15 +178,18 @@ public static Filter lt(String fieldPath, Object value) { return createFilter(fieldPath, value, LESS_THAN); } - public static Filter ge(EntityColumn column, Object value) { + public static QueryFilter ge(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); return createFilter(column, value, GREATER_OR_EQUAL); } - public static Filter ge(SubscribableField field, Object value) { + public static SubscriptionFilter + ge(SubscribableField field, Object value) { checkNotNull(field); checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); return createFilter(field, value, GREATER_OR_EQUAL); } @@ -200,15 +211,18 @@ public static Filter ge(String fieldPath, Object value) { return createFilter(fieldPath, value, GREATER_OR_EQUAL); } - public static Filter le(EntityColumn column, Object value) { + public static QueryFilter le(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); return createFilter(column, value, LESS_OR_EQUAL); } - public static Filter le(SubscribableField field, Object value) { + public static SubscriptionFilter + le(SubscribableField field, Object value) { checkNotNull(field); checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); return createFilter(field, value, LESS_OR_EQUAL); } @@ -230,6 +244,22 @@ public static Filter le(String fieldPath, Object value) { return createFilter(fieldPath, value, LESS_OR_EQUAL); } + @SafeVarargs + public static CompositeQueryFilter + all(QueryFilter first, QueryFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeQueryFilter<>(asList(first, rest), ALL); + } + + @SafeVarargs + public static CompositeSubscriptionFilter + all(SubscriptionFilter first, SubscriptionFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeSubscriptionFilter<>(asList(first, rest), ALL); + } + /** * Creates new conjunction composite filter. * @@ -250,6 +280,22 @@ public static CompositeFilter all(Filter first, Filter... rest) { return composeFilters(asList(first, rest), ALL); } + @SafeVarargs + public static CompositeQueryFilter + either(QueryFilter first, QueryFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeQueryFilter<>(asList(first, rest), EITHER); + } + + @SafeVarargs + public static CompositeSubscriptionFilter + either(SubscriptionFilter first, SubscriptionFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeSubscriptionFilter<>(asList(first, rest), EITHER); + } + /** * Creates new disjunction composite filter. * @@ -289,20 +335,12 @@ static CompositeFilter all(Collection filters) { return composeFilters(filters, ALL); } - private static Filter createFilter(EntityColumn column, Object value, Operator operator) { - return createFilter(column.value(), value, operator); - } - - private static Filter createFilter(SubscribableField field, Object value, Operator operator) { - return createFilter(field.getFieldPath(), value, operator); - } - - private static Filter createFilter(String fieldPath, Object value, Operator operator) { + static Filter createFilter(String fieldPath, Object value, Operator operator) { FieldPath path = Field.parse(fieldPath).path(); return createFilter(path, value, operator); } - private static Filter createFilter(FieldPath path, Object value, Operator operator) { + static Filter createFilter(FieldPath path, Object value, Operator operator) { Any wrappedValue = toAny(value); Filter filter = Filter .newBuilder() @@ -313,8 +351,17 @@ private static Filter createFilter(FieldPath path, Object value, Operator operat return filter; } - private static CompositeFilter composeFilters(Collection filters, - CompositeOperator operator) { + private static QueryFilter + createFilter(EntityColumn column, Object value, Operator operator) { + return new QueryFilter<>(column, value, operator); + } + + private static SubscriptionFilter + createFilter(SubscribableField field, Object value, Operator operator) { + return new SubscriptionFilter<>(field, value, operator); + } + + static CompositeFilter composeFilters(Collection filters, CompositeOperator operator) { CompositeFilter result = CompositeFilter .newBuilder() .addAllFilter(filters) diff --git a/client/src/main/java/io/spine/client/QueryFilter.java b/client/src/main/java/io/spine/client/QueryFilter.java new file mode 100644 index 00000000000..081b5be5cd8 --- /dev/null +++ b/client/src/main/java/io/spine/client/QueryFilter.java @@ -0,0 +1,41 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.client; + +import io.spine.base.EntityColumn; +import io.spine.base.EntityState; +import io.spine.client.Filter.Operator; + +import static io.spine.client.Filters.createFilter; + +public final class QueryFilter { + + private final Filter wrappedFilter; + + public QueryFilter(EntityColumn column, Object expected, Operator operator) { + String fieldPath = column.value(); + this.wrappedFilter = createFilter(fieldPath, expected, operator); + } + + public Filter wrappedFilter() { + return wrappedFilter; + } +} diff --git a/client/src/main/java/io/spine/client/QueryRequest.java b/client/src/main/java/io/spine/client/QueryRequest.java index c30f4291b2e..4ec5b0741d5 100644 --- a/client/src/main/java/io/spine/client/QueryRequest.java +++ b/client/src/main/java/io/spine/client/QueryRequest.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableList; import io.spine.base.EntityState; +import java.util.Arrays; import java.util.function.Function; import static com.google.common.collect.ImmutableList.toImmutableList; @@ -62,6 +63,24 @@ public final class QueryRequest super(parent, type); } + @SafeVarargs + public final QueryRequest where(QueryFilter... filter) { + Filter[] filters = Arrays.stream(filter) + .map(QueryFilter::wrappedFilter) + .toArray(Filter[]::new); + builder().where(filters); + return this; + } + + @SafeVarargs + public final QueryRequest where(CompositeQueryFilter... filter) { + CompositeFilter[] filters = Arrays.stream(filter) + .map(CompositeQueryFilter::filter) + .toArray(CompositeFilter[]::new); + builder().where(filters); + return this; + } + /** * Sets the sorting order by the target column and order direction. * diff --git a/client/src/main/java/io/spine/client/SubscribingRequest.java b/client/src/main/java/io/spine/client/SubscribingRequest.java index bd5039ed478..6c63212a5dc 100644 --- a/client/src/main/java/io/spine/client/SubscribingRequest.java +++ b/client/src/main/java/io/spine/client/SubscribingRequest.java @@ -25,6 +25,7 @@ import io.grpc.stub.StreamObserver; import io.spine.base.MessageContext; +import java.util.Arrays; import java.util.function.Consumer; /** @@ -57,6 +58,24 @@ abstract MessageConsumer toMessageConsumer(Consumer consumer); + @SafeVarargs + public final B where(SubscriptionFilter... filter) { + Filter[] filters = Arrays.stream(filter) + .map(SubscriptionFilter::filter) + .toArray(Filter[]::new); + builder().where(filters); + return self(); + } + + @SafeVarargs + public final B where(CompositeSubscriptionFilter... filter) { + CompositeFilter[] filters = Arrays.stream(filter) + .map(CompositeSubscriptionFilter::filter) + .toArray(CompositeFilter[]::new); + builder().where(filters); + return self(); + } + /** * Subscribes the passed consumer to receive messages of the subscribed type. */ diff --git a/client/src/main/java/io/spine/client/SubscriptionFilter.java b/client/src/main/java/io/spine/client/SubscriptionFilter.java new file mode 100644 index 00000000000..2f91add05cc --- /dev/null +++ b/client/src/main/java/io/spine/client/SubscriptionFilter.java @@ -0,0 +1,42 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.client; + +import com.google.protobuf.Message; +import io.spine.base.FieldPath; +import io.spine.base.SubscribableField; +import io.spine.client.Filter.Operator; + +import static io.spine.client.Filters.createFilter; + +public final class SubscriptionFilter { + + private final Filter filter; + + public SubscriptionFilter(SubscribableField field, Object expected, Operator operator) { + FieldPath fieldPath = field.getFieldPath(); + this.filter = createFilter(fieldPath, expected, operator); + } + + public Filter filter() { + return filter; + } +} From 112ca00af43ca2fd48b64cc1962c722c82fe4557 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Wed, 8 Jan 2020 21:30:53 +0200 Subject: [PATCH 05/53] Fix the `Filters` test --- client/src/test/java/io/spine/client/FiltersTest.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index 6eb7691f970..f51e8dd0182 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -85,6 +85,11 @@ void passNullToleranceCheck() { .setDefault(Filter.class, Filter.getDefaultInstance()) .setDefault(EntityColumn.class, TestEntity.Columns.firstField()) .setDefault(SubscribableField.class, TestEntity.Fields.id()) + .setDefault(QueryFilter.class, + new QueryFilter<>(TestEntity.Columns.firstField(), "some value", EQUAL)) + .setDefault(SubscriptionFilter.class, + new SubscriptionFilter<>(TestEntity.Fields.firstField(), + "some value", EQUAL)) .testAllPublicStaticMethods(Filters.class); } @@ -145,7 +150,7 @@ private void checkCreatesInstance(Filter filter, Operator operator) { @Test @DisplayName("create a filter for an entity column") void createForEntityColumn() { - Filter eq = eq(TestEntity.Columns.firstField(), "some-value"); + QueryFilter eq = eq(TestEntity.Columns.firstField(), "some-value"); System.out.println("Entity column filter"); System.out.println(eq); } @@ -153,7 +158,7 @@ void createForEntityColumn() { @Test @DisplayName("create a filter for a subscribable field") void createForField() { - Filter eq = Filters.eq(TestEntity.Fields.name().value(), "some-name"); + SubscriptionFilter eq = eq(TestEntity.Fields.name().value(), "some-name"); System.out.println("Field filter"); System.out.println(eq); } From e7836e69d7f5457028238478f084d18ac99e38e2 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Mon, 13 Jan 2020 13:09:24 +0200 Subject: [PATCH 06/53] Migrate to new `SubscribableField` It now wraps `Field` value instead of `FieldPath`. --- client/src/main/java/io/spine/client/SubscriptionFilter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/main/java/io/spine/client/SubscriptionFilter.java b/client/src/main/java/io/spine/client/SubscriptionFilter.java index 2f91add05cc..807bb5a0ccb 100644 --- a/client/src/main/java/io/spine/client/SubscriptionFilter.java +++ b/client/src/main/java/io/spine/client/SubscriptionFilter.java @@ -32,7 +32,8 @@ public final class SubscriptionFilter { private final Filter filter; public SubscriptionFilter(SubscribableField field, Object expected, Operator operator) { - FieldPath fieldPath = field.getFieldPath(); + FieldPath fieldPath = field.getField() + .path(); this.filter = createFilter(fieldPath, expected, operator); } From a304380ab502502cdc1acb27d1fc7f675d29e4a0 Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sun, 19 Jan 2020 20:05:18 +0200 Subject: [PATCH 07/53] Migrate to the latest generated fields format from `base` The strict field and column parametrization for now is removed. --- .../io/spine/client/CompositeQueryFilter.java | 5 +- .../client/CompositeSubscriptionFilter.java | 5 +- .../main/java/io/spine/client/Filters.java | 64 ++++++++----------- .../java/io/spine/client/QueryFilter.java | 7 +- .../java/io/spine/client/QueryRequest.java | 6 +- .../io/spine/client/SubscribingRequest.java | 6 +- .../io/spine/client/SubscriptionFilter.java | 5 +- .../java/io/spine/client/FiltersTest.java | 9 ++- 8 files changed, 42 insertions(+), 65 deletions(-) diff --git a/client/src/main/java/io/spine/client/CompositeQueryFilter.java b/client/src/main/java/io/spine/client/CompositeQueryFilter.java index 1937241e04d..8ffd00fabc2 100644 --- a/client/src/main/java/io/spine/client/CompositeQueryFilter.java +++ b/client/src/main/java/io/spine/client/CompositeQueryFilter.java @@ -20,7 +20,6 @@ package io.spine.client; -import io.spine.base.EntityState; import io.spine.client.CompositeFilter.CompositeOperator; import java.util.Collection; @@ -29,11 +28,11 @@ import static io.spine.client.Filters.composeFilters; import static java.util.stream.Collectors.toList; -public final class CompositeQueryFilter { +public final class CompositeQueryFilter { private final CompositeFilter filter; - public CompositeQueryFilter(Collection> filters, CompositeOperator operator) { + public CompositeQueryFilter(Collection filters, CompositeOperator operator) { List filterList = filters.stream() .map(QueryFilter::wrappedFilter) .collect(toList()); diff --git a/client/src/main/java/io/spine/client/CompositeSubscriptionFilter.java b/client/src/main/java/io/spine/client/CompositeSubscriptionFilter.java index 32bd80faeb7..483f85c5092 100644 --- a/client/src/main/java/io/spine/client/CompositeSubscriptionFilter.java +++ b/client/src/main/java/io/spine/client/CompositeSubscriptionFilter.java @@ -20,7 +20,6 @@ package io.spine.client; -import com.google.protobuf.Message; import io.spine.client.CompositeFilter.CompositeOperator; import java.util.Collection; @@ -29,11 +28,11 @@ import static io.spine.client.Filters.composeFilters; import static java.util.stream.Collectors.toList; -public final class CompositeSubscriptionFilter { +public final class CompositeSubscriptionFilter { private final CompositeFilter filter; - public CompositeSubscriptionFilter(Collection> filters, + public CompositeSubscriptionFilter(Collection filters, CompositeOperator operator) { List filterList = filters.stream() .map(SubscriptionFilter::filter) diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index e1a15dc06ba..051803da01e 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -22,11 +22,9 @@ import com.google.common.primitives.Primitives; import com.google.protobuf.Any; -import com.google.protobuf.Message; import com.google.protobuf.Timestamp; import io.spine.annotation.Internal; import io.spine.base.EntityColumn; -import io.spine.base.EntityState; import io.spine.base.Field; import io.spine.base.FieldPath; import io.spine.base.SubscribableField; @@ -84,14 +82,13 @@ public final class Filters { private Filters() { } - public static QueryFilter eq(EntityColumn column, Object value) { + public static QueryFilter eq(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); return createFilter(column, value, EQUAL); } - public static SubscriptionFilter - eq(SubscribableField field, Object value) { + public static SubscriptionFilter eq(SubscribableField field, Object value) { checkNotNull(field); checkNotNull(value); return createFilter(field, value, EQUAL); @@ -112,15 +109,14 @@ public static Filter eq(String fieldPath, Object value) { return createFilter(fieldPath, value, EQUAL); } - public static QueryFilter gt(EntityColumn column, Object value) { + public static QueryFilter gt(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); return createFilter(column, value, GREATER_THAN); } - public static SubscriptionFilter - gt(SubscribableField field, Object value) { + public static SubscriptionFilter gt(SubscribableField field, Object value) { checkNotNull(field); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); @@ -145,15 +141,14 @@ public static Filter gt(String fieldPath, Object value) { return createFilter(fieldPath, value, GREATER_THAN); } - public static QueryFilter lt(EntityColumn column, Object value) { + public static QueryFilter lt(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); return createFilter(column, value, LESS_THAN); } - public static SubscriptionFilter - lt(SubscribableField field, Object value) { + public static SubscriptionFilter lt(SubscribableField field, Object value) { checkNotNull(field); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); @@ -178,15 +173,14 @@ public static Filter lt(String fieldPath, Object value) { return createFilter(fieldPath, value, LESS_THAN); } - public static QueryFilter ge(EntityColumn column, Object value) { + public static QueryFilter ge(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); return createFilter(column, value, GREATER_OR_EQUAL); } - public static SubscriptionFilter - ge(SubscribableField field, Object value) { + public static SubscriptionFilter ge(SubscribableField field, Object value) { checkNotNull(field); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); @@ -211,15 +205,14 @@ public static Filter ge(String fieldPath, Object value) { return createFilter(fieldPath, value, GREATER_OR_EQUAL); } - public static QueryFilter le(EntityColumn column, Object value) { + public static QueryFilter le(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); return createFilter(column, value, LESS_OR_EQUAL); } - public static SubscriptionFilter - le(SubscribableField field, Object value) { + public static SubscriptionFilter le(SubscribableField field, Object value) { checkNotNull(field); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); @@ -244,20 +237,17 @@ public static Filter le(String fieldPath, Object value) { return createFilter(fieldPath, value, LESS_OR_EQUAL); } - @SafeVarargs - public static CompositeQueryFilter - all(QueryFilter first, QueryFilter... rest) { + public static CompositeQueryFilter all(QueryFilter first, QueryFilter... rest) { checkNotNull(first); checkNotNull(rest); - return new CompositeQueryFilter<>(asList(first, rest), ALL); + return new CompositeQueryFilter(asList(first, rest), ALL); } - @SafeVarargs - public static CompositeSubscriptionFilter - all(SubscriptionFilter first, SubscriptionFilter... rest) { + public static CompositeSubscriptionFilter + all(SubscriptionFilter first, SubscriptionFilter... rest) { checkNotNull(first); checkNotNull(rest); - return new CompositeSubscriptionFilter<>(asList(first, rest), ALL); + return new CompositeSubscriptionFilter(asList(first, rest), ALL); } /** @@ -280,20 +270,17 @@ public static CompositeFilter all(Filter first, Filter... rest) { return composeFilters(asList(first, rest), ALL); } - @SafeVarargs - public static CompositeQueryFilter - either(QueryFilter first, QueryFilter... rest) { + public static CompositeQueryFilter either(QueryFilter first, QueryFilter... rest) { checkNotNull(first); checkNotNull(rest); - return new CompositeQueryFilter<>(asList(first, rest), EITHER); + return new CompositeQueryFilter(asList(first, rest), EITHER); } - @SafeVarargs - public static CompositeSubscriptionFilter - either(SubscriptionFilter first, SubscriptionFilter... rest) { + public static CompositeSubscriptionFilter + either(SubscriptionFilter first, SubscriptionFilter... rest) { checkNotNull(first); checkNotNull(rest); - return new CompositeSubscriptionFilter<>(asList(first, rest), EITHER); + return new CompositeSubscriptionFilter(asList(first, rest), EITHER); } /** @@ -351,14 +338,13 @@ static Filter createFilter(FieldPath path, Object value, Operator operator) { return filter; } - private static QueryFilter - createFilter(EntityColumn column, Object value, Operator operator) { - return new QueryFilter<>(column, value, operator); + private static QueryFilter createFilter(EntityColumn column, Object value, Operator operator) { + return new QueryFilter(column, value, operator); } - private static SubscriptionFilter - createFilter(SubscribableField field, Object value, Operator operator) { - return new SubscriptionFilter<>(field, value, operator); + private static SubscriptionFilter + createFilter(SubscribableField field, Object value, Operator operator) { + return new SubscriptionFilter(field, value, operator); } static CompositeFilter composeFilters(Collection filters, CompositeOperator operator) { diff --git a/client/src/main/java/io/spine/client/QueryFilter.java b/client/src/main/java/io/spine/client/QueryFilter.java index 081b5be5cd8..662efbb7c27 100644 --- a/client/src/main/java/io/spine/client/QueryFilter.java +++ b/client/src/main/java/io/spine/client/QueryFilter.java @@ -21,17 +21,16 @@ package io.spine.client; import io.spine.base.EntityColumn; -import io.spine.base.EntityState; import io.spine.client.Filter.Operator; import static io.spine.client.Filters.createFilter; -public final class QueryFilter { +public final class QueryFilter { private final Filter wrappedFilter; - public QueryFilter(EntityColumn column, Object expected, Operator operator) { - String fieldPath = column.value(); + public QueryFilter(EntityColumn column, Object expected, Operator operator) { + String fieldPath = column.name(); this.wrappedFilter = createFilter(fieldPath, expected, operator); } diff --git a/client/src/main/java/io/spine/client/QueryRequest.java b/client/src/main/java/io/spine/client/QueryRequest.java index 0f8efc5ad1f..413a31a9233 100644 --- a/client/src/main/java/io/spine/client/QueryRequest.java +++ b/client/src/main/java/io/spine/client/QueryRequest.java @@ -63,8 +63,7 @@ public final class QueryRequest super(parent, type); } - @SafeVarargs - public final QueryRequest where(QueryFilter... filter) { + public final QueryRequest where(QueryFilter... filter) { Filter[] filters = Arrays.stream(filter) .map(QueryFilter::wrappedFilter) .toArray(Filter[]::new); @@ -72,8 +71,7 @@ public final QueryRequest where(QueryFilter... filter) { return this; } - @SafeVarargs - public final QueryRequest where(CompositeQueryFilter... filter) { + public final QueryRequest where(CompositeQueryFilter... filter) { CompositeFilter[] filters = Arrays.stream(filter) .map(CompositeQueryFilter::filter) .toArray(CompositeFilter[]::new); diff --git a/client/src/main/java/io/spine/client/SubscribingRequest.java b/client/src/main/java/io/spine/client/SubscribingRequest.java index d9c1d52bc0e..088cb07873a 100644 --- a/client/src/main/java/io/spine/client/SubscribingRequest.java +++ b/client/src/main/java/io/spine/client/SubscribingRequest.java @@ -58,8 +58,7 @@ abstract MessageConsumer toMessageConsumer(Consumer consumer); - @SafeVarargs - public final B where(SubscriptionFilter... filter) { + public final B where(SubscriptionFilter... filter) { Filter[] filters = Arrays.stream(filter) .map(SubscriptionFilter::filter) .toArray(Filter[]::new); @@ -67,8 +66,7 @@ public final B where(SubscriptionFilter... filter) { return self(); } - @SafeVarargs - public final B where(CompositeSubscriptionFilter... filter) { + public final B where(CompositeSubscriptionFilter... filter) { CompositeFilter[] filters = Arrays.stream(filter) .map(CompositeSubscriptionFilter::filter) .toArray(CompositeFilter[]::new); diff --git a/client/src/main/java/io/spine/client/SubscriptionFilter.java b/client/src/main/java/io/spine/client/SubscriptionFilter.java index 807bb5a0ccb..0781bce3305 100644 --- a/client/src/main/java/io/spine/client/SubscriptionFilter.java +++ b/client/src/main/java/io/spine/client/SubscriptionFilter.java @@ -20,18 +20,17 @@ package io.spine.client; -import com.google.protobuf.Message; import io.spine.base.FieldPath; import io.spine.base.SubscribableField; import io.spine.client.Filter.Operator; import static io.spine.client.Filters.createFilter; -public final class SubscriptionFilter { +public final class SubscriptionFilter { private final Filter filter; - public SubscriptionFilter(SubscribableField field, Object expected, Operator operator) { + public SubscriptionFilter(SubscribableField field, Object expected, Operator operator) { FieldPath fieldPath = field.getField() .path(); this.filter = createFilter(fieldPath, expected, operator); diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index 0cbbc055d97..9a9eba3db0b 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -86,10 +86,9 @@ void passNullToleranceCheck() { .setDefault(EntityColumn.class, TestEntity.Columns.firstField()) .setDefault(SubscribableField.class, TestEntity.Fields.id()) .setDefault(QueryFilter.class, - new QueryFilter<>(TestEntity.Columns.firstField(), "some value", EQUAL)) + new QueryFilter(TestEntity.Columns.firstField(), "some value", EQUAL)) .setDefault(SubscriptionFilter.class, - new SubscriptionFilter<>(TestEntity.Fields.firstField(), - "some value", EQUAL)) + new SubscriptionFilter(TestEntity.Fields.firstField(), "some value", EQUAL)) .testAllPublicStaticMethods(Filters.class); } @@ -150,7 +149,7 @@ private void checkCreatesInstance(Filter filter, Operator operator) { @Test @DisplayName("create a filter for an entity column") void createForEntityColumn() { - QueryFilter eq = eq(TestEntity.Columns.firstField(), "some-value"); + QueryFilter eq = eq(TestEntity.Columns.firstField(), "some-value"); System.out.println("Entity column filter"); System.out.println(eq); } @@ -158,7 +157,7 @@ void createForEntityColumn() { @Test @DisplayName("create a filter for a subscribable field") void createForField() { - SubscriptionFilter eq = eq(TestEntity.Fields.name().value(), "some-name"); + SubscriptionFilter eq = eq(TestEntity.Fields.name().value(), "some-name"); System.out.println("Field filter"); System.out.println(eq); } From 58d5b71a2b821050e848a02e784b06d55d015cf8 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Wed, 22 Jan 2020 22:06:06 +0200 Subject: [PATCH 08/53] Introduce the typed filter hierarchy to distinguish targeted fields --- ...r.java => CompositeEntityStateFilter.java} | 23 ++- .../io/spine/client/CompositeEventFilter.java | 19 ++- .../io/spine/client/CompositeQueryFilter.java | 22 ++- ...tionFilter.java => EntityStateFilter.java} | 21 +-- .../io/spine/client/EventContextField.java | 80 --------- .../java/io/spine/client/EventFilter.java | 40 ++++- .../client/EventSubscriptionRequest.java | 17 ++ .../io/spine/client/EventsAfterCommand.java | 11 +- .../java/io/spine/client/FilteringField.java | 10 +- .../main/java/io/spine/client/Filters.java | 152 ++++++++++++++---- .../java/io/spine/client/QueryFilter.java | 18 ++- .../java/io/spine/client/QueryRequest.java | 2 +- .../io/spine/client/SubscribingRequest.java | 17 -- .../io/spine/client/SubscriptionRequest.java | 17 ++ .../java/io/spine/client/FiltersTest.java | 25 ++- 15 files changed, 299 insertions(+), 175 deletions(-) rename client/src/main/java/io/spine/client/{CompositeSubscriptionFilter.java => CompositeEntityStateFilter.java} (68%) rename client/src/main/java/io/spine/client/{SubscriptionFilter.java => EntityStateFilter.java} (72%) delete mode 100644 client/src/main/java/io/spine/client/EventContextField.java diff --git a/client/src/main/java/io/spine/client/CompositeSubscriptionFilter.java b/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java similarity index 68% rename from client/src/main/java/io/spine/client/CompositeSubscriptionFilter.java rename to client/src/main/java/io/spine/client/CompositeEntityStateFilter.java index 483f85c5092..8bb1534f5c3 100644 --- a/client/src/main/java/io/spine/client/CompositeSubscriptionFilter.java +++ b/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java @@ -20,6 +20,8 @@ package io.spine.client; +import com.google.common.collect.ImmutableList; +import io.spine.base.EntityState; import io.spine.client.CompositeFilter.CompositeOperator; import java.util.Collection; @@ -28,19 +30,30 @@ import static io.spine.client.Filters.composeFilters; import static java.util.stream.Collectors.toList; -public final class CompositeSubscriptionFilter { +public final class CompositeEntityStateFilter implements CompositeMessageFilter { private final CompositeFilter filter; + private final ImmutableList> filters; - public CompositeSubscriptionFilter(Collection filters, - CompositeOperator operator) { + CompositeEntityStateFilter(Collection filters, CompositeOperator operator) { List filterList = filters.stream() - .map(SubscriptionFilter::filter) + .map(EntityStateFilter::filter) .collect(toList()); this.filter = composeFilters(filterList, operator); + this.filters = ImmutableList.copyOf(filters); } - public CompositeFilter filter() { + CompositeFilter filter() { return filter; } + + @Override + public List> filters() { + return filters; + } + + @Override + public CompositeOperator operator() { + return filter.operator(); + } } diff --git a/client/src/main/java/io/spine/client/CompositeEventFilter.java b/client/src/main/java/io/spine/client/CompositeEventFilter.java index 7bf10ec1aac..fe6cb473975 100644 --- a/client/src/main/java/io/spine/client/CompositeEventFilter.java +++ b/client/src/main/java/io/spine/client/CompositeEventFilter.java @@ -23,15 +23,18 @@ import com.google.common.collect.ImmutableList; import io.spine.core.Event; +import java.util.Collection; import java.util.List; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; +import static io.spine.client.Filters.composeFilters; +import static java.util.stream.Collectors.toList; /** * Filters events by composite criteria which can test both event messages and their contexts. */ -final class CompositeEventFilter implements CompositeMessageFilter { +public final class CompositeEventFilter implements CompositeMessageFilter { /** The filter data as composed when creating a topic. */ private final CompositeFilter filter; @@ -47,6 +50,16 @@ final class CompositeEventFilter implements CompositeMessageFilter { .collect(toImmutableList()); } + CompositeEventFilter(Collection filters, + CompositeFilter.CompositeOperator operator) { + List filterList = checkNotNull(filters) + .stream() + .map(EventFilter::filter) + .collect(toList()); + this.filter = composeFilters(filterList, operator); + this.filters = ImmutableList.copyOf(filters); + } + @Override public List> filters() { return filters; @@ -57,6 +70,10 @@ public CompositeFilter.CompositeOperator operator() { return filter.operator(); } + CompositeFilter filter() { + return filter; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/client/src/main/java/io/spine/client/CompositeQueryFilter.java b/client/src/main/java/io/spine/client/CompositeQueryFilter.java index 8ffd00fabc2..ca28469f337 100644 --- a/client/src/main/java/io/spine/client/CompositeQueryFilter.java +++ b/client/src/main/java/io/spine/client/CompositeQueryFilter.java @@ -20,6 +20,8 @@ package io.spine.client; +import com.google.common.collect.ImmutableList; +import io.spine.base.EntityState; import io.spine.client.CompositeFilter.CompositeOperator; import java.util.Collection; @@ -28,18 +30,30 @@ import static io.spine.client.Filters.composeFilters; import static java.util.stream.Collectors.toList; -public final class CompositeQueryFilter { +public final class CompositeQueryFilter implements CompositeMessageFilter { private final CompositeFilter filter; + private final ImmutableList> filters; - public CompositeQueryFilter(Collection filters, CompositeOperator operator) { + CompositeQueryFilter(Collection filters, CompositeOperator operator) { List filterList = filters.stream() - .map(QueryFilter::wrappedFilter) + .map(QueryFilter::filter) .collect(toList()); this.filter = composeFilters(filterList, operator); + this.filters = ImmutableList.copyOf(filters); } - public CompositeFilter filter() { + CompositeFilter filter() { return filter; } + + @Override + public List> filters() { + return filters; + } + + @Override + public CompositeOperator operator() { + return filter.operator(); + } } diff --git a/client/src/main/java/io/spine/client/SubscriptionFilter.java b/client/src/main/java/io/spine/client/EntityStateFilter.java similarity index 72% rename from client/src/main/java/io/spine/client/SubscriptionFilter.java rename to client/src/main/java/io/spine/client/EntityStateFilter.java index 0781bce3305..bccac9fcc9a 100644 --- a/client/src/main/java/io/spine/client/SubscriptionFilter.java +++ b/client/src/main/java/io/spine/client/EntityStateFilter.java @@ -20,23 +20,24 @@ package io.spine.client; -import io.spine.base.FieldPath; -import io.spine.base.SubscribableField; +import io.spine.base.EntityState; +import io.spine.base.EntityStateField; import io.spine.client.Filter.Operator; -import static io.spine.client.Filters.createFilter; - -public final class SubscriptionFilter { +public final class EntityStateFilter implements MessageFilter { private final Filter filter; - public SubscriptionFilter(SubscribableField field, Object expected, Operator operator) { - FieldPath fieldPath = field.getField() - .path(); - this.filter = createFilter(fieldPath, expected, operator); + EntityStateFilter(EntityStateField field, Object expected, Operator operator) { + this.filter = Filters.createFilter(field.getField(), expected, operator); } - public Filter filter() { + Filter filter() { return filter; } + + @Override + public boolean test(EntityState state) { + return filter.test(state); + } } diff --git a/client/src/main/java/io/spine/client/EventContextField.java b/client/src/main/java/io/spine/client/EventContextField.java deleted file mode 100644 index b1b5d92d047..00000000000 --- a/client/src/main/java/io/spine/client/EventContextField.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2020, TeamDev. All rights reserved. - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package io.spine.client; - -import io.spine.base.Field; -import io.spine.core.Event; -import io.spine.core.EventContext; - -import static java.lang.String.format; - -/** - * Utility class for obtaining the {@code context} field in the {@code Event} proto type. - * - * @implNote This class uses field numbers instead of string constants, which is safer than - * using string constants for referencing proto fields. In the (unlikely) event of renaming - * the referenced fields, this class would still provide correct references to fields and - * their new names. - */ -final class EventContextField { - - /** References the {@code context} field in {@code Event}. */ - private static final Field CONTEXT_FIELD = - Field.withNumberIn(Event.CONTEXT_FIELD_NUMBER, Event.getDescriptor()); - - /** The name of the {@code context} field. */ - private static final String CONTEXT_FIELD_NAME = CONTEXT_FIELD.toString(); - - private static final String PAST_MESSAGE = pastMessageField(); - - /** Prevents instantiation of this utility class. */ - private EventContextField() { - } - - /** Obtains the instance of the {@code context} field. */ - static Field instance() { - return CONTEXT_FIELD; - } - - /** Obtains the name of the {@code context} field. */ - static String name() { - return CONTEXT_FIELD_NAME; - } - - /** - * Obtains the path to the "context.past_message" field of the {@code Event} proto type. - */ - static String pastMessage() { - return PAST_MESSAGE; - } - - /** - * Obtains the path to the "context.past_message" field of {@code Event} proto type. - * - *

This method is safer than using a string constant because it relies on field numbers, - * rather than names (that might be changed). - */ - private static String pastMessageField() { - Field pastMessage = Field.withNumberIn(EventContext.PAST_MESSAGE_FIELD_NUMBER, - EventContext.getDescriptor()); - return format("%s.%s", name(), pastMessage.toString()); - } -} diff --git a/client/src/main/java/io/spine/client/EventFilter.java b/client/src/main/java/io/spine/client/EventFilter.java index 80665bd15ee..561505022b1 100644 --- a/client/src/main/java/io/spine/client/EventFilter.java +++ b/client/src/main/java/io/spine/client/EventFilter.java @@ -20,27 +20,41 @@ package io.spine.client; +import io.spine.base.EventContextField; +import io.spine.base.EventMessageField; import io.spine.core.Event; import static com.google.common.base.Preconditions.checkNotNull; +import static io.spine.client.Filters.createContextFilter; +import static io.spine.client.Filters.createFilter; /** * Filters events by conditions on both message and context. */ -final class EventFilter implements MessageFilter { +public final class EventFilter implements MessageFilter { private final Filter filter; + private final boolean byContext; - EventFilter(Filter filter) { + private EventFilter(Filter filter, boolean byContext) { this.filter = checkNotNull(filter); + this.byContext = byContext; + } + + EventFilter(Filter filter) { + this(filter, isContextFilter(filter)); + } + + EventFilter(EventMessageField field, Object expected, Filter.Operator operator) { + this(createFilter(field.getField(), expected, operator), false); + } + + EventFilter(EventContextField field, Object expected, Filter.Operator operator) { + this(createContextFilter(field.getField(), expected, operator), true); } @Override public boolean test(Event event) { - boolean byContext = - filter.getFieldPath() - .getFieldName(0) - .equals(EventContextField.name()); if (byContext) { // Since we reference the context field with `context` prefix, we need to pass // the whole `Event` instance. @@ -49,6 +63,10 @@ public boolean test(Event event) { return filter.test(event.enclosedMessage()); } + Filter filter() { + return filter; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -65,4 +83,14 @@ public boolean equals(Object o) { public int hashCode() { return filter.hashCode(); } + + private static boolean isContextFilter(Filter filter) { + String contextFieldName = Event.Fields.context() + .getField() + .toString(); + String firstInPath = filter.getFieldPath() + .getFieldName(0); + boolean result = contextFieldName.equals(firstInPath); + return result; + } } diff --git a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java index e86e19049b3..fbcc7a9ad03 100644 --- a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java +++ b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java @@ -25,6 +25,7 @@ import io.spine.core.Event; import io.spine.core.EventContext; +import java.util.Arrays; import java.util.function.Consumer; import java.util.function.Function; @@ -64,6 +65,22 @@ public final class EventSubscriptionRequest this.consumers = EventConsumers.newBuilder(); } + public final EventSubscriptionRequest where(EventFilter... filter) { + Filter[] filters = Arrays.stream(filter) + .map(EventFilter::filter) + .toArray(Filter[]::new); + builder().where(filters); + return self(); + } + + public final EventSubscriptionRequest where(CompositeEventFilter... filter) { + CompositeFilter[] filters = Arrays.stream(filter) + .map(CompositeEventFilter::filter) + .toArray(CompositeFilter[]::new); + builder().where(filters); + return self(); + } + @Override EventConsumers.Builder consumers() { return consumers; diff --git a/client/src/main/java/io/spine/client/EventsAfterCommand.java b/client/src/main/java/io/spine/client/EventsAfterCommand.java index 15dd30d1342..9ae3e25033d 100644 --- a/client/src/main/java/io/spine/client/EventsAfterCommand.java +++ b/client/src/main/java/io/spine/client/EventsAfterCommand.java @@ -23,8 +23,10 @@ import com.google.common.collect.ImmutableSet; import io.grpc.stub.StreamObserver; import io.spine.base.EventMessage; +import io.spine.base.Field; import io.spine.core.Command; import io.spine.core.Event; +import io.spine.core.EventContext; import io.spine.core.UserId; import io.spine.logging.Logging; import org.checkerframework.checker.nullness.qual.Nullable; @@ -75,11 +77,16 @@ private ImmutableSet subscribeWith(@Nullable ErrorHandler errorHan } /** - * Creates subscription topics for the subscribed events which has the passed command + * Creates subscription topics for the subscribed events which have the passed command * as the origin. */ private ImmutableSet eventsOf(Command c) { - String fieldName = EventContextField.pastMessage(); + Field pastMessage = EventContext.Fields.pastMessage() + .getField(); + String fieldName = Event.Fields.context() + .getField() + .nested(pastMessage) + .toString(); ImmutableSet> eventTypes = consumers.eventTypes(); TopicFactory topic = client.requestOf(user) .topic(); diff --git a/client/src/main/java/io/spine/client/FilteringField.java b/client/src/main/java/io/spine/client/FilteringField.java index bd112cd309c..4335ba9894d 100644 --- a/client/src/main/java/io/spine/client/FilteringField.java +++ b/client/src/main/java/io/spine/client/FilteringField.java @@ -27,6 +27,7 @@ import io.spine.base.Field; import io.spine.base.FieldPath; import io.spine.code.proto.FieldDeclaration; +import io.spine.core.Event; import io.spine.core.EventContext; import java.util.Optional; @@ -77,9 +78,12 @@ private void checkFieldOfEvent(Descriptor descriptor) { } private boolean refersToContext() { - String firstInPath = field.path() - .getFieldName(0); - return firstInPath.equals(EventContextField.name()); + String contextFieldName = Event.Fields.context() + .getField() + .toString(); + String firstInPath = field.path().getFieldName(0); + boolean result = contextFieldName.equals(firstInPath); + return result; } private void checkPresentInEventContext() { diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index 051803da01e..13ae0a5dea9 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -25,9 +25,11 @@ import com.google.protobuf.Timestamp; import io.spine.annotation.Internal; import io.spine.base.EntityColumn; +import io.spine.base.EntityStateField; +import io.spine.base.EventContextField; +import io.spine.base.EventMessageField; import io.spine.base.Field; import io.spine.base.FieldPath; -import io.spine.base.SubscribableField; import io.spine.client.CompositeFilter.CompositeOperator; import io.spine.core.Event; import io.spine.core.Version; @@ -85,13 +87,25 @@ private Filters() { public static QueryFilter eq(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); - return createFilter(column, value, EQUAL); + return new QueryFilter(column, value, EQUAL); } - public static SubscriptionFilter eq(SubscribableField field, Object value) { + public static EntityStateFilter eq(EntityStateField field, Object value) { checkNotNull(field); checkNotNull(value); - return createFilter(field, value, EQUAL); + return new EntityStateFilter(field, value, EQUAL); + } + + public static EventFilter eq(EventMessageField field, Object value) { + checkNotNull(field); + checkNotNull(value); + return new EventFilter(field, value, EQUAL); + } + + public static EventFilter eq(EventContextField field, Object value) { + checkNotNull(field); + checkNotNull(value); + return new EventFilter(field, value, EQUAL); } /** @@ -113,14 +127,28 @@ public static QueryFilter gt(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); - return createFilter(column, value, GREATER_THAN); + return new QueryFilter(column, value, GREATER_THAN); + } + + public static EntityStateFilter gt(EntityStateField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EntityStateFilter(field, value, GREATER_THAN); + } + + public static EventFilter gt(EventMessageField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, GREATER_THAN); } - public static SubscriptionFilter gt(SubscribableField field, Object value) { + public static EventFilter gt(EventContextField field, Object value) { checkNotNull(field); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); - return createFilter(field, value, GREATER_THAN); + return new EventFilter(field, value, GREATER_THAN); } /** @@ -145,14 +173,28 @@ public static QueryFilter lt(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); - return createFilter(column, value, LESS_THAN); + return new QueryFilter(column, value, LESS_THAN); + } + + public static EntityStateFilter lt(EntityStateField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EntityStateFilter(field, value, LESS_THAN); + } + + public static EventFilter lt(EventMessageField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, LESS_THAN); } - public static SubscriptionFilter lt(SubscribableField field, Object value) { + public static EventFilter lt(EventContextField field, Object value) { checkNotNull(field); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); - return createFilter(field, value, LESS_THAN); + return new EventFilter(field, value, LESS_THAN); } /** @@ -177,14 +219,28 @@ public static QueryFilter ge(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); - return createFilter(column, value, GREATER_OR_EQUAL); + return new QueryFilter(column, value, GREATER_OR_EQUAL); + } + + public static EntityStateFilter ge(EntityStateField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EntityStateFilter(field, value, GREATER_OR_EQUAL); + } + + public static EventFilter ge(EventMessageField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, GREATER_OR_EQUAL); } - public static SubscriptionFilter ge(SubscribableField field, Object value) { + public static EventFilter ge(EventContextField field, Object value) { checkNotNull(field); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); - return createFilter(field, value, GREATER_OR_EQUAL); + return new EventFilter(field, value, GREATER_OR_EQUAL); } /** @@ -209,14 +265,28 @@ public static QueryFilter le(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); - return createFilter(column, value, LESS_OR_EQUAL); + return new QueryFilter(column, value, LESS_OR_EQUAL); + } + + public static EntityStateFilter le(EntityStateField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EntityStateFilter(field, value, LESS_OR_EQUAL); + } + + public static EventFilter le(EventMessageField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, LESS_OR_EQUAL); } - public static SubscriptionFilter le(SubscribableField field, Object value) { + public static EventFilter le(EventContextField field, Object value) { checkNotNull(field); checkNotNull(value); checkSupportedOrderingComparisonType(value.getClass()); - return createFilter(field, value, LESS_OR_EQUAL); + return new EventFilter(field, value, LESS_OR_EQUAL); } /** @@ -243,11 +313,17 @@ public static CompositeQueryFilter all(QueryFilter first, QueryFilter... rest) { return new CompositeQueryFilter(asList(first, rest), ALL); } - public static CompositeSubscriptionFilter - all(SubscriptionFilter first, SubscriptionFilter... rest) { + public static CompositeEntityStateFilter + all(EntityStateFilter first, EntityStateFilter... rest) { checkNotNull(first); checkNotNull(rest); - return new CompositeSubscriptionFilter(asList(first, rest), ALL); + return new CompositeEntityStateFilter(asList(first, rest), ALL); + } + + public static CompositeEventFilter all(EventFilter first, EventFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeEventFilter(asList(first, rest), ALL); } /** @@ -276,11 +352,17 @@ public static CompositeQueryFilter either(QueryFilter first, QueryFilter... rest return new CompositeQueryFilter(asList(first, rest), EITHER); } - public static CompositeSubscriptionFilter - either(SubscriptionFilter first, SubscriptionFilter... rest) { + public static CompositeEntityStateFilter + either(EntityStateFilter first, EntityStateFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeEntityStateFilter(asList(first, rest), EITHER); + } + + public static CompositeEventFilter either(EventFilter first, EventFilter... rest) { checkNotNull(first); checkNotNull(rest); - return new CompositeSubscriptionFilter(asList(first, rest), EITHER); + return new CompositeEventFilter(asList(first, rest), EITHER); } /** @@ -323,8 +405,21 @@ static CompositeFilter all(Collection filters) { } static Filter createFilter(String fieldPath, Object value, Operator operator) { - FieldPath path = Field.parse(fieldPath).path(); - return createFilter(path, value, operator); + Field field = Field.parse(fieldPath); + return createFilter(field, value, operator); + } + + static Filter createFilter(Field field, Object value, Operator operator) { + FieldPath fieldPath = field.path(); + return createFilter(fieldPath, value, operator); + } + + static Filter createContextFilter(Field field, Object value, Operator operator) { + FieldPath fieldPath = Event.Fields.context() + .getField() + .nested(field) + .path(); + return createFilter(fieldPath, value, operator); } static Filter createFilter(FieldPath path, Object value, Operator operator) { @@ -338,15 +433,6 @@ static Filter createFilter(FieldPath path, Object value, Operator operator) { return filter; } - private static QueryFilter createFilter(EntityColumn column, Object value, Operator operator) { - return new QueryFilter(column, value, operator); - } - - private static SubscriptionFilter - createFilter(SubscribableField field, Object value, Operator operator) { - return new SubscriptionFilter(field, value, operator); - } - static CompositeFilter composeFilters(Collection filters, CompositeOperator operator) { CompositeFilter result = CompositeFilter .newBuilder() diff --git a/client/src/main/java/io/spine/client/QueryFilter.java b/client/src/main/java/io/spine/client/QueryFilter.java index 662efbb7c27..5fba841d280 100644 --- a/client/src/main/java/io/spine/client/QueryFilter.java +++ b/client/src/main/java/io/spine/client/QueryFilter.java @@ -21,20 +21,26 @@ package io.spine.client; import io.spine.base.EntityColumn; +import io.spine.base.EntityState; import io.spine.client.Filter.Operator; import static io.spine.client.Filters.createFilter; -public final class QueryFilter { +public final class QueryFilter implements MessageFilter { - private final Filter wrappedFilter; + private final Filter filter; - public QueryFilter(EntityColumn column, Object expected, Operator operator) { + QueryFilter(EntityColumn column, Object expected, Operator operator) { String fieldPath = column.name(); - this.wrappedFilter = createFilter(fieldPath, expected, operator); + this.filter = createFilter(fieldPath, expected, operator); } - public Filter wrappedFilter() { - return wrappedFilter; + Filter filter() { + return filter; + } + + @Override + public boolean test(EntityState state) { + return filter.test(state); } } diff --git a/client/src/main/java/io/spine/client/QueryRequest.java b/client/src/main/java/io/spine/client/QueryRequest.java index 413a31a9233..46c76d7b096 100644 --- a/client/src/main/java/io/spine/client/QueryRequest.java +++ b/client/src/main/java/io/spine/client/QueryRequest.java @@ -65,7 +65,7 @@ public final class QueryRequest public final QueryRequest where(QueryFilter... filter) { Filter[] filters = Arrays.stream(filter) - .map(QueryFilter::wrappedFilter) + .map(QueryFilter::filter) .toArray(Filter[]::new); builder().where(filters); return this; diff --git a/client/src/main/java/io/spine/client/SubscribingRequest.java b/client/src/main/java/io/spine/client/SubscribingRequest.java index 088cb07873a..88a8e1bff54 100644 --- a/client/src/main/java/io/spine/client/SubscribingRequest.java +++ b/client/src/main/java/io/spine/client/SubscribingRequest.java @@ -25,7 +25,6 @@ import io.grpc.stub.StreamObserver; import io.spine.base.MessageContext; -import java.util.Arrays; import java.util.function.Consumer; /** @@ -58,22 +57,6 @@ abstract MessageConsumer toMessageConsumer(Consumer consumer); - public final B where(SubscriptionFilter... filter) { - Filter[] filters = Arrays.stream(filter) - .map(SubscriptionFilter::filter) - .toArray(Filter[]::new); - builder().where(filters); - return self(); - } - - public final B where(CompositeSubscriptionFilter... filter) { - CompositeFilter[] filters = Arrays.stream(filter) - .map(CompositeSubscriptionFilter::filter) - .toArray(CompositeFilter[]::new); - builder().where(filters); - return self(); - } - /** * Subscribes the passed consumer to receive messages of the subscribed type. */ diff --git a/client/src/main/java/io/spine/client/SubscriptionRequest.java b/client/src/main/java/io/spine/client/SubscriptionRequest.java index 9a3cd0fdae9..299c2d616d9 100644 --- a/client/src/main/java/io/spine/client/SubscriptionRequest.java +++ b/client/src/main/java/io/spine/client/SubscriptionRequest.java @@ -23,6 +23,7 @@ import io.spine.base.EntityState; import io.spine.core.EmptyContext; +import java.util.Arrays; import java.util.function.Consumer; import java.util.function.Function; @@ -42,6 +43,22 @@ public final class SubscriptionRequest this.consumers = StateConsumers.newBuilder(); } + public final SubscriptionRequest where(EntityStateFilter... filter) { + Filter[] filters = Arrays.stream(filter) + .map(EntityStateFilter::filter) + .toArray(Filter[]::new); + builder().where(filters); + return self(); + } + + public final SubscriptionRequest where(CompositeEntityStateFilter... filter) { + CompositeFilter[] filters = Arrays.stream(filter) + .map(CompositeEntityStateFilter::filter) + .toArray(CompositeFilter[]::new); + builder().where(filters); + return self(); + } + @Override StateConsumers.Builder consumers() { return consumers; diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index 9a9eba3db0b..81571c61422 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -26,10 +26,14 @@ import com.google.protobuf.StringValue; import com.google.protobuf.Timestamp; import io.spine.base.EntityColumn; -import io.spine.base.SubscribableField; +import io.spine.base.EntityStateField; +import io.spine.base.EventContextField; +import io.spine.base.EventMessageField; import io.spine.client.Filter.Operator; +import io.spine.core.EventContext; import io.spine.core.Version; import io.spine.core.Versions; +import io.spine.test.client.ClProjectCreated; import io.spine.test.client.TestEntity; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -80,15 +84,22 @@ void haveUtilityConstructor() { @Test @DisplayName(NOT_ACCEPT_NULLS) void passNullToleranceCheck() { + QueryFilter queryFilter = + new QueryFilter(TestEntity.Columns.firstField(), "some value", EQUAL); + EntityStateFilter entityStateFilter = + new EntityStateFilter(TestEntity.Fields.firstField(), "some field value", EQUAL); + EventFilter eventFilter = + new EventFilter(ClProjectCreated.Fields.name().value(), "some project name", EQUAL); new NullPointerTester() .setDefault(Timestamp.class, Timestamp.getDefaultInstance()) .setDefault(Filter.class, Filter.getDefaultInstance()) .setDefault(EntityColumn.class, TestEntity.Columns.firstField()) - .setDefault(SubscribableField.class, TestEntity.Fields.id()) - .setDefault(QueryFilter.class, - new QueryFilter(TestEntity.Columns.firstField(), "some value", EQUAL)) - .setDefault(SubscriptionFilter.class, - new SubscriptionFilter(TestEntity.Fields.firstField(), "some value", EQUAL)) + .setDefault(EntityStateField.class, TestEntity.Fields.id()) + .setDefault(EventMessageField.class, ClProjectCreated.Fields.id()) + .setDefault(EventContextField.class, EventContext.Fields.timestamp()) + .setDefault(QueryFilter.class, queryFilter) + .setDefault(EntityStateFilter.class, entityStateFilter) + .setDefault(EventFilter.class, eventFilter) .testAllPublicStaticMethods(Filters.class); } @@ -157,7 +168,7 @@ void createForEntityColumn() { @Test @DisplayName("create a filter for a subscribable field") void createForField() { - SubscriptionFilter eq = eq(TestEntity.Fields.name().value(), "some-name"); + EntityStateFilter eq = eq(TestEntity.Fields.name().value(), "some-name"); System.out.println("Field filter"); System.out.println(eq); } From b4da05814e24909f006507ebcd15ec187963deb6 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Thu, 23 Jan 2020 13:28:27 +0200 Subject: [PATCH 09/53] Reword doc --- client/src/main/proto/spine/client/filters.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/main/proto/spine/client/filters.proto b/client/src/main/proto/spine/client/filters.proto index 607e9d61e1c..3d23a593347 100644 --- a/client/src/main/proto/spine/client/filters.proto +++ b/client/src/main/proto/spine/client/filters.proto @@ -106,7 +106,7 @@ message Filter { // // If the filter is a query filter, this path should contain only top-level message fields that // are marked with `(column)`. For subscriptions, any field can be specified including nested - // one. + // ones. base.FieldPath field_path = 1 [(required) = true]; // The value to compare upon. From b616685b677d5a26b19ccab2bd39853c9696ea29 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Thu, 23 Jan 2020 13:45:57 +0200 Subject: [PATCH 10/53] Static import a utility method --- .../spine/client/EventSubscriptionRequest.java | 17 ++++++++++------- .../main/java/io/spine/client/QueryRequest.java | 16 +++++++++------- .../io/spine/client/SubscriptionRequest.java | 17 ++++++++++------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java index fbcc7a9ad03..953b6cbe35a 100644 --- a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java +++ b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java @@ -25,10 +25,11 @@ import io.spine.core.Event; import io.spine.core.EventContext; -import java.util.Arrays; import java.util.function.Consumer; import java.util.function.Function; +import static java.util.Arrays.stream; + /** * Allows to subscribe to events using filtering conditions. * @@ -66,17 +67,19 @@ public final class EventSubscriptionRequest } public final EventSubscriptionRequest where(EventFilter... filter) { - Filter[] filters = Arrays.stream(filter) - .map(EventFilter::filter) - .toArray(Filter[]::new); + Filter[] filters = + stream(filter) + .map(EventFilter::filter) + .toArray(Filter[]::new); builder().where(filters); return self(); } public final EventSubscriptionRequest where(CompositeEventFilter... filter) { - CompositeFilter[] filters = Arrays.stream(filter) - .map(CompositeEventFilter::filter) - .toArray(CompositeFilter[]::new); + CompositeFilter[] filters = + stream(filter) + .map(CompositeEventFilter::filter) + .toArray(CompositeFilter[]::new); builder().where(filters); return self(); } diff --git a/client/src/main/java/io/spine/client/QueryRequest.java b/client/src/main/java/io/spine/client/QueryRequest.java index 46c76d7b096..e4323838af1 100644 --- a/client/src/main/java/io/spine/client/QueryRequest.java +++ b/client/src/main/java/io/spine/client/QueryRequest.java @@ -23,10 +23,10 @@ import com.google.common.collect.ImmutableList; import io.spine.base.EntityState; -import java.util.Arrays; import java.util.function.Function; import static com.google.common.collect.ImmutableList.toImmutableList; +import static java.util.Arrays.stream; /** * Allows to create a post a query for messages of the given type. @@ -64,17 +64,19 @@ public final class QueryRequest } public final QueryRequest where(QueryFilter... filter) { - Filter[] filters = Arrays.stream(filter) - .map(QueryFilter::filter) - .toArray(Filter[]::new); + Filter[] filters = + stream(filter) + .map(QueryFilter::filter) + .toArray(Filter[]::new); builder().where(filters); return this; } public final QueryRequest where(CompositeQueryFilter... filter) { - CompositeFilter[] filters = Arrays.stream(filter) - .map(CompositeQueryFilter::filter) - .toArray(CompositeFilter[]::new); + CompositeFilter[] filters = + stream(filter) + .map(CompositeQueryFilter::filter) + .toArray(CompositeFilter[]::new); builder().where(filters); return this; } diff --git a/client/src/main/java/io/spine/client/SubscriptionRequest.java b/client/src/main/java/io/spine/client/SubscriptionRequest.java index 299c2d616d9..2b64301ad48 100644 --- a/client/src/main/java/io/spine/client/SubscriptionRequest.java +++ b/client/src/main/java/io/spine/client/SubscriptionRequest.java @@ -23,10 +23,11 @@ import io.spine.base.EntityState; import io.spine.core.EmptyContext; -import java.util.Arrays; import java.util.function.Consumer; import java.util.function.Function; +import static java.util.Arrays.stream; + /** * Allows to subscribe to updates of entity states using filtering conditions. * @@ -44,17 +45,19 @@ public final class SubscriptionRequest } public final SubscriptionRequest where(EntityStateFilter... filter) { - Filter[] filters = Arrays.stream(filter) - .map(EntityStateFilter::filter) - .toArray(Filter[]::new); + Filter[] filters = + stream(filter) + .map(EntityStateFilter::filter) + .toArray(Filter[]::new); builder().where(filters); return self(); } public final SubscriptionRequest where(CompositeEntityStateFilter... filter) { - CompositeFilter[] filters = Arrays.stream(filter) - .map(CompositeEntityStateFilter::filter) - .toArray(CompositeFilter[]::new); + CompositeFilter[] filters = + stream(filter) + .map(CompositeEntityStateFilter::filter) + .toArray(CompositeFilter[]::new); builder().where(filters); return self(); } From 87b163f5c92ac7b24577835ac86bc773fd5634c3 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Thu, 23 Jan 2020 15:52:18 +0200 Subject: [PATCH 11/53] Improve formatting --- client/src/test/java/io/spine/client/FiltersTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index 81571c61422..977f93ee63f 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -90,6 +90,7 @@ void passNullToleranceCheck() { new EntityStateFilter(TestEntity.Fields.firstField(), "some field value", EQUAL); EventFilter eventFilter = new EventFilter(ClProjectCreated.Fields.name().value(), "some project name", EQUAL); + new NullPointerTester() .setDefault(Timestamp.class, Timestamp.getDefaultInstance()) .setDefault(Filter.class, Filter.getDefaultInstance()) From 783ac4a54e3cf0338df86f591309192ccef38e8f Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Thu, 23 Jan 2020 16:38:03 +0200 Subject: [PATCH 12/53] Static import methods --- .../src/main/java/io/spine/client/EntityStateFilter.java | 4 +++- client/src/main/java/io/spine/client/Filters.java | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/client/src/main/java/io/spine/client/EntityStateFilter.java b/client/src/main/java/io/spine/client/EntityStateFilter.java index bccac9fcc9a..c7bcb2d4238 100644 --- a/client/src/main/java/io/spine/client/EntityStateFilter.java +++ b/client/src/main/java/io/spine/client/EntityStateFilter.java @@ -24,12 +24,14 @@ import io.spine.base.EntityStateField; import io.spine.client.Filter.Operator; +import static io.spine.client.Filters.createFilter; + public final class EntityStateFilter implements MessageFilter { private final Filter filter; EntityStateFilter(EntityStateField field, Object expected, Operator operator) { - this.filter = Filters.createFilter(field.getField(), expected, operator); + this.filter = createFilter(field.getField(), expected, operator); } Filter filter() { diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index 13ae0a5dea9..14627268988 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -49,6 +49,7 @@ import static io.spine.client.Filter.Operator.LESS_OR_EQUAL; import static io.spine.client.Filter.Operator.LESS_THAN; import static io.spine.protobuf.TypeConverter.toAny; +import static java.util.Arrays.stream; /** * A factory of {@link Filter} instances. @@ -442,6 +443,12 @@ static CompositeFilter composeFilters(Collection filters, CompositeOpera return result; } + static Filter[] extractFilters(QueryFilter[] filters) { + return stream(filters) + .map(QueryFilter::filter) + .toArray(Filter[]::new); + } + private static void checkSupportedOrderingComparisonType(Class cls) { Class dataType = Primitives.wrap(cls); boolean supported = isSupportedNumber(dataType) @@ -463,6 +470,7 @@ private static boolean isSupportedNumber(Class wrapperClass) { * Creates a filter of events which can apply conditions from the passed * {@code CompositeFilter} to both event message and its context. * + * // TODO:2019-12-20:dmytro.kuzmin:WIP: Update the doc here and all similar places. *

Please use the {@code "context."} prefix for referencing a field of the event context. */ @Internal From d8c69cc5e8aef594d5d6ae06eb22c0949467c975 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Thu, 23 Jan 2020 16:39:03 +0200 Subject: [PATCH 13/53] Update the format of filtering by context in tests --- .../java/io/spine/client/EventSubscriptionRequestTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java b/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java index b5c80b91fca..8def71e3163 100644 --- a/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java +++ b/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java @@ -101,8 +101,10 @@ void subscribeWithFiltering() { .user(); client().asGuest() .subscribeToEvent(UserLoggedIn.class) - .where(all(eq("user", userId), - eq("context.past_message.actor_context.actor", guestUser))) + .where(all(eq(UserLoggedIn.Fields.user(), userId), + eq(EventContext.Fields.pastMessage() + .actorContext() + .actor(), guestUser))) .observe((e, c) -> { rememberedMessage = e; rememberedContext = c; From 73b320c7bc68949984eb17d5fb9e06b7ff713906 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Thu, 23 Jan 2020 16:39:33 +0200 Subject: [PATCH 14/53] Add todos about updating doc --- .../main/java/io/spine/client/EventSubscriptionRequest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java index 953b6cbe35a..9a25bd75f42 100644 --- a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java +++ b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java @@ -43,11 +43,14 @@ * } * *

In addition to regular filtering conditions, event subscription requests may also reference + * // TODO:2019-12-20:dmytro.kuzmin:WIP: Update the doc here and all similar places. * fields of {@code "spine.core.EventContext"} using {@code "context."} notation. For example, * in order to filter events originate from commands of the given user, please use the following * code: *

{@code
  * clientRequest.subscribeToEvent(MyEventMessage.class)
+ * // TODO:2019-12-20:dmytro.kuzmin:WIP: Update the doc here and all similar places.
+ *
  *              .where(eq("context.past_message.actor_context.actor"), userId)
  *              .observe((event, context) -> {...})
  *              .post();

From 15131c3f8aa4f0b1503cf7f969546ad10297f908 Mon Sep 17 00:00:00 2001
From: dmitrykuzmin 
Date: Thu, 23 Jan 2020 17:44:08 +0200
Subject: [PATCH 15/53] Extract common filter traits to the abstract base
 classes

---
 .../client/CompositeEntityStateFilter.java    | 30 +-------
 .../io/spine/client/CompositeEventFilter.java | 61 ++--------------
 .../spine/client/CompositeFilterHolder.java   | 71 +++++++++++++++++++
 .../io/spine/client/CompositeQueryFilter.java | 30 +-------
 .../io/spine/client/EntityStateFilter.java    | 15 +---
 .../java/io/spine/client/EventFilter.java     | 33 ++-------
 .../client/EventSubscriptionRequest.java      | 14 +---
 .../java/io/spine/client/FilterHolder.java    | 46 ++++++++++++
 .../main/java/io/spine/client/Filters.java    | 20 +++++-
 .../java/io/spine/client/QueryFilter.java     | 16 +----
 .../java/io/spine/client/QueryRequest.java    | 14 +---
 .../io/spine/client/SubscriptionRequest.java  | 14 +---
 12 files changed, 168 insertions(+), 196 deletions(-)
 create mode 100644 client/src/main/java/io/spine/client/CompositeFilterHolder.java
 create mode 100644 client/src/main/java/io/spine/client/FilterHolder.java

diff --git a/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java b/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java
index 8bb1534f5c3..61a40a96726 100644
--- a/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java
+++ b/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java
@@ -20,40 +20,16 @@
 
 package io.spine.client;
 
-import com.google.common.collect.ImmutableList;
 import io.spine.base.EntityState;
 import io.spine.client.CompositeFilter.CompositeOperator;
 
 import java.util.Collection;
-import java.util.List;
 
-import static io.spine.client.Filters.composeFilters;
-import static java.util.stream.Collectors.toList;
+public final class CompositeEntityStateFilter extends CompositeFilterHolder {
 
-public final class CompositeEntityStateFilter implements CompositeMessageFilter {
-
-    private final CompositeFilter filter;
-    private final ImmutableList> filters;
+    private static final long serialVersionUID = 0L;
 
     CompositeEntityStateFilter(Collection filters, CompositeOperator operator) {
-        List filterList = filters.stream()
-                                         .map(EntityStateFilter::filter)
-                                         .collect(toList());
-        this.filter = composeFilters(filterList, operator);
-        this.filters = ImmutableList.copyOf(filters);
-    }
-
-    CompositeFilter filter() {
-        return filter;
-    }
-
-    @Override
-    public List> filters() {
-        return filters;
-    }
-
-    @Override
-    public CompositeOperator operator() {
-        return filter.operator();
+        super(filters, operator);
     }
 }
diff --git a/client/src/main/java/io/spine/client/CompositeEventFilter.java b/client/src/main/java/io/spine/client/CompositeEventFilter.java
index fe6cb473975..b7a39419ae8 100644
--- a/client/src/main/java/io/spine/client/CompositeEventFilter.java
+++ b/client/src/main/java/io/spine/client/CompositeEventFilter.java
@@ -20,74 +20,25 @@
 
 package io.spine.client;
 
-import com.google.common.collect.ImmutableList;
+import io.spine.client.CompositeFilter.CompositeOperator;
 import io.spine.core.Event;
 
 import java.util.Collection;
-import java.util.List;
 
 import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.ImmutableList.toImmutableList;
-import static io.spine.client.Filters.composeFilters;
-import static java.util.stream.Collectors.toList;
 
 /**
  * Filters events by composite criteria which can test both event messages and their contexts.
  */
-public final class CompositeEventFilter implements CompositeMessageFilter {
+public final class CompositeEventFilter extends CompositeFilterHolder {
 
-    /** The filter data as composed when creating a topic. */
-    private final CompositeFilter filter;
-    /** Filters adopted to filter events basing on the passed filter data. */
-    private final ImmutableList> filters;
+    private static final long serialVersionUID = 0L;
 
     CompositeEventFilter(CompositeFilter filter) {
-        this.filter = checkNotNull(filter);
-        this.filters =
-                filter.getFilterList()
-                      .stream()
-                      .map(EventFilter::new)
-                      .collect(toImmutableList());
+        super(checkNotNull(filter), EventFilter::new);
     }
 
-    CompositeEventFilter(Collection filters,
-                         CompositeFilter.CompositeOperator operator) {
-        List filterList = checkNotNull(filters)
-                .stream()
-                .map(EventFilter::filter)
-                .collect(toList());
-        this.filter = composeFilters(filterList, operator);
-        this.filters = ImmutableList.copyOf(filters);
-    }
-
-    @Override
-    public List> filters() {
-        return filters;
-    }
-
-    @Override
-    public CompositeFilter.CompositeOperator operator() {
-        return filter.operator();
-    }
-
-    CompositeFilter filter() {
-        return filter;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        CompositeEventFilter other = (CompositeEventFilter) o;
-        return filter.equals(other.filter);
-    }
-
-    @Override
-    public int hashCode() {
-        return filter.hashCode();
+    CompositeEventFilter(Collection filters, CompositeOperator operator) {
+        super(filters, operator);
     }
 }
diff --git a/client/src/main/java/io/spine/client/CompositeFilterHolder.java b/client/src/main/java/io/spine/client/CompositeFilterHolder.java
new file mode 100644
index 00000000000..41b4efe0c17
--- /dev/null
+++ b/client/src/main/java/io/spine/client/CompositeFilterHolder.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020, TeamDev. All rights reserved.
+ *
+ * Redistribution and use in source and/or binary forms, with or without
+ * modification, must retain the above copyright notice and the following
+ * disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.spine.client;
+
+import com.google.common.collect.ImmutableList;
+import com.google.protobuf.Message;
+import io.spine.client.CompositeFilter.CompositeOperator;
+import io.spine.value.ValueHolder;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static io.spine.client.Filters.composeFilters;
+import static io.spine.client.Filters.extractFilters;
+
+abstract class CompositeFilterHolder
+        extends ValueHolder
+        implements CompositeMessageFilter {
+
+    private static final long serialVersionUID = 0L;
+
+    private final ImmutableList> filters;
+
+    CompositeFilterHolder(CompositeFilter filter, Function> wrapper) {
+        super(filter);
+        this.filters = filter.getFilterList()
+                             .stream()
+                             .map(wrapper)
+                             .collect(toImmutableList());
+    }
+
+    CompositeFilterHolder(Collection> filters,
+                          CompositeOperator operator) {
+        super(composeFilters(extractFilters(filters), operator));
+        this.filters = ImmutableList.copyOf(filters);
+    }
+
+    CompositeFilter filter() {
+        return value();
+    }
+
+    @Override
+    public List> filters() {
+        return filters;
+    }
+
+    @Override
+    public CompositeOperator operator() {
+        return filter().operator();
+    }
+}
diff --git a/client/src/main/java/io/spine/client/CompositeQueryFilter.java b/client/src/main/java/io/spine/client/CompositeQueryFilter.java
index ca28469f337..08cba247bed 100644
--- a/client/src/main/java/io/spine/client/CompositeQueryFilter.java
+++ b/client/src/main/java/io/spine/client/CompositeQueryFilter.java
@@ -20,40 +20,16 @@
 
 package io.spine.client;
 
-import com.google.common.collect.ImmutableList;
 import io.spine.base.EntityState;
 import io.spine.client.CompositeFilter.CompositeOperator;
 
 import java.util.Collection;
-import java.util.List;
 
-import static io.spine.client.Filters.composeFilters;
-import static java.util.stream.Collectors.toList;
+public final class CompositeQueryFilter extends CompositeFilterHolder {
 
-public final class CompositeQueryFilter implements CompositeMessageFilter {
-
-    private final CompositeFilter filter;
-    private final ImmutableList> filters;
+    private static final long serialVersionUID = 0L;
 
     CompositeQueryFilter(Collection filters, CompositeOperator operator) {
-        List filterList = filters.stream()
-                                         .map(QueryFilter::filter)
-                                         .collect(toList());
-        this.filter = composeFilters(filterList, operator);
-        this.filters = ImmutableList.copyOf(filters);
-    }
-
-    CompositeFilter filter() {
-        return filter;
-    }
-
-    @Override
-    public List> filters() {
-        return filters;
-    }
-
-    @Override
-    public CompositeOperator operator() {
-        return filter.operator();
+        super(filters, operator);
     }
 }
diff --git a/client/src/main/java/io/spine/client/EntityStateFilter.java b/client/src/main/java/io/spine/client/EntityStateFilter.java
index c7bcb2d4238..88d5b10c8fe 100644
--- a/client/src/main/java/io/spine/client/EntityStateFilter.java
+++ b/client/src/main/java/io/spine/client/EntityStateFilter.java
@@ -26,20 +26,11 @@
 
 import static io.spine.client.Filters.createFilter;
 
-public final class EntityStateFilter implements MessageFilter {
+public final class EntityStateFilter extends FilterHolder {
 
-    private final Filter filter;
+    private static final long serialVersionUID = 0L;
 
     EntityStateFilter(EntityStateField field, Object expected, Operator operator) {
-        this.filter = createFilter(field.getField(), expected, operator);
-    }
-
-    Filter filter() {
-        return filter;
-    }
-
-    @Override
-    public boolean test(EntityState state) {
-        return filter.test(state);
+        super(createFilter(field.getField(), expected, operator));
     }
 }
diff --git a/client/src/main/java/io/spine/client/EventFilter.java b/client/src/main/java/io/spine/client/EventFilter.java
index 561505022b1..e4537ddfc4a 100644
--- a/client/src/main/java/io/spine/client/EventFilter.java
+++ b/client/src/main/java/io/spine/client/EventFilter.java
@@ -24,20 +24,20 @@
 import io.spine.base.EventMessageField;
 import io.spine.core.Event;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import static io.spine.client.Filters.createContextFilter;
 import static io.spine.client.Filters.createFilter;
 
 /**
  * Filters events by conditions on both message and context.
  */
-public final class EventFilter implements MessageFilter {
+public final class EventFilter extends FilterHolder {
+
+    private static final long serialVersionUID = 0L;
 
-    private final Filter filter;
     private final boolean byContext;
 
     private EventFilter(Filter filter, boolean byContext) {
-        this.filter = checkNotNull(filter);
+        super(filter);
         this.byContext = byContext;
     }
 
@@ -58,30 +58,9 @@ public boolean test(Event event) {
         if (byContext) {
             // Since we reference the context field with `context` prefix, we need to pass
             // the whole `Event` instance.
-            return filter.test(event);
+            return filter().test(event);
         }
-        return filter.test(event.enclosedMessage());
-    }
-
-    Filter filter() {
-        return filter;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        EventFilter other = (EventFilter) o;
-        return filter.equals(other.filter);
-    }
-
-    @Override
-    public int hashCode() {
-        return filter.hashCode();
+        return filter().test(event.enclosedMessage());
     }
 
     private static boolean isContextFilter(Filter filter) {
diff --git a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java
index 9a25bd75f42..9a2c41a0484 100644
--- a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java
+++ b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java
@@ -28,7 +28,7 @@
 import java.util.function.Consumer;
 import java.util.function.Function;
 
-import static java.util.Arrays.stream;
+import static io.spine.client.Filters.extractFilters;
 
 /**
  * Allows to subscribe to events using filtering conditions.
@@ -70,20 +70,12 @@ public final class EventSubscriptionRequest
     }
 
     public final EventSubscriptionRequest where(EventFilter... filter) {
-        Filter[] filters =
-                stream(filter)
-                        .map(EventFilter::filter)
-                        .toArray(Filter[]::new);
-        builder().where(filters);
+        builder().where(extractFilters(filter));
         return self();
     }
 
     public final EventSubscriptionRequest where(CompositeEventFilter... filter) {
-        CompositeFilter[] filters =
-                stream(filter)
-                        .map(CompositeEventFilter::filter)
-                        .toArray(CompositeFilter[]::new);
-        builder().where(filters);
+        builder().where(extractFilters(filter));
         return self();
     }
 
diff --git a/client/src/main/java/io/spine/client/FilterHolder.java b/client/src/main/java/io/spine/client/FilterHolder.java
new file mode 100644
index 00000000000..01cc1290127
--- /dev/null
+++ b/client/src/main/java/io/spine/client/FilterHolder.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2020, TeamDev. All rights reserved.
+ *
+ * Redistribution and use in source and/or binary forms, with or without
+ * modification, must retain the above copyright notice and the following
+ * disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.spine.client;
+
+import com.google.protobuf.Message;
+import io.spine.value.ValueHolder;
+
+@SuppressWarnings("AbstractClassWithoutAbstractMethods")
+// Prevent instantiation of this abstract value holder in favor of concrete descendants.
+abstract class FilterHolder
+        extends ValueHolder
+        implements MessageFilter {
+
+    private static final long serialVersionUID = 0L;
+
+    FilterHolder(Filter value) {
+        super(value);
+    }
+
+    Filter filter() {
+        return value();
+    }
+
+    @Override
+    public boolean test(M m) {
+        return filter().test(m);
+    }
+}
diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java
index 14627268988..bbc7b1a4478 100644
--- a/client/src/main/java/io/spine/client/Filters.java
+++ b/client/src/main/java/io/spine/client/Filters.java
@@ -20,8 +20,10 @@
 
 package io.spine.client;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.primitives.Primitives;
 import com.google.protobuf.Any;
+import com.google.protobuf.Message;
 import com.google.protobuf.Timestamp;
 import io.spine.annotation.Internal;
 import io.spine.base.EntityColumn;
@@ -39,6 +41,7 @@
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.ImmutableList.toImmutableList;
 import static com.google.common.collect.Lists.asList;
 import static io.spine.client.CompositeFilter.CompositeOperator.ALL;
 import static io.spine.client.CompositeFilter.CompositeOperator.EITHER;
@@ -443,12 +446,25 @@ static CompositeFilter composeFilters(Collection filters, CompositeOpera
         return result;
     }
 
-    static Filter[] extractFilters(QueryFilter[] filters) {
+    static Filter[] extractFilters(FilterHolder[] filters) {
         return stream(filters)
-                .map(QueryFilter::filter)
+                .map(FilterHolder::filter)
                 .toArray(Filter[]::new);
     }
 
+    static  ImmutableList
+    extractFilters(Collection> filters) {
+        return filters.stream()
+                      .map(FilterHolder::filter)
+                      .collect(toImmutableList());
+    }
+
+    static CompositeFilter[] extractFilters(CompositeFilterHolder[] filters) {
+        return stream(filters)
+                .map(CompositeFilterHolder::filter)
+                .toArray(CompositeFilter[]::new);
+    }
+
     private static void checkSupportedOrderingComparisonType(Class cls) {
         Class dataType = Primitives.wrap(cls);
         boolean supported = isSupportedNumber(dataType)
diff --git a/client/src/main/java/io/spine/client/QueryFilter.java b/client/src/main/java/io/spine/client/QueryFilter.java
index 5fba841d280..09b0d921a31 100644
--- a/client/src/main/java/io/spine/client/QueryFilter.java
+++ b/client/src/main/java/io/spine/client/QueryFilter.java
@@ -26,21 +26,11 @@
 
 import static io.spine.client.Filters.createFilter;
 
-public final class QueryFilter implements MessageFilter {
+public final class QueryFilter extends FilterHolder {
 
-    private final Filter filter;
+    private static final long serialVersionUID = 0L;
 
     QueryFilter(EntityColumn column, Object expected, Operator operator) {
-        String fieldPath = column.name();
-        this.filter = createFilter(fieldPath, expected, operator);
-    }
-
-    Filter filter() {
-        return filter;
-    }
-
-    @Override
-    public boolean test(EntityState state) {
-        return filter.test(state);
+        super(createFilter(column.name(), expected, operator));
     }
 }
diff --git a/client/src/main/java/io/spine/client/QueryRequest.java b/client/src/main/java/io/spine/client/QueryRequest.java
index e4323838af1..7f4024b3daa 100644
--- a/client/src/main/java/io/spine/client/QueryRequest.java
+++ b/client/src/main/java/io/spine/client/QueryRequest.java
@@ -26,7 +26,7 @@
 import java.util.function.Function;
 
 import static com.google.common.collect.ImmutableList.toImmutableList;
-import static java.util.Arrays.stream;
+import static io.spine.client.Filters.extractFilters;
 
 /**
  * Allows to create a post a query for messages of the given type.
@@ -64,20 +64,12 @@ public final class QueryRequest
     }
 
     public final QueryRequest where(QueryFilter... filter) {
-        Filter[] filters =
-                stream(filter)
-                        .map(QueryFilter::filter)
-                        .toArray(Filter[]::new);
-        builder().where(filters);
+        builder().where(extractFilters(filter));
         return this;
     }
 
     public final QueryRequest where(CompositeQueryFilter... filter) {
-        CompositeFilter[] filters =
-                stream(filter)
-                        .map(CompositeQueryFilter::filter)
-                        .toArray(CompositeFilter[]::new);
-        builder().where(filters);
+        builder().where(extractFilters(filter));
         return this;
     }
 
diff --git a/client/src/main/java/io/spine/client/SubscriptionRequest.java b/client/src/main/java/io/spine/client/SubscriptionRequest.java
index 2b64301ad48..5b09811ec75 100644
--- a/client/src/main/java/io/spine/client/SubscriptionRequest.java
+++ b/client/src/main/java/io/spine/client/SubscriptionRequest.java
@@ -26,7 +26,7 @@
 import java.util.function.Consumer;
 import java.util.function.Function;
 
-import static java.util.Arrays.stream;
+import static io.spine.client.Filters.extractFilters;
 
 /**
  * Allows to subscribe to updates of entity states using filtering conditions.
@@ -45,20 +45,12 @@ public final class SubscriptionRequest
     }
 
     public final SubscriptionRequest where(EntityStateFilter... filter) {
-        Filter[] filters =
-                stream(filter)
-                        .map(EntityStateFilter::filter)
-                        .toArray(Filter[]::new);
-        builder().where(filters);
+        builder().where(extractFilters(filter));
         return self();
     }
 
     public final SubscriptionRequest where(CompositeEntityStateFilter... filter) {
-        CompositeFilter[] filters =
-                stream(filter)
-                        .map(CompositeEntityStateFilter::filter)
-                        .toArray(CompositeFilter[]::new);
-        builder().where(filters);
+        builder().where(extractFilters(filter));
         return self();
     }
 

From 14e6922198ff8cd6410007bae350ef04bf8f9382 Mon Sep 17 00:00:00 2001
From: dmitrykuzmin 
Date: Thu, 23 Jan 2020 19:08:17 +0200
Subject: [PATCH 16/53] Deprecate the old `where` methods and get rid of their
 usages

---
 .../java/io/spine/client/EventSubscriptionRequest.java    | 4 ++--
 .../src/main/java/io/spine/client/FilteringRequest.java   | 2 ++
 client/src/main/java/io/spine/client/QueryRequest.java    | 8 ++++----
 .../main/java/io/spine/client/SubscriptionRequest.java    | 4 ++--
 server/src/test/java/io/spine/client/ClientTest.java      | 7 +++----
 5 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java
index 9a2c41a0484..cc850fad437 100644
--- a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java
+++ b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java
@@ -69,12 +69,12 @@ public final class EventSubscriptionRequest
         this.consumers = EventConsumers.newBuilder();
     }
 
-    public final EventSubscriptionRequest where(EventFilter... filter) {
+    public EventSubscriptionRequest where(EventFilter... filter) {
         builder().where(extractFilters(filter));
         return self();
     }
 
-    public final EventSubscriptionRequest where(CompositeEventFilter... filter) {
+    public EventSubscriptionRequest where(CompositeEventFilter... filter) {
         builder().where(extractFilters(filter));
         return self();
     }
diff --git a/client/src/main/java/io/spine/client/FilteringRequest.java b/client/src/main/java/io/spine/client/FilteringRequest.java
index b4bf4d85d3b..a087b7e2ec6 100644
--- a/client/src/main/java/io/spine/client/FilteringRequest.java
+++ b/client/src/main/java/io/spine/client/FilteringRequest.java
@@ -140,6 +140,7 @@ public B byId(String... ids) {
     /**
      * Configures the request to return results matching all the passed filters.
      */
+    @Deprecated
     public B where(Filter... filter) {
         builder().where(filter);
         return self();
@@ -148,6 +149,7 @@ public B where(Filter... filter) {
     /**
      * Configures the request to return results matching all the passed filters.
      */
+    @Deprecated
     public B where(CompositeFilter... filter) {
         builder().where(filter);
         return self();
diff --git a/client/src/main/java/io/spine/client/QueryRequest.java b/client/src/main/java/io/spine/client/QueryRequest.java
index 7f4024b3daa..b4f1ba957eb 100644
--- a/client/src/main/java/io/spine/client/QueryRequest.java
+++ b/client/src/main/java/io/spine/client/QueryRequest.java
@@ -48,8 +48,8 @@
  *          .run();
  * }
* - *

Filtering by field values (via {@link #where(Filter...)} and - * {@link #where(CompositeFilter...)} methods) can be composed using the {@link Filters} + *

Filtering by field values (via {@link #where(QueryFilter...)} and + * {@link #where(CompositeQueryFilter...)} methods) can be composed using the {@link Filters} * utility class. * * @param @@ -63,12 +63,12 @@ public final class QueryRequest super(parent, type); } - public final QueryRequest where(QueryFilter... filter) { + public QueryRequest where(QueryFilter... filter) { builder().where(extractFilters(filter)); return this; } - public final QueryRequest where(CompositeQueryFilter... filter) { + public QueryRequest where(CompositeQueryFilter... filter) { builder().where(extractFilters(filter)); return this; } diff --git a/client/src/main/java/io/spine/client/SubscriptionRequest.java b/client/src/main/java/io/spine/client/SubscriptionRequest.java index 5b09811ec75..835148f2751 100644 --- a/client/src/main/java/io/spine/client/SubscriptionRequest.java +++ b/client/src/main/java/io/spine/client/SubscriptionRequest.java @@ -44,12 +44,12 @@ public final class SubscriptionRequest this.consumers = StateConsumers.newBuilder(); } - public final SubscriptionRequest where(EntityStateFilter... filter) { + public SubscriptionRequest where(EntityStateFilter... filter) { builder().where(extractFilters(filter)); return self(); } - public final SubscriptionRequest where(CompositeEntityStateFilter... filter) { + public SubscriptionRequest where(CompositeEntityStateFilter... filter) { builder().where(extractFilters(filter)); return self(); } diff --git a/server/src/test/java/io/spine/client/ClientTest.java b/server/src/test/java/io/spine/client/ClientTest.java index e73ce26e249..62c2d203c7f 100644 --- a/server/src/test/java/io/spine/client/ClientTest.java +++ b/server/src/test/java/io/spine/client/ClientTest.java @@ -100,24 +100,23 @@ class Subscriptions { void createSubscriptions() { subscriptions = new ArrayList<>(); UserId currentUser = GivenUserId.generated(); - String userField = "user"; Client client = client(); Subscription userLoggedIn = client.onBehalfOf(currentUser) .subscribeToEvent(UserLoggedIn.class) - .where(eq(userField, currentUser)) + .where(eq(UserLoggedIn.Fields.user(), currentUser)) .observe((e) -> {}) .post(); Subscription userLoggedOut = client.onBehalfOf(currentUser) .subscribeToEvent(UserLoggedOut.class) - .where(eq(userField, currentUser)) + .where(eq(UserLoggedOut.Fields.user(), currentUser)) .observe((e) -> {}) .post(); Subscription loginStatus = client.onBehalfOf(currentUser) .subscribeTo(LoginStatus.class) - .where(eq("user_id", currentUser.getValue())) + .where(eq(LoginStatus.Fields.userId(), currentUser.getValue())) .observe((s) -> {}) .post(); From 79efd55f33eb1aae915f12f250b43c2e6da1b301 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Thu, 23 Jan 2020 20:46:38 +0200 Subject: [PATCH 17/53] Add tests for strongly-typed filter creation --- .../java/io/spine/client/FiltersTest.java | 215 +++++++++++++----- .../spine/test/queries/client_requests.proto | 20 ++ .../java/io/spine/client/package-info.java | 2 +- 3 files changed, 185 insertions(+), 52 deletions(-) diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index 977f93ee63f..634a7bc252c 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -21,20 +21,23 @@ package io.spine.client; import com.google.common.testing.NullPointerTester; +import com.google.common.truth.Correspondence; import com.google.protobuf.DoubleValue; -import com.google.protobuf.ProtocolStringList; +import com.google.protobuf.Message; import com.google.protobuf.StringValue; import com.google.protobuf.Timestamp; import io.spine.base.EntityColumn; import io.spine.base.EntityStateField; import io.spine.base.EventContextField; import io.spine.base.EventMessageField; +import io.spine.base.Field; import io.spine.client.Filter.Operator; import io.spine.core.EventContext; import io.spine.core.Version; import io.spine.core.Versions; import io.spine.test.client.ClProjectCreated; import io.spine.test.client.TestEntity; +import io.spine.test.client.TestEntityOwner; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -52,6 +55,7 @@ import static io.spine.client.Filter.Operator.GREATER_THAN; import static io.spine.client.Filter.Operator.LESS_OR_EQUAL; import static io.spine.client.Filter.Operator.LESS_THAN; +import static io.spine.client.Filters.all; import static io.spine.client.Filters.eq; import static io.spine.client.Filters.ge; import static io.spine.client.Filters.gt; @@ -60,20 +64,22 @@ import static io.spine.protobuf.AnyPacker.pack; import static io.spine.protobuf.AnyPacker.unpack; import static io.spine.protobuf.TypeConverter.toAny; +import static io.spine.test.client.TestEntityOwner.Role.ADMIN; import static io.spine.testing.DisplayNames.HAVE_PARAMETERLESS_CTOR; import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; import static io.spine.testing.Tests.assertHasPrivateParameterlessCtor; -import static java.lang.String.join; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -@DisplayName("Filters utility should") +@DisplayName("`Filters` utility should") class FiltersTest { - private static final String FIELD_PATH = "some.field.path"; + private static final EntityStateField FIELD = TestEntity.Fields.owner() + .whenLastVisited(); private static final Timestamp REQUESTED_VALUE = currentTime(); - private static final String ENUM_FIELD_PATH = "enum.field"; - private static final Operator ENUM_VALUE = EQUAL; + private static final EntityStateField ENUM_FIELD = TestEntity.Fields.owner() + .role(); + private static final TestEntityOwner.Role ENUM_VALUE = ADMIN; @Test @DisplayName(HAVE_PARAMETERLESS_CTOR) @@ -92,7 +98,6 @@ void passNullToleranceCheck() { new EventFilter(ClProjectCreated.Fields.name().value(), "some project name", EQUAL); new NullPointerTester() - .setDefault(Timestamp.class, Timestamp.getDefaultInstance()) .setDefault(Filter.class, Filter.getDefaultInstance()) .setDefault(EntityColumn.class, TestEntity.Columns.firstField()) .setDefault(EntityStateField.class, TestEntity.Fields.id()) @@ -111,67 +116,106 @@ class CreateFilterOfType { @Test @DisplayName("`equals`") void equals() { - checkCreatesInstance(eq(FIELD_PATH, REQUESTED_VALUE), EQUAL); + checkCreatesInstance(eq(FIELD, REQUESTED_VALUE), EQUAL); } @Test @DisplayName("`greater than`") void greaterThan() { - checkCreatesInstance(gt(FIELD_PATH, REQUESTED_VALUE), GREATER_THAN); + checkCreatesInstance(gt(FIELD, REQUESTED_VALUE), GREATER_THAN); } @Test @DisplayName("`greater than or equals`") void greaterOrEqual() { - checkCreatesInstance(ge(FIELD_PATH, REQUESTED_VALUE), GREATER_OR_EQUAL); + checkCreatesInstance(ge(FIELD, REQUESTED_VALUE), GREATER_OR_EQUAL); } @Test @DisplayName("`less than`") void lessThan() { - checkCreatesInstance(lt(FIELD_PATH, REQUESTED_VALUE), LESS_THAN); + checkCreatesInstance(lt(FIELD, REQUESTED_VALUE), LESS_THAN); } @Test @DisplayName("`less than or equals`") void lessOrEqual() { - checkCreatesInstance(le(FIELD_PATH, REQUESTED_VALUE), LESS_OR_EQUAL); + checkCreatesInstance(le(FIELD, REQUESTED_VALUE), LESS_OR_EQUAL); } @Test @DisplayName("`equals` for enumerated types") void equalsForEnum() { - Filter filter = eq(ENUM_FIELD_PATH, ENUM_VALUE); - ProtocolStringList pathElements = filter.getFieldPath() - .getFieldNameList(); - assertEquals(ENUM_FIELD_PATH, join(".", pathElements)); + EntityStateFilter stateFilter = eq(ENUM_FIELD, ENUM_VALUE); + Filter filter = stateFilter.filter(); + + assertEquals(ENUM_FIELD.getField().path(), filter.getFieldPath()); assertEquals(toAny(ENUM_VALUE), filter.getValue()); assertEquals(EQUAL, filter.getOperator()); } - private void checkCreatesInstance(Filter filter, Operator operator) { - ProtocolStringList pathElements = filter.getFieldPath() - .getFieldNameList(); - assertEquals(FIELD_PATH, join(".", pathElements)); + private void checkCreatesInstance(EntityStateFilter stateFilter, Operator operator) { + Filter filter = stateFilter.filter(); + + assertEquals(FIELD.getField().path(), filter.getFieldPath()); assertEquals(pack(REQUESTED_VALUE), filter.getValue()); assertEquals(operator, filter.getOperator()); } } - @Test - @DisplayName("create a filter for an entity column") - void createForEntityColumn() { - QueryFilter eq = eq(TestEntity.Columns.firstField(), "some-value"); - System.out.println("Entity column filter"); - System.out.println(eq); - } + @SuppressWarnings("DuplicateStringLiteralInspection") + // Duplication needed to test the validness of the generated code. + @Nested + @DisplayName("create filter targeting") + class CreateFilterTargeting { - @Test - @DisplayName("create a filter for a subscribable field") - void createForField() { - EntityStateFilter eq = eq(TestEntity.Fields.name().value(), "some-name"); - System.out.println("Field filter"); - System.out.println(eq); + @Test + @DisplayName("an entity column") + void entityColumn() { + EntityColumn column = TestEntity.Columns.firstField(); + checkFieldPath(eq(column, "some string value"), "first_field"); + } + + @Test + @DisplayName("an entity state field") + void entityField() { + EntityStateField field = TestEntity.Fields.name() + .value(); + checkFieldPath(eq(field, "some entity name"), "name.value"); + } + + @Test + @DisplayName("an event message field") + void eventField() { + EventMessageField field = ClProjectCreated.Fields.name() + .value(); + checkFieldPath(eq(field, "some project name"), "name.value"); + } + + @Test + @DisplayName("an event context field") + void eventContextField() { + EventContextField field = EventContext.Fields.pastMessage(); + checkFieldPath(eq(field, "some user ID"), "context.past_message"); + } + + @Test + @DisplayName("a custom field passed via field path") + void customField() { + String fieldPath = "project.when_created"; + Filter filter = eq(fieldPath, currentTime()); + String fieldPathInFilter = Field.withPath(filter.getFieldPath()) + .toString(); + + assertThat(fieldPathInFilter).isEqualTo(fieldPath); + } + + private void checkFieldPath(FilterHolder filterWrapper, String expectedFieldPath) { + Filter filter = filterWrapper.filter(); + String fieldPath = Field.withPath(filter.getFieldPath()) + .toString(); + assertThat(fieldPath).isEqualTo(expectedFieldPath); + } } @Nested @@ -181,9 +225,9 @@ class CreateCompositeFilterOfType { @Test @DisplayName("`all`") void all() { - Filter[] filters = { - le(FIELD_PATH, REQUESTED_VALUE), - ge(FIELD_PATH, REQUESTED_VALUE) + EntityStateFilter[] filters = { + le(FIELD, REQUESTED_VALUE), + ge(FIELD, REQUESTED_VALUE) }; checkCreatesInstance(Filters.all(filters[0], filters[1]), ALL, filters); } @@ -191,18 +235,76 @@ void all() { @Test @DisplayName("`either`") void either() { - Filter[] filters = { - lt(FIELD_PATH, REQUESTED_VALUE), - gt(FIELD_PATH, REQUESTED_VALUE) + EntityStateFilter[] filters = { + lt(FIELD, REQUESTED_VALUE), + gt(FIELD, REQUESTED_VALUE) }; checkCreatesInstance(Filters.either(filters[0], filters[1]), EITHER, filters); } - private void checkCreatesInstance(CompositeFilter filter, + private void checkCreatesInstance(CompositeEntityStateFilter filter, CompositeOperator operator, - Filter[] groupedFilters) { - assertEquals(operator, filter.getOperator()); - assertThat(filter.getFilterList()).containsAtLeastElementsIn(groupedFilters); + EntityStateFilter[] groupedFilters) { + CompositeFilter compositeFilter = filter.filter(); + + assertEquals(operator, compositeFilter.getOperator()); + assertThat(compositeFilter.getFilterList()) + .comparingElementsUsing(filterHolderCorrespondence()) + .containsExactlyElementsIn(groupedFilters); + } + } + + @Nested + @DisplayName("create composite filter targeting") + class CreateCompositeFilterTargeting { + + @Test + @DisplayName("entity columns") + void entityColumns() { + QueryFilter[] filters = { + le(TestEntity.Columns.firstField(), "a string value"), + ge(TestEntity.Columns.thirdField(), 42) + }; + checkCreatesInstance(all(filters[0], filters[1]), filters); + } + + @Test + @DisplayName("entity state fields") + void entityFields() { + EntityStateFilter[] filters = { + le(TestEntity.Fields.name().value(), "an entity name"), + ge(TestEntity.Fields.thirdField(), 42) + }; + checkCreatesInstance(all(filters[0], filters[1]), filters); + } + + @Test + @DisplayName("event message and event context fields") + void eventMessageAndContextFields() { + EventFilter[] filters = { + le(ClProjectCreated.Fields.name().value(), "a project name"), + eq(EventContext.Fields.external(), true) + }; + checkCreatesInstance(all(filters[0], filters[1]), filters); + } + + @Test + @DisplayName("custom fields specified through field paths") + void customFields() { + Filter[] filters = { + le("first_custom_field", "a string value"), + ge("second_custom_field", 154) + }; + CompositeFilter compositeFilter = all(filters[0], filters[1]); + assertThat(compositeFilter.getFilterList()).containsExactlyElementsIn(filters); + } + + private void checkCreatesInstance(CompositeFilterHolder filter, + FilterHolder[] groupedFilters) { + CompositeFilter compositeFilter = filter.filter(); + assertThat(compositeFilter.getFilterList()) + .comparingElementsUsing(filterHolderCorrespondence()) + .containsExactlyElementsIn(groupedFilters); } } @@ -214,8 +316,8 @@ class CreateOrderingFilter { @DisplayName("for numbers") void forNumbers() { double number = 3.14; - Filter filter = le("double_field", number); - assertThat(filter).isNotNull(); + QueryFilter queryFilter = le(TestEntity.Columns.thirdField(), number); + Filter filter = queryFilter.filter(); assertThat(filter.getOperator()).isEqualTo(LESS_OR_EQUAL); DoubleValue value = unpack(filter.getValue(), DoubleValue.class); @@ -226,8 +328,8 @@ void forNumbers() { @DisplayName("for strings") void forStrings() { String theString = "abc"; - Filter filter = gt("string_field", theString); - assertThat(filter).isNotNull(); + QueryFilter queryFilter = gt(TestEntity.Columns.firstField(), theString); + Filter filter = queryFilter.filter(); assertThat(filter.getOperator()).isEqualTo(GREATER_THAN); StringValue value = unpack(filter.getValue(), StringValue.class); @@ -238,8 +340,10 @@ void forStrings() { @DisplayName("for timestamps") void forTimestamps() { Timestamp timestamp = currentTime(); - Filter filter = gt("timestamp_field", timestamp); - assertThat(filter).isNotNull(); + EntityStateFilter stateFilter = + gt(TestEntity.Fields.owner().whenLastVisited(), timestamp); + Filter filter = stateFilter.filter(); + assertThat(filter.getOperator()).isEqualTo(GREATER_THAN); Timestamp value = unpack(filter.getValue(), Timestamp.class); assertThat(value).isEqualTo(timestamp); @@ -249,7 +353,8 @@ void forTimestamps() { @DisplayName("for versions") void forVersions() { Version version = Versions.zero(); - Filter filter = ge("version_field", version); + Filter filter = ge("some_version_field", version); + assertThat(filter).isNotNull(); assertThat(filter.getOperator()).isEqualTo(GREATER_OR_EQUAL); Version value = unpack(filter.getValue(), Version.class); @@ -265,7 +370,7 @@ class FailToCreateOrderingFilter { @DisplayName("for enumerated types") void forEnums() { assertThrows(IllegalArgumentException.class, - () -> ge(ENUM_FIELD_PATH, ENUM_VALUE)); + () -> ge(ENUM_FIELD, ENUM_VALUE)); } @Test @@ -282,4 +387,12 @@ void forUnsupportedTypes() { assertThrows(IllegalArgumentException.class, () -> le("invalidField", value)); } } + + private static Correspondence> filterHolderCorrespondence() { + return Correspondence.from(FiltersTest::isFilterEqual, "is wrapped by"); + } + + private static boolean isFilterEqual(Filter filter, FilterHolder wrapper) { + return filter.equals(wrapper.filter()); + } } diff --git a/client/src/test/proto/spine/test/queries/client_requests.proto b/client/src/test/proto/spine/test/queries/client_requests.proto index be3e989226b..0e2a81f29d5 100644 --- a/client/src/test/proto/spine/test/queries/client_requests.proto +++ b/client/src/test/proto/spine/test/queries/client_requests.proto @@ -28,6 +28,9 @@ option java_package="io.spine.test.client"; option java_multiple_files = true; option java_outer_classname = "ClientRequestsProto"; +import "google/protobuf/timestamp.proto"; +import "spine/core/user_id.proto"; + // Sample objects for testing Queries and Topics. // Simple ID for tests. @@ -51,6 +54,8 @@ message TestEntity { int32 third_field = 4 [(column) = true]; TestEntityName name = 5; + + TestEntityOwner owner = 6; } // A simple value holder. @@ -62,3 +67,18 @@ message TestEntityName { string value = 1 [(column) = true]; } + +message TestEntityOwner { + + spine.core.UserId id = 1; + + google.protobuf.Timestamp when_last_visited = 2; + + Role role = 3; + + enum Role { + UNDEFINED = 0; + ADMIN = 1; + USER = 2; + } +} diff --git a/server/src/test/java/io/spine/client/package-info.java b/server/src/test/java/io/spine/client/package-info.java index b21253408af..f82f611bb32 100644 --- a/server/src/test/java/io/spine/client/package-info.java +++ b/server/src/test/java/io/spine/client/package-info.java @@ -19,7 +19,7 @@ */ /** - * This package contains of high-level {@link io.spine.client.Client} API. For the tests of + * This package contains tests of high-level {@link io.spine.client.Client} API. For the tests of * low-level client API based on {@link io.spine.client.ActorRequestFactory} please see the same * package in the {@link ":client"} module. * From f9a96460aabb19f4cbbd4152af1922c32ca9135c Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Fri, 24 Jan 2020 17:23:11 +0200 Subject: [PATCH 18/53] Rename `FilterHolder` -> `TypedFilter` Also fetched the latest repackaging-related changes from `base`. --- .../spine/client/CompositeFilterHolder.java | 2 +- .../io/spine/client/EntityStateFilter.java | 4 ++-- .../java/io/spine/client/EventFilter.java | 6 +++--- .../main/java/io/spine/client/Filters.java | 17 ++++++++-------- .../java/io/spine/client/QueryFilter.java | 4 ++-- .../{FilterHolder.java => TypedFilter.java} | 6 +++--- .../java/io/spine/client/FiltersTest.java | 20 +++++++++---------- 7 files changed, 30 insertions(+), 29 deletions(-) rename client/src/main/java/io/spine/client/{FilterHolder.java => TypedFilter.java} (89%) diff --git a/client/src/main/java/io/spine/client/CompositeFilterHolder.java b/client/src/main/java/io/spine/client/CompositeFilterHolder.java index 41b4efe0c17..3aab7798cec 100644 --- a/client/src/main/java/io/spine/client/CompositeFilterHolder.java +++ b/client/src/main/java/io/spine/client/CompositeFilterHolder.java @@ -49,7 +49,7 @@ abstract class CompositeFilterHolder .collect(toImmutableList()); } - CompositeFilterHolder(Collection> filters, + CompositeFilterHolder(Collection> filters, CompositeOperator operator) { super(composeFilters(extractFilters(filters), operator)); this.filters = ImmutableList.copyOf(filters); diff --git a/client/src/main/java/io/spine/client/EntityStateFilter.java b/client/src/main/java/io/spine/client/EntityStateFilter.java index 88d5b10c8fe..4b59ba5634f 100644 --- a/client/src/main/java/io/spine/client/EntityStateFilter.java +++ b/client/src/main/java/io/spine/client/EntityStateFilter.java @@ -21,12 +21,12 @@ package io.spine.client; import io.spine.base.EntityState; -import io.spine.base.EntityStateField; import io.spine.client.Filter.Operator; +import io.spine.gen.EntityStateField; import static io.spine.client.Filters.createFilter; -public final class EntityStateFilter extends FilterHolder { +public final class EntityStateFilter extends TypedFilter { private static final long serialVersionUID = 0L; diff --git a/client/src/main/java/io/spine/client/EventFilter.java b/client/src/main/java/io/spine/client/EventFilter.java index e4537ddfc4a..307faeab90a 100644 --- a/client/src/main/java/io/spine/client/EventFilter.java +++ b/client/src/main/java/io/spine/client/EventFilter.java @@ -20,9 +20,9 @@ package io.spine.client; -import io.spine.base.EventContextField; -import io.spine.base.EventMessageField; import io.spine.core.Event; +import io.spine.gen.EventContextField; +import io.spine.gen.EventMessageField; import static io.spine.client.Filters.createContextFilter; import static io.spine.client.Filters.createFilter; @@ -30,7 +30,7 @@ /** * Filters events by conditions on both message and context. */ -public final class EventFilter extends FilterHolder { +public final class EventFilter extends TypedFilter { private static final long serialVersionUID = 0L; diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index bbc7b1a4478..4aa8964d4d8 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -26,15 +26,15 @@ import com.google.protobuf.Message; import com.google.protobuf.Timestamp; import io.spine.annotation.Internal; -import io.spine.base.EntityColumn; -import io.spine.base.EntityStateField; -import io.spine.base.EventContextField; -import io.spine.base.EventMessageField; import io.spine.base.Field; import io.spine.base.FieldPath; import io.spine.client.CompositeFilter.CompositeOperator; import io.spine.core.Event; import io.spine.core.Version; +import io.spine.gen.EntityColumn; +import io.spine.gen.EntityStateField; +import io.spine.gen.EventContextField; +import io.spine.gen.EventMessageField; import java.util.Collection; import java.util.function.Predicate; @@ -82,6 +82,7 @@ * * @see QueryBuilder for the application */ +@SuppressWarnings("ClassWithTooManyMethods") // Unifies a lot of methods for typed filter creation. public final class Filters { /** Prevents this utility class instantiation. */ @@ -446,16 +447,16 @@ static CompositeFilter composeFilters(Collection filters, CompositeOpera return result; } - static Filter[] extractFilters(FilterHolder[] filters) { + static Filter[] extractFilters(TypedFilter[] filters) { return stream(filters) - .map(FilterHolder::filter) + .map(TypedFilter::filter) .toArray(Filter[]::new); } static ImmutableList - extractFilters(Collection> filters) { + extractFilters(Collection> filters) { return filters.stream() - .map(FilterHolder::filter) + .map(TypedFilter::filter) .collect(toImmutableList()); } diff --git a/client/src/main/java/io/spine/client/QueryFilter.java b/client/src/main/java/io/spine/client/QueryFilter.java index 09b0d921a31..d75715e588b 100644 --- a/client/src/main/java/io/spine/client/QueryFilter.java +++ b/client/src/main/java/io/spine/client/QueryFilter.java @@ -20,13 +20,13 @@ package io.spine.client; -import io.spine.base.EntityColumn; import io.spine.base.EntityState; import io.spine.client.Filter.Operator; +import io.spine.gen.EntityColumn; import static io.spine.client.Filters.createFilter; -public final class QueryFilter extends FilterHolder { +public final class QueryFilter extends TypedFilter { private static final long serialVersionUID = 0L; diff --git a/client/src/main/java/io/spine/client/FilterHolder.java b/client/src/main/java/io/spine/client/TypedFilter.java similarity index 89% rename from client/src/main/java/io/spine/client/FilterHolder.java rename to client/src/main/java/io/spine/client/TypedFilter.java index 01cc1290127..ee3bbd1ba63 100644 --- a/client/src/main/java/io/spine/client/FilterHolder.java +++ b/client/src/main/java/io/spine/client/TypedFilter.java @@ -24,14 +24,14 @@ import io.spine.value.ValueHolder; @SuppressWarnings("AbstractClassWithoutAbstractMethods") -// Prevent instantiation of this abstract value holder in favor of concrete descendants. -abstract class FilterHolder +// Prevent instantiation of this abstract filter in favor of concrete descendants. +abstract class TypedFilter extends ValueHolder implements MessageFilter { private static final long serialVersionUID = 0L; - FilterHolder(Filter value) { + TypedFilter(Filter value) { super(value); } diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index 634a7bc252c..1af9aa10440 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -26,15 +26,15 @@ import com.google.protobuf.Message; import com.google.protobuf.StringValue; import com.google.protobuf.Timestamp; -import io.spine.base.EntityColumn; -import io.spine.base.EntityStateField; -import io.spine.base.EventContextField; -import io.spine.base.EventMessageField; import io.spine.base.Field; import io.spine.client.Filter.Operator; import io.spine.core.EventContext; import io.spine.core.Version; import io.spine.core.Versions; +import io.spine.gen.EntityColumn; +import io.spine.gen.EntityStateField; +import io.spine.gen.EventContextField; +import io.spine.gen.EventMessageField; import io.spine.test.client.ClProjectCreated; import io.spine.test.client.TestEntity; import io.spine.test.client.TestEntityOwner; @@ -210,7 +210,7 @@ void customField() { assertThat(fieldPathInFilter).isEqualTo(fieldPath); } - private void checkFieldPath(FilterHolder filterWrapper, String expectedFieldPath) { + private void checkFieldPath(TypedFilter filterWrapper, String expectedFieldPath) { Filter filter = filterWrapper.filter(); String fieldPath = Field.withPath(filter.getFieldPath()) .toString(); @@ -249,7 +249,7 @@ private void checkCreatesInstance(CompositeEntityStateFilter filter, assertEquals(operator, compositeFilter.getOperator()); assertThat(compositeFilter.getFilterList()) - .comparingElementsUsing(filterHolderCorrespondence()) + .comparingElementsUsing(typedFilterCorrespondence()) .containsExactlyElementsIn(groupedFilters); } } @@ -300,10 +300,10 @@ void customFields() { } private void checkCreatesInstance(CompositeFilterHolder filter, - FilterHolder[] groupedFilters) { + TypedFilter[] groupedFilters) { CompositeFilter compositeFilter = filter.filter(); assertThat(compositeFilter.getFilterList()) - .comparingElementsUsing(filterHolderCorrespondence()) + .comparingElementsUsing(typedFilterCorrespondence()) .containsExactlyElementsIn(groupedFilters); } } @@ -388,11 +388,11 @@ void forUnsupportedTypes() { } } - private static Correspondence> filterHolderCorrespondence() { + private static Correspondence> typedFilterCorrespondence() { return Correspondence.from(FiltersTest::isFilterEqual, "is wrapped by"); } - private static boolean isFilterEqual(Filter filter, FilterHolder wrapper) { + private static boolean isFilterEqual(Filter filter, TypedFilter wrapper) { return filter.equals(wrapper.filter()); } } From 6f44181991df67d547bb3b84ea2c921f8888726e Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Fri, 24 Jan 2020 22:40:15 +0200 Subject: [PATCH 19/53] Add a missing filter creation method --- client/src/main/java/io/spine/client/Filters.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index 4aa8964d4d8..0af11f50311 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -29,6 +29,7 @@ import io.spine.base.Field; import io.spine.base.FieldPath; import io.spine.client.CompositeFilter.CompositeOperator; +import io.spine.code.proto.FieldName; import io.spine.core.Event; import io.spine.core.Version; import io.spine.gen.EntityColumn; @@ -414,6 +415,11 @@ static Filter createFilter(String fieldPath, Object value, Operator operator) { return createFilter(field, value, operator); } + static Filter createFilter(FieldName fieldName, Object value, Operator operator) { + FieldPath fieldPath = fieldName.asPath(); + return createFilter(fieldPath, value, operator); + } + static Filter createFilter(Field field, Object value, Operator operator) { FieldPath fieldPath = field.path(); return createFilter(fieldPath, value, operator); From 5fac0e7843de8e6a2e187c50142b990543b8ebdd Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 17:30:18 +0200 Subject: [PATCH 20/53] Migrate to the latest packaging changes from `base` --- .../src/main/java/io/spine/client/EntityStateFilter.java | 2 +- client/src/main/java/io/spine/client/EventFilter.java | 4 ++-- client/src/main/java/io/spine/client/Filters.java | 8 ++++---- client/src/main/java/io/spine/client/QueryFilter.java | 2 +- client/src/test/java/io/spine/client/FiltersTest.java | 8 ++++---- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/client/src/main/java/io/spine/client/EntityStateFilter.java b/client/src/main/java/io/spine/client/EntityStateFilter.java index 4b59ba5634f..8b842c67d58 100644 --- a/client/src/main/java/io/spine/client/EntityStateFilter.java +++ b/client/src/main/java/io/spine/client/EntityStateFilter.java @@ -21,8 +21,8 @@ package io.spine.client; import io.spine.base.EntityState; +import io.spine.base.EntityStateField; import io.spine.client.Filter.Operator; -import io.spine.gen.EntityStateField; import static io.spine.client.Filters.createFilter; diff --git a/client/src/main/java/io/spine/client/EventFilter.java b/client/src/main/java/io/spine/client/EventFilter.java index 307faeab90a..04e8940d594 100644 --- a/client/src/main/java/io/spine/client/EventFilter.java +++ b/client/src/main/java/io/spine/client/EventFilter.java @@ -20,9 +20,9 @@ package io.spine.client; +import io.spine.base.EventContextField; +import io.spine.base.EventMessageField; import io.spine.core.Event; -import io.spine.gen.EventContextField; -import io.spine.gen.EventMessageField; import static io.spine.client.Filters.createContextFilter; import static io.spine.client.Filters.createFilter; diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index 0af11f50311..e9dfce69f7a 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -26,16 +26,16 @@ import com.google.protobuf.Message; import com.google.protobuf.Timestamp; import io.spine.annotation.Internal; +import io.spine.base.EntityColumn; +import io.spine.base.EntityStateField; +import io.spine.base.EventContextField; +import io.spine.base.EventMessageField; import io.spine.base.Field; import io.spine.base.FieldPath; import io.spine.client.CompositeFilter.CompositeOperator; import io.spine.code.proto.FieldName; import io.spine.core.Event; import io.spine.core.Version; -import io.spine.gen.EntityColumn; -import io.spine.gen.EntityStateField; -import io.spine.gen.EventContextField; -import io.spine.gen.EventMessageField; import java.util.Collection; import java.util.function.Predicate; diff --git a/client/src/main/java/io/spine/client/QueryFilter.java b/client/src/main/java/io/spine/client/QueryFilter.java index d75715e588b..a2e8477540c 100644 --- a/client/src/main/java/io/spine/client/QueryFilter.java +++ b/client/src/main/java/io/spine/client/QueryFilter.java @@ -20,9 +20,9 @@ package io.spine.client; +import io.spine.base.EntityColumn; import io.spine.base.EntityState; import io.spine.client.Filter.Operator; -import io.spine.gen.EntityColumn; import static io.spine.client.Filters.createFilter; diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index 1af9aa10440..c79fe7f2faa 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -26,15 +26,15 @@ import com.google.protobuf.Message; import com.google.protobuf.StringValue; import com.google.protobuf.Timestamp; +import io.spine.base.EntityColumn; +import io.spine.base.EntityStateField; +import io.spine.base.EventContextField; +import io.spine.base.EventMessageField; import io.spine.base.Field; import io.spine.client.Filter.Operator; import io.spine.core.EventContext; import io.spine.core.Version; import io.spine.core.Versions; -import io.spine.gen.EntityColumn; -import io.spine.gen.EntityStateField; -import io.spine.gen.EventContextField; -import io.spine.gen.EventMessageField; import io.spine.test.client.ClProjectCreated; import io.spine.test.client.TestEntity; import io.spine.test.client.TestEntityOwner; From d4998d9de352bc2a91375a84aac82c3f65392346 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 18:50:13 +0200 Subject: [PATCH 21/53] Fix method ordering Also reworded the warning suppression. --- .../main/java/io/spine/client/Filters.java | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index e9dfce69f7a..f88cda21cf5 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -83,7 +83,8 @@ * * @see QueryBuilder for the application */ -@SuppressWarnings("ClassWithTooManyMethods") // Unifies a lot of methods for typed filter creation. +@SuppressWarnings("ClassWithTooManyMethods") +// Unifies a lot of methods for convenient filter creation. public final class Filters { /** Prevents this utility class instantiation. */ @@ -352,6 +353,27 @@ public static CompositeFilter all(Filter first, Filter... rest) { return composeFilters(asList(first, rest), ALL); } + /** + * Creates new conjunction composite filter. + * + *

A record is considered matching this filter if and only if it matches all of + * the aggregated filters. + * + *

This method is used to create the default {@code ALL} filter if the user chooses to pass + * instances of {@link Filter} directly to the {@link QueryBuilder}. + * + * @param filters + * the aggregated filters + * @return new instance of {@link CompositeFilter} + * @see #all(Filter, Filter...) for the public API equivalent + */ + static CompositeFilter all(Collection filters) { + checkNotNull(filters); + checkArgument(!filters.isEmpty(), + "Composite filter must contain at least one simple filter in it."); + return composeFilters(filters, ALL); + } + public static CompositeQueryFilter either(QueryFilter first, QueryFilter... rest) { checkNotNull(first); checkNotNull(rest); @@ -389,27 +411,6 @@ public static CompositeFilter either(Filter first, Filter... rest) { return composeFilters(asList(first, rest), EITHER); } - /** - * Creates new conjunction composite filter. - * - *

A record is considered matching this filter if and only if it matches all of - * the aggregated filters. - * - *

This method is used to create the default {@code ALL} filter if the user chooses to pass - * instances of {@link Filter} directly to the {@link QueryBuilder}. - * - * @param filters - * the aggregated filters - * @return new instance of {@link CompositeFilter} - * @see #all(Filter, Filter...) for the public API equivalent - */ - static CompositeFilter all(Collection filters) { - checkNotNull(filters); - checkArgument(!filters.isEmpty(), - "Composite filter must contain at least one simple filter in it."); - return composeFilters(filters, ALL); - } - static Filter createFilter(String fieldPath, Object value, Operator operator) { Field field = Field.parse(fieldPath); return createFilter(field, value, operator); @@ -425,14 +426,6 @@ static Filter createFilter(Field field, Object value, Operator operator) { return createFilter(fieldPath, value, operator); } - static Filter createContextFilter(Field field, Object value, Operator operator) { - FieldPath fieldPath = Event.Fields.context() - .getField() - .nested(field) - .path(); - return createFilter(fieldPath, value, operator); - } - static Filter createFilter(FieldPath path, Object value, Operator operator) { Any wrappedValue = toAny(value); Filter filter = Filter @@ -444,6 +437,14 @@ static Filter createFilter(FieldPath path, Object value, Operator operator) { return filter; } + static Filter createContextFilter(Field field, Object value, Operator operator) { + FieldPath fieldPath = Event.Fields.context() + .getField() + .nested(field) + .path(); + return createFilter(fieldPath, value, operator); + } + static CompositeFilter composeFilters(Collection filters, CompositeOperator operator) { CompositeFilter result = CompositeFilter .newBuilder() From 02daecaa9182783890e6d735804302472a8cf387 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 18:53:55 +0200 Subject: [PATCH 22/53] Rename `CompositeFilterHolder` -> `TypedCompositeFilter` --- .../java/io/spine/client/CompositeEntityStateFilter.java | 2 +- .../main/java/io/spine/client/CompositeEventFilter.java | 2 +- .../main/java/io/spine/client/CompositeQueryFilter.java | 2 +- client/src/main/java/io/spine/client/Filters.java | 4 ++-- ...mpositeFilterHolder.java => TypedCompositeFilter.java} | 8 ++++---- client/src/test/java/io/spine/client/FiltersTest.java | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) rename client/src/main/java/io/spine/client/{CompositeFilterHolder.java => TypedCompositeFilter.java} (89%) diff --git a/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java b/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java index 61a40a96726..9a083635ff5 100644 --- a/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java +++ b/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java @@ -25,7 +25,7 @@ import java.util.Collection; -public final class CompositeEntityStateFilter extends CompositeFilterHolder { +public final class CompositeEntityStateFilter extends TypedCompositeFilter { private static final long serialVersionUID = 0L; diff --git a/client/src/main/java/io/spine/client/CompositeEventFilter.java b/client/src/main/java/io/spine/client/CompositeEventFilter.java index b7a39419ae8..6a2e5299257 100644 --- a/client/src/main/java/io/spine/client/CompositeEventFilter.java +++ b/client/src/main/java/io/spine/client/CompositeEventFilter.java @@ -30,7 +30,7 @@ /** * Filters events by composite criteria which can test both event messages and their contexts. */ -public final class CompositeEventFilter extends CompositeFilterHolder { +public final class CompositeEventFilter extends TypedCompositeFilter { private static final long serialVersionUID = 0L; diff --git a/client/src/main/java/io/spine/client/CompositeQueryFilter.java b/client/src/main/java/io/spine/client/CompositeQueryFilter.java index 08cba247bed..65bfc54dac9 100644 --- a/client/src/main/java/io/spine/client/CompositeQueryFilter.java +++ b/client/src/main/java/io/spine/client/CompositeQueryFilter.java @@ -25,7 +25,7 @@ import java.util.Collection; -public final class CompositeQueryFilter extends CompositeFilterHolder { +public final class CompositeQueryFilter extends TypedCompositeFilter { private static final long serialVersionUID = 0L; diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index f88cda21cf5..6be5fdb6ac1 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -467,9 +467,9 @@ static Filter[] extractFilters(TypedFilter[] filters) { .collect(toImmutableList()); } - static CompositeFilter[] extractFilters(CompositeFilterHolder[] filters) { + static CompositeFilter[] extractFilters(TypedCompositeFilter[] filters) { return stream(filters) - .map(CompositeFilterHolder::filter) + .map(TypedCompositeFilter::filter) .toArray(CompositeFilter[]::new); } diff --git a/client/src/main/java/io/spine/client/CompositeFilterHolder.java b/client/src/main/java/io/spine/client/TypedCompositeFilter.java similarity index 89% rename from client/src/main/java/io/spine/client/CompositeFilterHolder.java rename to client/src/main/java/io/spine/client/TypedCompositeFilter.java index 3aab7798cec..692493a811b 100644 --- a/client/src/main/java/io/spine/client/CompositeFilterHolder.java +++ b/client/src/main/java/io/spine/client/TypedCompositeFilter.java @@ -33,7 +33,7 @@ import static io.spine.client.Filters.composeFilters; import static io.spine.client.Filters.extractFilters; -abstract class CompositeFilterHolder +abstract class TypedCompositeFilter extends ValueHolder implements CompositeMessageFilter { @@ -41,7 +41,7 @@ abstract class CompositeFilterHolder private final ImmutableList> filters; - CompositeFilterHolder(CompositeFilter filter, Function> wrapper) { + TypedCompositeFilter(CompositeFilter filter, Function> wrapper) { super(filter); this.filters = filter.getFilterList() .stream() @@ -49,8 +49,8 @@ abstract class CompositeFilterHolder .collect(toImmutableList()); } - CompositeFilterHolder(Collection> filters, - CompositeOperator operator) { + TypedCompositeFilter(Collection> filters, + CompositeOperator operator) { super(composeFilters(extractFilters(filters), operator)); this.filters = ImmutableList.copyOf(filters); } diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index c79fe7f2faa..baef1f1caf9 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -299,7 +299,7 @@ void customFields() { assertThat(compositeFilter.getFilterList()).containsExactlyElementsIn(filters); } - private void checkCreatesInstance(CompositeFilterHolder filter, + private void checkCreatesInstance(TypedCompositeFilter filter, TypedFilter[] groupedFilters) { CompositeFilter compositeFilter = filter.filter(); assertThat(compositeFilter.getFilterList()) From 97fc8d450225865c254836aecc94a81f91a3d2cd Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 19:10:44 +0200 Subject: [PATCH 23/53] Move filter creation methods to corresponding filter types --- .../client/CompositeEntityStateFilter.java | 23 +- .../io/spine/client/CompositeEventFilter.java | 19 +- .../io/spine/client/CompositeQueryFilter.java | 19 +- .../io/spine/client/EntityStateFilter.java | 43 +++- .../java/io/spine/client/EventFilter.java | 83 ++++++- .../main/java/io/spine/client/Filters.java | 221 ++---------------- .../java/io/spine/client/QueryFilter.java | 43 +++- 7 files changed, 242 insertions(+), 209 deletions(-) diff --git a/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java b/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java index 9a083635ff5..21293245f40 100644 --- a/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java +++ b/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java @@ -25,11 +25,32 @@ import java.util.Collection; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Lists.asList; +import static io.spine.client.CompositeFilter.CompositeOperator.ALL; +import static io.spine.client.CompositeFilter.CompositeOperator.EITHER; + public final class CompositeEntityStateFilter extends TypedCompositeFilter { private static final long serialVersionUID = 0L; - CompositeEntityStateFilter(Collection filters, CompositeOperator operator) { + private CompositeEntityStateFilter(Collection filters, + CompositeOperator operator) { super(filters, operator); } + + public static CompositeEntityStateFilter + all(EntityStateFilter first, EntityStateFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeEntityStateFilter(asList(first, rest), ALL); + } + + public static CompositeEntityStateFilter + either(EntityStateFilter first, EntityStateFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeEntityStateFilter(asList(first, rest), EITHER); + } + } diff --git a/client/src/main/java/io/spine/client/CompositeEventFilter.java b/client/src/main/java/io/spine/client/CompositeEventFilter.java index 6a2e5299257..c8deed9226d 100644 --- a/client/src/main/java/io/spine/client/CompositeEventFilter.java +++ b/client/src/main/java/io/spine/client/CompositeEventFilter.java @@ -26,6 +26,9 @@ import java.util.Collection; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Lists.asList; +import static io.spine.client.CompositeFilter.CompositeOperator.ALL; +import static io.spine.client.CompositeFilter.CompositeOperator.EITHER; /** * Filters events by composite criteria which can test both event messages and their contexts. @@ -34,11 +37,23 @@ public final class CompositeEventFilter extends TypedCompositeFilter { private static final long serialVersionUID = 0L; + private CompositeEventFilter(Collection filters, CompositeOperator operator) { + super(filters, operator); + } + CompositeEventFilter(CompositeFilter filter) { super(checkNotNull(filter), EventFilter::new); } - CompositeEventFilter(Collection filters, CompositeOperator operator) { - super(filters, operator); + public static CompositeEventFilter all(EventFilter first, EventFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeEventFilter(asList(first, rest), ALL); + } + + public static CompositeEventFilter either(EventFilter first, EventFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeEventFilter(asList(first, rest), EITHER); } } diff --git a/client/src/main/java/io/spine/client/CompositeQueryFilter.java b/client/src/main/java/io/spine/client/CompositeQueryFilter.java index 65bfc54dac9..735ce6b12c3 100644 --- a/client/src/main/java/io/spine/client/CompositeQueryFilter.java +++ b/client/src/main/java/io/spine/client/CompositeQueryFilter.java @@ -25,11 +25,28 @@ import java.util.Collection; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Lists.asList; +import static io.spine.client.CompositeFilter.CompositeOperator.ALL; +import static io.spine.client.CompositeFilter.CompositeOperator.EITHER; + public final class CompositeQueryFilter extends TypedCompositeFilter { private static final long serialVersionUID = 0L; - CompositeQueryFilter(Collection filters, CompositeOperator operator) { + private CompositeQueryFilter(Collection filters, CompositeOperator operator) { super(filters, operator); } + + public static CompositeQueryFilter all(QueryFilter first, QueryFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeQueryFilter(asList(first, rest), ALL); + } + + public static CompositeQueryFilter either(QueryFilter first, QueryFilter... rest) { + checkNotNull(first); + checkNotNull(rest); + return new CompositeQueryFilter(asList(first, rest), EITHER); + } } diff --git a/client/src/main/java/io/spine/client/EntityStateFilter.java b/client/src/main/java/io/spine/client/EntityStateFilter.java index 8b842c67d58..522d3e2af63 100644 --- a/client/src/main/java/io/spine/client/EntityStateFilter.java +++ b/client/src/main/java/io/spine/client/EntityStateFilter.java @@ -24,13 +24,54 @@ import io.spine.base.EntityStateField; import io.spine.client.Filter.Operator; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.spine.client.Filter.Operator.EQUAL; +import static io.spine.client.Filter.Operator.GREATER_OR_EQUAL; +import static io.spine.client.Filter.Operator.GREATER_THAN; +import static io.spine.client.Filter.Operator.LESS_OR_EQUAL; +import static io.spine.client.Filter.Operator.LESS_THAN; +import static io.spine.client.Filters.checkSupportedOrderingComparisonType; import static io.spine.client.Filters.createFilter; public final class EntityStateFilter extends TypedFilter { private static final long serialVersionUID = 0L; - EntityStateFilter(EntityStateField field, Object expected, Operator operator) { + private EntityStateFilter(EntityStateField field, Object expected, Operator operator) { super(createFilter(field.getField(), expected, operator)); } + + public static EntityStateFilter eq(EntityStateField field, Object value) { + checkNotNull(field); + checkNotNull(value); + return new EntityStateFilter(field, value, EQUAL); + } + + public static EntityStateFilter gt(EntityStateField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EntityStateFilter(field, value, GREATER_THAN); + } + + public static EntityStateFilter lt(EntityStateField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EntityStateFilter(field, value, LESS_THAN); + } + + public static EntityStateFilter ge(EntityStateField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EntityStateFilter(field, value, GREATER_OR_EQUAL); + } + + public static EntityStateFilter le(EntityStateField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EntityStateFilter(field, value, LESS_OR_EQUAL); + } } diff --git a/client/src/main/java/io/spine/client/EventFilter.java b/client/src/main/java/io/spine/client/EventFilter.java index 04e8940d594..1da771a1239 100644 --- a/client/src/main/java/io/spine/client/EventFilter.java +++ b/client/src/main/java/io/spine/client/EventFilter.java @@ -24,6 +24,13 @@ import io.spine.base.EventMessageField; import io.spine.core.Event; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.spine.client.Filter.Operator.EQUAL; +import static io.spine.client.Filter.Operator.GREATER_OR_EQUAL; +import static io.spine.client.Filter.Operator.GREATER_THAN; +import static io.spine.client.Filter.Operator.LESS_OR_EQUAL; +import static io.spine.client.Filter.Operator.LESS_THAN; +import static io.spine.client.Filters.checkSupportedOrderingComparisonType; import static io.spine.client.Filters.createContextFilter; import static io.spine.client.Filters.createFilter; @@ -41,16 +48,84 @@ private EventFilter(Filter filter, boolean byContext) { this.byContext = byContext; } + private EventFilter(EventMessageField field, Object expected, Filter.Operator operator) { + this(createFilter(field.getField(), expected, operator), false); + } + + private EventFilter(EventContextField field, Object expected, Filter.Operator operator) { + this(createContextFilter(field.getField(), expected, operator), true); + } + EventFilter(Filter filter) { this(filter, isContextFilter(filter)); } - EventFilter(EventMessageField field, Object expected, Filter.Operator operator) { - this(createFilter(field.getField(), expected, operator), false); + public static EventFilter eq(EventMessageField field, Object value) { + checkNotNull(field); + checkNotNull(value); + return new EventFilter(field, value, EQUAL); } - EventFilter(EventContextField field, Object expected, Filter.Operator operator) { - this(createContextFilter(field.getField(), expected, operator), true); + public static EventFilter eq(EventContextField field, Object value) { + checkNotNull(field); + checkNotNull(value); + return new EventFilter(field, value, EQUAL); + } + + public static EventFilter gt(EventMessageField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, GREATER_THAN); + } + + public static EventFilter gt(EventContextField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, GREATER_THAN); + } + + public static EventFilter lt(EventMessageField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, LESS_THAN); + } + + public static EventFilter lt(EventContextField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, LESS_THAN); + } + + public static EventFilter ge(EventMessageField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, GREATER_OR_EQUAL); + } + + public static EventFilter ge(EventContextField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, GREATER_OR_EQUAL); + } + + public static EventFilter le(EventMessageField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, LESS_OR_EQUAL); + } + + public static EventFilter le(EventContextField field, Object value) { + checkNotNull(field); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new EventFilter(field, value, LESS_OR_EQUAL); } @Override diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index 6be5fdb6ac1..e4541ab46e3 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -26,10 +26,6 @@ import com.google.protobuf.Message; import com.google.protobuf.Timestamp; import io.spine.annotation.Internal; -import io.spine.base.EntityColumn; -import io.spine.base.EntityStateField; -import io.spine.base.EventContextField; -import io.spine.base.EventMessageField; import io.spine.base.Field; import io.spine.base.FieldPath; import io.spine.client.CompositeFilter.CompositeOperator; @@ -82,39 +78,16 @@ * * * @see QueryBuilder for the application + * @see QueryFilter + * @see EntityStateFilter + * @see EventFilter */ -@SuppressWarnings("ClassWithTooManyMethods") -// Unifies a lot of methods for convenient filter creation. public final class Filters { /** Prevents this utility class instantiation. */ private Filters() { } - public static QueryFilter eq(EntityColumn column, Object value) { - checkNotNull(column); - checkNotNull(value); - return new QueryFilter(column, value, EQUAL); - } - - public static EntityStateFilter eq(EntityStateField field, Object value) { - checkNotNull(field); - checkNotNull(value); - return new EntityStateFilter(field, value, EQUAL); - } - - public static EventFilter eq(EventMessageField field, Object value) { - checkNotNull(field); - checkNotNull(value); - return new EventFilter(field, value, EQUAL); - } - - public static EventFilter eq(EventContextField field, Object value) { - checkNotNull(field); - checkNotNull(value); - return new EventFilter(field, value, EQUAL); - } - /** * Creates new equality {@link Filter}. * @@ -130,34 +103,6 @@ public static Filter eq(String fieldPath, Object value) { return createFilter(fieldPath, value, EQUAL); } - public static QueryFilter gt(EntityColumn column, Object value) { - checkNotNull(column); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new QueryFilter(column, value, GREATER_THAN); - } - - public static EntityStateFilter gt(EntityStateField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EntityStateFilter(field, value, GREATER_THAN); - } - - public static EventFilter gt(EventMessageField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EventFilter(field, value, GREATER_THAN); - } - - public static EventFilter gt(EventContextField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EventFilter(field, value, GREATER_THAN); - } - /** * Creates new "greater than" {@link Filter}. * @@ -176,34 +121,6 @@ public static Filter gt(String fieldPath, Object value) { return createFilter(fieldPath, value, GREATER_THAN); } - public static QueryFilter lt(EntityColumn column, Object value) { - checkNotNull(column); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new QueryFilter(column, value, LESS_THAN); - } - - public static EntityStateFilter lt(EntityStateField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EntityStateFilter(field, value, LESS_THAN); - } - - public static EventFilter lt(EventMessageField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EventFilter(field, value, LESS_THAN); - } - - public static EventFilter lt(EventContextField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EventFilter(field, value, LESS_THAN); - } - /** * Creates new "less than" {@link Filter}. * @@ -222,34 +139,6 @@ public static Filter lt(String fieldPath, Object value) { return createFilter(fieldPath, value, LESS_THAN); } - public static QueryFilter ge(EntityColumn column, Object value) { - checkNotNull(column); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new QueryFilter(column, value, GREATER_OR_EQUAL); - } - - public static EntityStateFilter ge(EntityStateField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EntityStateFilter(field, value, GREATER_OR_EQUAL); - } - - public static EventFilter ge(EventMessageField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EventFilter(field, value, GREATER_OR_EQUAL); - } - - public static EventFilter ge(EventContextField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EventFilter(field, value, GREATER_OR_EQUAL); - } - /** * Creates new "greater or equal" {@link Filter}. * @@ -268,34 +157,6 @@ public static Filter ge(String fieldPath, Object value) { return createFilter(fieldPath, value, GREATER_OR_EQUAL); } - public static QueryFilter le(EntityColumn column, Object value) { - checkNotNull(column); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new QueryFilter(column, value, LESS_OR_EQUAL); - } - - public static EntityStateFilter le(EntityStateField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EntityStateFilter(field, value, LESS_OR_EQUAL); - } - - public static EventFilter le(EventMessageField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EventFilter(field, value, LESS_OR_EQUAL); - } - - public static EventFilter le(EventContextField field, Object value) { - checkNotNull(field); - checkNotNull(value); - checkSupportedOrderingComparisonType(value.getClass()); - return new EventFilter(field, value, LESS_OR_EQUAL); - } - /** * Creates new "less or equal" {@link Filter}. * @@ -314,25 +175,6 @@ public static Filter le(String fieldPath, Object value) { return createFilter(fieldPath, value, LESS_OR_EQUAL); } - public static CompositeQueryFilter all(QueryFilter first, QueryFilter... rest) { - checkNotNull(first); - checkNotNull(rest); - return new CompositeQueryFilter(asList(first, rest), ALL); - } - - public static CompositeEntityStateFilter - all(EntityStateFilter first, EntityStateFilter... rest) { - checkNotNull(first); - checkNotNull(rest); - return new CompositeEntityStateFilter(asList(first, rest), ALL); - } - - public static CompositeEventFilter all(EventFilter first, EventFilter... rest) { - checkNotNull(first); - checkNotNull(rest); - return new CompositeEventFilter(asList(first, rest), ALL); - } - /** * Creates new conjunction composite filter. * @@ -353,6 +195,24 @@ public static CompositeFilter all(Filter first, Filter... rest) { return composeFilters(asList(first, rest), ALL); } + /** + * Creates new disjunction composite filter. + * + *

A record is considered matching this filter if it matches at least one of the aggregated + * filters. + * + * @param first + * the first {@link Filter} + * @param rest + * the array of additional {@linkplain Filter filters}, possibly empty + * @return new instance of {@link CompositeFilter} + */ + public static CompositeFilter either(Filter first, Filter... rest) { + checkNotNull(first); + checkNotNull(rest); + return composeFilters(asList(first, rest), EITHER); + } + /** * Creates new conjunction composite filter. * @@ -374,43 +234,6 @@ static CompositeFilter all(Collection filters) { return composeFilters(filters, ALL); } - public static CompositeQueryFilter either(QueryFilter first, QueryFilter... rest) { - checkNotNull(first); - checkNotNull(rest); - return new CompositeQueryFilter(asList(first, rest), EITHER); - } - - public static CompositeEntityStateFilter - either(EntityStateFilter first, EntityStateFilter... rest) { - checkNotNull(first); - checkNotNull(rest); - return new CompositeEntityStateFilter(asList(first, rest), EITHER); - } - - public static CompositeEventFilter either(EventFilter first, EventFilter... rest) { - checkNotNull(first); - checkNotNull(rest); - return new CompositeEventFilter(asList(first, rest), EITHER); - } - - /** - * Creates new disjunction composite filter. - * - *

A record is considered matching this filter if it matches at least one of the aggregated - * filters. - * - * @param first - * the first {@link Filter} - * @param rest - * the array of additional {@linkplain Filter filters}, possibly empty - * @return new instance of {@link CompositeFilter} - */ - public static CompositeFilter either(Filter first, Filter... rest) { - checkNotNull(first); - checkNotNull(rest); - return composeFilters(asList(first, rest), EITHER); - } - static Filter createFilter(String fieldPath, Object value, Operator operator) { Field field = Field.parse(fieldPath); return createFilter(field, value, operator); @@ -473,7 +296,7 @@ static CompositeFilter[] extractFilters(TypedCompositeFilter[] filters) { .toArray(CompositeFilter[]::new); } - private static void checkSupportedOrderingComparisonType(Class cls) { + static void checkSupportedOrderingComparisonType(Class cls) { Class dataType = Primitives.wrap(cls); boolean supported = isSupportedNumber(dataType) || Timestamp.class.isAssignableFrom(dataType) diff --git a/client/src/main/java/io/spine/client/QueryFilter.java b/client/src/main/java/io/spine/client/QueryFilter.java index a2e8477540c..4373a4888e8 100644 --- a/client/src/main/java/io/spine/client/QueryFilter.java +++ b/client/src/main/java/io/spine/client/QueryFilter.java @@ -24,13 +24,54 @@ import io.spine.base.EntityState; import io.spine.client.Filter.Operator; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.spine.client.Filter.Operator.EQUAL; +import static io.spine.client.Filter.Operator.GREATER_OR_EQUAL; +import static io.spine.client.Filter.Operator.GREATER_THAN; +import static io.spine.client.Filter.Operator.LESS_OR_EQUAL; +import static io.spine.client.Filter.Operator.LESS_THAN; +import static io.spine.client.Filters.checkSupportedOrderingComparisonType; import static io.spine.client.Filters.createFilter; public final class QueryFilter extends TypedFilter { private static final long serialVersionUID = 0L; - QueryFilter(EntityColumn column, Object expected, Operator operator) { + private QueryFilter(EntityColumn column, Object expected, Operator operator) { super(createFilter(column.name(), expected, operator)); } + + public static QueryFilter eq(EntityColumn column, Object value) { + checkNotNull(column); + checkNotNull(value); + return new QueryFilter(column, value, EQUAL); + } + + public static QueryFilter gt(EntityColumn column, Object value) { + checkNotNull(column); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new QueryFilter(column, value, GREATER_THAN); + } + + public static QueryFilter lt(EntityColumn column, Object value) { + checkNotNull(column); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new QueryFilter(column, value, LESS_THAN); + } + + public static QueryFilter ge(EntityColumn column, Object value) { + checkNotNull(column); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new QueryFilter(column, value, GREATER_OR_EQUAL); + } + + public static QueryFilter le(EntityColumn column, Object value) { + checkNotNull(column); + checkNotNull(value); + checkSupportedOrderingComparisonType(value.getClass()); + return new QueryFilter(column, value, LESS_OR_EQUAL); + } } From 3271ad50606746f63e5196c45aa153c517ae5169 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 19:36:28 +0200 Subject: [PATCH 24/53] Cover typed filters and their creation methods with doc --- .../io/spine/client/EntityStateFilter.java | 55 +++++++++ .../java/io/spine/client/EventFilter.java | 109 +++++++++++++++++- .../main/java/io/spine/client/Filters.java | 16 +-- .../java/io/spine/client/QueryFilter.java | 55 +++++++++ .../java/io/spine/client/TypedFilter.java | 6 + 5 files changed, 232 insertions(+), 9 deletions(-) diff --git a/client/src/main/java/io/spine/client/EntityStateFilter.java b/client/src/main/java/io/spine/client/EntityStateFilter.java index 522d3e2af63..d42013328e0 100644 --- a/client/src/main/java/io/spine/client/EntityStateFilter.java +++ b/client/src/main/java/io/spine/client/EntityStateFilter.java @@ -33,6 +33,9 @@ import static io.spine.client.Filters.checkSupportedOrderingComparisonType; import static io.spine.client.Filters.createFilter; +/** + * A subscription filter which targets an {@link EntityState}. + */ public final class EntityStateFilter extends TypedFilter { private static final long serialVersionUID = 0L; @@ -41,12 +44,31 @@ private EntityStateFilter(EntityStateField field, Object expected, Operator oper super(createFilter(field.getField(), expected, operator)); } + /** + * Creates a new equality filter. + * + * @param field + * the message field from which the actual value is taken + * @param value + * the expected value + */ public static EntityStateFilter eq(EntityStateField field, Object value) { checkNotNull(field); checkNotNull(value); return new EntityStateFilter(field, value, EQUAL); } + /** + * Creates a new "greater than" filter. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the message field from which the actual value is taken + * @param value + * the expected value + */ public static EntityStateFilter gt(EntityStateField field, Object value) { checkNotNull(field); checkNotNull(value); @@ -54,6 +76,17 @@ public static EntityStateFilter gt(EntityStateField field, Object value) { return new EntityStateFilter(field, value, GREATER_THAN); } + /** + * Creates a new "less than" filter. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the message field from which the actual value is taken + * @param value + * the expected value + */ public static EntityStateFilter lt(EntityStateField field, Object value) { checkNotNull(field); checkNotNull(value); @@ -61,6 +94,17 @@ public static EntityStateFilter lt(EntityStateField field, Object value) { return new EntityStateFilter(field, value, LESS_THAN); } + /** + * Creates a new "greater than or equals" filter. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the message field from which the actual value is taken + * @param value + * the expected value + */ public static EntityStateFilter ge(EntityStateField field, Object value) { checkNotNull(field); checkNotNull(value); @@ -68,6 +112,17 @@ public static EntityStateFilter ge(EntityStateField field, Object value) { return new EntityStateFilter(field, value, GREATER_OR_EQUAL); } + /** + * Creates a new "less than or equals" filter. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the message field from which the actual value is taken + * @param value + * the expected value + */ public static EntityStateFilter le(EntityStateField field, Object value) { checkNotNull(field); checkNotNull(value); diff --git a/client/src/main/java/io/spine/client/EventFilter.java b/client/src/main/java/io/spine/client/EventFilter.java index 1da771a1239..972aaa0755b 100644 --- a/client/src/main/java/io/spine/client/EventFilter.java +++ b/client/src/main/java/io/spine/client/EventFilter.java @@ -35,7 +35,10 @@ import static io.spine.client.Filters.createFilter; /** - * Filters events by conditions on both message and context. + * A subscription filter which targets an {@link Event}. + * + *

Can filter events by conditions on both message and context. See factory methods of the + * class for details. */ public final class EventFilter extends TypedFilter { @@ -60,18 +63,45 @@ private EventFilter(EventContextField field, Object expected, Filter.Operator op this(filter, isContextFilter(filter)); } + /** + * Creates a new equality filter which targets a field in the event message. + * + * @param field + * the message field from which the actual value is taken + * @param value + * the expected value + */ public static EventFilter eq(EventMessageField field, Object value) { checkNotNull(field); checkNotNull(value); return new EventFilter(field, value, EQUAL); } + /** + * Creates a new equality filter which targets a field in the event context. + * + * @param field + * the context field from which the actual value is taken + * @param value + * the expected value + */ public static EventFilter eq(EventContextField field, Object value) { checkNotNull(field); checkNotNull(value); return new EventFilter(field, value, EQUAL); } + /** + * Creates a new "greater than" filter which targets a field in the event message. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the message field from which the actual value is taken + * @param value + * the expected value + */ public static EventFilter gt(EventMessageField field, Object value) { checkNotNull(field); checkNotNull(value); @@ -79,6 +109,17 @@ public static EventFilter gt(EventMessageField field, Object value) { return new EventFilter(field, value, GREATER_THAN); } + /** + * Creates a new "greater than" filter which targets a field in the event context. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the context field from which the actual value is taken + * @param value + * the expected value + */ public static EventFilter gt(EventContextField field, Object value) { checkNotNull(field); checkNotNull(value); @@ -86,6 +127,17 @@ public static EventFilter gt(EventContextField field, Object value) { return new EventFilter(field, value, GREATER_THAN); } + /** + * Creates a new "less than" filter which targets a field in the event message. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the message field from which the actual value is taken + * @param value + * the expected value + */ public static EventFilter lt(EventMessageField field, Object value) { checkNotNull(field); checkNotNull(value); @@ -93,6 +145,17 @@ public static EventFilter lt(EventMessageField field, Object value) { return new EventFilter(field, value, LESS_THAN); } + /** + * Creates a new "less than" filter which targets a field in the event context. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the context field from which the actual value is taken + * @param value + * the expected value + */ public static EventFilter lt(EventContextField field, Object value) { checkNotNull(field); checkNotNull(value); @@ -100,6 +163,17 @@ public static EventFilter lt(EventContextField field, Object value) { return new EventFilter(field, value, LESS_THAN); } + /** + * Creates a new "greater than or equals" filter which targets a field in the event message. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the message field from which the actual value is taken + * @param value + * the expected value + */ public static EventFilter ge(EventMessageField field, Object value) { checkNotNull(field); checkNotNull(value); @@ -107,6 +181,17 @@ public static EventFilter ge(EventMessageField field, Object value) { return new EventFilter(field, value, GREATER_OR_EQUAL); } + /** + * Creates a new "greater than or equals" filter which targets a field in the event context. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the context field from which the actual value is taken + * @param value + * the expected value + */ public static EventFilter ge(EventContextField field, Object value) { checkNotNull(field); checkNotNull(value); @@ -114,6 +199,17 @@ public static EventFilter ge(EventContextField field, Object value) { return new EventFilter(field, value, GREATER_OR_EQUAL); } + /** + * Creates a new "less than or equals" filter which targets a field in the event message. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the message field from which the actual value is taken + * @param value + * the expected value + */ public static EventFilter le(EventMessageField field, Object value) { checkNotNull(field); checkNotNull(value); @@ -121,6 +217,17 @@ public static EventFilter le(EventMessageField field, Object value) { return new EventFilter(field, value, LESS_OR_EQUAL); } + /** + * Creates a new "less than or equals" filter which targets a field in the event context. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param field + * the context field from which the actual value is taken + * @param value + * the expected value + */ public static EventFilter le(EventContextField field, Object value) { checkNotNull(field); checkNotNull(value); diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index e4541ab46e3..f363f05b512 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -89,7 +89,7 @@ private Filters() { } /** - * Creates new equality {@link Filter}. + * Creates a new equality {@link Filter}. * * @param fieldPath * the field path or the entity column name for entity filters @@ -104,7 +104,7 @@ public static Filter eq(String fieldPath, Object value) { } /** - * Creates new "greater than" {@link Filter}. + * Creates a new "greater than" {@link Filter}. * *

For the supported types description see Comparison types section. * @@ -122,7 +122,7 @@ public static Filter gt(String fieldPath, Object value) { } /** - * Creates new "less than" {@link Filter}. + * Creates a new "less than" {@link Filter}. * *

See Comparison types section for the supported types description. * @@ -140,7 +140,7 @@ public static Filter lt(String fieldPath, Object value) { } /** - * Creates new "greater or equal" {@link Filter}. + * Creates a new "greater or equal" {@link Filter}. * *

See Comparison types section for the supported types description. * @@ -158,7 +158,7 @@ public static Filter ge(String fieldPath, Object value) { } /** - * Creates new "less or equal" {@link Filter}. + * Creates a new "less or equal" {@link Filter}. * *

See Comparison types section for the supported types description. * @@ -176,7 +176,7 @@ public static Filter le(String fieldPath, Object value) { } /** - * Creates new conjunction composite filter. + * Creates a new conjunction composite filter. * *

A record is considered matching this filter if and only if it matches all of the * aggregated filters. @@ -196,7 +196,7 @@ public static CompositeFilter all(Filter first, Filter... rest) { } /** - * Creates new disjunction composite filter. + * Creates a new disjunction composite filter. * *

A record is considered matching this filter if it matches at least one of the aggregated * filters. @@ -214,7 +214,7 @@ public static CompositeFilter either(Filter first, Filter... rest) { } /** - * Creates new conjunction composite filter. + * Creates a new conjunction composite filter. * *

A record is considered matching this filter if and only if it matches all of * the aggregated filters. diff --git a/client/src/main/java/io/spine/client/QueryFilter.java b/client/src/main/java/io/spine/client/QueryFilter.java index 4373a4888e8..d18be6b605e 100644 --- a/client/src/main/java/io/spine/client/QueryFilter.java +++ b/client/src/main/java/io/spine/client/QueryFilter.java @@ -33,6 +33,9 @@ import static io.spine.client.Filters.checkSupportedOrderingComparisonType; import static io.spine.client.Filters.createFilter; +/** + * A query filter which targets a {@linkplain EntityColumn column} of an entity. + */ public final class QueryFilter extends TypedFilter { private static final long serialVersionUID = 0L; @@ -41,12 +44,31 @@ private QueryFilter(EntityColumn column, Object expected, Operator operator) { super(createFilter(column.name(), expected, operator)); } + /** + * Creates a new equality filter. + * + * @param column + * the entity column from which the actual value is taken + * @param value + * the expected value + */ public static QueryFilter eq(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); return new QueryFilter(column, value, EQUAL); } + /** + * Creates a new "greater than" filter. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param column + * the entity column from which the actual value is taken + * @param value + * the expected value + */ public static QueryFilter gt(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); @@ -54,6 +76,17 @@ public static QueryFilter gt(EntityColumn column, Object value) { return new QueryFilter(column, value, GREATER_THAN); } + /** + * Creates a new "less than" filter. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param column + * the entity column from which the actual value is taken + * @param value + * the expected value + */ public static QueryFilter lt(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); @@ -61,6 +94,17 @@ public static QueryFilter lt(EntityColumn column, Object value) { return new QueryFilter(column, value, LESS_THAN); } + /** + * Creates a new "greater than or equals" filter. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param column + * the entity column from which the actual value is taken + * @param value + * the expected value + */ public static QueryFilter ge(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); @@ -68,6 +112,17 @@ public static QueryFilter ge(EntityColumn column, Object value) { return new QueryFilter(column, value, GREATER_OR_EQUAL); } + /** + * Creates a new "less than or equals" filter. + * + *

NOTE: not all value types are supported for ordering comparison. See {@link Filters} for + * details. + * + * @param column + * the entity column from which the actual value is taken + * @param value + * the expected value + */ public static QueryFilter le(EntityColumn column, Object value) { checkNotNull(column); checkNotNull(value); diff --git a/client/src/main/java/io/spine/client/TypedFilter.java b/client/src/main/java/io/spine/client/TypedFilter.java index ee3bbd1ba63..8366cfed912 100644 --- a/client/src/main/java/io/spine/client/TypedFilter.java +++ b/client/src/main/java/io/spine/client/TypedFilter.java @@ -23,6 +23,12 @@ import com.google.protobuf.Message; import io.spine.value.ValueHolder; +/** + * A typed wrapper around the {@link Filter} instance. + * + * @param + * the type of a filtered message + */ @SuppressWarnings("AbstractClassWithoutAbstractMethods") // Prevent instantiation of this abstract filter in favor of concrete descendants. abstract class TypedFilter From 7ed51358e7080876c3bd903da3edb39b77e7601b Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 19:50:49 +0200 Subject: [PATCH 25/53] Cover composite filters with doc --- .../spine/client/CompositeEntityStateFilter.java | 15 +++++++++++++++ .../io/spine/client/CompositeEventFilter.java | 14 +++++++++++++- .../io/spine/client/CompositeQueryFilter.java | 16 ++++++++++++++++ .../io/spine/client/TypedCompositeFilter.java | 6 ++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java b/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java index 21293245f40..acd723db9b0 100644 --- a/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java +++ b/client/src/main/java/io/spine/client/CompositeEntityStateFilter.java @@ -30,6 +30,9 @@ import static io.spine.client.CompositeFilter.CompositeOperator.ALL; import static io.spine.client.CompositeFilter.CompositeOperator.EITHER; +/** + * A subscription filter which aggregates one or more {@link EntityState} filters. + */ public final class CompositeEntityStateFilter extends TypedCompositeFilter { private static final long serialVersionUID = 0L; @@ -39,6 +42,12 @@ private CompositeEntityStateFilter(Collection filters, super(filters, operator); } + /** + * Creates a new conjunction composite filter. + * + *

A record is considered matching this filter if and only if it matches all of the + * passed filters. + */ public static CompositeEntityStateFilter all(EntityStateFilter first, EntityStateFilter... rest) { checkNotNull(first); @@ -46,6 +55,12 @@ private CompositeEntityStateFilter(Collection filters, return new CompositeEntityStateFilter(asList(first, rest), ALL); } + /** + * Creates a new disjunction composite filter. + * + *

A record is considered matching this filter if it matches at least one of the passed + * filters. + */ public static CompositeEntityStateFilter either(EntityStateFilter first, EntityStateFilter... rest) { checkNotNull(first); diff --git a/client/src/main/java/io/spine/client/CompositeEventFilter.java b/client/src/main/java/io/spine/client/CompositeEventFilter.java index c8deed9226d..c1b805c8cdc 100644 --- a/client/src/main/java/io/spine/client/CompositeEventFilter.java +++ b/client/src/main/java/io/spine/client/CompositeEventFilter.java @@ -31,7 +31,7 @@ import static io.spine.client.CompositeFilter.CompositeOperator.EITHER; /** - * Filters events by composite criteria which can test both event messages and their contexts. + * A composite subscription filter which can aggregate both event message and event context filters. */ public final class CompositeEventFilter extends TypedCompositeFilter { @@ -45,12 +45,24 @@ private CompositeEventFilter(Collection filters, CompositeOperator super(checkNotNull(filter), EventFilter::new); } + /** + * Creates a new conjunction composite filter. + * + *

A record is considered matching this filter if and only if it matches all of the + * passed filters. + */ public static CompositeEventFilter all(EventFilter first, EventFilter... rest) { checkNotNull(first); checkNotNull(rest); return new CompositeEventFilter(asList(first, rest), ALL); } + /** + * Creates a new disjunction composite filter. + * + *

A record is considered matching this filter if it matches at least one of the passed + * filters. + */ public static CompositeEventFilter either(EventFilter first, EventFilter... rest) { checkNotNull(first); checkNotNull(rest); diff --git a/client/src/main/java/io/spine/client/CompositeQueryFilter.java b/client/src/main/java/io/spine/client/CompositeQueryFilter.java index 735ce6b12c3..801ad31582e 100644 --- a/client/src/main/java/io/spine/client/CompositeQueryFilter.java +++ b/client/src/main/java/io/spine/client/CompositeQueryFilter.java @@ -30,6 +30,10 @@ import static io.spine.client.CompositeFilter.CompositeOperator.ALL; import static io.spine.client.CompositeFilter.CompositeOperator.EITHER; +/** + * A composite query filter which targets one or more entity + * {@link io.spine.base.EntityColumn columns}. + */ public final class CompositeQueryFilter extends TypedCompositeFilter { private static final long serialVersionUID = 0L; @@ -38,12 +42,24 @@ private CompositeQueryFilter(Collection filters, CompositeOperator super(filters, operator); } + /** + * Creates a new conjunction composite filter. + * + *

A record is considered matching this filter if and only if it matches all of the + * passed filters. + */ public static CompositeQueryFilter all(QueryFilter first, QueryFilter... rest) { checkNotNull(first); checkNotNull(rest); return new CompositeQueryFilter(asList(first, rest), ALL); } + /** + * Creates a new disjunction composite filter. + * + *

A record is considered matching this filter if it matches at least one of the passed + * filters. + */ public static CompositeQueryFilter either(QueryFilter first, QueryFilter... rest) { checkNotNull(first); checkNotNull(rest); diff --git a/client/src/main/java/io/spine/client/TypedCompositeFilter.java b/client/src/main/java/io/spine/client/TypedCompositeFilter.java index 692493a811b..5cf52428cfa 100644 --- a/client/src/main/java/io/spine/client/TypedCompositeFilter.java +++ b/client/src/main/java/io/spine/client/TypedCompositeFilter.java @@ -33,6 +33,12 @@ import static io.spine.client.Filters.composeFilters; import static io.spine.client.Filters.extractFilters; +/** + * A typed wrapper around the {@link CompositeFilter} instance. + * + * @param + * the type of a filtered message + */ abstract class TypedCompositeFilter extends ValueHolder implements CompositeMessageFilter { From c16384aff48e486bee3f497f497bb02fb81c55fb Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 19:51:20 +0200 Subject: [PATCH 26/53] Add clarification doc to the constructor --- client/src/main/java/io/spine/client/EventFilter.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/src/main/java/io/spine/client/EventFilter.java b/client/src/main/java/io/spine/client/EventFilter.java index 972aaa0755b..e802848a393 100644 --- a/client/src/main/java/io/spine/client/EventFilter.java +++ b/client/src/main/java/io/spine/client/EventFilter.java @@ -59,6 +59,12 @@ private EventFilter(EventContextField field, Object expected, Filter.Operator op this(createContextFilter(field.getField(), expected, operator), true); } + /** + * Creates an instance from the passed {@code Filter} message. + * + *

The filter is considered targeting event context if the field path in the filter starts + * with {@code "context."}. + */ EventFilter(Filter filter) { this(filter, isContextFilter(filter)); } From 54098af27bf33581c9d159cc59fc61102c858417 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 20:45:21 +0200 Subject: [PATCH 27/53] Improve typed filter tests and move them to the respective test types --- .../spine/client/EntityStateFilterTest.java | 111 +++++++++++ .../java/io/spine/client/EventFilterTest.java | 181 ++++++++++++++++++ .../java/io/spine/client/FiltersTest.java | 178 +++-------------- .../java/io/spine/client/QueryFilterTest.java | 110 +++++++++++ 4 files changed, 424 insertions(+), 156 deletions(-) create mode 100644 client/src/test/java/io/spine/client/EntityStateFilterTest.java create mode 100644 client/src/test/java/io/spine/client/EventFilterTest.java create mode 100644 client/src/test/java/io/spine/client/QueryFilterTest.java diff --git a/client/src/test/java/io/spine/client/EntityStateFilterTest.java b/client/src/test/java/io/spine/client/EntityStateFilterTest.java new file mode 100644 index 00000000000..02eb9b832f4 --- /dev/null +++ b/client/src/test/java/io/spine/client/EntityStateFilterTest.java @@ -0,0 +1,111 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.client; + +import com.google.common.testing.NullPointerTester; +import com.google.protobuf.Int32Value; +import io.spine.base.EntityStateField; +import io.spine.base.FieldPath; +import io.spine.protobuf.AnyPacker; +import io.spine.test.client.TestEntity; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.function.BiFunction; + +import static com.google.common.truth.Truth.assertThat; +import static io.spine.client.Filter.Operator.EQUAL; +import static io.spine.client.Filter.Operator.GREATER_OR_EQUAL; +import static io.spine.client.Filter.Operator.GREATER_THAN; +import static io.spine.client.Filter.Operator.LESS_OR_EQUAL; +import static io.spine.client.Filter.Operator.LESS_THAN; +import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; + +@DisplayName("`EntityStateFilter` should") +class EntityStateFilterTest { + + @Test + @DisplayName(NOT_ACCEPT_NULLS) + void passNullToleranceCheck() { + new NullPointerTester() + .setDefault(EntityStateField.class, TestEntity.Fields.firstField()) + .testAllPublicStaticMethods(EntityStateFilter.class); + } + + @Nested + @DisplayName("create") + class Create { + + @Test + @DisplayName("an `equals` filter") + void eqFilter() { + checkCreates(EntityStateFilter::eq, EQUAL); + } + + @Test + @DisplayName("a `greater than` filter") + void gtFilter() { + checkCreates(EntityStateFilter::gt, GREATER_THAN); + } + + @Test + @DisplayName("a `less than` filter") + void ltFilter() { + checkCreates(EntityStateFilter::lt, LESS_THAN); + } + + @Test + @DisplayName("a `greater than or equals` filter") + void geFilter() { + checkCreates(EntityStateFilter::ge, GREATER_OR_EQUAL); + } + + @Test + @DisplayName("a `less than or equals` filter") + void leFilter() { + checkCreates(EntityStateFilter::le, LESS_OR_EQUAL); + } + + private void + checkCreates(BiFunction factoryMethod, + Filter.Operator expectedOperator) { + EntityStateField field = TestEntity.Fields.thirdField(); + int value = 42; + EntityStateFilter stateFilter = factoryMethod.apply(field, value); + Filter filter = stateFilter.filter(); + + FieldPath fieldPath = filter.getFieldPath(); + int nameCount = fieldPath.getFieldNameCount(); + assertThat(nameCount).isEqualTo(1); + + String fieldName = fieldPath.getFieldName(0); + String expectedFieldName = field.getField() + .toString(); + assertThat(fieldName).isEqualTo(expectedFieldName); + + assertThat(filter.getOperator()).isEqualTo(expectedOperator); + + Int32Value unpacked = AnyPacker.unpack(filter.getValue(), Int32Value.class); + assertThat(unpacked.getValue()).isEqualTo(value); + } + } +} diff --git a/client/src/test/java/io/spine/client/EventFilterTest.java b/client/src/test/java/io/spine/client/EventFilterTest.java new file mode 100644 index 00000000000..549f287ddfc --- /dev/null +++ b/client/src/test/java/io/spine/client/EventFilterTest.java @@ -0,0 +1,181 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.client; + +import com.google.common.testing.NullPointerTester; +import com.google.protobuf.StringValue; +import io.spine.base.EventContextField; +import io.spine.base.EventMessageField; +import io.spine.base.Field; +import io.spine.base.FieldPath; +import io.spine.core.EventContext; +import io.spine.protobuf.AnyPacker; +import io.spine.test.client.ClProjectCreated; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.function.BiFunction; + +import static com.google.common.truth.Truth.assertThat; +import static io.spine.client.Filter.Operator.EQUAL; +import static io.spine.client.Filter.Operator.GREATER_OR_EQUAL; +import static io.spine.client.Filter.Operator.GREATER_THAN; +import static io.spine.client.Filter.Operator.LESS_OR_EQUAL; +import static io.spine.client.Filter.Operator.LESS_THAN; +import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; +import static java.lang.String.format; + +@DisplayName("`EventFilter` should") +class EventFilterTest { + + @Test + @DisplayName(NOT_ACCEPT_NULLS) + void passNullToleranceCheck() { + new NullPointerTester() + .setDefault(EventMessageField.class, ClProjectCreated.Fields.name()) + .setDefault(EventContextField.class, EventContext.Fields.external()) + .testAllPublicStaticMethods(EventFilter.class); + } + + @Nested + @DisplayName("create a filter targeting event message and having operator") + class CreateForEventMessage { + + @Test + @DisplayName("`equals`") + void eqFilter() { + checkCreates(EventFilter::eq, EQUAL); + } + + @Test + @DisplayName("`greater than`") + void gtFilter() { + checkCreates(EventFilter::gt, GREATER_THAN); + } + + @Test + @DisplayName("`less than`") + void ltFilter() { + checkCreates(EventFilter::lt, LESS_THAN); + } + + @Test + @DisplayName("`greater than or equals`") + void geFilter() { + checkCreates(EventFilter::ge, GREATER_OR_EQUAL); + } + + @Test + @DisplayName("`less than or equals`") + void leFilter() { + checkCreates(EventFilter::le, LESS_OR_EQUAL); + } + + private void + checkCreates(BiFunction factoryMethod, + Filter.Operator expectedOperator) { + EventMessageField field = ClProjectCreated.Fields.id(); + String value = "some-ID"; + EventFilter eventFilter = factoryMethod.apply(field, value); + Filter filter = eventFilter.filter(); + + FieldPath fieldPath = filter.getFieldPath(); + int nameCount = fieldPath.getFieldNameCount(); + assertThat(nameCount).isEqualTo(1); + + String fieldName = fieldPath.getFieldName(0); + String expectedFieldName = field.getField() + .toString(); + assertThat(fieldName).isEqualTo(expectedFieldName); + + assertThat(filter.getOperator()).isEqualTo(expectedOperator); + + StringValue unpacked = AnyPacker.unpack(filter.getValue(), StringValue.class); + assertThat(unpacked.getValue()).isEqualTo(value); + } + } + + @Nested + @DisplayName("create a filter targeting event context and having operator") + class CreateForEventContext { + + @Test + @DisplayName("`equals`") + void eqFilter() { + checkCreates(EventFilter::eq, EQUAL); + } + + @Test + @DisplayName("`greater than`") + void gtFilter() { + checkCreates(EventFilter::gt, GREATER_THAN); + } + + @Test + @DisplayName("`less than`") + void ltFilter() { + checkCreates(EventFilter::lt, LESS_THAN); + } + + @Test + @DisplayName("`greater than or equals`") + void geFilter() { + checkCreates(EventFilter::ge, GREATER_OR_EQUAL); + } + + @Test + @DisplayName("`less than or equals`") + void leFilter() { + checkCreates(EventFilter::le, LESS_OR_EQUAL); + } + + private void + checkCreates(BiFunction factoryMethod, + Filter.Operator expectedOperator) { + EventContextField field = EventContext.Fields.commandId() + .uuid(); + String value = "some-UUID"; + EventFilter eventFilter = factoryMethod.apply(field, value); + Filter filter = eventFilter.filter(); + + FieldPath fieldPath = filter.getFieldPath(); + int nameCount = fieldPath.getFieldNameCount(); + assertThat(nameCount).isEqualTo(3); + + String actualFieldPath = Field.withPath(fieldPath) + .toString(); + String expectedFieldPath = format("context.%s", field.getField()); + assertThat(actualFieldPath).isEqualTo(expectedFieldPath); + + assertThat(filter.getOperator()).isEqualTo(expectedOperator); + + StringValue unpacked = AnyPacker.unpack(filter.getValue(), StringValue.class); + assertThat(unpacked.getValue()).isEqualTo(value); + } + } + + @Test + @DisplayName("automatically prepend `context.` to the field path if the filter targets context") + void prependContextPath() { + + } +} diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index baef1f1caf9..771811dad56 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -21,9 +21,7 @@ package io.spine.client; import com.google.common.testing.NullPointerTester; -import com.google.common.truth.Correspondence; import com.google.protobuf.DoubleValue; -import com.google.protobuf.Message; import com.google.protobuf.StringValue; import com.google.protobuf.Timestamp; import io.spine.base.EntityColumn; @@ -31,6 +29,7 @@ import io.spine.base.EventContextField; import io.spine.base.EventMessageField; import io.spine.base.Field; +import io.spine.base.FieldPath; import io.spine.client.Filter.Operator; import io.spine.core.EventContext; import io.spine.core.Version; @@ -55,7 +54,6 @@ import static io.spine.client.Filter.Operator.GREATER_THAN; import static io.spine.client.Filter.Operator.LESS_OR_EQUAL; import static io.spine.client.Filter.Operator.LESS_THAN; -import static io.spine.client.Filters.all; import static io.spine.client.Filters.eq; import static io.spine.client.Filters.ge; import static io.spine.client.Filters.gt; @@ -74,11 +72,10 @@ @DisplayName("`Filters` utility should") class FiltersTest { - private static final EntityStateField FIELD = TestEntity.Fields.owner() - .whenLastVisited(); + private static final String FIELD = "owner.when_last_visited"; private static final Timestamp REQUESTED_VALUE = currentTime(); - private static final EntityStateField ENUM_FIELD = TestEntity.Fields.owner() - .role(); + + private static final String ENUM_FIELD = "owner.role"; private static final TestEntityOwner.Role ENUM_VALUE = ADMIN; @Test @@ -90,12 +87,6 @@ void haveUtilityConstructor() { @Test @DisplayName(NOT_ACCEPT_NULLS) void passNullToleranceCheck() { - QueryFilter queryFilter = - new QueryFilter(TestEntity.Columns.firstField(), "some value", EQUAL); - EntityStateFilter entityStateFilter = - new EntityStateFilter(TestEntity.Fields.firstField(), "some field value", EQUAL); - EventFilter eventFilter = - new EventFilter(ClProjectCreated.Fields.name().value(), "some project name", EQUAL); new NullPointerTester() .setDefault(Filter.class, Filter.getDefaultInstance()) @@ -103,9 +94,6 @@ void passNullToleranceCheck() { .setDefault(EntityStateField.class, TestEntity.Fields.id()) .setDefault(EventMessageField.class, ClProjectCreated.Fields.id()) .setDefault(EventContextField.class, EventContext.Fields.timestamp()) - .setDefault(QueryFilter.class, queryFilter) - .setDefault(EntityStateFilter.class, entityStateFilter) - .setDefault(EventFilter.class, eventFilter) .testAllPublicStaticMethods(Filters.class); } @@ -146,78 +134,25 @@ void lessOrEqual() { @Test @DisplayName("`equals` for enumerated types") void equalsForEnum() { - EntityStateFilter stateFilter = eq(ENUM_FIELD, ENUM_VALUE); - Filter filter = stateFilter.filter(); + Filter filter = eq(ENUM_FIELD, ENUM_VALUE); - assertEquals(ENUM_FIELD.getField().path(), filter.getFieldPath()); + FieldPath fieldPath = filter.getFieldPath(); + String actual = Field.withPath(fieldPath) + .toString(); + assertEquals(ENUM_FIELD, actual); assertEquals(toAny(ENUM_VALUE), filter.getValue()); assertEquals(EQUAL, filter.getOperator()); } - private void checkCreatesInstance(EntityStateFilter stateFilter, Operator operator) { - Filter filter = stateFilter.filter(); - - assertEquals(FIELD.getField().path(), filter.getFieldPath()); + private void checkCreatesInstance(Filter filter, Operator operator) { + String actual = Field.withPath(filter.getFieldPath()) + .toString(); + assertEquals(FIELD, actual); assertEquals(pack(REQUESTED_VALUE), filter.getValue()); assertEquals(operator, filter.getOperator()); } } - @SuppressWarnings("DuplicateStringLiteralInspection") - // Duplication needed to test the validness of the generated code. - @Nested - @DisplayName("create filter targeting") - class CreateFilterTargeting { - - @Test - @DisplayName("an entity column") - void entityColumn() { - EntityColumn column = TestEntity.Columns.firstField(); - checkFieldPath(eq(column, "some string value"), "first_field"); - } - - @Test - @DisplayName("an entity state field") - void entityField() { - EntityStateField field = TestEntity.Fields.name() - .value(); - checkFieldPath(eq(field, "some entity name"), "name.value"); - } - - @Test - @DisplayName("an event message field") - void eventField() { - EventMessageField field = ClProjectCreated.Fields.name() - .value(); - checkFieldPath(eq(field, "some project name"), "name.value"); - } - - @Test - @DisplayName("an event context field") - void eventContextField() { - EventContextField field = EventContext.Fields.pastMessage(); - checkFieldPath(eq(field, "some user ID"), "context.past_message"); - } - - @Test - @DisplayName("a custom field passed via field path") - void customField() { - String fieldPath = "project.when_created"; - Filter filter = eq(fieldPath, currentTime()); - String fieldPathInFilter = Field.withPath(filter.getFieldPath()) - .toString(); - - assertThat(fieldPathInFilter).isEqualTo(fieldPath); - } - - private void checkFieldPath(TypedFilter filterWrapper, String expectedFieldPath) { - Filter filter = filterWrapper.filter(); - String fieldPath = Field.withPath(filter.getFieldPath()) - .toString(); - assertThat(fieldPath).isEqualTo(expectedFieldPath); - } - } - @Nested @DisplayName("create composite filter of type") class CreateCompositeFilterOfType { @@ -225,7 +160,7 @@ class CreateCompositeFilterOfType { @Test @DisplayName("`all`") void all() { - EntityStateFilter[] filters = { + Filter[] filters = { le(FIELD, REQUESTED_VALUE), ge(FIELD, REQUESTED_VALUE) }; @@ -235,75 +170,18 @@ void all() { @Test @DisplayName("`either`") void either() { - EntityStateFilter[] filters = { + Filter[] filters = { lt(FIELD, REQUESTED_VALUE), gt(FIELD, REQUESTED_VALUE) }; checkCreatesInstance(Filters.either(filters[0], filters[1]), EITHER, filters); } - private void checkCreatesInstance(CompositeEntityStateFilter filter, + private void checkCreatesInstance(CompositeFilter filter, CompositeOperator operator, - EntityStateFilter[] groupedFilters) { - CompositeFilter compositeFilter = filter.filter(); - - assertEquals(operator, compositeFilter.getOperator()); - assertThat(compositeFilter.getFilterList()) - .comparingElementsUsing(typedFilterCorrespondence()) - .containsExactlyElementsIn(groupedFilters); - } - } - - @Nested - @DisplayName("create composite filter targeting") - class CreateCompositeFilterTargeting { - - @Test - @DisplayName("entity columns") - void entityColumns() { - QueryFilter[] filters = { - le(TestEntity.Columns.firstField(), "a string value"), - ge(TestEntity.Columns.thirdField(), 42) - }; - checkCreatesInstance(all(filters[0], filters[1]), filters); - } - - @Test - @DisplayName("entity state fields") - void entityFields() { - EntityStateFilter[] filters = { - le(TestEntity.Fields.name().value(), "an entity name"), - ge(TestEntity.Fields.thirdField(), 42) - }; - checkCreatesInstance(all(filters[0], filters[1]), filters); - } - - @Test - @DisplayName("event message and event context fields") - void eventMessageAndContextFields() { - EventFilter[] filters = { - le(ClProjectCreated.Fields.name().value(), "a project name"), - eq(EventContext.Fields.external(), true) - }; - checkCreatesInstance(all(filters[0], filters[1]), filters); - } - - @Test - @DisplayName("custom fields specified through field paths") - void customFields() { - Filter[] filters = { - le("first_custom_field", "a string value"), - ge("second_custom_field", 154) - }; - CompositeFilter compositeFilter = all(filters[0], filters[1]); - assertThat(compositeFilter.getFilterList()).containsExactlyElementsIn(filters); - } - - private void checkCreatesInstance(TypedCompositeFilter filter, - TypedFilter[] groupedFilters) { - CompositeFilter compositeFilter = filter.filter(); - assertThat(compositeFilter.getFilterList()) - .comparingElementsUsing(typedFilterCorrespondence()) + Filter[] groupedFilters) { + assertEquals(operator, filter.getOperator()); + assertThat(filter.getFilterList()) .containsExactlyElementsIn(groupedFilters); } } @@ -316,8 +194,7 @@ class CreateOrderingFilter { @DisplayName("for numbers") void forNumbers() { double number = 3.14; - QueryFilter queryFilter = le(TestEntity.Columns.thirdField(), number); - Filter filter = queryFilter.filter(); + Filter filter = le("third_field", number); assertThat(filter.getOperator()).isEqualTo(LESS_OR_EQUAL); DoubleValue value = unpack(filter.getValue(), DoubleValue.class); @@ -328,8 +205,7 @@ void forNumbers() { @DisplayName("for strings") void forStrings() { String theString = "abc"; - QueryFilter queryFilter = gt(TestEntity.Columns.firstField(), theString); - Filter filter = queryFilter.filter(); + Filter filter = gt("first_field", theString); assertThat(filter.getOperator()).isEqualTo(GREATER_THAN); StringValue value = unpack(filter.getValue(), StringValue.class); @@ -340,9 +216,7 @@ void forStrings() { @DisplayName("for timestamps") void forTimestamps() { Timestamp timestamp = currentTime(); - EntityStateFilter stateFilter = - gt(TestEntity.Fields.owner().whenLastVisited(), timestamp); - Filter filter = stateFilter.filter(); + Filter filter = gt("owner.when_last_visited", timestamp); assertThat(filter.getOperator()).isEqualTo(GREATER_THAN); Timestamp value = unpack(filter.getValue(), Timestamp.class); @@ -387,12 +261,4 @@ void forUnsupportedTypes() { assertThrows(IllegalArgumentException.class, () -> le("invalidField", value)); } } - - private static Correspondence> typedFilterCorrespondence() { - return Correspondence.from(FiltersTest::isFilterEqual, "is wrapped by"); - } - - private static boolean isFilterEqual(Filter filter, TypedFilter wrapper) { - return filter.equals(wrapper.filter()); - } } diff --git a/client/src/test/java/io/spine/client/QueryFilterTest.java b/client/src/test/java/io/spine/client/QueryFilterTest.java new file mode 100644 index 00000000000..99f49a6c700 --- /dev/null +++ b/client/src/test/java/io/spine/client/QueryFilterTest.java @@ -0,0 +1,110 @@ +/* + * Copyright 2020, TeamDev. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.client; + +import com.google.common.testing.NullPointerTester; +import com.google.protobuf.Int32Value; +import io.spine.base.EntityColumn; +import io.spine.base.FieldPath; +import io.spine.protobuf.AnyPacker; +import io.spine.test.client.TestEntity; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.function.BiFunction; + +import static com.google.common.truth.Truth.assertThat; +import static io.spine.client.Filter.Operator.EQUAL; +import static io.spine.client.Filter.Operator.GREATER_OR_EQUAL; +import static io.spine.client.Filter.Operator.GREATER_THAN; +import static io.spine.client.Filter.Operator.LESS_OR_EQUAL; +import static io.spine.client.Filter.Operator.LESS_THAN; +import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS; + +@DisplayName("`QueryFilter` should") +class QueryFilterTest { + + @Test + @DisplayName(NOT_ACCEPT_NULLS) + void passNullToleranceCheck() { + new NullPointerTester() + .setDefault(EntityColumn.class, TestEntity.Columns.firstField()) + .testAllPublicStaticMethods(QueryFilter.class); + } + + @Nested + @DisplayName("create") + class Create { + + @Test + @DisplayName("an `equals` filter") + void eqFilter() { + checkCreates(QueryFilter::eq, EQUAL); + } + + @Test + @DisplayName("a `greater than` filter") + void gtFilter() { + checkCreates(QueryFilter::gt, GREATER_THAN); + } + + @Test + @DisplayName("a `less than` filter") + void ltFilter() { + checkCreates(QueryFilter::lt, LESS_THAN); + } + + @Test + @DisplayName("a `greater than or equals` filter") + void geFilter() { + checkCreates(QueryFilter::ge, GREATER_OR_EQUAL); + } + + @Test + @DisplayName("a `less than or equals` filter") + void leFilter() { + checkCreates(QueryFilter::le, LESS_OR_EQUAL); + } + + private void checkCreates(BiFunction factoryMethod, + Filter.Operator expectedOperator) { + EntityColumn column = TestEntity.Columns.thirdField(); + int value = 42; + QueryFilter queryFilter = factoryMethod.apply(column, value); + Filter filter = queryFilter.filter(); + + FieldPath fieldPath = filter.getFieldPath(); + int nameCount = fieldPath.getFieldNameCount(); + assertThat(nameCount).isEqualTo(1); + + String fieldName = fieldPath.getFieldName(0); + String columnName = column.name() + .value(); + assertThat(fieldName).isEqualTo(columnName); + + assertThat(filter.getOperator()).isEqualTo(expectedOperator); + + Int32Value unpacked = AnyPacker.unpack(filter.getValue(), Int32Value.class); + assertThat(unpacked.getValue()).isEqualTo(value); + } + } +} From c052bcebaf7762ae365459ae225f0aefc74267f0 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 20:50:48 +0200 Subject: [PATCH 28/53] Reformat doc --- .../main/java/io/spine/client/CompositeEventFilter.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/src/main/java/io/spine/client/CompositeEventFilter.java b/client/src/main/java/io/spine/client/CompositeEventFilter.java index c1b805c8cdc..c89a96eeaaf 100644 --- a/client/src/main/java/io/spine/client/CompositeEventFilter.java +++ b/client/src/main/java/io/spine/client/CompositeEventFilter.java @@ -31,7 +31,8 @@ import static io.spine.client.CompositeFilter.CompositeOperator.EITHER; /** - * A composite subscription filter which can aggregate both event message and event context filters. + * A composite subscription filter which can aggregate both event message and event context + * filters. */ public final class CompositeEventFilter extends TypedCompositeFilter { @@ -48,8 +49,8 @@ private CompositeEventFilter(Collection filters, CompositeOperator /** * Creates a new conjunction composite filter. * - *

A record is considered matching this filter if and only if it matches all of the - * passed filters. + *

A record is considered matching this filter if and only if it matches all of the passed + * filters. */ public static CompositeEventFilter all(EventFilter first, EventFilter... rest) { checkNotNull(first); From 26aca4d7fd2c9a1a53ce59495a9721226ec911c9 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 20:55:13 +0200 Subject: [PATCH 29/53] Remove a redundant test case which is already checked --- client/src/test/java/io/spine/client/EventFilterTest.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/client/src/test/java/io/spine/client/EventFilterTest.java b/client/src/test/java/io/spine/client/EventFilterTest.java index 549f287ddfc..72fa1b92a96 100644 --- a/client/src/test/java/io/spine/client/EventFilterTest.java +++ b/client/src/test/java/io/spine/client/EventFilterTest.java @@ -172,10 +172,4 @@ void leFilter() { assertThat(unpacked.getValue()).isEqualTo(value); } } - - @Test - @DisplayName("automatically prepend `context.` to the field path if the filter targets context") - void prependContextPath() { - - } } From 8422fd566c2977e5b74542b9458b3b920f1ed37c Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 21:08:00 +0200 Subject: [PATCH 30/53] Enable generated columns usage in `QueryRequest.orderBy(...)` Also updated the class doc. --- .../java/io/spine/client/QueryRequest.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/client/src/main/java/io/spine/client/QueryRequest.java b/client/src/main/java/io/spine/client/QueryRequest.java index b4f1ba957eb..64b9d94925f 100644 --- a/client/src/main/java/io/spine/client/QueryRequest.java +++ b/client/src/main/java/io/spine/client/QueryRequest.java @@ -21,6 +21,7 @@ package io.spine.client; import com.google.common.collect.ImmutableList; +import io.spine.base.EntityColumn; import io.spine.base.EntityState; import java.util.function.Function; @@ -40,9 +41,9 @@ * .select(Customer.class) * .byId(westCoastCustomerIds()) * .withMask("name", "address", "email") - * .where(eq("type", "permanent"), - * eq("discountPercent", 10), - * eq("companySize", Company.Size.SMALL)) + * .where(eq(Customer.Columns.type(), "permanent"), + * eq(Customer.Columns.discountPercent(), 10), + * eq(Customer.Columns.companySize(), Company.Size.SMALL)) * .orderBy("name", ASCENDING) * .limit(20) * .run(); @@ -80,12 +81,30 @@ public QueryRequest where(CompositeQueryFilter... filter) { * the column to sort by * @param direction * sorting direction + * @deprecated Please use the {@linkplain #orderBy(EntityColumn, OrderBy.Direction) alternative} + * which relies on strongly-typed columns instead. */ + @Deprecated public QueryRequest orderBy(String column, OrderBy.Direction direction) { builder().orderBy(column, direction); return this; } + /** + * Sets the sorting order by the target column and order direction. + * + * @param column + * the column to sort by + * @param direction + * sorting direction + */ + public QueryRequest orderBy(EntityColumn column, OrderBy.Direction direction) { + String columnName = column.name() + .value(); + builder().orderBy(columnName, direction); + return this; + } + /** * Limits the number of results returned by the query. * From 93f9eb64177c91993c4a790f6ba39bb9cfe35500 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 21:08:55 +0200 Subject: [PATCH 31/53] Update outdated doc Also fixed imports in a test. --- .../io/spine/client/EventSubscriptionRequest.java | 12 ++++-------- client/src/main/java/io/spine/client/Filters.java | 4 ++-- .../spine/client/EventSubscriptionRequestTest.java | 4 ++-- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java index cc850fad437..c1263eed3ce 100644 --- a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java +++ b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java @@ -37,21 +37,17 @@ * values of the proto types of subscribed messages: *

{@code
  * clientRequest.subscribeToEvent(MyEventMessage.class)
- *              .where(eq("my_proto_field"), fieldValue)
+ *              .where(eq(MyEventMessage.Fields.myProtoField(), fieldValue))
  *              .observe((event, context) -> {...})
  *              .post();
  * }
* *

In addition to regular filtering conditions, event subscription requests may also reference - * // TODO:2019-12-20:dmytro.kuzmin:WIP: Update the doc here and all similar places. - * fields of {@code "spine.core.EventContext"} using {@code "context."} notation. For example, - * in order to filter events originate from commands of the given user, please use the following - * code: + * fields of {@code spine.core.EventContext}. For example, in order to filter events originate from + * commands of the given user, please use the following code: *

{@code
  * clientRequest.subscribeToEvent(MyEventMessage.class)
- * // TODO:2019-12-20:dmytro.kuzmin:WIP: Update the doc here and all similar places.
- *
- *              .where(eq("context.past_message.actor_context.actor"), userId)
+ *              .where(eq(EventContext.Fields.pastMessage().actorContext().actor(), userId))
  *              .observe((event, context) -> {...})
  *              .post();
  * }
diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index f363f05b512..e79f9466a81 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -317,8 +317,8 @@ private static boolean isSupportedNumber(Class wrapperClass) { * Creates a filter of events which can apply conditions from the passed * {@code CompositeFilter} to both event message and its context. * - * // TODO:2019-12-20:dmytro.kuzmin:WIP: Update the doc here and all similar places. - *

Please use the {@code "context."} prefix for referencing a field of the event context. + *

The filter is deemed addressing the event context if the field path specified in it + * starts with the {@code "context."} prefix. */ @Internal public static Predicate toEventFilter(CompositeFilter filterData) { diff --git a/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java b/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java index 8def71e3163..e159a04869a 100644 --- a/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java +++ b/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java @@ -38,8 +38,8 @@ import org.junit.jupiter.api.Test; import static com.google.common.truth.Truth.assertThat; -import static io.spine.client.Filters.all; -import static io.spine.client.Filters.eq; +import static io.spine.client.CompositeEventFilter.all; +import static io.spine.client.EventFilter.eq; @DisplayName("`EventSubscriptionRequest` should") class EventSubscriptionRequestTest extends AbstractClientTest { From f980f071f913e901c3a330ff5781fc5dee3cd3d7 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 21:29:24 +0200 Subject: [PATCH 32/53] Reword doc --- client/src/main/proto/spine/client/filters.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/main/proto/spine/client/filters.proto b/client/src/main/proto/spine/client/filters.proto index 3d23a593347..da843623b88 100644 --- a/client/src/main/proto/spine/client/filters.proto +++ b/client/src/main/proto/spine/client/filters.proto @@ -105,8 +105,8 @@ message Filter { // The path to the field to be matched. // // If the filter is a query filter, this path should contain only top-level message fields that - // are marked with `(column)`. For subscriptions, any field can be specified including nested - // ones. + // are marked with `(column)` option. For subscriptions, any message field can be specified + // including nested ones. base.FieldPath field_path = 1 [(required) = true]; // The value to compare upon. From 89b1e4d3ea06d0202e21fc8e2cee7f73eb6ace1c Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 21:29:44 +0200 Subject: [PATCH 33/53] Fix old API usage in the doc --- client/src/main/java/io/spine/client/QueryRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/main/java/io/spine/client/QueryRequest.java b/client/src/main/java/io/spine/client/QueryRequest.java index 64b9d94925f..6bca0e30385 100644 --- a/client/src/main/java/io/spine/client/QueryRequest.java +++ b/client/src/main/java/io/spine/client/QueryRequest.java @@ -44,7 +44,7 @@ * .where(eq(Customer.Columns.type(), "permanent"), * eq(Customer.Columns.discountPercent(), 10), * eq(Customer.Columns.companySize(), Company.Size.SMALL)) - * .orderBy("name", ASCENDING) + * .orderBy(Customer.Columns.name(), ASCENDING) * .limit(20) * .run(); * } From bab9e0ed311367ab1e4f32cc28a074dc89e5f015 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 21:29:55 +0200 Subject: [PATCH 34/53] Fix a compilation error in test --- server/src/test/java/io/spine/client/ClientTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server/src/test/java/io/spine/client/ClientTest.java b/server/src/test/java/io/spine/client/ClientTest.java index 62c2d203c7f..cc05135a9c0 100644 --- a/server/src/test/java/io/spine/client/ClientTest.java +++ b/server/src/test/java/io/spine/client/ClientTest.java @@ -38,7 +38,7 @@ import java.util.List; import static com.google.common.truth.Truth.assertThat; -import static io.spine.client.Filters.eq; +import static io.spine.client.EventFilter.eq; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -116,7 +116,8 @@ void createSubscriptions() { Subscription loginStatus = client.onBehalfOf(currentUser) .subscribeTo(LoginStatus.class) - .where(eq(LoginStatus.Fields.userId(), currentUser.getValue())) + .where(EntityStateFilter.eq(LoginStatus.Fields.userId(), + currentUser.getValue())) .observe((s) -> {}) .post(); From b4f0c5e295292335aaecded7c1fcdb8b98f64798 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 21:33:06 +0200 Subject: [PATCH 35/53] Remove redundant configurations of a `NullPointerTester` instance --- client/src/test/java/io/spine/client/FiltersTest.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index 771811dad56..345544fd87b 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -87,13 +87,8 @@ void haveUtilityConstructor() { @Test @DisplayName(NOT_ACCEPT_NULLS) void passNullToleranceCheck() { - new NullPointerTester() .setDefault(Filter.class, Filter.getDefaultInstance()) - .setDefault(EntityColumn.class, TestEntity.Columns.firstField()) - .setDefault(EntityStateField.class, TestEntity.Fields.id()) - .setDefault(EventMessageField.class, ClProjectCreated.Fields.id()) - .setDefault(EventContextField.class, EventContext.Fields.timestamp()) .testAllPublicStaticMethods(Filters.class); } From 91e1c5140e1cb0d11c61f707e55fb2f00f77b3b6 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 21:39:06 +0200 Subject: [PATCH 36/53] Add doc to the new `where(...)` methods Also added notes about deprecation of the old methods. --- .../io/spine/client/EventSubscriptionRequest.java | 12 ++++++++++++ .../main/java/io/spine/client/FilteringRequest.java | 4 ++++ .../src/main/java/io/spine/client/QueryRequest.java | 6 ++++++ .../java/io/spine/client/SubscriptionRequest.java | 6 ++++++ 4 files changed, 28 insertions(+) diff --git a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java index c1263eed3ce..cfe4d754155 100644 --- a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java +++ b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java @@ -65,11 +65,23 @@ public final class EventSubscriptionRequest this.consumers = EventConsumers.newBuilder(); } + /** + * Configures the request to return results matching all the passed filters. + * + *

Please note that the {@link EventFilter} instances may target both event message and + * event context fields. See {@link EventFilter} for details. + */ public EventSubscriptionRequest where(EventFilter... filter) { builder().where(extractFilters(filter)); return self(); } + /** + * Configures the request to return results matching all the passed filters. + * + *

Please note that the {@link CompositeEventFilter} instances may target both event message + * and event context fields. See {@link CompositeEventFilter} for details. + */ public EventSubscriptionRequest where(CompositeEventFilter... filter) { builder().where(extractFilters(filter)); return self(); diff --git a/client/src/main/java/io/spine/client/FilteringRequest.java b/client/src/main/java/io/spine/client/FilteringRequest.java index a087b7e2ec6..29c89693f50 100644 --- a/client/src/main/java/io/spine/client/FilteringRequest.java +++ b/client/src/main/java/io/spine/client/FilteringRequest.java @@ -139,6 +139,8 @@ public B byId(String... ids) { /** * Configures the request to return results matching all the passed filters. + * + * @deprecated Please use the type-specific overloads which rely on strongly-typed filters. */ @Deprecated public B where(Filter... filter) { @@ -148,6 +150,8 @@ public B where(Filter... filter) { /** * Configures the request to return results matching all the passed filters. + * + * @deprecated Please use the type-specific overloads which rely on strongly-typed filters. */ @Deprecated public B where(CompositeFilter... filter) { diff --git a/client/src/main/java/io/spine/client/QueryRequest.java b/client/src/main/java/io/spine/client/QueryRequest.java index 6bca0e30385..dfb9b677e6c 100644 --- a/client/src/main/java/io/spine/client/QueryRequest.java +++ b/client/src/main/java/io/spine/client/QueryRequest.java @@ -64,11 +64,17 @@ public final class QueryRequest super(parent, type); } + /** + * Configures the request to return results matching all the passed filters. + */ public QueryRequest where(QueryFilter... filter) { builder().where(extractFilters(filter)); return this; } + /** + * Configures the request to return results matching all the passed filters. + */ public QueryRequest where(CompositeQueryFilter... filter) { builder().where(extractFilters(filter)); return this; diff --git a/client/src/main/java/io/spine/client/SubscriptionRequest.java b/client/src/main/java/io/spine/client/SubscriptionRequest.java index 835148f2751..1b4acd0610b 100644 --- a/client/src/main/java/io/spine/client/SubscriptionRequest.java +++ b/client/src/main/java/io/spine/client/SubscriptionRequest.java @@ -44,11 +44,17 @@ public final class SubscriptionRequest this.consumers = StateConsumers.newBuilder(); } + /** + * Configures the request to return results matching all the passed filters. + */ public SubscriptionRequest where(EntityStateFilter... filter) { builder().where(extractFilters(filter)); return self(); } + /** + * Configures the request to return results matching all the passed filters. + */ public SubscriptionRequest where(CompositeEntityStateFilter... filter) { builder().where(extractFilters(filter)); return self(); From fd0eed4fcdd5f763debdfd5109d0359f3b4361a8 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 21:40:24 +0200 Subject: [PATCH 37/53] Bump Spine version, update `base` and `time` dependencies --- version.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/version.gradle b/version.gradle index 3acac615ed4..5b72cea23da 100644 --- a/version.gradle +++ b/version.gradle @@ -25,15 +25,15 @@ * as we want to manage the versions in a single source. */ -final def spineVersion = '1.4.4' +final def spineVersion = '1.4.5' ext { // The version of the modules in this project. versionToPublish = spineVersion // Depend on `base` for the general definitions and a model compiler. - spineBaseVersion = '1.4.3' + spineBaseVersion = '1.4.4' // Depend on `time` for `ZoneId`, `ZoneOffset` and other date/time types and utilities. - spineTimeVersion = '1.4.0' + spineTimeVersion = '1.4.1' } From 0db238b922088684fe2c9b511a3ff3102e4224e5 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 22:29:43 +0200 Subject: [PATCH 38/53] Reword doc in `filters.proto` --- client/src/main/proto/spine/client/filters.proto | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/main/proto/spine/client/filters.proto b/client/src/main/proto/spine/client/filters.proto index da843623b88..6ab8796b8a3 100644 --- a/client/src/main/proto/spine/client/filters.proto +++ b/client/src/main/proto/spine/client/filters.proto @@ -104,9 +104,10 @@ message Filter { // The path to the field to be matched. // - // If the filter is a query filter, this path should contain only top-level message fields that - // are marked with `(column)` option. For subscriptions, any message field can be specified + // If the filter is a query filter, this path should contain a top-level message field that + // is marked with the `(column)` option. For subscriptions, any message fields can be specified // including nested ones. + // base.FieldPath field_path = 1 [(required) = true]; // The value to compare upon. From 40096828d52c26668cec891fba950858f2025964 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Tue, 28 Jan 2020 22:30:04 +0200 Subject: [PATCH 39/53] Fix a string literal duplication --- client/src/test/java/io/spine/client/FiltersTest.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/client/src/test/java/io/spine/client/FiltersTest.java b/client/src/test/java/io/spine/client/FiltersTest.java index 345544fd87b..2b191837519 100644 --- a/client/src/test/java/io/spine/client/FiltersTest.java +++ b/client/src/test/java/io/spine/client/FiltersTest.java @@ -24,18 +24,11 @@ import com.google.protobuf.DoubleValue; import com.google.protobuf.StringValue; import com.google.protobuf.Timestamp; -import io.spine.base.EntityColumn; -import io.spine.base.EntityStateField; -import io.spine.base.EventContextField; -import io.spine.base.EventMessageField; import io.spine.base.Field; import io.spine.base.FieldPath; import io.spine.client.Filter.Operator; -import io.spine.core.EventContext; import io.spine.core.Version; import io.spine.core.Versions; -import io.spine.test.client.ClProjectCreated; -import io.spine.test.client.TestEntity; import io.spine.test.client.TestEntityOwner; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -211,7 +204,7 @@ void forStrings() { @DisplayName("for timestamps") void forTimestamps() { Timestamp timestamp = currentTime(); - Filter filter = gt("owner.when_last_visited", timestamp); + Filter filter = gt(FIELD, timestamp); assertThat(filter.getOperator()).isEqualTo(GREATER_THAN); Timestamp value = unpack(filter.getValue(), Timestamp.class); From 6ca1f9b947e734d3832a175e68e41122b9b55403 Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Thu, 6 Feb 2020 20:29:34 +0200 Subject: [PATCH 40/53] Migrate to the new field and column generation config format --- client/src/main/java/io/spine/client/EventFilter.java | 2 +- .../test/java/io/spine/client/EventFilterTest.java | 2 +- core/build.gradle | 7 +++++++ .../main/java/io/spine/core/EventContextField.java | 11 +++++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/io/spine/core/EventContextField.java diff --git a/client/src/main/java/io/spine/client/EventFilter.java b/client/src/main/java/io/spine/client/EventFilter.java index e802848a393..6ce1e49dd75 100644 --- a/client/src/main/java/io/spine/client/EventFilter.java +++ b/client/src/main/java/io/spine/client/EventFilter.java @@ -20,9 +20,9 @@ package io.spine.client; -import io.spine.base.EventContextField; import io.spine.base.EventMessageField; import io.spine.core.Event; +import io.spine.core.EventContextField; import static com.google.common.base.Preconditions.checkNotNull; import static io.spine.client.Filter.Operator.EQUAL; diff --git a/client/src/test/java/io/spine/client/EventFilterTest.java b/client/src/test/java/io/spine/client/EventFilterTest.java index 72fa1b92a96..d0a4018f192 100644 --- a/client/src/test/java/io/spine/client/EventFilterTest.java +++ b/client/src/test/java/io/spine/client/EventFilterTest.java @@ -22,11 +22,11 @@ import com.google.common.testing.NullPointerTester; import com.google.protobuf.StringValue; -import io.spine.base.EventContextField; import io.spine.base.EventMessageField; import io.spine.base.Field; import io.spine.base.FieldPath; import io.spine.core.EventContext; +import io.spine.core.EventContextField; import io.spine.protobuf.AnyPacker; import io.spine.test.client.ClProjectCreated; import org.junit.jupiter.api.DisplayName; diff --git a/core/build.gradle b/core/build.gradle index 146f4f35c3c..a783f46ae27 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -26,5 +26,12 @@ dependencies { testImplementation "io.spine:spine-testutil-time:$spineTimeVersion" } +modelCompiler { + fields { + generateFor "spine.core.Event", markAs("io.spine.base.EntityStateField") + generateFor "spine.core.EventContext", markAs("io.spine.core.EventContextField") + } +} + apply from: deps.scripts.testArtifacts apply from: deps.scripts.publishProto diff --git a/core/src/main/java/io/spine/core/EventContextField.java b/core/src/main/java/io/spine/core/EventContextField.java new file mode 100644 index 00000000000..0fc20e32424 --- /dev/null +++ b/core/src/main/java/io/spine/core/EventContextField.java @@ -0,0 +1,11 @@ +package io.spine.core; + +import io.spine.base.Field; +import io.spine.base.SubscribableField; + +public class EventContextField extends SubscribableField { + + public EventContextField(Field field) { + super(field); + } +} From 5cf3f3e220c99e8e060cddcdd5384c83aee0bc8e Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Fri, 7 Feb 2020 19:44:35 +0200 Subject: [PATCH 41/53] Migrate to singular names of generated column/field containers --- .../src/main/java/io/spine/client/EventFilter.java | 6 +++--- .../java/io/spine/client/EventsAfterCommand.java | 12 ++++++------ .../main/java/io/spine/client/FilteringField.java | 6 +++--- client/src/main/java/io/spine/client/Filters.java | 8 ++++---- .../java/io/spine/client/EntityStateFilterTest.java | 4 ++-- .../test/java/io/spine/client/EventFilterTest.java | 10 +++++----- .../test/java/io/spine/client/QueryFilterTest.java | 4 ++-- server/src/test/java/io/spine/client/ClientTest.java | 6 +++--- .../spine/client/EventSubscriptionRequestTest.java | 8 ++++---- 9 files changed, 32 insertions(+), 32 deletions(-) diff --git a/client/src/main/java/io/spine/client/EventFilter.java b/client/src/main/java/io/spine/client/EventFilter.java index 6ce1e49dd75..716d565001a 100644 --- a/client/src/main/java/io/spine/client/EventFilter.java +++ b/client/src/main/java/io/spine/client/EventFilter.java @@ -252,9 +252,9 @@ public boolean test(Event event) { } private static boolean isContextFilter(Filter filter) { - String contextFieldName = Event.Fields.context() - .getField() - .toString(); + String contextFieldName = Event.Field.context() + .getField() + .toString(); String firstInPath = filter.getFieldPath() .getFieldName(0); boolean result = contextFieldName.equals(firstInPath); diff --git a/client/src/main/java/io/spine/client/EventsAfterCommand.java b/client/src/main/java/io/spine/client/EventsAfterCommand.java index 9ae3e25033d..c3bd68a07ae 100644 --- a/client/src/main/java/io/spine/client/EventsAfterCommand.java +++ b/client/src/main/java/io/spine/client/EventsAfterCommand.java @@ -81,12 +81,12 @@ private ImmutableSet subscribeWith(@Nullable ErrorHandler errorHan * as the origin. */ private ImmutableSet eventsOf(Command c) { - Field pastMessage = EventContext.Fields.pastMessage() - .getField(); - String fieldName = Event.Fields.context() - .getField() - .nested(pastMessage) - .toString(); + Field pastMessage = EventContext.Field.pastMessage() + .getField(); + String fieldName = Event.Field.context() + .getField() + .nested(pastMessage) + .toString(); ImmutableSet> eventTypes = consumers.eventTypes(); TopicFactory topic = client.requestOf(user) .topic(); diff --git a/client/src/main/java/io/spine/client/FilteringField.java b/client/src/main/java/io/spine/client/FilteringField.java index 4335ba9894d..bb5e78afe18 100644 --- a/client/src/main/java/io/spine/client/FilteringField.java +++ b/client/src/main/java/io/spine/client/FilteringField.java @@ -78,9 +78,9 @@ private void checkFieldOfEvent(Descriptor descriptor) { } private boolean refersToContext() { - String contextFieldName = Event.Fields.context() - .getField() - .toString(); + String contextFieldName = Event.Field.context() + .getField() + .toString(); String firstInPath = field.path().getFieldName(0); boolean result = contextFieldName.equals(firstInPath); return result; diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index e79f9466a81..ab22c02e6d0 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -261,10 +261,10 @@ static Filter createFilter(FieldPath path, Object value, Operator operator) { } static Filter createContextFilter(Field field, Object value, Operator operator) { - FieldPath fieldPath = Event.Fields.context() - .getField() - .nested(field) - .path(); + FieldPath fieldPath = Event.Field.context() + .getField() + .nested(field) + .path(); return createFilter(fieldPath, value, operator); } diff --git a/client/src/test/java/io/spine/client/EntityStateFilterTest.java b/client/src/test/java/io/spine/client/EntityStateFilterTest.java index 02eb9b832f4..4666ebc84a0 100644 --- a/client/src/test/java/io/spine/client/EntityStateFilterTest.java +++ b/client/src/test/java/io/spine/client/EntityStateFilterTest.java @@ -47,7 +47,7 @@ class EntityStateFilterTest { @DisplayName(NOT_ACCEPT_NULLS) void passNullToleranceCheck() { new NullPointerTester() - .setDefault(EntityStateField.class, TestEntity.Fields.firstField()) + .setDefault(EntityStateField.class, TestEntity.Field.firstField()) .testAllPublicStaticMethods(EntityStateFilter.class); } @@ -88,7 +88,7 @@ void leFilter() { private void checkCreates(BiFunction factoryMethod, Filter.Operator expectedOperator) { - EntityStateField field = TestEntity.Fields.thirdField(); + EntityStateField field = TestEntity.Field.thirdField(); int value = 42; EntityStateFilter stateFilter = factoryMethod.apply(field, value); Filter filter = stateFilter.filter(); diff --git a/client/src/test/java/io/spine/client/EventFilterTest.java b/client/src/test/java/io/spine/client/EventFilterTest.java index d0a4018f192..428e4185b95 100644 --- a/client/src/test/java/io/spine/client/EventFilterTest.java +++ b/client/src/test/java/io/spine/client/EventFilterTest.java @@ -51,8 +51,8 @@ class EventFilterTest { @DisplayName(NOT_ACCEPT_NULLS) void passNullToleranceCheck() { new NullPointerTester() - .setDefault(EventMessageField.class, ClProjectCreated.Fields.name()) - .setDefault(EventContextField.class, EventContext.Fields.external()) + .setDefault(EventMessageField.class, ClProjectCreated.Field.name()) + .setDefault(EventContextField.class, EventContext.Field.external()) .testAllPublicStaticMethods(EventFilter.class); } @@ -93,7 +93,7 @@ void leFilter() { private void checkCreates(BiFunction factoryMethod, Filter.Operator expectedOperator) { - EventMessageField field = ClProjectCreated.Fields.id(); + EventMessageField field = ClProjectCreated.Field.id(); String value = "some-ID"; EventFilter eventFilter = factoryMethod.apply(field, value); Filter filter = eventFilter.filter(); @@ -151,8 +151,8 @@ void leFilter() { private void checkCreates(BiFunction factoryMethod, Filter.Operator expectedOperator) { - EventContextField field = EventContext.Fields.commandId() - .uuid(); + EventContextField field = EventContext.Field.commandId() + .uuid(); String value = "some-UUID"; EventFilter eventFilter = factoryMethod.apply(field, value); Filter filter = eventFilter.filter(); diff --git a/client/src/test/java/io/spine/client/QueryFilterTest.java b/client/src/test/java/io/spine/client/QueryFilterTest.java index 99f49a6c700..7b8c35a2e9a 100644 --- a/client/src/test/java/io/spine/client/QueryFilterTest.java +++ b/client/src/test/java/io/spine/client/QueryFilterTest.java @@ -47,7 +47,7 @@ class QueryFilterTest { @DisplayName(NOT_ACCEPT_NULLS) void passNullToleranceCheck() { new NullPointerTester() - .setDefault(EntityColumn.class, TestEntity.Columns.firstField()) + .setDefault(EntityColumn.class, TestEntity.Column.firstField()) .testAllPublicStaticMethods(QueryFilter.class); } @@ -87,7 +87,7 @@ void leFilter() { private void checkCreates(BiFunction factoryMethod, Filter.Operator expectedOperator) { - EntityColumn column = TestEntity.Columns.thirdField(); + EntityColumn column = TestEntity.Column.thirdField(); int value = 42; QueryFilter queryFilter = factoryMethod.apply(column, value); Filter filter = queryFilter.filter(); diff --git a/server/src/test/java/io/spine/client/ClientTest.java b/server/src/test/java/io/spine/client/ClientTest.java index cc05135a9c0..269fc1537aa 100644 --- a/server/src/test/java/io/spine/client/ClientTest.java +++ b/server/src/test/java/io/spine/client/ClientTest.java @@ -104,19 +104,19 @@ void createSubscriptions() { Subscription userLoggedIn = client.onBehalfOf(currentUser) .subscribeToEvent(UserLoggedIn.class) - .where(eq(UserLoggedIn.Fields.user(), currentUser)) + .where(eq(UserLoggedIn.Field.user(), currentUser)) .observe((e) -> {}) .post(); Subscription userLoggedOut = client.onBehalfOf(currentUser) .subscribeToEvent(UserLoggedOut.class) - .where(eq(UserLoggedOut.Fields.user(), currentUser)) + .where(eq(UserLoggedOut.Field.user(), currentUser)) .observe((e) -> {}) .post(); Subscription loginStatus = client.onBehalfOf(currentUser) .subscribeTo(LoginStatus.class) - .where(EntityStateFilter.eq(LoginStatus.Fields.userId(), + .where(EntityStateFilter.eq(LoginStatus.Field.userId(), currentUser.getValue())) .observe((s) -> {}) .post(); diff --git a/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java b/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java index e159a04869a..25ca61ea509 100644 --- a/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java +++ b/server/src/test/java/io/spine/client/EventSubscriptionRequestTest.java @@ -101,10 +101,10 @@ void subscribeWithFiltering() { .user(); client().asGuest() .subscribeToEvent(UserLoggedIn.class) - .where(all(eq(UserLoggedIn.Fields.user(), userId), - eq(EventContext.Fields.pastMessage() - .actorContext() - .actor(), guestUser))) + .where(all(eq(UserLoggedIn.Field.user(), userId), + eq(EventContext.Field.pastMessage() + .actorContext() + .actor(), guestUser))) .observe((e, c) -> { rememberedMessage = e; rememberedContext = c; From a6e9c484bf75a02013e577394b77ab3f120585b1 Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sat, 8 Feb 2020 15:05:44 +0200 Subject: [PATCH 42/53] Reword deprecation doc --- client/src/main/java/io/spine/client/FilteringRequest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/src/main/java/io/spine/client/FilteringRequest.java b/client/src/main/java/io/spine/client/FilteringRequest.java index 29c89693f50..e07acd85e03 100644 --- a/client/src/main/java/io/spine/client/FilteringRequest.java +++ b/client/src/main/java/io/spine/client/FilteringRequest.java @@ -140,7 +140,8 @@ public B byId(String... ids) { /** * Configures the request to return results matching all the passed filters. * - * @deprecated Please use the type-specific overloads which rely on strongly-typed filters. + * @deprecated Please use the overloads which reside in descendants and rely on strongly-typed + * filters. */ @Deprecated public B where(Filter... filter) { @@ -151,7 +152,8 @@ public B where(Filter... filter) { /** * Configures the request to return results matching all the passed filters. * - * @deprecated Please use the type-specific overloads which rely on strongly-typed filters. + * @deprecated Please use the overloads which reside in descendants and rely on strongly-typed + * filters. */ @Deprecated public B where(CompositeFilter... filter) { From 40a0fbdbe02d05fa08adf5a954709dda0cd596a8 Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sat, 8 Feb 2020 15:08:43 +0200 Subject: [PATCH 43/53] Fix the outdated generated type names in doc --- .../java/io/spine/client/EventSubscriptionRequest.java | 4 ++-- client/src/main/java/io/spine/client/QueryRequest.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java index cfe4d754155..d5f16b8a3cc 100644 --- a/client/src/main/java/io/spine/client/EventSubscriptionRequest.java +++ b/client/src/main/java/io/spine/client/EventSubscriptionRequest.java @@ -37,7 +37,7 @@ * values of the proto types of subscribed messages: *

{@code
  * clientRequest.subscribeToEvent(MyEventMessage.class)
- *              .where(eq(MyEventMessage.Fields.myProtoField(), fieldValue))
+ *              .where(eq(MyEventMessage.Field.myProtoField(), fieldValue))
  *              .observe((event, context) -> {...})
  *              .post();
  * }
@@ -47,7 +47,7 @@ * commands of the given user, please use the following code: *
{@code
  * clientRequest.subscribeToEvent(MyEventMessage.class)
- *              .where(eq(EventContext.Fields.pastMessage().actorContext().actor(), userId))
+ *              .where(eq(EventContext.Field.pastMessage().actorContext().actor(), userId))
  *              .observe((event, context) -> {...})
  *              .post();
  * }
diff --git a/client/src/main/java/io/spine/client/QueryRequest.java b/client/src/main/java/io/spine/client/QueryRequest.java index dfb9b677e6c..761c51938db 100644 --- a/client/src/main/java/io/spine/client/QueryRequest.java +++ b/client/src/main/java/io/spine/client/QueryRequest.java @@ -41,10 +41,10 @@ * .select(Customer.class) * .byId(westCoastCustomerIds()) * .withMask("name", "address", "email") - * .where(eq(Customer.Columns.type(), "permanent"), - * eq(Customer.Columns.discountPercent(), 10), - * eq(Customer.Columns.companySize(), Company.Size.SMALL)) - * .orderBy(Customer.Columns.name(), ASCENDING) + * .where(eq(Customer.Column.type(), "permanent"), + * eq(Customer.Column.discountPercent(), 10), + * eq(Customer.Column.companySize(), Company.Size.SMALL)) + * .orderBy(Customer.Column.name(), ASCENDING) * .limit(20) * .run(); * } From 60187442c8ef02768900cef746c2f7a6fcdefc08 Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sat, 8 Feb 2020 15:16:00 +0200 Subject: [PATCH 44/53] Add doc to `EventContextField` --- core/src/main/java/io/spine/core/EventContextField.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/main/java/io/spine/core/EventContextField.java b/core/src/main/java/io/spine/core/EventContextField.java index 0fc20e32424..5493f75faae 100644 --- a/core/src/main/java/io/spine/core/EventContextField.java +++ b/core/src/main/java/io/spine/core/EventContextField.java @@ -3,6 +3,13 @@ import io.spine.base.Field; import io.spine.base.SubscribableField; +/** + * A subscribable field of an event context. + * + *

When such field is specified to a subscription filter on creation, the {@code "context."} + * prefix will be automatically appended to the field path, allowing to distinguish between event + * context and event message filters when sending the request to a server side. + */ public class EventContextField extends SubscribableField { public EventContextField(Field field) { From 648779b128d099744ee1147cf50f8e4d3bbaaad3 Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sat, 8 Feb 2020 16:17:07 +0200 Subject: [PATCH 45/53] Document the additional field generation configurations --- core/build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/build.gradle b/core/build.gradle index a783f46ae27..10eb8a86b6e 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -28,7 +28,12 @@ dependencies { modelCompiler { fields { + // Enable the strongly-typed fields generation for `spine.core.Event` as currently it's + // a queryable entity state. generateFor "spine.core.Event", markAs("io.spine.base.EntityStateField") + + // Enable the strongly-typed fields generation for `spine.core.EventContext` to allow + // creation of typed event filters based on context. generateFor "spine.core.EventContext", markAs("io.spine.core.EventContextField") } } From efa7fe8a43acb6177c81327ba66d5078dc728dc6 Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sat, 8 Feb 2020 16:26:47 +0200 Subject: [PATCH 46/53] Reword doc --- core/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/build.gradle b/core/build.gradle index 10eb8a86b6e..48460f21072 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -29,7 +29,7 @@ dependencies { modelCompiler { fields { // Enable the strongly-typed fields generation for `spine.core.Event` as currently it's - // a queryable entity state. + // a subscribable entity state. generateFor "spine.core.Event", markAs("io.spine.base.EntityStateField") // Enable the strongly-typed fields generation for `spine.core.EventContext` to allow From a589a633cb6d22ccfee640627bc1e73c0b37c413 Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sat, 8 Feb 2020 18:22:55 +0200 Subject: [PATCH 47/53] Reword doc --- client/src/main/java/io/spine/client/FilteringRequest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/main/java/io/spine/client/FilteringRequest.java b/client/src/main/java/io/spine/client/FilteringRequest.java index e07acd85e03..ee8ae1d58dd 100644 --- a/client/src/main/java/io/spine/client/FilteringRequest.java +++ b/client/src/main/java/io/spine/client/FilteringRequest.java @@ -140,7 +140,7 @@ public B byId(String... ids) { /** * Configures the request to return results matching all the passed filters. * - * @deprecated Please use the overloads which reside in descendants and rely on strongly-typed + * @deprecated Please use the overloads from the descendants that rely on strongly-typed * filters. */ @Deprecated @@ -152,7 +152,7 @@ public B where(Filter... filter) { /** * Configures the request to return results matching all the passed filters. * - * @deprecated Please use the overloads which reside in descendants and rely on strongly-typed + * @deprecated Please use the overloads from the descendants that rely on strongly-typed * filters. */ @Deprecated From 8542b515019faab8d97873f276fec52ced0eb827 Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sat, 8 Feb 2020 18:24:00 +0200 Subject: [PATCH 48/53] Weaken the param type --- client/src/main/java/io/spine/client/Filters.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/main/java/io/spine/client/Filters.java b/client/src/main/java/io/spine/client/Filters.java index ab22c02e6d0..62bc8fa518a 100644 --- a/client/src/main/java/io/spine/client/Filters.java +++ b/client/src/main/java/io/spine/client/Filters.java @@ -268,7 +268,7 @@ static Filter createContextFilter(Field field, Object value, Operator operator) return createFilter(fieldPath, value, operator); } - static CompositeFilter composeFilters(Collection filters, CompositeOperator operator) { + static CompositeFilter composeFilters(Iterable filters, CompositeOperator operator) { CompositeFilter result = CompositeFilter .newBuilder() .addAllFilter(filters) From a6352a4951f99a93429711e742bce3faf566420b Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sat, 8 Feb 2020 18:32:21 +0200 Subject: [PATCH 49/53] Document a test message type --- client/src/test/proto/spine/test/queries/client_requests.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/test/proto/spine/test/queries/client_requests.proto b/client/src/test/proto/spine/test/queries/client_requests.proto index 0e2a81f29d5..07d27919b79 100644 --- a/client/src/test/proto/spine/test/queries/client_requests.proto +++ b/client/src/test/proto/spine/test/queries/client_requests.proto @@ -68,8 +68,8 @@ message TestEntityName { string value = 1 [(column) = true]; } +// A message-typed field of the `TestEntity` which is used to test operations on nested fields. message TestEntityOwner { - spine.core.UserId id = 1; google.protobuf.Timestamp when_last_visited = 2; From 8953980973efd8013275665092304e4b65d42646 Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sat, 8 Feb 2020 18:34:55 +0200 Subject: [PATCH 50/53] Reword doc --- core/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/build.gradle b/core/build.gradle index 48460f21072..ecf65432b7a 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -33,7 +33,7 @@ modelCompiler { generateFor "spine.core.Event", markAs("io.spine.base.EntityStateField") // Enable the strongly-typed fields generation for `spine.core.EventContext` to allow - // creation of typed event filters based on context. + // creation of typed event filters based on event context. generateFor "spine.core.EventContext", markAs("io.spine.core.EventContextField") } } From 2f0339a52c17675dd005df77dbcd5de8b3252316 Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sat, 8 Feb 2020 18:37:32 +0200 Subject: [PATCH 51/53] Reword doc --- core/src/main/java/io/spine/core/EventContextField.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/io/spine/core/EventContextField.java b/core/src/main/java/io/spine/core/EventContextField.java index 5493f75faae..09a1c1e6793 100644 --- a/core/src/main/java/io/spine/core/EventContextField.java +++ b/core/src/main/java/io/spine/core/EventContextField.java @@ -6,9 +6,9 @@ /** * A subscribable field of an event context. * - *

When such field is specified to a subscription filter on creation, the {@code "context."} - * prefix will be automatically appended to the field path, allowing to distinguish between event - * context and event message filters when sending the request to a server side. + *

When such field is specified to a subscription filter, the {@code "context."} prefix will be + * automatically appended to the field path, allowing to distinguish between event context and + * event message filters when sending the request to a server side. */ public class EventContextField extends SubscribableField { From 894b54e69046b1b66252c93e445da9b5a6057dd6 Mon Sep 17 00:00:00 2001 From: Dima Kuzmin Date: Sat, 8 Feb 2020 18:50:46 +0200 Subject: [PATCH 52/53] Update Spine base version to `1.4.5` --- license-report.md | 112 +++++++++++++++++++++++----------------------- pom.xml | 24 +++++----- version.gradle | 2 +- 3 files changed, 69 insertions(+), 69 deletions(-) diff --git a/license-report.md b/license-report.md index eab9dd599d5..3e7e88091e5 100644 --- a/license-report.md +++ b/license-report.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine:spine-client:1.4.4` +# Dependencies of `io.spine:spine-client:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -47,11 +47,11 @@ * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -183,15 +183,15 @@ * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.3 * **POM Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) @@ -415,12 +415,12 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:33 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Sat Feb 08 18:47:51 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-core:1.4.4` +# Dependencies of `io.spine:spine-core:1.4.5` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -459,11 +459,11 @@ This report was generated on **Thu Jan 23 17:10:33 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -559,15 +559,15 @@ This report was generated on **Thu Jan 23 17:10:33 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.3 * **POM Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) @@ -791,12 +791,12 @@ This report was generated on **Thu Jan 23 17:10:33 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Sat Feb 08 18:47:57 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-model-assembler:1.4.4` +# Dependencies of `io.spine.tools:spine-model-assembler:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -843,11 +843,11 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -979,15 +979,15 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.3 * **POM Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) @@ -1206,12 +1206,12 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Sat Feb 08 18:48:03 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-model-verifier:1.4.4` +# Dependencies of `io.spine.tools:spine-model-verifier:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -1266,11 +1266,11 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/protobuf-gradle-plugin](https://github.com/google/protobuf-gradle-plugin) * **POM License: BSD 3-Clause** - [http://opensource.org/licenses/BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -1430,15 +1430,15 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/protobuf-gradle-plugin](https://github.com/google/protobuf-gradle-plugin) * **POM License: BSD 3-Clause** - [http://opensource.org/licenses/BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.3 * **POM Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) @@ -1681,12 +1681,12 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Sat Feb 08 18:48:11 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-server:1.4.4` +# Dependencies of `io.spine:spine-server:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -1733,11 +1733,11 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -1877,15 +1877,15 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.3 * **POM Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) @@ -2113,12 +2113,12 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:35 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Sat Feb 08 18:48:18 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-testutil-client:1.4.4` +# Dependencies of `io.spine:spine-testutil-client:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -2171,11 +2171,11 @@ This report was generated on **Thu Jan 23 17:10:35 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -2359,15 +2359,15 @@ This report was generated on **Thu Jan 23 17:10:35 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.3 * **POM Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) @@ -2586,12 +2586,12 @@ This report was generated on **Thu Jan 23 17:10:35 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:37 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Sat Feb 08 18:48:29 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-testutil-core:1.4.4` +# Dependencies of `io.spine:spine-testutil-core:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -2644,11 +2644,11 @@ This report was generated on **Thu Jan 23 17:10:37 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -2840,15 +2840,15 @@ This report was generated on **Thu Jan 23 17:10:37 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.3 * **POM Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) @@ -3067,12 +3067,12 @@ This report was generated on **Thu Jan 23 17:10:37 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:38 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Sat Feb 08 18:48:38 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-testutil-server:1.4.4` +# Dependencies of `io.spine:spine-testutil-server:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -3125,11 +3125,11 @@ This report was generated on **Thu Jan 23 17:10:38 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -3313,15 +3313,15 @@ This report was generated on **Thu Jan 23 17:10:38 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protoc **Version:** 3.11.3 * **POM Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) @@ -3584,4 +3584,4 @@ This report was generated on **Thu Jan 23 17:10:38 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:41 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file +This report was generated on **Sat Feb 08 18:48:51 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/pom.xml b/pom.xml index 427278181c6..553fc5ecb94 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ all modules and does not describe the project structure per-subproject. io.spine spine-core-java -1.4.4 +1.4.5 2015 @@ -70,25 +70,25 @@ all modules and does not describe the project structure per-subproject. io.spine spine-base - 1.4.3 + 1.4.5 compile io.spine spine-time - 1.4.0 + 1.4.1 compile io.spine.tools spine-model-compiler - 1.4.3 + 1.4.5 compile io.spine.tools spine-plugin-base - 1.4.3 + 1.4.5 compile @@ -130,25 +130,25 @@ all modules and does not describe the project structure per-subproject. io.spine spine-testlib - 1.4.3 + 1.4.5 test io.spine spine-testutil-time - 1.4.0 + 1.4.1 test io.spine.tools spine-mute-logging - 1.4.3 + 1.4.5 test io.spine.tools spine-plugin-testlib - 1.4.3 + 1.4.5 test @@ -200,7 +200,7 @@ all modules and does not describe the project structure per-subproject. com.google.protobuf protoc - 3.11.1 + 3.11.3 io.grpc @@ -210,12 +210,12 @@ all modules and does not describe the project structure per-subproject. io.spine.tools spine-javadoc-filter - 1.4.3 + 1.4.5 io.spine.tools spine-protoc-plugin - 1.4.3 + 1.4.5 net.sourceforge.pmd diff --git a/version.gradle b/version.gradle index 5b72cea23da..34584f4ebdc 100644 --- a/version.gradle +++ b/version.gradle @@ -32,7 +32,7 @@ ext { versionToPublish = spineVersion // Depend on `base` for the general definitions and a model compiler. - spineBaseVersion = '1.4.4' + spineBaseVersion = spineVersion // Depend on `time` for `ZoneId`, `ZoneOffset` and other date/time types and utilities. spineTimeVersion = '1.4.1' From 2ff741454bd380ff48447781fb9137de5f78fa6c Mon Sep 17 00:00:00 2001 From: dmitrykuzmin Date: Fri, 14 Feb 2020 14:09:04 +0200 Subject: [PATCH 53/53] Update to the latest `config` --- config | 2 +- license-report.md | 96 +++++++++++++++++++++++------------------------ pom.xml | 22 +++++------ 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/config b/config index 6c2bf59a626..2f239bb2534 160000 --- a/config +++ b/config @@ -1 +1 @@ -Subproject commit 6c2bf59a6260d7fbe1e15e4a5d8a49af24195992 +Subproject commit 2f239bb25349e117902a8a0d0b1df57d2a7d48f9 diff --git a/license-report.md b/license-report.md index eab9dd599d5..d0c369f13f6 100644 --- a/license-report.md +++ b/license-report.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine:spine-client:1.4.4` +# Dependencies of `io.spine:spine-client:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -47,11 +47,11 @@ * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -183,11 +183,11 @@ * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -415,12 +415,12 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:33 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Feb 14 14:07:03 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-core:1.4.4` +# Dependencies of `io.spine:spine-core:1.4.5` ## Runtime 1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2 @@ -459,11 +459,11 @@ This report was generated on **Thu Jan 23 17:10:33 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -559,11 +559,11 @@ This report was generated on **Thu Jan 23 17:10:33 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -791,12 +791,12 @@ This report was generated on **Thu Jan 23 17:10:33 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Feb 14 14:07:04 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-model-assembler:1.4.4` +# Dependencies of `io.spine.tools:spine-model-assembler:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -843,11 +843,11 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -979,11 +979,11 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -1206,12 +1206,12 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Feb 14 14:07:05 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:spine-model-verifier:1.4.4` +# Dependencies of `io.spine.tools:spine-model-verifier:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -1266,11 +1266,11 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/protobuf-gradle-plugin](https://github.com/google/protobuf-gradle-plugin) * **POM License: BSD 3-Clause** - [http://opensource.org/licenses/BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -1430,11 +1430,11 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/protobuf-gradle-plugin](https://github.com/google/protobuf-gradle-plugin) * **POM License: BSD 3-Clause** - [http://opensource.org/licenses/BSD-3-Clause](http://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -1681,12 +1681,12 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Feb 14 14:07:06 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-server:1.4.4` +# Dependencies of `io.spine:spine-server:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -1733,11 +1733,11 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -1877,11 +1877,11 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -2113,12 +2113,12 @@ This report was generated on **Thu Jan 23 17:10:34 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:35 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Feb 14 14:07:07 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-testutil-client:1.4.4` +# Dependencies of `io.spine:spine-testutil-client:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -2171,11 +2171,11 @@ This report was generated on **Thu Jan 23 17:10:35 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -2359,11 +2359,11 @@ This report was generated on **Thu Jan 23 17:10:35 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -2586,12 +2586,12 @@ This report was generated on **Thu Jan 23 17:10:35 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:37 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Feb 14 14:07:10 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-testutil-core:1.4.4` +# Dependencies of `io.spine:spine-testutil-core:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -2644,11 +2644,11 @@ This report was generated on **Thu Jan 23 17:10:37 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -2840,11 +2840,11 @@ This report was generated on **Thu Jan 23 17:10:37 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -3067,12 +3067,12 @@ This report was generated on **Thu Jan 23 17:10:37 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:38 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Fri Feb 14 14:07:11 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:spine-testutil-server:1.4.4` +# Dependencies of `io.spine:spine-testutil-server:1.4.5` ## Runtime 1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4 @@ -3125,11 +3125,11 @@ This report was generated on **Thu Jan 23 17:10:38 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -3313,11 +3313,11 @@ This report was generated on **Thu Jan 23 17:10:38 EET 2020** using [Gradle-Lice * **POM Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/) * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt) -1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) -1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.1 +1. **Group:** com.google.protobuf **Name:** protobuf-java-util **Version:** 3.11.3 * **Manifest Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/) * **POM License: 3-Clause BSD License** - [https://opensource.org/licenses/BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause) @@ -3584,4 +3584,4 @@ This report was generated on **Thu Jan 23 17:10:38 EET 2020** using [Gradle-Lice The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Jan 23 17:10:41 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file +This report was generated on **Fri Feb 14 14:07:15 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/pom.xml b/pom.xml index 427278181c6..032e9e3e3ca 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ all modules and does not describe the project structure per-subproject. io.spine spine-core-java -1.4.4 +1.4.5 2015 @@ -70,25 +70,25 @@ all modules and does not describe the project structure per-subproject. io.spine spine-base - 1.4.3 + 1.4.4 compile io.spine spine-time - 1.4.0 + 1.4.1 compile io.spine.tools spine-model-compiler - 1.4.3 + 1.4.4 compile io.spine.tools spine-plugin-base - 1.4.3 + 1.4.4 compile @@ -130,25 +130,25 @@ all modules and does not describe the project structure per-subproject. io.spine spine-testlib - 1.4.3 + 1.4.4 test io.spine spine-testutil-time - 1.4.0 + 1.4.1 test io.spine.tools spine-mute-logging - 1.4.3 + 1.4.4 test io.spine.tools spine-plugin-testlib - 1.4.3 + 1.4.4 test @@ -210,12 +210,12 @@ all modules and does not describe the project structure per-subproject. io.spine.tools spine-javadoc-filter - 1.4.3 + 1.4.4 io.spine.tools spine-protoc-plugin - 1.4.3 + 1.4.4 net.sourceforge.pmd