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
1 change: 0 additions & 1 deletion netflix-sel/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
dependencies {
implementation jodaTimeDep
api slf4jApiDep

testImplementation junitDep
Expand Down
3 changes: 1 addition & 2 deletions netflix-sel/gradle.lockfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
joda-time:joda-time:2.10.14=compileClasspath
org.slf4j:slf4j-api:1.7.36=compileClasspath
org.slf4j:slf4j-api:1.7.36=compileClasspath,runtimeClasspath
empty=annotationProcessor
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.ResourceBundle;
import org.joda.time.DateTimeZone;
import org.joda.time.tz.Provider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -33,7 +31,7 @@ final class SelClassLoader extends ClassLoader {

// hold references to avoid evicting objects during GC.
private final List<Class<?>> preloadedClasses = new ArrayList<>();
private final List<DateTimeZone> preloadedTimezones = new ArrayList<>();
private final List<ZoneId> preloadedTimezones = new ArrayList<>();

private SelClassLoader() {
loadSelClasses();
Expand All @@ -44,11 +42,8 @@ private void loadSelClasses() {
loadClassesInPackage("com.netflix.sel.type");
loadClassesInPackage("com.netflix.sel.visitor");
loadClassesInPackage("com.netflix.sel.ext");
loadClassesInPackage("org.joda.time");
ResourceBundle.getBundle("org.joda.time.format.messages");

Provider provider = DateTimeZone.getProvider(); // loads all zone info
provider.getAvailableIDs().forEach(id -> preloadedTimezones.add(provider.getZone(id)));
ZoneId.getAvailableZoneIds().forEach(id -> preloadedTimezones.add(ZoneId.of(id)));
}

private void loadClassInPackage(String path, String clazzName) {
Expand Down
419 changes: 236 additions & 183 deletions netflix-sel/src/main/java/com/netflix/sel/type/SelJodaDateTime.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,19 @@
package com.netflix.sel.type;

import com.netflix.sel.visitor.SelOp;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import org.joda.time.Days;

/** Wrapper class to support org.joda.time.Days. */
/** Wrapper class to support days logic. */
public final class SelJodaDateTimeDays extends AbstractSelType {
private Days val;
private long val;

private SelJodaDateTimeDays(Days val) {
private SelJodaDateTimeDays(long val) {
this.val = val;
}

static SelJodaDateTimeDays of(Days d) {
static SelJodaDateTimeDays of(long d) {
return new SelJodaDateTimeDays(d);
}

Expand All @@ -44,19 +45,18 @@ public SelJodaDateTimeDays assignOps(SelOp op, SelType rhs) {
}

@Override
public Days getInternalVal() {
public Long getInternalVal() {
return val;
}

@Override
public SelType call(String methodName, SelType[] args) {
if (args.length == 0 && "getDays".equals(methodName)) {
return SelLong.of((long) val.getDays());
return SelLong.of(val);
} else if (args.length == 2 && "daysBetween".equals(methodName)) {
return new SelJodaDateTimeDays(
Days.daysBetween(
((SelJodaDateTime) args[0]).getInternalVal(),
((SelJodaDateTime) args[1]).getInternalVal()));
ZonedDateTime d1 = (ZonedDateTime) ((SelJodaDateTime) args[0]).getInternalVal();
ZonedDateTime d2 = (ZonedDateTime) ((SelJodaDateTime) args[1]).getInternalVal();
return new SelJodaDateTimeDays(ChronoUnit.DAYS.between(d1.toLocalDate(), d2.toLocalDate()));
}
throw new UnsupportedOperationException(
type()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
package com.netflix.sel.type;

import com.netflix.sel.visitor.SelOp;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

/** Wrapper class to support org.joda.time.format.DateTimeFormatter. */
/** Wrapper class to support java.time.format.DateTimeFormatter. */
public final class SelJodaDateTimeFormatter extends AbstractSelType {
private DateTimeFormatter val;

Expand Down Expand Up @@ -54,24 +55,46 @@ public SelType call(String methodName, SelType[] args) {
if (args.length == 1) {
if ("withZone".equals(methodName)) {
return new SelJodaDateTimeFormatter(
val.withZone(((SelJodaDateTimeZone) args[0]).getInternalVal()));
val.withZone((ZoneId) ((SelJodaDateTimeZone) args[0]).getInternalVal()));
} else if ("parseDateTime".equals(methodName)) {
switch (args[0].type()) {
case STRING:
case LONG:
return SelJodaDateTime.of(val.parseDateTime(args[0].toString()));
java.time.temporal.TemporalAccessor parsed = val.parse(args[0].toString());
ZoneId zone = val.getZone() != null ? val.getZone() : ZoneId.of("UTC");
try {
zone = ZoneId.from(parsed);
} catch (Exception e) {}
return SelJodaDateTime.of(java.time.LocalDateTime.from(parsed).atZone(zone));
}
} else if ("parseMillis".equals(methodName)) {
return SelLong.of(val.parseMillis(((SelString) args[0]).getInternalVal()));
java.time.temporal.TemporalAccessor parsed = val.parse(((SelString) args[0]).getInternalVal());
ZoneId zone = val.getZone() != null ? val.getZone() : ZoneId.of("UTC");
try {
zone = ZoneId.from(parsed);
} catch (Exception e) {}
return SelLong.of(java.time.LocalDateTime.from(parsed).atZone(zone).toInstant().toEpochMilli());
} else if ("forPattern".equals(methodName)) {
String pattern = ((SelString) args[0]).getInternalVal().replace("YYYY", "uuuu").replace("yyyy", "uuuu").replace("ww", "ww").replace("DD", "DDD");
return new SelJodaDateTimeFormatter(
DateTimeFormat.forPattern(((SelString) args[0]).getInternalVal()));
new java.time.format.DateTimeFormatterBuilder()
.appendPattern(pattern)
.parseDefaulting(java.time.temporal.ChronoField.YEAR, 1970)
.parseDefaulting(java.time.temporal.ChronoField.MONTH_OF_YEAR, 1)
.parseDefaulting(java.time.temporal.ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(java.time.temporal.ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(java.time.temporal.ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(java.time.temporal.ChronoField.SECOND_OF_MINUTE, 0)
.parseDefaulting(java.time.temporal.ChronoField.MILLI_OF_SECOND, 0)
.toFormatter(java.util.Locale.US)
.withZone(val != null && val.getZone() != null ? val.getZone() : ZoneId.of("UTC")) // Preserve zone if any
);
} else if ("print".equals(methodName)) {
switch (args[0].type()) {
case LONG:
return SelString.of(val.print(((SelLong) args[0]).longVal()));
return SelString.of(val.format(ZonedDateTime.ofInstant(java.time.Instant.ofEpochMilli(((SelLong) args[0]).longVal()), val.getZone() != null ? val.getZone() : ZoneId.of("UTC"))));
case DATETIME:
return SelString.of(val.print(((SelJodaDateTime) args[0]).getInternalVal()));
return SelString.of(val.format((ZonedDateTime) ((SelJodaDateTime) args[0]).getInternalVal()));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,24 @@
package com.netflix.sel.type;

import com.netflix.sel.visitor.SelOp;
import java.time.ZonedDateTime;
import java.time.format.TextStyle;
import java.time.temporal.TemporalField;
import java.util.Arrays;
import java.util.Locale;
import org.joda.time.DateTime;

/** Wrapper class to support org.joda.time.DateTime.Property. */
/** Wrapper class to support date time property. */
public final class SelJodaDateTimeProperty extends AbstractSelType {
private DateTime.Property val;
private ZonedDateTime zdt;
private TemporalField field;

private SelJodaDateTimeProperty(DateTime.Property val) {
this.val = val;
private SelJodaDateTimeProperty(ZonedDateTime zdt, TemporalField field) {
this.zdt = zdt;
this.field = field;
}

static SelJodaDateTimeProperty of(DateTime.Property p) {
return new SelJodaDateTimeProperty(p);
static SelJodaDateTimeProperty of(ZonedDateTime zdt, TemporalField field) {
return new SelJodaDateTimeProperty(zdt, field);
}

@Override
Expand All @@ -38,28 +42,34 @@ public SelTypes type() {
public SelJodaDateTimeProperty assignOps(SelOp op, SelType rhs) {
if (op == SelOp.ASSIGN) {
SelTypeUtil.checkTypeMatch(this.type(), rhs.type());
this.val = ((SelJodaDateTimeProperty) rhs).val;
this.zdt = ((SelJodaDateTimeProperty) rhs).zdt;
this.field = ((SelJodaDateTimeProperty) rhs).field;
return this;
}
throw new UnsupportedOperationException(type() + " DO NOT support assignment operation " + op);
}

@Override
public DateTime.Property getInternalVal() {
return val;
public Object getInternalVal() {
return this; // not directly used
}

@Override
public SelType call(String methodName, SelType[] args) {
if (args.length == 0) {
if ("getAsText".equals(methodName)) {
return SelString.of(val.getAsText(Locale.US));
if (field == java.time.temporal.ChronoField.DAY_OF_WEEK) {
return SelString.of(java.time.format.DateTimeFormatter.ofPattern("EEEE", Locale.US).format(zdt));
} else if (field == java.time.temporal.ChronoField.MONTH_OF_YEAR) {
return SelString.of(java.time.format.DateTimeFormatter.ofPattern("MMMM", Locale.US).format(zdt));
}
return SelString.of(Long.toString(zdt.get(field)));
} else if ("withMinimumValue".equals(methodName)) {
return SelJodaDateTime.of(val.withMinimumValue());
return SelJodaDateTime.of(zdt.with(field, field.range().getMinimum()));
} else if ("withMaximumValue".equals(methodName)) {
return SelJodaDateTime.of(val.withMaximumValue());
return SelJodaDateTime.of(zdt.with(field, field.range().getMaximum()));
} else if ("get".equals(methodName)) {
return SelLong.of((long) val.get());
return SelLong.of((long) zdt.get(field));
}
}
throw new UnsupportedOperationException(
Expand All @@ -72,6 +82,6 @@ public SelType call(String methodName, SelType[] args) {

@Override
public String toString() {
return String.valueOf(val);
return "Property[" + field + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,19 @@
package com.netflix.sel.type;

import com.netflix.sel.visitor.SelOp;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Arrays;
import org.joda.time.DateTimeZone;

/** Wrapper class to support org.joda.time.DateTimeZone. */
/** Wrapper class to support java.time.ZoneId. */
public final class SelJodaDateTimeZone extends AbstractSelType {
private DateTimeZone val;
private ZoneId val;

private SelJodaDateTimeZone(DateTimeZone val) {
private SelJodaDateTimeZone(ZoneId val) {
this.val = val;
}

static SelJodaDateTimeZone of(DateTimeZone dtz) {
static SelJodaDateTimeZone of(ZoneId dtz) {
return new SelJodaDateTimeZone(dtz);
}

Expand All @@ -44,17 +45,17 @@ public SelJodaDateTimeZone assignOps(SelOp op, SelType rhs) {
}

@Override
public DateTimeZone getInternalVal() {
public ZoneId getInternalVal() {
return val;
}

@Override
public SelType call(String methodName, SelType[] args) {
if (args.length == 1) {
if ("forID".equals(methodName)) {
return new SelJodaDateTimeZone(DateTimeZone.forID(((SelString) args[0]).getInternalVal()));
return new SelJodaDateTimeZone(ZoneId.of(((SelString) args[0]).getInternalVal()));
} else if ("getOffset".equals(methodName)) {
return SelLong.of((long) val.getOffset(((SelJodaDateTime) args[0]).getInternalVal()));
return SelLong.of((long) val.getRules().getOffset(((ZonedDateTime) ((SelJodaDateTime) args[0]).getInternalVal()).toInstant()).getTotalSeconds() * 1000L);
}
}
throw new UnsupportedOperationException(
Expand All @@ -69,7 +70,7 @@ public SelType call(String methodName, SelType[] args) {
public SelJodaDateTimeZone field(SelString field) {
String fieldName = field.getInternalVal();
if ("UTC".equals(fieldName)) {
return new SelJodaDateTimeZone(DateTimeZone.UTC);
return new SelJodaDateTimeZone(ZoneId.of("UTC"));
}
throw new UnsupportedOperationException(type() + " DO NOT support accessing field: " + field);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
package com.netflix.sel.type;

import java.util.Arrays;
import org.joda.time.DateTimeConstants;
import org.joda.time.DateTimeUtils;

/** Util class to include static methods */
public final class SelMiscFunc implements SelType {
Expand All @@ -36,7 +34,7 @@ public String toString() {
@Override
public SelType call(String methodName, SelType[] args) {
if (args.length == 0 && "currentTimeMillis".equals(methodName)) {
return SelLong.of(DateTimeUtils.currentTimeMillis());
return SelLong.of(SelJodaDateTime.CLOCK.millis());
}
// no-op to support Arrays.asList
if (args.length == 1 && "asList".equals(methodName)) {
Expand All @@ -55,7 +53,7 @@ public SelType call(String methodName, SelType[] args) {
public SelLong field(SelString field) {
String fieldName = field.getInternalVal();
if ("SUNDAY".equals(fieldName)) {
return SelLong.of(DateTimeConstants.SUNDAY);
return SelLong.of(7); // java.time.DayOfWeek.SUNDAY.getValue() is 7
}
throw new UnsupportedOperationException(type() + " DO NOT support accessing field: " + field);
}
Expand Down
27 changes: 15 additions & 12 deletions netflix-sel/src/main/java/com/netflix/sel/type/SelTypeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@
package com.netflix.sel.type;

import java.lang.invoke.MethodHandle;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Days;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

/** Internal util class */
public final class SelTypeUtil {
Expand Down Expand Up @@ -104,9 +102,15 @@ public static SelType box(Object o) {
case MAP:
return SelMap.of((Map<String, Object>) o);
case DATETIME:
return SelJodaDateTime.of((DateTime) o);
return SelJodaDateTime.of((ZonedDateTime) o);
case DATETIME_PROPERTY:
return SelJodaDateTimeProperty.of((DateTime.Property) o);
return (SelJodaDateTimeProperty) o;
case DATETIME_DAYS:
return (SelJodaDateTimeDays) o;
case DATETIME_ZONE:
return SelJodaDateTimeZone.of((ZoneId) o);
case DATETIME_FORMATTER:
return SelJodaDateTimeFormatter.of((DateTimeFormatter) o);
}
throw new UnsupportedOperationException(
"Not support to box an object " + o + " for type " + type.name());
Expand Down Expand Up @@ -180,12 +184,11 @@ public static SelTypes fromStringToSelType(String clazz) {
map.put(HashMap.class, SelTypes.MAP);
map.put(LinkedHashMap.class, SelTypes.MAP);

map.put(DateTime.class, SelTypes.DATETIME);
map.put(DateTimeZone.class, SelTypes.DATETIME_ZONE);
map.put(ZonedDateTime.class, SelTypes.DATETIME);
map.put(ZoneId.class, SelTypes.DATETIME_ZONE);
map.put(DateTimeFormatter.class, SelTypes.DATETIME_FORMATTER);
map.put(DateTimeFormat.class, SelTypes.DATETIME_FORMATTER);
map.put(DateTime.Property.class, SelTypes.DATETIME_PROPERTY);
map.put(Days.class, SelTypes.DATETIME_DAYS);
map.put(SelJodaDateTimeProperty.class, SelTypes.DATETIME_PROPERTY);
map.put(SelJodaDateTimeDays.class, SelTypes.DATETIME_DAYS);

JAVA_CLAZZ_TO_SEL_TYPES = Collections.unmodifiableMap(map);
}
Expand Down
4 changes: 2 additions & 2 deletions netflix-sel/src/main/java/com/netflix/sel/type/SelTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ public SelType newSelTypeObj() {
case DATETIME_ZONE:
return SelJodaDateTimeZone.of(null);
case DATETIME_DAYS:
return SelJodaDateTimeDays.of(null);
return SelJodaDateTimeDays.of(0L);
case DATETIME_PROPERTY:
return SelJodaDateTimeProperty.of(null);
return SelJodaDateTimeProperty.of(null, null);
case DATETIME_FORMATTER:
return SelJodaDateTimeFormatter.of(null);

Expand Down
Loading