package mandelbrot.ocamljava_maven_plugin; import java.io.File; import java.util.Collection; import mandelbrot.ocamljava_maven_plugin.util.FilesByExtensionGatherer; import mandelbrot.ocamljava_maven_plugin.util.JarAppender; import ocaml.compilers.ocamljavaMain; import org.apache.commons.io.FileUtils; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Parameter; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; import com.google.common.base.*; public abstract class OcamlJavaJarAbstractMojo extends OcamlJavaAbstractMojo { /*** * Whether to replace the main artifact jar with ocaml enhanced version. */ @Parameter(defaultValue="true") protected boolean replaceMainArtfact = true; protected abstract String chooseTargetJar(); @Override public void execute() throws MojoExecutionException, MojoFailureException { final Object object = System.getProperty(FORK_PROPERTY_NAME); if (Boolean.parseBoolean(Optional.fromNullable(object).or(Boolean.TRUE) .toString())) { getLog().info("forking process"); final boolean forkAgain = false; invokePlugin(fullyQualifiedGoal(), forkAgain); return; } if (!ensureTargetDirectoryExists()) { getLog().error("Could not create target directory"); return; } try { final File root = new File(getOcamlCompiledSourcesTargetFullPath()); final Multimap<String, String> ocamlCompiledSourceFiles = new FilesByExtensionGatherer( this, ImmutableSet.of( OcamlJavaConstants.COMPILED_IMPL_JAVA_EXTENSION, OcamlJavaConstants.COMPILED_INTERFACE_EXTENSION)) .gather(root); if (ocamlCompiledSourceFiles.isEmpty()) { getLog().info("No sources to add to jar (scanned directory: " + root.getPath() + ")"); return; } final String[] args = generateCommandLineArguments(ocamlCompiledSourceFiles.get( OcamlJavaConstants.COMPILED_IMPL_JAVA_EXTENSION)).toArray(new String[]{}); getLog().info("args: " + ImmutableList.copyOf(args)); final ocamljavaMain mainWithReturn = ocamljavaMain.mainWithReturn(args); checkForErrors("ocaml java jar execution failed", mainWithReturn); if (attachCompiledModules) { final Collection<String> compiledModuleInterfaces = ocamlCompiledSourceFiles.get(OcamlJavaConstants.COMPILED_INTERFACE_EXTENSION); final Collection<String> all = ImmutableList.<String>builder() .add(chooseDependencyGraphTargetFullPath().getPath()) .addAll(compiledModuleInterfaces) .addAll(ocamlCompiledSourceFiles.get(OcamlJavaConstants.COMPILED_IMPL_OCAML_EXTENSION)) .addAll(ocamlCompiledSourceFiles.get(OcamlJavaConstants.COMPILED_IMPL_JAVA_EXTENSION)).build(); new JarAppender(this).addFiles(getTargetOcamlJarFullPath(), all, getOcamlCompiledSourcesTargetFullPath()); } if (replaceMainArtfact) { getLog().info(("replacing main artifact " + getTargetJarFullPath() + " with " + getTargetOcamlJarFullPath())); FileUtils.copyFile(new File(getTargetOcamlJarFullPath()), new File(getTargetJarFullPath())); } } catch (final Exception e) { throw new MojoExecutionException("ocamljava threw an error", e); } } // TODO make abstract public abstract String fullyQualifiedGoal(); public String getTargetJarFullPath() { return outputDirectory.getPath() + File.separator + chooseTargetJar(); } public String getTargetOcamlJarFullPath() { return outputDirectory.getPath() + File.separator + chooseTargetOcamlJar(); } /*** * Determines whether to attach the compiled modules and module interfaces to the final packaged jar. * This is necessary for projects that will invoke the ocaml wrap goal and reference this artifact. */ @Parameter(defaultValue="true") protected boolean attachCompiledModules; private ImmutableList<String> generateCommandLineArguments( final Collection<String> ocamlSourceFiles) { return ImmutableList.<String>builder() .add(OcamlJavaConstants.ADD_TO_JAR_SOURCES_OPTION) .add(getTargetOcamlJarFullPath()) .add(OcamlJavaConstants.ADDITIONAL_JAR_OPTION) .add(getTargetJarFullPath()) .addAll(ocamlSourceFiles) .build(); } private boolean ensureTargetDirectoryExists() { if (outputDirectory.exists()) { return true; } return outputDirectory.mkdirs(); } protected abstract String chooseTargetOcamlJar(); }