Java tutorial
package org.codehaus.mojo.latex; /* * Copyright 2010 INRIA / CITI Laboratory / Amazones Research Team. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.io.FileUtils; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.Collection; import java.util.Iterator; import static org.apache.commons.exec.CommandLine.parse; import static org.apache.commons.io.FileUtils.copyDirectory; import static org.apache.commons.io.FileUtils.copyFile; import static org.apache.commons.io.FileUtils.iterateFiles; /** * LaTeX documents building goal. * * @author Julien Ponge * @goal latex * @phase compile */ public class LaTeXMojo extends AbstractMojo { /** * The documents root. * * @parameter expression="${latex.docsRoot}" default-value="src/main/latex" * @required */ private File docsRoot; /** * Common files directory inside the documents root (the only directory to be skipped). * * @parameter expression="${latex.commonsDirName}" default-value="common" * @required */ private String commonsDirName; /** * The Maven build directory. * * @parameter expression="${project.build.directory}" * @required * @readonly */ private File buildDir; /** * The LaTeX builds directory. * * @parameter expression="${project.latex.build.directory}" default-value="${project.build.directory}/latex" * @required */ private File latexBuildDir; /** * Path to the LaTeX binaries installation. * * @parameter expression="${latex.binariesPath}" default-value="" */ private String binariesPath; /** * Name of bibtex executable. Use this to invoke bibtex8 or biber instead of bibtex. * * @parameter expression="${latex.bibtex}" default-value="bibtex" */ private String bibtex; public void execute() throws MojoExecutionException, MojoFailureException { try { final File[] docDirs = getDocDirs(); final File[] buildDirs = prepareLaTeXBuildDirectories(docDirs); buildDocuments(buildDirs); } catch (IOException e) { getLog().error(e); throw new MojoFailureException(e.getMessage()); } } private void buildDocuments(File[] buildDirs) throws IOException, MojoFailureException { for (File dir : buildDirs) { final File texFile = new File(dir, dir.getName() + ".tex"); final File pdfFile = new File(dir, dir.getName() + ".pdf"); final File bibFile = new File(dir, dir.getName() + ".bib"); if (requiresBuilding(dir, pdfFile)) { final CommandLine pdfLaTeX = parse(executablePath("pdflatex")).addArgument("-shell-escape") .addArgument("--halt-on-error").addArgument(texFile.getAbsolutePath()); if (getLog().isDebugEnabled()) { getLog().debug("pdflatex: " + pdfLaTeX); } final CommandLine bibTeX = parse(executablePath(bibtex)).addArgument(dir.getName()); if (getLog().isDebugEnabled()) { getLog().debug("bibtex: " + bibTeX); } execute(pdfLaTeX, dir); if (bibFile.exists()) { execute(bibTeX, dir); execute(pdfLaTeX, dir); } execute(pdfLaTeX, dir); copyFile(pdfFile, new File(buildDir, pdfFile.getName())); } } } private boolean requiresBuilding(File dir, File pdfFile) throws IOException { Collection texFiles = FileUtils.listFiles(dir, new String[] { "tex", "bib" }, true); getLog().info(texFiles.toString()); if (pdfFile.exists()) { boolean upToDate = true; Iterator it = texFiles.iterator(); while (it.hasNext() && upToDate) { File file = (File) it.next(); if (FileUtils.isFileNewer(file, pdfFile)) { if (getLog().isInfoEnabled()) { getLog().info("Changes detected on " + file.getAbsolutePath()); } return true; } if (getLog().isInfoEnabled()) { getLog().info("No change detected on " + file.getAbsolutePath()); } } if (getLog().isInfoEnabled()) { getLog().info("Skipping: no LaTeX changes detected in " + dir.getCanonicalPath()); } return false; } else { return true; } } private String executablePath(String executable) { if (binariesPath == null) { return executable; } else { return new StringBuilder().append(binariesPath).append(File.separator).append(executable).toString(); } } private void execute(CommandLine commandLine, File dir) throws IOException, MojoFailureException { final DefaultExecutor executor = new DefaultExecutor(); executor.setWorkingDirectory(dir); if (executor.execute(commandLine) != 0) { throw new MojoFailureException("Error code returned for: " + commandLine.toString()); } } private File[] prepareLaTeXBuildDirectories(File[] docDirs) throws IOException { final File[] buildDirs = new File[docDirs.length]; final File commonsDir = new File(docsRoot, commonsDirName); for (int i = 0; i < docDirs.length; i++) { final File dir = docDirs[i]; final File target = new File(latexBuildDir, docDirs[i].getName()); buildDirs[i] = target; copyDirectory(dir, target); if (commonsDir.exists()) { copyDirectory(commonsDir, target); } final Iterator iterator = iterateFiles(target, new String[] { ".svn" }, true); while (iterator.hasNext()) { FileUtils.deleteDirectory((File) iterator.next()); } } return buildDirs; } private File[] getDocDirs() { return docsRoot.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isDirectory() && !(pathname.getName().equals(commonsDirName)) && !(pathname.isHidden()); } }); } }