Skip to content
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

Broken feature: EnumMap lookup #1083

Open
TWiStErRob opened this issue Nov 25, 2023 · 1 comment
Open

Broken feature: EnumMap lookup #1083

TWiStErRob opened this issue Nov 25, 2023 · 1 comment

Comments

@TWiStErRob
Copy link

I have a model property Map<Line, StatusChange> statuses = new EnumMap(Line.class);
where these are the enum definitions:

public enum Line {
    unknown /*Line$1*/, Bakerloo /*Line$2*/, ...
}
public enum StatusChange {
    Better("status-better"), ...
    private final String cssClass;
    StatusChange(String cssClass) {
        this.cssClass = cssClass;
    }
    public String getCssClass() { return cssClass; }
}

and this template: {{statuses.[lineStatus.line].cssClass}}, which now I understand is wrong, I think I need lookup.

However I did not get that understanding from the error message, since it was:

Caused by: com.github.jknack.handlebars.HandlebarsException: /views/LineStatus.hbs:99:24:
java.lang.IllegalArgumentException: net.twisterrob.blt.model.Line$2 is not an enum class
	at java.base/java.lang.Class.enumConstantDirectory(Class.java:3862)
	at java.base/java.lang.Enum.valueOf(Enum.java:267)
	at com.github.jknack.handlebars.context.MapValueResolver.resolve(MapValueResolver.java:52)

I had a look at the sources:

and debugged, where I confirmed that the code is passing in the wrong class:

-Enum.valueOf(first.getClass(), name)
+Enum.valueOf(first.getDeclaringClass(), name)

then the error becomes a more meaningful:

java.lang.IllegalArgumentException: No enum constant net.twisterrob.blt.model.Line.lineStatus.line

Sadly this not only affects the error cases, the feature to be able to index into an EnumMap via a String in [] is broken too, because it won't find the valueOf given the wrong class. I tried {{statuses.[Bakerloo].cssClass}} and got the same is not an enum class exception, even though according to the MapValueResolver it should've "just worked".

@TWiStErRob
Copy link
Author

TWiStErRob commented Nov 25, 2023

Caused by original implementation: #237

Also affects {{lookup statuses lineStatus.line}} syntax.

Workaround:

handlebars.registerHelpers(new HelperSource());
public static class HelperSource {
	/**
	 * Workaround for `myEnumMap.[Foo]` and `lookup myEnumMap Foo` not working.
	 * Usage: Replace {@code (lookup someEnumMap someEnumKey)} with {@code (lookupEnumMap someEnumMap someEnumKey)}.
	 * @see https://github.com/jknack/handlebars.java/issues/1083
	 */
	public static <E extends Enum<E>> Object lookupEnumMap(EnumMap<E, ?> map, E key) {
		return map.get(key);
	}
}

@TWiStErRob TWiStErRob changed the title Broken feature: EnumMap lookup via myEnumMap.[Foo] syntax Broken feature: EnumMap lookup Nov 25, 2023
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

No branches or pull requests

1 participant