ggrossetie / asciidoctorg

Asciidoctor.js on the JVM using GraalVM!
2 stars 0 forks source link

Implement the AsciidoctorJ Extension API #3

Open ggrossetie opened 5 years ago

ggrossetie commented 5 years ago

Using Java extension is not an easy task because we need to register dynamically a Java function an call it from JavaScript with instance (instantiated in the JavaScript engine).

Let's take an example:

public class YellBlock extends BlockProcessor {

  public YellBlock(String name, Map<String, Object> config) {
    super(name, config);
  }

  @Override
  public Object process(StructuralNode parent, Reader reader, Map<String, Object> attributes) {
    List<String> lines = reader.readLines();
    String upperLines = lines.stream().map(String::toUpperCase).collect(Collectors.joining("\n"));
    return createBlock(parent, "paragraph", Arrays.asList(upperLines), attributes, new HashMap<>());
  }
}

In the example above, we need to call the process method from JavaScript with a StructuralNode instance, a Reader instance and a Map of attributes. The JavaScript runtime has a parent and a reader object in memory but these objects are not available in Java. The Java code is also calling the createBlock method with a StructuralNode (Java), so again we need to resolve this object in the JavaScript runtime.

Technically using a shared memory with "pointer" in the JavaScript runtime is working but I don't know if it's the best approach here.

ggrossetie commented 5 years ago

We could maybe define Proxy to customize Java interoperability:

https://www.graalvm.org/docs/graalvm-as-a-platform/embed/#computed-arrays-using-polyglot-proxies https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/proxy/Proxy.html