From ac300641b4e4aa152f6a659dd9392455e472fad9 Mon Sep 17 00:00:00 2001 From: Robert Panzer Date: Thu, 21 Jul 2016 11:25:03 +0200 Subject: [PATCH] Invoke JavaExtensionRegistry by reflection to take care of binary incompatibilities with AsciidoctorJ 1.6.0 (#255) --- .../AsciidoctorJExtensionRegistry.java | 69 ++++++++++++++++--- .../maven/extensions/ExtensionRegistry.java | 3 +- 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/asciidoctor/maven/extensions/AsciidoctorJExtensionRegistry.java b/src/main/java/org/asciidoctor/maven/extensions/AsciidoctorJExtensionRegistry.java index 66347e8c..ba31c5a2 100644 --- a/src/main/java/org/asciidoctor/maven/extensions/AsciidoctorJExtensionRegistry.java +++ b/src/main/java/org/asciidoctor/maven/extensions/AsciidoctorJExtensionRegistry.java @@ -1,5 +1,7 @@ package org.asciidoctor.maven.extensions; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; import org.asciidoctor.Asciidoctor; import org.asciidoctor.extension.BlockMacroProcessor; import org.asciidoctor.extension.BlockProcessor; @@ -12,6 +14,10 @@ import org.asciidoctor.extension.Processor; import org.asciidoctor.extension.Treeprocessor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; + /** * Class responsible for registering extensions. This class is inspired by * {@link org.asciidoctor.extension.spi.ExtensionRegistry} @@ -34,7 +40,7 @@ public AsciidoctorJExtensionRegistry(Asciidoctor asciidoctorInstance) { */ @Override @SuppressWarnings("unchecked") - public void register(String extensionClassName, String blockName) { + public void register(String extensionClassName, String blockName) throws MojoExecutionException { Class clazz; try { @@ -46,23 +52,68 @@ public void register(String extensionClassName, String blockName) { throw new RuntimeException("'" + extensionClassName + "' not found in classpath"); } + // TODO: Replace with direct method calls again as soon as this project compiles against AsciidoctorJ 1.6.0 if (DocinfoProcessor.class.isAssignableFrom(clazz)) { - javaExtensionRegistry.docinfoProcessor((Class) clazz); + register(javaExtensionRegistry, "docinfoProcessor", clazz); } else if (Preprocessor.class.isAssignableFrom(clazz)) { - javaExtensionRegistry.preprocessor((Class) clazz); + register(javaExtensionRegistry, "preprocessor", clazz); } else if (Postprocessor.class.isAssignableFrom(clazz)) { - javaExtensionRegistry.postprocessor((Class) clazz); + register(javaExtensionRegistry, "postprocessor", clazz); } else if (Treeprocessor.class.isAssignableFrom(clazz)) { - javaExtensionRegistry.treeprocessor((Class) clazz); + register(javaExtensionRegistry, "treeprocessor", clazz); } else if (BlockProcessor.class.isAssignableFrom(clazz)) { - javaExtensionRegistry.block(blockName, (Class) clazz); + if (blockName == null) { + register(javaExtensionRegistry, "block", clazz); + } else { + register(javaExtensionRegistry, "block", blockName, clazz); + } } else if (IncludeProcessor.class.isAssignableFrom(clazz)) { - javaExtensionRegistry.includeProcessor((Class) clazz); + register(javaExtensionRegistry, "includeProcessor", clazz); } else if (BlockMacroProcessor.class.isAssignableFrom(clazz)) { - javaExtensionRegistry.blockMacro(blockName, (Class) clazz); + if (blockName == null) { + register(javaExtensionRegistry, "blockMacro", clazz); + } else { + register(javaExtensionRegistry, "blockMacro", blockName, clazz); + } } else if (InlineMacroProcessor.class.isAssignableFrom(clazz)) { - javaExtensionRegistry.inlineMacro(blockName, (Class) clazz); + if (blockName == null) { + register(javaExtensionRegistry, "inlineMacro", clazz); + } else { + register(javaExtensionRegistry, "inlineMacro", blockName, clazz); + } + } + } + + private void register(Object target, String methodName, Object... args) throws MojoExecutionException { + for (Method method: javaExtensionRegistry.getClass().getMethods()) { + + if (isMethodMatching(method, methodName, args)) { + try { + method.invoke(target, args); + return; + } catch (Exception e) { + throw new MojoExecutionException("Unexpected exception while registering extensions", e); + } + } + + } + throw new MojoExecutionException("Internal Error. Could not register " + methodName + " with arguments " + Arrays.asList(args)); + } + + private boolean isMethodMatching(Method method, String methodName, Object[] args) { + if (!method.getName().equals(methodName)) { + return false; + } + if (method.getParameterTypes().length != args.length) { + return false; + } + // Don't care for primitives here, there's no method on JavaExtensionRegistry with primitives. + for (int i = 0; i < method.getParameterTypes().length; i++) { + if (args[i] != null && !method.getParameterTypes()[i].isAssignableFrom(args[i].getClass())) { + return false; + } } + return true; } } diff --git a/src/main/java/org/asciidoctor/maven/extensions/ExtensionRegistry.java b/src/main/java/org/asciidoctor/maven/extensions/ExtensionRegistry.java index 3c886d50..e1a622a9 100644 --- a/src/main/java/org/asciidoctor/maven/extensions/ExtensionRegistry.java +++ b/src/main/java/org/asciidoctor/maven/extensions/ExtensionRegistry.java @@ -1,5 +1,6 @@ package org.asciidoctor.maven.extensions; +import org.apache.maven.plugin.MojoExecutionException; import org.asciidoctor.extension.Processor; public interface ExtensionRegistry { @@ -14,6 +15,6 @@ public interface ExtensionRegistry { * required when declaring * */ - public abstract void register(String extensionClassName, String blockName); + public abstract void register(String extensionClassName, String blockName) throws MojoExecutionException; } \ No newline at end of file