Skip to content

Commit a55eeba

Browse files
committed
Reuse existing Operator enum
1 parent cd19343 commit a55eeba

File tree

8 files changed

+106
-67
lines changed

8 files changed

+106
-67
lines changed

api/src/main/java/jakarta/data/Limit.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
*
3535
* <pre>
3636
* &#64;Find
37-
* Product[] named(&#64;By(_Product.NAME) &#64;Is(LIKE_ANY_CASE) String namePattern,
37+
* Product[] named(&#64;By(_Product.NAME) &#64;Is(LIKE) &#64;IgnoreCase String namePattern,
3838
* Limit limit,
3939
* Sort&lt;Product&gt;... sorts);
4040
*

api/src/main/java/jakarta/data/metamodel/restrict/Operator.java

+22-1
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,23 @@ public enum Operator {
2727
LIKE,
2828
NOT_EQUAL,
2929
NOT_IN,
30-
NOT_LIKE;
30+
NOT_LIKE,
31+
NOT_PREFIXED,
32+
NOT_SUBSTRINGED,
33+
NOT_SUFFIXED,
34+
PREFIXED,
35+
SUBSTRINGED,
36+
SUFFIXED;
3137

3238
/**
3339
* Representation of the operator as it appears in query language.
3440
* For example, {@link #GREATER_THAN} is represented as {@code >}
3541
* in query langugae.
3642
*
3743
* @return the representation of the operator in query language.
44+
* For operators that have a more complex representation in
45+
* query language, this method returns the {@link #name()}
46+
* of the operator.
3847
*/
3948
String asQueryLanguage() {
4049
return switch (this) {
@@ -48,6 +57,12 @@ String asQueryLanguage() {
4857
case NOT_EQUAL -> "<>";
4958
case NOT_IN -> "NOT IN";
5059
case NOT_LIKE -> "NOT LIKE";
60+
case NOT_PREFIXED -> NOT_PREFIXED.name();
61+
case NOT_SUBSTRINGED -> NOT_SUBSTRINGED.name();
62+
case NOT_SUFFIXED -> NOT_SUFFIXED.name();
63+
case PREFIXED -> PREFIXED.name();
64+
case SUBSTRINGED -> SUBSTRINGED.name();
65+
case SUFFIXED -> SUFFIXED.name();
5166
};
5267
}
5368

@@ -68,6 +83,12 @@ Operator negate() {
6883
case NOT_EQUAL -> EQUAL;
6984
case NOT_IN -> IN;
7085
case NOT_LIKE -> LIKE;
86+
case NOT_PREFIXED -> PREFIXED;
87+
case NOT_SUBSTRINGED -> SUBSTRINGED;
88+
case NOT_SUFFIXED -> SUFFIXED;
89+
case PREFIXED -> NOT_PREFIXED;
90+
case SUBSTRINGED -> NOT_SUBSTRINGED;
91+
case SUFFIXED -> NOT_SUFFIXED;
7192
};
7293
}
7394
}

api/src/main/java/jakarta/data/page/PageRequest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
* &#64;Find
4141
* &#64;OrderBy("age")
4242
* &#64;OrderBy("ssn")
43-
* Person[] agedBetween(&#64;By("age") &#64;Is(GREATER_THAN_EQ) int minAge,
44-
* &#64;By("age") &#64;Is(LESS_THAN_EQ) int maxAge,
43+
* Person[] agedBetween(&#64;By("age") &#64;Is(GREATER_THAN_EQUAL) int minAge,
44+
* &#64;By("age") &#64;Is(LESS_THAN_EQUAL) int maxAge,
4545
* PageRequest pageRequest);
4646
* </pre>
4747
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2024,2025 Contributors to the Eclipse Foundation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
*/
18+
package jakarta.data.repository;
19+
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
import jakarta.data.metamodel.restrict.Operator;
26+
27+
/**
28+
* <p>Annotates a parameter of a repository {@link Find} or {@link Delete} method,
29+
* indicating that a persistent field should be compared ignoring case.
30+
* The {@link By} annotation can be used on the same parameter to identify the
31+
* persistent field. Otherwise, if the {@code -parameters} compile option is
32+
* enabled, the the persistent field is inferred by matching the name of the
33+
* method parameter. The {@link Operator#EQUAL EQUAL} comparison is assumed
34+
* unless the {@link Is} annotation is used on the same parameter to choose a
35+
* different type of comparison.</p>
36+
*
37+
* <p>For example,</p>
38+
*
39+
* <pre>
40+
* &#64;Repository
41+
* public interface People extends BasicRepository&lt;Person, Long&gt; {
42+
*
43+
* // Find all Person entities where the lastName matches the respective value
44+
* // ignoring case.
45+
* &#64;Find
46+
* List&lt;Person&gt; withSurname(&#64;By(_Person.LASTNAME) &#64;IgnoreCase String surname);
47+
*
48+
* // Find a page of Person entities where the lastName field begins with the
49+
* // supplied prefix, ignoring case.
50+
* &#64;Find
51+
* Page&lt;Person&gt; withSurnamePrefix(&#64;By(_Product.LASTNAME) &#64;Is(PREFIXED) &#64;IgnoreCase String prefix,
52+
* PageRequest pagination,
53+
* Order&lt;Person&gt; order);
54+
* }
55+
* </pre>
56+
*/
57+
@Retention(RetentionPolicy.RUNTIME)
58+
@Target(ElementType.PARAMETER)
59+
public @interface IgnoreCase {
60+
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024 Contributors to the Eclipse Foundation
2+
* Copyright (c) 2024,2025 Contributors to the Eclipse Foundation
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,6 +22,8 @@
2222
import java.lang.annotation.RetentionPolicy;
2323
import java.lang.annotation.Target;
2424

25+
import jakarta.data.metamodel.restrict.Operator;
26+
2527
/**
2628
* <p>Annotates a parameter of a repository {@link Find} or {@link Delete} method,
2729
* indicating how a persistent field is compared against the parameter's value.
@@ -42,7 +44,7 @@
4244
*
4345
* // Find a page of Product entities where the name field matches a pattern, ignoring case.
4446
* &#64;Find
45-
* Page&lt;Product&gt; search(&#64;By(_Product.NAME) &#64;Is(LIKE_ANY_CASE) String pattern,
47+
* Page&lt;Product&gt; search(&#64;By(_Product.NAME) &#64;Is(LIKE) &#64;IgnoreCase String pattern,
4648
* PageRequest pagination,
4749
* Order&lt;Product&gt; order);
4850
*
@@ -67,65 +69,21 @@
6769
* <pre>
6870
* &#64;Find
6971
* &#64;OrderBy(_Person.YEAR_BORN)
70-
* List&lt;Person&gt; bornWithin(&#64;By(_Person.YEAR_BORN) &#64;Is(GREATER_THAN_EQ) float minYear,
71-
* &#64;By(_Person.YEAR_BORN) &#64;Is(LESS_THAN_EQ) float maxYear);
72+
* List&lt;Person&gt; bornWithin(&#64;By(_Person.YEAR_BORN) &#64;Is(GREATER_THAN_EQUAL) float minYear,
73+
* &#64;By(_Person.YEAR_BORN) &#64;Is(LESS_THAN_EQUAL) float maxYear);
7274
* </pre>
7375
*
74-
* <p>The default comparison operation is the {@linkplain #EQUAL equality}
76+
* <p>The default comparison operation is the {@linkplain Operator#EQUAL equality}
7577
* comparison.</p>
7678
*
7779
* <p>For concise code, it can be convenient for a repository interface to
7880
* statically import one or more constants from this class. For example:</p>
7981
*
8082
* <pre>
81-
* import static jakarta.data.repository.Is.Op.*;
83+
* import static jakarta.data.metamodel.restrict.Operator.*;
8284
* </pre>
8385
*
8486
* @return the type of comparison operation.
8587
*/
86-
Op value() default Op.EQUAL;
87-
88-
/**
89-
* <p>Comparison operations for the {@link Is} annotation.</p>
90-
*
91-
* <p>For more concise code, it can be convenient to statically import one
92-
* or more comparison operations. For example:</p>
93-
*
94-
* <pre>
95-
* import static jakarta.data.repository.Is.Op.*;
96-
* </pre>
97-
*/
98-
public static enum Op {
99-
// TODO add JavaDoc with examples to these
100-
ANY_CASE,
101-
EQUAL,
102-
GREATER_THAN,
103-
GREATER_THAN_ANY_CASE,
104-
GREATER_THAN_EQ,
105-
GREATER_THAN_EQ_ANY_CASE,
106-
IN,
107-
LESS_THAN,
108-
LESS_THAN_ANY_CASE,
109-
LESS_THAN_EQ,
110-
LESS_THAN_EQ_ANY_CASE,
111-
LIKE,
112-
LIKE_ANY_CASE,
113-
PREFIXED,
114-
PREFIXED_ANY_CASE,
115-
SUBSTRINGED,
116-
SUBSTRINGED_ANY_CASE,
117-
SUFFIXED,
118-
SUFFIXED_ANY_CASE,
119-
NOT,
120-
NOT_ANY_CASE,
121-
NOT_IN,
122-
NOT_LIKE,
123-
NOT_LIKE_ANY_CASE,
124-
NOT_PREFIXED,
125-
NOT_PREFIXED_ANY_CASE,
126-
NOT_SUBSTRINGED,
127-
NOT_SUBSTRINGED_ANY_CASE,
128-
NOT_SUFFIXED,
129-
NOT_SUFFIXED_ANY_CASE;
130-
}
88+
Operator value() default Operator.EQUAL;
13189
}

api/src/main/java/jakarta/data/repository/OrderBy.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@
118118
* <pre>
119119
* &#64;Find
120120
* &#64;OrderBy("age")
121-
* Stream&lt;Person&gt; withLastName(&#64;By("lastName") &#64;Is(ANY_CASE) String surname);
121+
* Stream&lt;Person&gt; withLastName(&#64;By("lastName") &#64;IgnoreCase String surname);
122122
* </pre>
123123
*
124124
* @return entity attribute name.

api/src/main/java/jakarta/data/repository/Repository.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
*
4040
* &#64;Find
4141
* &#64;OrderBy("price")
42-
* List&lt;Product&gt; named(&#64;By("name") &#64;Is(LIKE_ANY_CASE) String namePattern);
42+
* List&lt;Product&gt; named(&#64;By("name") &#64;Is(LIKE) &#64;IgnoreCase String namePattern);
4343
*
4444
* &#64;Query("UPDATE Product SET price = price - (price * ?1) WHERE price * ?1 &lt;= ?2")
4545
* int putOnSale(float rateOfDiscount, float maxDiscount);

api/src/main/java/module-info.java

+10-10
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@
7474
* &#64;Find
7575
* &#64;OrderBy("price")
7676
* List&lt;Product&gt; search(
77-
* &#64;By("name") &#64;Is(LIKE_ANY_CASE) String namePattern,
78-
* &#64;By("price") &#64;Is(lESS_THAN_EQ) float max);
77+
* &#64;By("name") &#64;Is(LIKE) &#64;IgnoreCase String namePattern,
78+
* &#64;By("price") &#64;Is(lESS_THAN_EQUAL) float max);
7979
*
8080
* &#64;Query("UPDATE Product SET price = price * (1.0 - ?1) WHERE yearProduced &lt;= ?2")
8181
* int discountOldInventory(float rateOfDiscount, int maxYear);
@@ -767,8 +767,8 @@
767767
* &#64;Find
768768
* Vehicle[] search(String make,
769769
* String model,
770-
* &#64;By(_Vehicle.YEAR) &#64;Is(GREATER_THAN_EQ) int minYear,
771-
* &#64;By(_Vehicle.YEAR) &#64;Is(LESS_THAN_EQ) int maxYear,
770+
* &#64;By(_Vehicle.YEAR) &#64;Is(GREATER_THAN_EQUAL) int minYear,
771+
* &#64;By(_Vehicle.YEAR) &#64;Is(LESS_THAN_EQUAL) int maxYear,
772772
* Sort&lt;?&gt;... sorts);
773773
* </pre>
774774
*
@@ -810,7 +810,7 @@
810810
* &#64;Find
811811
* &#64;OrderBy(value = _Product.AMOUNT_SOLD, descending = true)
812812
* &#64;OrderBy(ID)
813-
* Product[] named(&#64;By(_Product.NAME) &#64;Is(LIKE_ANY_CASE) String pattern,
813+
* Product[] named(&#64;By(_Product.NAME) &#64;Is(LIKE) &#64;IgnoreCase String pattern,
814814
* PageRequest pageRequest);
815815
* ...
816816
* page1 = products.named("%phone%", PageRequest.ofSize(20));
@@ -828,9 +828,9 @@
828828
*
829829
* <pre>
830830
* &#64;Find
831-
* Product[] search(&#64;By("name") &#64;Is(LIKE_ANY_CASE) String pattern,
832-
* &#64;By("price") &#64;Is(GREATER_THAN_EQ) float minPrice,
833-
* &#64;By("price") &#64;Is(LESS_THAN_EQ) float maxPrice,
831+
* Product[] search(&#64;By("name") &#64;Is(LIKE) &#64;IgnoreCase String pattern,
832+
* &#64;By("price") &#64;Is(GREATER_THAN_EQUAL) float minPrice,
833+
* &#64;By("price") &#64;Is(LESS_THAN_EQUAL) float maxPrice,
834834
* PageRequest pageRequest,
835835
* Order&lt;Product&gt; order);
836836
*
@@ -848,7 +848,7 @@
848848
*
849849
* <pre>
850850
* &#64;Find
851-
* Product[] named(&#64;By("name") &#64;Is(LIKE_ANY_CASE) String pattern,
851+
* Product[] named(&#64;By("name") &#64;Is(LIKE) &#64;IgnoreCase String pattern,
852852
* Limit max,
853853
* Order&lt;Product&gt; sortBy);
854854
*
@@ -866,7 +866,7 @@
866866
*
867867
* <pre>
868868
* &#64;Find
869-
* Product[] named(&#64;By("name") &#64;Is(LIKE_ANY_CASE) String pattern,
869+
* Product[] named(&#64;By("name") &#64;Is(LIKE) &#64;IgnoreCase String pattern,
870870
* Limit max,
871871
* {@code Sort<?>...} sortBy);
872872
*

0 commit comments

Comments
 (0)