Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import org.projectnessie.cel.common.ULong;
import org.projectnessie.cel.common.types.DoubleT;
Expand Down Expand Up @@ -135,8 +136,12 @@ public static Val maybeNativeToValue(TypeAdapter a, Object value) {
if (value instanceof Object[]) {
return newGenericArrayList(a, (Object[]) value);
}
if (value instanceof List) {
return newGenericArrayList(a, ((List<?>) value).toArray());
if (value instanceof Collection) {
return newGenericArrayList(a, ((Collection<?>) value).toArray());
}
if (value instanceof Optional) {
Optional<?> optional = (Optional<?>) value;
return optional.map(a::nativeToValue).orElse(NullT.NullValue);
}
if (value instanceof Map) {
return newMaybeWrappedMap(a, (Map<?, ?>) value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@
import com.google.protobuf.Timestamp;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.projectnessie.cel.checker.Decls;
import org.projectnessie.cel.common.ULong;
import org.projectnessie.cel.common.types.TypeT;
Expand Down Expand Up @@ -103,15 +104,17 @@ com.google.api.expr.v1alpha1.Type findTypeForJacksonType(JavaType type, TypeQuer
|| Instant.class.isAssignableFrom(rawClass)
|| ZonedDateTime.class.isAssignableFrom(rawClass)) {
return Checked.checkedTimestamp;
} else if (Optional.class.isAssignableFrom(rawClass)) {
return findTypeForJacksonType(elementType(type), typeQuery);
} else if (Map.class.isAssignableFrom(rawClass)) {
com.google.api.expr.v1alpha1.Type keyType =
findTypeForJacksonType(type.getKeyType(), typeQuery);
com.google.api.expr.v1alpha1.Type valueType =
findTypeForJacksonType(type.getContentType(), typeQuery);
findTypeForJacksonType(elementType(type), typeQuery);
return Decls.newMapType(keyType, valueType);
} else if (List.class.isAssignableFrom(rawClass)) {
} else if (Collection.class.isAssignableFrom(rawClass)) {
com.google.api.expr.v1alpha1.Type valueType =
findTypeForJacksonType(type.getContentType(), typeQuery);
findTypeForJacksonType(elementType(type), typeQuery);
return Decls.newListType(valueType);
} else if (type.isEnumType()) {
return typeQuery.getType(type);
Expand All @@ -124,6 +127,18 @@ com.google.api.expr.v1alpha1.Type findTypeForJacksonType(JavaType type, TypeQuer
}
}

private JavaType elementType(JavaType type) {
JavaType elementType = type.getContentType();
if (elementType == null && type.containedTypeCount() > 0) {
elementType = type.containedType(0);
}
if (elementType == null) {
throw new UnsupportedOperationException(
String.format("Unsupported Java Type '%s' without element type", type));
}
return elementType;
}

boolean hasProperty(String property) {
return fieldTypes.containsKey(property);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.projectnessie.cel.common.ULong;
import org.projectnessie.cel.common.types.Err;
Expand Down Expand Up @@ -218,6 +220,27 @@ void types() {
checkListType(reg, "bytesList", ByteString.class, Checked.checkedBytes);
checkListType(reg, "floatList", Float.class, Checked.checkedDouble);
checkListType(reg, "doubleList", Double.class, Checked.checkedDouble);
checkListType(reg, "stringCollection", String.class, Checked.checkedString);
checkListType(reg, "stringSet", String.class, Checked.checkedString);

// verify optional fields use their contained type

checkFieldType(reg, "optionalString", Checked.checkedString);
checkFieldType(reg, "emptyOptionalString", Checked.checkedString);
checkFieldType(
reg,
"optionalInnerType",
com.google.api.expr.v1alpha1.Type.newBuilder()
.setMessageType(InnerType.class.getName())
.build());
}

private void checkFieldType(
JacksonRegistry reg, String prop, com.google.api.expr.v1alpha1.Type type) {
JacksonFieldType ft =
(JacksonFieldType) reg.findFieldType(CollectionsObject.class.getName(), prop);
assertThat(ft).isNotNull();
assertThat(ft.type).isEqualTo(type);
}

private void checkListType(
Expand Down Expand Up @@ -362,6 +385,8 @@ void collectionsObjectTypeTest() throws Exception {
ByteString.copyFrom(new byte[] {(byte) 3}));
collectionsObject.floatList = asList(1f, 2f, 3f);
collectionsObject.doubleList = asList(1d, 2d, 3d);
collectionsObject.stringCollection = asList("collection-a", "collection-b");
collectionsObject.stringSet = new LinkedHashSet<>(asList("set-a", "set-b"));

// populate inner/nested type list/map

Expand All @@ -374,13 +399,16 @@ void collectionsObjectTypeTest() throws Exception {
inner2.intProp = 3;
inner2.wrappedIntProp = 4;
collectionsObject.innerTypes = asList(inner1, inner2);
collectionsObject.optionalInnerType = Optional.of(inner2);

// populate enum-related fields

collectionsObject.anEnum = AnEnum.ENUM_VALUE_2;
collectionsObject.anEnumList = asList(AnEnum.ENUM_VALUE_2, AnEnum.ENUM_VALUE_3);
collectionsObject.anEnumStringMap = singletonMap(AnEnum.ENUM_VALUE_2, "a");
collectionsObject.stringAnEnumMap = singletonMap("a", AnEnum.ENUM_VALUE_2);
collectionsObject.optionalString = Optional.of("optional-a");
collectionsObject.emptyOptionalString = Optional.empty();

// prepare registry

Expand All @@ -401,7 +429,7 @@ void collectionsObjectTypeTest() throws Exception {
Object fieldObj = CollectionsObject.class.getDeclaredField(field).get(collectionsObject);
if (fieldObj instanceof Map) {
assertThat(fieldVal).isInstanceOf(MapT.class);
} else if (fieldObj instanceof List) {
} else if (fieldObj instanceof Collection) {
assertThat(fieldVal).isInstanceOf(ListT.class);
}

Expand Down Expand Up @@ -434,6 +462,11 @@ void collectionsObjectTypeTest() throws Exception {
l -> l.get(intOf(2)))
.containsExactly(intOf(3), False, True, True, True, uintOf(1), uintOf(2), uintOf(3));

listVal = (ListT) obj.get(stringOf("stringSet"));
assertThat(listVal)
.extracting(ListT::size, l -> l.get(intOf(0)), l -> l.get(intOf(1)))
.containsExactly(intOf(2), stringOf("set-a"), stringOf("set-b"));

mapVal = (MapT) obj.get(stringOf("stringInnerMap"));
assertThat(mapVal)
.extracting(MapT::size, m -> m.contains(stringOf("42")), m -> m.contains(stringOf("a")))
Expand All @@ -454,6 +487,11 @@ void collectionsObjectTypeTest() throws Exception {
.extracting(o -> o.get(stringOf("intProp")), o -> o.get(stringOf("wrappedIntProp")))
.containsExactly(intOf(3), intOf(4));

i = (ObjectT) obj.get(stringOf("optionalInnerType"));
assertThat(i)
.extracting(o -> o.get(stringOf("intProp")), o -> o.get(stringOf("wrappedIntProp")))
.containsExactly(intOf(3), intOf(4));

// verify enums

Val x = obj.get(stringOf("anEnum"));
Expand All @@ -471,5 +509,10 @@ void collectionsObjectTypeTest() throws Exception {
assertThat(mapVal)
.extracting(l -> l.get(stringOf("a")))
.isEqualTo(intOf(AnEnum.ENUM_VALUE_2.ordinal()));

assertThat(obj.isSet(stringOf("optionalString"))).isSameAs(True);
assertThat(obj.get(stringOf("optionalString"))).isEqualTo(stringOf("optional-a"));
assertThat(obj.isSet(stringOf("emptyOptionalString"))).isSameAs(True);
assertThat(obj.get(stringOf("emptyOptionalString"))).isSameAs(NullT.NullValue);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
import com.google.protobuf.Duration;
import com.google.protobuf.Timestamp;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.projectnessie.cel.common.ULong;

public class CollectionsObject {
Expand Down Expand Up @@ -50,14 +53,19 @@ public class CollectionsObject {
public List<ByteString> bytesList;
public List<Float> floatList;
public List<Double> doubleList;
public Collection<String> stringCollection;
public Set<String> stringSet;

public Map<String, InnerType> stringInnerMap;
public List<InnerType> innerTypes;
public Optional<InnerType> optionalInnerType;

public AnEnum anEnum;
public List<AnEnum> anEnumList;
public Map<AnEnum, String> anEnumStringMap;
public Map<String, AnEnum> stringAnEnumMap;
public Optional<String> optionalString;
public Optional<String> emptyOptionalString;

public static final List<String> ALL_PROPERTIES =
asList(
Expand All @@ -84,10 +92,15 @@ public class CollectionsObject {
"bytesList",
"floatList",
"doubleList",
"stringCollection",
"stringSet",
"stringInnerMap",
"innerTypes",
"optionalInnerType",
"anEnum",
"anEnumList",
"anEnumStringMap",
"stringAnEnumMap");
"stringAnEnumMap",
"optionalString",
"emptyOptionalString");
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
import com.google.protobuf.Timestamp;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.projectnessie.cel.checker.Decls;
import org.projectnessie.cel.common.ULong;
import org.projectnessie.cel.common.types.TypeT;
Expand Down Expand Up @@ -103,15 +104,17 @@ com.google.api.expr.v1alpha1.Type findTypeForJacksonType(JavaType type, TypeQuer
|| Instant.class.isAssignableFrom(rawClass)
|| ZonedDateTime.class.isAssignableFrom(rawClass)) {
return Checked.checkedTimestamp;
} else if (Optional.class.isAssignableFrom(rawClass)) {
return findTypeForJacksonType(elementType(type), typeQuery);
} else if (Map.class.isAssignableFrom(rawClass)) {
com.google.api.expr.v1alpha1.Type keyType =
findTypeForJacksonType(type.getKeyType(), typeQuery);
com.google.api.expr.v1alpha1.Type valueType =
findTypeForJacksonType(type.getContentType(), typeQuery);
findTypeForJacksonType(elementType(type), typeQuery);
return Decls.newMapType(keyType, valueType);
} else if (List.class.isAssignableFrom(rawClass)) {
} else if (Collection.class.isAssignableFrom(rawClass)) {
com.google.api.expr.v1alpha1.Type valueType =
findTypeForJacksonType(type.getContentType(), typeQuery);
findTypeForJacksonType(elementType(type), typeQuery);
return Decls.newListType(valueType);
} else if (type.isEnumType()) {
return typeQuery.getType(type);
Expand All @@ -124,6 +127,18 @@ com.google.api.expr.v1alpha1.Type findTypeForJacksonType(JavaType type, TypeQuer
}
}

private JavaType elementType(JavaType type) {
JavaType elementType = type.getContentType();
if (elementType == null && type.containedTypeCount() > 0) {
elementType = type.containedType(0);
}
if (elementType == null) {
throw new UnsupportedOperationException(
String.format("Unsupported Java Type '%s' without element type", type));
}
return elementType;
}

boolean hasProperty(String property) {
return fieldTypes.containsKey(property);
}
Expand Down
Loading
Loading