Skip to content

Commit

Permalink
Merge pull request quarkusio#30626 from Sgitario/30605
Browse files Browse the repository at this point in the history
Fix support of primitive types for filtering in REST Data Panache
  • Loading branch information
geoand authored Jan 26, 2023
2 parents aad2385 + 34dfe2a commit cbe3dbd
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 19 deletions.
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/rest-data-panache.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ Additionally, you can also filter by the entity fields by adding a query param w
]
----

IMPORTANT: Filtering by fields is only supported for primitive types.
IMPORTANT: Filtering by fields is only supported for String, Boolean, Character, Double, Float, Integer, Long, Short, Byte and the primitive types.

== Complex filtering to list entities using @NamedQuery

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,26 @@ void shouldListSimpleObjects() {
.and().body("name", contains("first", "second"));
}

@Test
void shouldListWithPrimitiveFilter() {
given().accept("application/json")
.when()
.queryParam("type", 100)
.get("/collections")
.then().statusCode(200)
.and().body("id", contains("empty", "full"));
}

@Test
void shouldListWithPrimitiveFilterAndNoResults() {
given().accept("application/json")
.when()
.queryParam("type", 99)
.get("/collections")
.then().statusCode(200)
.and().body("id", empty());
}

@Test
void shouldListWithFilter() {
given().accept("application/json")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.LinkedList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
Expand All @@ -18,6 +19,12 @@ public class Collection extends PanacheEntityBase {

public String name;

/**
* This field is used to reproduce the issue: https://github.com/quarkusio/quarkus/issues/30605
*/
@Column(name = "type", columnDefinition = "int default 100")
public int type;

@OneToMany(fetch = FetchType.EAGER, mappedBy = "collection")
public List<Item> items = new LinkedList<>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.LinkedList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
Expand All @@ -18,6 +19,12 @@ public class Collection extends PanacheEntityBase {

public String name;

/**
* This field is used to reproduce the issue: https://github.com/quarkusio/quarkus/issues/30605
*/
@Column(name = "type", columnDefinition = "int default 100")
public int type;

@OneToMany(fetch = FetchType.EAGER, mappedBy = "collection")
public List<Item> items = new LinkedList<>();
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package io.quarkus.rest.data.panache.deployment.methods;

import static io.quarkus.arc.processor.DotNames.BOOLEAN;
import static io.quarkus.arc.processor.DotNames.BYTE;
import static io.quarkus.arc.processor.DotNames.CHARACTER;
import static io.quarkus.arc.processor.DotNames.DOUBLE;
import static io.quarkus.arc.processor.DotNames.FLOAT;
import static io.quarkus.arc.processor.DotNames.INTEGER;
import static io.quarkus.arc.processor.DotNames.LONG;
import static io.quarkus.arc.processor.DotNames.SHORT;
import static io.quarkus.arc.processor.DotNames.STRING;
import static io.quarkus.gizmo.MethodDescriptor.ofConstructor;
import static io.quarkus.gizmo.MethodDescriptor.ofMethod;
Expand All @@ -15,6 +17,7 @@
import static io.quarkus.rest.data.panache.deployment.utils.SignatureMethodCreator.param;
import static io.quarkus.rest.data.panache.deployment.utils.SignatureMethodCreator.responseType;
import static io.quarkus.rest.data.panache.deployment.utils.SignatureMethodCreator.uniType;
import static io.quarkus.rest.data.panache.deployment.utils.TypeUtils.primitiveToClass;

import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -255,7 +258,8 @@ private Collection<SignatureMethodCreator.Parameter> getFieldsToQuery(ResourceMe
return resourceMetadata.getFields().entrySet()
.stream()
.filter(e -> isFieldTypeCompatibleForQueryParam(e.getValue()))
.map(e -> param(e.getKey(), e.getValue().name().toString()))
// we need to map primitive types to classes to make the fields nullable
.map(e -> param(e.getKey(), primitiveToClass(e.getValue().name().toString())))
.collect(Collectors.toList());
}

Expand Down Expand Up @@ -354,9 +358,11 @@ private boolean isFieldTypeCompatibleForQueryParam(Type fieldType) {
|| fieldType.name().equals(BOOLEAN)
|| fieldType.name().equals(CHARACTER)
|| fieldType.name().equals(DOUBLE)
|| fieldType.name().equals(SHORT)
|| fieldType.name().equals(FLOAT)
|| fieldType.name().equals(INTEGER)
|| fieldType.name().equals(LONG)
|| fieldType.name().equals(BYTE)
|| fieldType.kind() == Type.Kind.PRIMITIVE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import io.quarkus.gizmo.ClassCreator;
import io.quarkus.gizmo.FieldDescriptor;
import io.quarkus.gizmo.TryBlock;
import io.quarkus.gizmo.Type;
import io.quarkus.rest.data.panache.RestDataPanacheException;
import io.quarkus.rest.data.panache.deployment.ResourceMetadata;
import io.quarkus.rest.data.panache.deployment.properties.ResourceProperties;
Expand Down Expand Up @@ -236,19 +235,6 @@ protected boolean isNotReactivePanache() {
return !capabilities.isPresent(Capability.HIBERNATE_REACTIVE);
}

public static Type toType(Object object) {
if (object instanceof Type) {
return (Type) object;
} else if (object instanceof String) {
return Type.classType((String) object);
} else if (object instanceof Class) {
return Type.classType((Class<?>) object);
}

throw new IllegalArgumentException("Unsupported object of type " + object.getClass()
+ ". Supported types are Type, String and Class");
}

private static Class<?> toClass(String className) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import static io.quarkus.gizmo.Type.classType;
import static io.quarkus.gizmo.Type.parameterizedType;
import static io.quarkus.rest.data.panache.deployment.methods.StandardMethodImplementor.toType;
import static io.quarkus.rest.data.panache.deployment.utils.TypeUtils.toGizmoType;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -52,7 +52,7 @@ public static MethodCreator getMethodCreator(String methodName, ClassCreator cla
}

public static Parameter param(String name, Object type) {
return param(name, type, toType(type));
return param(name, type, toGizmoType(type));
}

public static Parameter param(String name, Object clazz, Type type) {
Expand Down Expand Up @@ -90,7 +90,7 @@ public static ReturnType uniType(Object... arguments) {
ReturnType returnType = new ReturnType();
Type[] typeArguments = new Type[arguments.length];
for (int index = 0; index < arguments.length; index++) {
typeArguments[index] = toType(arguments[index]);
typeArguments[index] = toGizmoType(arguments[index]);
}

returnType.classType = Uni.class;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.quarkus.rest.data.panache.deployment.utils;

import java.util.HashMap;
import java.util.Map;

import io.quarkus.gizmo.Type;

public final class TypeUtils {

private static final Map<String, Class> PRIMITIVE_TO_CLASS_MAPPING = new HashMap<>();

static {
PRIMITIVE_TO_CLASS_MAPPING.put("int", Integer.class);
PRIMITIVE_TO_CLASS_MAPPING.put("byte", Byte.class);
PRIMITIVE_TO_CLASS_MAPPING.put("char", Character.class);
PRIMITIVE_TO_CLASS_MAPPING.put("short", Short.class);
PRIMITIVE_TO_CLASS_MAPPING.put("long", Long.class);
PRIMITIVE_TO_CLASS_MAPPING.put("float", Float.class);
PRIMITIVE_TO_CLASS_MAPPING.put("double", Double.class);
PRIMITIVE_TO_CLASS_MAPPING.put("boolean", Boolean.class);
}

private TypeUtils() {

}

public static Object primitiveToClass(String type) {
Class<?> clazz = PRIMITIVE_TO_CLASS_MAPPING.get(type);
return clazz != null ? clazz : type;
}

public static Type toGizmoType(Object object) {
if (object instanceof Type) {
return (Type) object;
} else if (object instanceof String) {
return Type.classType((String) object);
} else if (object instanceof Class) {
return Type.classType((Class<?>) object);
}

throw new IllegalArgumentException("Unsupported object of type " + object.getClass()
+ ". Supported types are Type, String and Class");
}

}

0 comments on commit cbe3dbd

Please sign in to comment.