Skip to content

Investigate requirement for reflective access to convert date/time values. #1969

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
christophstrobl opened this issue Oct 22, 2021 · 4 comments · Fixed by #1970
Closed

Investigate requirement for reflective access to convert date/time values. #1969

christophstrobl opened this issue Oct 22, 2021 · 4 comments · Fixed by #1970
Assignees

Comments

@christophstrobl
Copy link
Member

The ElasticsearchDateConverter is making use of reflection to access the from method for eg. java.time.Instant. This requires additional configuration for GraalVM native image.
Currently we are adding the required configuration for java.time types via the general processing of Spring Data repositories, but it would be nice to get rid of that extra bit of reflection config if possible.

@christophstrobl christophstrobl changed the title Investigate requirement for reflective access to parse date/time values. Investigate requirement for reflective access to convert date/time values. Oct 22, 2021
@sothawo
Copy link
Collaborator

sothawo commented Oct 22, 2021

We could create a list of all implementations of TemporalAccessor that have a static method from(Temporal) from the JDK and then replace that reflection code with something like

if(type instanceof LocalDate) {
  return LocalDate.from(template);
} else if (type instance of SomeOtherTemporalAccessor.class) {
  return SomeOtherTemporalAccessor.from(temporal);
} else ...

@sothawo
Copy link
Collaborator

sothawo commented Oct 22, 2021

I wrote a small program that gets all the relevant classes from the java.time package and that spits out the following code that could replace the existing one:

@SuppressWarnings("unchecked")
private static <T extends TemporalAccessor> TemporalQuery<T> getTemporalQuery(Class<T> type) {
	return temporal -> {
		if (type == java.time.chrono.HijrahDate.class) {
			return (T) java.time.chrono.HijrahDate.from(temporal);
		}
		if (type == java.time.chrono.JapaneseDate.class) {
			return (T) java.time.chrono.JapaneseDate.from(temporal);
		}
		if (type == java.time.ZonedDateTime.class) {
			return (T) java.time.ZonedDateTime.from(temporal);
		}
		if (type == java.time.LocalDateTime.class) {
			return (T) java.time.LocalDateTime.from(temporal);
		}
		if (type == java.time.chrono.ThaiBuddhistDate.class) {
			return (T) java.time.chrono.ThaiBuddhistDate.from(temporal);
		}
		if (type == java.time.LocalTime.class) {
			return (T) java.time.LocalTime.from(temporal);
		}
		if (type == java.time.ZoneOffset.class) {
			return (T) java.time.ZoneOffset.from(temporal);
		}
		if (type == java.time.OffsetTime.class) {
			return (T) java.time.OffsetTime.from(temporal);
		}
		if (type == java.time.chrono.ChronoLocalDate.class) {
			return (T) java.time.chrono.ChronoLocalDate.from(temporal);
		}
		if (type == java.time.Month.class) {
			return (T) java.time.Month.from(temporal);
		}
		if (type == java.time.chrono.ChronoLocalDateTime.class) {
			return (T) java.time.chrono.ChronoLocalDateTime.from(temporal);
		}
		if (type == java.time.MonthDay.class) {
			return (T) java.time.MonthDay.from(temporal);
		}
		if (type == java.time.Instant.class) {
			return (T) java.time.Instant.from(temporal);
		}
		if (type == java.time.OffsetDateTime.class) {
			return (T) java.time.OffsetDateTime.from(temporal);
		}
		if (type == java.time.chrono.ChronoZonedDateTime.class) {
			return (T) java.time.chrono.ChronoZonedDateTime.from(temporal);
		}
		if (type == java.time.chrono.MinguoDate.class) {
			return (T) java.time.chrono.MinguoDate.from(temporal);
		}
		if (type == java.time.Year.class) {
			return (T) java.time.Year.from(temporal);
		}
		if (type == java.time.DayOfWeek.class) {
			return (T) java.time.DayOfWeek.from(temporal);
		}
		if (type == java.time.LocalDate.class) {
			return (T) java.time.LocalDate.from(temporal);
		}
		if (type == java.time.YearMonth.class) {
			return (T) java.time.YearMonth.from(temporal);
		}
		throw new ConversionException("could not create object of class " + type.getName());
	};
}

Looks a little ugly, but should do. The only thing we'd loose is the ability to have a user have her own implementation of TemporalAccessor providing a from() method, but I guess this is a rather hypthetical problem.

@sothawo sothawo self-assigned this Oct 22, 2021
@christophstrobl
Copy link
Member Author

thanks @sothawo! You could leave the reflection variant in as a fallback. In that case users could still manually register a TypeHint for their implementation if needed.

@sothawo
Copy link
Collaborator

sothawo commented Oct 22, 2021

ok, though I think that will never happen ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants