Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue jakartaee#829 dynamic query restrictions
Browse files Browse the repository at this point in the history
Signed-off-by: Nathan Rauh <[email protected]>
njr-11 committed Nov 6, 2024
1 parent a164aa7 commit 920050d
Showing 8 changed files with 370 additions and 4 deletions.
14 changes: 14 additions & 0 deletions api/src/main/java/jakarta/data/metamodel/Attribute.java
Original file line number Diff line number Diff line change
@@ -17,6 +17,8 @@
*/
package jakarta.data.metamodel;

import java.util.Set;

import jakarta.data.Sort;

/**
@@ -25,11 +27,23 @@
* @param <T> entity class of the static metamodel.
*/
public interface Attribute<T> {
<V> Restriction.Single<T, V> equal(V value);

<V> Restriction.Single<T, Set<V>> in(@SuppressWarnings("unchecked") V... values);

Restriction.Single<T, Object> isNull();

/**
* Obtain the entity attribute name, suitable for use wherever the specification requires
* an entity attribute name. For example, as the parameter to {@link Sort#asc(String)}.
*
* @return the entity attribute name.
*/
String name();

<V> Restriction.Single<T, V> not(V value);

<V> Restriction.Single<T, Set<V>> notIn(@SuppressWarnings("unchecked") V... values);

Restriction.Single<T, Object> notNull();
}
35 changes: 35 additions & 0 deletions api/src/main/java/jakarta/data/metamodel/Restrict.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package jakarta.data.metamodel;

import java.util.List;

public enum Restrict {
All,
Any;

@SafeVarargs
static <T> Restriction<T> all(Restriction<T>... restrictions) {
return new Restriction.Multiple<>(All, List.of(restrictions));
}

@SafeVarargs
static <T> Restriction<T> any(Restriction<T>... restrictions) {
return new Restriction.Multiple<>(Any, List.of(restrictions));
}
}
40 changes: 40 additions & 0 deletions api/src/main/java/jakarta/data/metamodel/Restriction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package jakarta.data.metamodel;

import java.util.List;

import jakarta.data.repository.Is;

public interface Restriction<T> {
record Multiple<T>(
Restrict type,
List<Restriction<T>> list) implements Restriction<T> {
}

// TODO it was quicker to write this by sharing the Op enumeration from the Is
// annotation, so I temporarily did that, but we might decide it's better to
// keep these things separate
record Single<T, V>(
String name,
Is.Op comparison,
V value) implements Restriction<T> {
}

// TODO Need to think more about how to best cover not/negation
}
Original file line number Diff line number Diff line change
@@ -49,4 +49,11 @@ public interface SortableAttribute<T> extends Attribute<T> {
*/
Sort<T> desc();

<V> Restriction.Single<T, V> greaterThan(V value);

<V> Restriction.Single<T, V> greaterThanEqual(V value);

<V> Restriction.Single<T, V> lessThan(V value);

<V> Restriction.Single<T, V> lessThanEqual(V value);
}
36 changes: 36 additions & 0 deletions api/src/main/java/jakarta/data/metamodel/TextAttribute.java
Original file line number Diff line number Diff line change
@@ -33,11 +33,47 @@ public interface TextAttribute<T> extends SortableAttribute<T> {
*/
Sort<T> ascIgnoreCase();

Restriction.Single<T, String> contains(String pattern);

Restriction.Single<T, String> containsIgnoreCase(String pattern);

/**
* Obtain a request for a descending, case insensitive {@link Sort} based on the entity attribute.
*
* @return a request for a descending, case insensitive sort on the entity attribute.
*/
Sort<T> descIgnoreCase();

Restriction.Single<T, String> endsWith(String pattern);

Restriction.Single<T, String> endsWithIgnoreCase(String pattern);

Restriction.Single<T, String> equalIgnoreCase(String value);

Restriction.Single<T, String> like(String pattern);

Restriction.Single<T, String> likeIgnoreCase(String pattern);

Restriction.Single<T, String> notContains(String pattern);

Restriction.Single<T, String> notContainsIgnoreCase(String pattern);

Restriction.Single<T, String> notEndsWith(String pattern);

Restriction.Single<T, String> notEndsWithIgnoreCase(String pattern);

Restriction.Single<T, String> notIgnoreCase(String value);

Restriction.Single<T, String> notLike(String pattern);

Restriction.Single<T, String> notLikeIgnoreCase(String pattern);

Restriction.Single<T, String> notStartsWith(String pattern);

Restriction.Single<T, String> notStartsWithIgnoreCase(String pattern);

Restriction.Single<T, String> startsWith(String pattern);

Restriction.Single<T, String> startsWithIgnoreCase(String pattern);

}
35 changes: 35 additions & 0 deletions api/src/main/java/jakarta/data/metamodel/impl/AttributeRecord.java
Original file line number Diff line number Diff line change
@@ -17,7 +17,11 @@
*/
package jakarta.data.metamodel.impl;

import java.util.Set;

import jakarta.data.repository.Is;
import jakarta.data.metamodel.Attribute;
import jakarta.data.metamodel.Restriction;

/**
* Record type implementing {@link jakarta.data.metamodel.TextAttribute}.
@@ -28,5 +32,36 @@
*/
public record AttributeRecord<T>(String name)
implements Attribute<T> {

@Override
public <V> Restriction.Single<T, V> equal(V value) {
return new Restriction.Single<>(name, Is.Op.Equal, value);
}

@Override
public <V> Restriction.Single<T, Set<V>> in(@SuppressWarnings("unchecked") V... values) {
Set.of(values);

This comment has been minimized.

Copy link
@pipinet

pipinet Nov 6, 2024

It's redundant,remove it.

This comment has been minimized.

Copy link
@njr-11

njr-11 Nov 6, 2024

Author Owner

Thanks for spotting that. I removed the redundant line.

return new Restriction.Single<>(name, Is.Op.In, Set.of(values));
}

@Override
public Restriction.Single<T, Object> isNull() {
return new Restriction.Single<>(name, Is.Op.Equal, null);
}

@Override
public <V> Restriction.Single<T, V> not(V value) {
return new Restriction.Single<>(name, Is.Op.Not, value);
}

@Override
public <V> Restriction.Single<T, Set<V>> notIn(@SuppressWarnings("unchecked") V... values) {
return new Restriction.Single<>(name, Is.Op.NotIn, Set.of(values));
}

@Override
public Restriction.Single<T, Object> notNull() {
return new Restriction.Single<>(name, Is.Op.Not, null);
}
}

Original file line number Diff line number Diff line change
@@ -17,7 +17,11 @@
*/
package jakarta.data.metamodel.impl;

import java.util.Set;

import jakarta.data.repository.Is;
import jakarta.data.Sort;
import jakarta.data.metamodel.Restriction;
import jakarta.data.metamodel.SortableAttribute;

/**
@@ -37,5 +41,56 @@ public Sort<T> asc() {
public Sort<T> desc() {
return Sort.desc(name);
}

@Override
public <V> Restriction.Single<T, V> equal(V value) {
return new Restriction.Single<>(name, Is.Op.Equal, value);
}

@Override
public <V> Restriction.Single<T, V> greaterThan(V value) {
return new Restriction.Single<>(name, Is.Op.GreaterThan, value);
}

@Override
public <V> Restriction.Single<T, V> greaterThanEqual(V value) {
return new Restriction.Single<>(name, Is.Op.GreaterThanEqual, value);
}

@Override
public <V> Restriction.Single<T, Set<V>> in(@SuppressWarnings("unchecked") V... values) {
Set.of(values);

This comment has been minimized.

Copy link
@pipinet

pipinet Nov 6, 2024

It's redundant,remove it.

return new Restriction.Single<>(name, Is.Op.In, Set.of(values));
}

@Override
public Restriction.Single<T, Object> isNull() {
return new Restriction.Single<>(name, Is.Op.Equal, null);
}

@Override
public <V> Restriction.Single<T, V> lessThan(V value) {
return new Restriction.Single<>(name, Is.Op.LessThan, value);
}

@Override
public <V> Restriction.Single<T, V> lessThanEqual(V value) {
return new Restriction.Single<>(name, Is.Op.LessThanEqual, value);
}

@Override
public <V> Restriction.Single<T, V> not(V value) {
return new Restriction.Single<>(name, Is.Op.Not, value);
}

@Override
public <V> Restriction.Single<T, Set<V>> notIn(@SuppressWarnings("unchecked") V... values) {
return new Restriction.Single<>(name, Is.Op.NotIn, Set.of(values));
}

@Override
public Restriction.Single<T, Object> notNull() {
return new Restriction.Single<>(name, Is.Op.Not, null);
}
}

Loading

0 comments on commit 920050d

Please sign in to comment.