/* * $Id$ * * Copyright 2006, The jCoderZ.org Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the jCoderZ.org Project nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.jcoderz.commons.taskdefs; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.FileSet; import org.jcoderz.commons.util.IoUtil; /** * Ant task that performs XSL transformation for a set of input files. * * @author Michael Griffel */ public class XsltBatchProcessor extends Task { private String mStyleSheet = "default.xsl"; private FileSet mFiles = new FileSet(); private boolean mResolveExternalEntities = true; /** terminate ant build on error. */ private boolean mFailOnError = false; /** * Set whether we should fail on an error. * * @param b Whether we should fail on an error. */ public void setFailonerror (boolean b) { mFailOnError = b; } /** * Set the XSL Stylesheet to use. * * @param f The name of the XSL Stylesheet file. * @see XsltBasedTask#getDefaultStyleSheet() */ public void setXsl (String f) { mStyleSheet = f; } /** * XML files that are used as input documents for the * transformation. * * @param fs fileset of XML files. */ public void addFiles (FileSet fs) { mFiles = fs; } /** * {@inheritDoc} */ public void execute () throws BuildException { try { final XsltBasedTask xsltTask = new XsltBasedTask() { String getDefaultStyleSheet () { return mStyleSheet; } }; final Project myProject = getProject(); final DirectoryScanner ds = mFiles.getDirectoryScanner(myProject); final String[] includedFiles = ds.getIncludedFiles(); log("Transforming " + includedFiles.length + " files in directory " + ds.getBasedir()); for (int i = 0; i < includedFiles.length; i++) { final String f = includedFiles[i]; final File orig = new File(ds.getBasedir(), f); final File out; try { out = File.createTempFile("jcoderz", "tmp"); } catch (IOException e) { throw new BuildException( "Failed to create temp file: " + e, e); } xsltTask.setProject(myProject); xsltTask.setTaskName("xslt"); xsltTask.setIn(orig); xsltTask.setOut(out); xsltTask.setDestdir(myProject.getBaseDir()); xsltTask.setForce(true); xsltTask.setFailonerror(mFailOnError); xsltTask.setLogLevel(Project.MSG_VERBOSE); xsltTask.resolveExternalEntities(mResolveExternalEntities); log("Transforming file " + orig, Project.MSG_VERBOSE); xsltTask.execute(); if (out.exists()) { if (!orig.delete()) { throw new BuildException("Failed to delete " + orig); } if (!out.renameTo(orig)) { // try copy && delete try { safeMove(out, orig); } catch (IOException e) { throw new BuildException("Failed to move file " + out, e); } } } } } catch (BuildException e) { if (mFailOnError) { throw e; } log(e.getMessage(), Project.MSG_ERR); } } /** * If set to <tt>false</tt>, external entities will not be * resolved. * * @param b new value. */ public void resolveExternalEntities (boolean b) { mResolveExternalEntities = b; } private void safeMove (File source, File dest) throws IOException { final FileInputStream in = new FileInputStream(source); final FileOutputStream out = new FileOutputStream(dest); try { IoUtil.copy(in, out); if (!source.delete()) { throw new BuildException("Failed to delete " + source); } } finally { IoUtil.close(in); IoUtil.close(out); } } }