Created
July 2, 2020 09:27
-
-
Save joyheron/1467e043c978d089457896a0e7baa66f to your computer and use it in GitHub Desktop.
Migrating from Nashorn to graaljs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package my.lovely.pkg; | |
import org.complate.core.ComplateRenderer; | |
import org.complate.core.ComplateSource; | |
import org.complate.graal.GraalComplateRenderer; | |
import org.complate.spring.mvc.ComplateViewResolver; | |
import org.complate.spring.source.ResourceComplateSource; | |
import org.springframework.beans.factory.annotation.Value; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.core.io.Resource; | |
@Configuration | |
public class ComplateConfiguration { | |
private static final String GRAAL_HELPERS = "Graal"; | |
@Bean | |
public ComplateSource complateSource( | |
@Value("classpath:/templates/complate/bundle.js") Resource resource) { | |
return new ResourceComplateSource(resource); | |
} | |
@Bean | |
public ComplateRenderer complateRenderer(ComplateSource source) { | |
/* | |
* Adding this binding makes the GraalHelper methods available to the JSX | |
* as `Graal.toObject` and `Graal.toArray` | |
* | |
* Since `Graal.toArray` is compatible with Nashorn `Java.from`, using | |
* `Graal.toArray` in place of `Java.from` may be sufficient to avoid | |
* having to set `js.nashorn-compat=true` if you do not need other | |
* compatibility features from Nashorn | |
*/ | |
return return GraalComplateRenderer.of(source) | |
.withBinding(GRAAL_HELPERS, new GraalHelper()) | |
.build(); | |
} | |
@Bean | |
public ComplateViewResolver complateViewResolver(ComplateRenderer renderer) { | |
return new ComplateViewResolver(renderer); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package my.lovely.pkg; | |
import org.graalvm.polyglot.proxy.ProxyArray; | |
import org.graalvm.polyglot.proxy.ProxyObject; | |
import java.util.Collection; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.stream.Collectors; | |
public class GraalHelper { | |
/** | |
* This is a helper which will try to convert any Java Collection to a | |
* JavaScript Array. The helper will also iterate over the Collection and | |
* try to convert any Java {@link Map} objects to JavaScript objects using | |
* the {@link #toObject(Object)} method. | |
* | |
* If the helper receives something which is not a {@link Collection}, | |
* then it will return the argument without attempting any conversion. | |
* | |
* @param javaCollection | |
* @return converted JavaScript Array | |
*/ | |
public Object toArray(Object javaCollection) { | |
if (!(javaCollection instanceof Collection)) { | |
return null; | |
} | |
Collection collection = (Collection) javaCollection; | |
return ProxyArray.fromList((List) collection.stream() | |
.map(this::toObject) | |
.collect(Collectors.toList())); | |
} | |
/** | |
* This is a helper which will try to convert any Java {@link Map} to a | |
* JavaScript Array. | |
* | |
* If the helper receives something which is not a {@link Map}, | |
* then it will return the argument without attempting any conversion. | |
* | |
* @param javaObject | |
* @return converted JavaScript object | |
*/ | |
public Object toObject(Object javaObject) { | |
if (!(javaObject instanceof Map)) { | |
return javaObject; | |
} | |
return ProxyObject.fromMap((Map) javaObject); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package my.lovely.pkg; | |
import org.graalvm.polyglot.proxy.ProxyArray; | |
import org.graalvm.polyglot.proxy.ProxyObject; | |
import org.junit.jupiter.api.Test; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
import static org.hamcrest.MatcherAssert.assertThat; | |
import static org.hamcrest.Matchers.containsInAnyOrder; | |
import static org.hamcrest.Matchers.is; | |
import static org.hamcrest.Matchers.nullValue; | |
class GraalHelperTest { | |
@Test | |
void toObject_calling_with_non_map_returns_the_object() { | |
// arrange | |
String object = "foo"; | |
// assert | |
assertThat(new GraalHelper().toObject(object), is(object)); | |
} | |
@Test | |
void toObject_calling_with_null_returns_null() { | |
assertThat(new GraalHelper().toObject(null), is(nullValue())); | |
} | |
@Test | |
void toObject_calling_with_map_converts_map() { | |
// arrange | |
Map<String, Object> objectMap = new HashMap<>(); | |
objectMap.put("foo", "Foo"); | |
List<String> complicatedObject = List.of("a", "b", "c"); | |
objectMap.put("bar", complicatedObject); | |
// act | |
ProxyObject object = (ProxyObject) new GraalHelper().toObject(objectMap); | |
// assert | |
assertThat(object.getMember("foo"), is("Foo")); | |
assertThat(object.getMember("bar"), is(complicatedObject)); | |
} | |
@Test | |
void toArray_calling_with_null_returns_null() { | |
assertThat(new GraalHelper().toArray(null), is(nullValue())); | |
} | |
@Test | |
void toArray_calling_with_list_returns_array() { | |
// arrange | |
List<String> list = List.of("a", "b", "c"); | |
// act | |
ProxyArray array = (ProxyArray) new GraalHelper().toArray(list); | |
// assert | |
assertThat(array.get(0), is("a")); | |
assertThat(array.get(1), is("b")); | |
assertThat(array.get(2), is("c")); | |
} | |
@Test | |
void toArray_calling_with_list_of_maps_converts_to_objects() { | |
// arrange | |
var list = List.of( | |
Map.of("k1", "v1"), | |
Map.of("k2", "v2"), | |
Map.of("k3", "v3")); | |
// act | |
ProxyArray array = (ProxyArray) new GraalHelper().toArray(list); | |
ProxyObject v1 = (ProxyObject) array.get(0); | |
ProxyObject v2 = (ProxyObject) array.get(1); | |
ProxyObject v3 = (ProxyObject) array.get(2); | |
// assert | |
assertThat(v1.getMember("k1"), is("v1")); | |
assertThat(v2.getMember("k2"), is("v2")); | |
assertThat(v3.getMember("k3"), is("v3")); | |
} | |
@Test | |
void toArray_calling_with_sets_returns_array() { | |
// arrange | |
var set = Set.of("a", "b", "c"); | |
// act | |
ProxyArray array = (ProxyArray) new GraalHelper().toArray(set); | |
Set<Object> elements = new HashSet<>(); | |
for (int i = 0; i < array.getSize(); i++) { | |
elements.add(array.get(i)); | |
} | |
// assert | |
assertThat(elements, containsInAnyOrder("a", "b", "c")); | |
} | |
@Test | |
void toArray_calling_set_with_map_also_converts_it_to_object() { | |
// arrange | |
var set = Set.of(Map.of("foo", "bar")); | |
// act | |
ProxyArray array = (ProxyArray) new GraalHelper().toArray(set); | |
// assert | |
assertThat(((ProxyObject) array.get(0)).getMember("foo"), is("bar")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment