package brainslug.maven; import brainslug.flow.builder.FlowBuilder; import brainslug.flow.renderer.DefaultSkin; import brainslug.flow.renderer.Format; import brainslug.flow.renderer.JGraphBpmnRenderer; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.net.URL; import java.net.URLClassLoader; import java.util.HashSet; import java.util.List; import java.util.Set; @Mojo(name = "render-flows", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME) public class RenderFlowsMojo extends AbstractMojo { @Parameter(defaultValue = "${project}", required = true, readonly = true) private MavenProject project; @Parameter(property = "project.compileClasspathElements", required = true, readonly = true) private List<String> classpath; @Parameter(required = true) private String flows; @Parameter(required = false) private String format = "PNG"; @Parameter(required = false) private String outputDir = "flows"; @Override public void execute() throws MojoExecutionException, MojoFailureException { for (String flowName : flows.split(",")) { FlowBuilder flowBuilder = createFlowInstance(flowName.trim(), setupClassPath()); renderImage(flowBuilder); } } private void renderImage(FlowBuilder flowBuilder) { Format imageFormat = Format.valueOf(format.toUpperCase()); FileOutputStream fileOutputStream = getFileOutputStream(getOutputFile(flows + "." + imageFormat.name().toLowerCase())); new JGraphBpmnRenderer(new DefaultSkin()).render(flowBuilder, fileOutputStream, imageFormat); } private FlowBuilder createFlowInstance(String flowName, ClassLoader classLoader) { try { Class<FlowBuilder> flowClass = (Class<FlowBuilder>) Class.forName(flowName, true, classLoader); try { return flowClass.newInstance(); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } catch (ClassNotFoundException e) { throw new RuntimeException("unable to find flow with name: " + flowName, e); } } private File getOutputFile(String fileName) { return new File(getOutputDirectory().getAbsolutePath() + File.separatorChar + fileName); } private File getOutputDirectory() { File outputDirectory = new File(project.getBuild().getDirectory() + File.separatorChar + outputDir); outputDirectory.mkdirs(); return outputDirectory; } private FileOutputStream getFileOutputStream(File outputFile) { try { return new FileOutputStream(outputFile); } catch (FileNotFoundException e) { throw new IllegalArgumentException(outputFile + " is a invalid path."); } } ClassLoader setupClassPath() { try { Set<URL> urls = new HashSet<URL>(); for (String element : classpath) { urls.add(new File(element).toURI().toURL()); } ClassLoader contextClassLoader = URLClassLoader.newInstance( urls.toArray(new URL[0]), Thread.currentThread().getContextClassLoader()); Thread.currentThread().setContextClassLoader(contextClassLoader); return contextClassLoader; } catch (Exception e) { throw new RuntimeException(e); } } }