Package net.sourceforge.chaperon.ant

Source Code of net.sourceforge.chaperon.ant.ChaperonParse

/*
*  Copyright (C) Chaperon. All rights reserved.                              
*  -------------------------------------------------------------------------
*  This software is published under the terms of the Apache Software License
*  version 1.1, a copy of which has been included  with this distribution in
*  the LICENSE file.                                                        
*/
package net.sourceforge.chaperon.ant;

import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.xml.serialize.Method;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.xml.sax.InputSource;
import net.sourceforge.chaperon.parser.output.EventQueue;
import net.sourceforge.chaperon.parser.output.SAXEventAdapter;
import net.sourceforge.chaperon.parser.ParserException;
import net.sourceforge.chaperon.parser.Parser;
import net.sourceforge.chaperon.parser.ParserTable;

/**
* A ant task for parsing text files
*
* @author Stephan Michels
* @version %version%
*/
public class ChaperonParse extends MatchingTask
{
  private File destDir = null;

  private File baseDir = null;

  private String parsertableFilename = null;

  private String targetExtension = ".xml";
  private Vector params = new Vector();

  private File inFile = null;

  private File outFile = null;

  private String encoding = null;
  private boolean ignorableTokens = false;
  private boolean indent = false;

  private FileUtils fileUtils;

  private int msgLevel = Project.MSG_ERR;
  private AntLogger logger;

  private Parser parser;
  private SAXEventAdapter adapter;

  /**
   * Constructs the task
   */
  public ChaperonParse()
  {
    fileUtils = FileUtils.newFileUtils();
  }

  /**
   * Executes the task
   *
   * @throws BuildException
   */
  public void execute() throws BuildException
  {
    logger = new AntLogger(this, msgLevel);
    parser = new Parser();
    parser.enableLogging(logger)

    DirectoryScanner scanner;
    String[] list;
    String[] dirs;

    if (parsertableFilename == null)
      throw new BuildException("no parsertable specified", location);

    if (baseDir == null)
      baseDir = project.resolveFile(".");

    File parsertableFile = project.resolveFile(parsertableFilename);

    if (!parsertableFile.exists())
    {
      parsertableFile = fileUtils.resolveFile(baseDir, parsertableFilename);
      if (parsertableFile.exists())
      {
        log("DEPRECATED - the parsertable attribute should be relative to the project\'s");
        log("             basedir, not the tasks\'s basedir.");
      }
    }

    if ((inFile != null) && (outFile != null))
    {
      process(inFile, outFile, parsertableFile);
      return;
    }

    if (destDir == null)
    {
      String msg = "destdir attributes must be set!";

      throw new BuildException(msg);
    }
    scanner = getDirectoryScanner(baseDir);
    log("Transforming into " + destDir, Project.MSG_INFO);

    list = scanner.getIncludedFiles();
    for (int i = 0; i < list.length; ++i)
      process(baseDir, list[i], destDir, parsertableFile);

    dirs = scanner.getIncludedDirectories();
    for (int j = 0; j < dirs.length; ++j)
    {
      list = new File(baseDir, dirs[j]).list();
      for (int i = 0; i < list.length; ++i)
        process(baseDir, list[i], destDir, parsertableFile);
    }
  }

  /**
   * Set the base directory.
   *
   * @param dir Base directory
   */
  public void setBasedir(File dir)
  {
    baseDir = dir;
  }

  /**
   * Set the destination directory into which the result
   * files should be copied to
   *
   * @param dir Destination directory
   */
  public void setDestdir(File dir)
  {
    destDir = dir;
  }

  /**
   * Set the desired file extension to be used for the target
   *
   * @param name The extension to use
   */
  public void setExtension(String name)
  {
    targetExtension = name;
  }

  /**
   * Sets the parsertable to use for parsing relative to the base directory
   * of this task.
   *
   * @param parsertableFilename File name of the parser table
   */
  public void setParserTable(String parsertableFilename)
  {
    this.parsertableFilename = parsertableFilename;
  }

  /**
   * Sets an output file
   *
   * @param outFile The output file   
   */
  public void setOut(File outFile)
  {
    this.outFile = outFile;
  }

  /**
   * Sets an input xml file to be parsed
   *
   * @param inFile The input file
   */
  public void setIn(File inFile)
  {
    this.inFile = inFile;
  }

  /**
   * Sets the message level
   *
   * @param inFile The grammar file
   */
  public void setMsglevel(String msgLevel)
  {
    if (msgLevel.equalsIgnoreCase("debug"))
      this.msgLevel = Project.MSG_DEBUG;
    else if (msgLevel.equalsIgnoreCase("verbose"))
      this.msgLevel = Project.MSG_VERBOSE;
    else if (msgLevel.equalsIgnoreCase("info"))
      this.msgLevel = Project.MSG_INFO;
    else if (msgLevel.equalsIgnoreCase("warn"))
      this.msgLevel = Project.MSG_WARN;
    else if (msgLevel.equalsIgnoreCase("error"))
      this.msgLevel = Project.MSG_ERR;
  }

  /**
   * Sets the encoding for the input file
   *
   * @param encoding Encoding of the document
   */
  public void setEncoding(String encoding)
  {
    this.encoding = encoding;
  }

  /**
   * Set if the output document should include
   * the ignorable tokens
   *
   * @param ignorableTokens If the output document should include
   *                        the ignorable tokens
   */
  public void setIgnorabletokens(boolean ignorableTokens)
  {
    this.ignorableTokens = ignorableTokens;
  }

  /**
   * Set if the output document should be indented
   *
   * @param ignorableTokens If the output document should be indented
   *                        the ignorable tokens
   */
  public void setIndent(boolean indent)
  {
    this.indent = indent;
  }

  /**
   * Processes the given input XML file and stores the result
   * in the given resultFile.
   *
   * @param baseDir Base directory
   * @param xmlFile File, which should parsed
   * @param destDir Destination directory
   * @param parsertableFile Parser table file
   *
   * @throws BuildException
   */
  private void process(File baseDir, String xmlFile, File destDir,
                       File parsertableFile) throws BuildException
  {
    String fileExt = targetExtension;
    File outFile = null;
    File inFile = null;

    try
    {
      long parsertableLastModified = parsertableFile.lastModified();

      inFile = new File(baseDir, xmlFile);
      int dotPos = xmlFile.lastIndexOf('.');

      if (dotPos > 0)
        outFile = new File(destDir,
                           xmlFile.substring(0, xmlFile.lastIndexOf('.'))
                           + fileExt);
      else
        outFile = new File(destDir, xmlFile + fileExt);

      if (!inFile.exists())
      {
        log("File " + inFile + " doesn't exists");
        return;
      }

      if (!parsertableFile.exists())
      {
        log("File " + parsertableFile + " doesn't exists");
        return;
      }

      if ((inFile.lastModified() > outFile.lastModified())
              || (parsertableLastModified > outFile.lastModified()))
      {
        ensureDirectoryFor(outFile);
        log("Parsing files from " + destDir);

        ObjectInputStream in = new ObjectInputStream(new FileInputStream(parsertableFile));

        EventQueue queue = parser.parse((ParserTable)in.readObject(), new FileInputStream(inFile), encoding);
        in.close();

        OutputFormat format = new OutputFormat(Method.XML, "ASCII", indent); // Serialize DOM

        if (indent)
        {
          format.setIndenting(true);
          format.setIndent(1);
        }
        else
          format.setPreserveSpace(true);

        StringWriter stringOut = new StringWriter(); // Writer will be a String
        XMLSerializer serial = new XMLSerializer(stringOut, format);

        SAXEventAdapter adapter = new SAXEventAdapter(serial.asContentHandler(), ignorableTokens, false);
        adapter.enableLogging(new AntLogger(this, msgLevel));
        queue.fireEvents(adapter);

        FileOutputStream outputstream = new FileOutputStream(outFile);
        PrintWriter printstream = new PrintWriter(outputstream);

        printstream.println(stringOut.toString());
        printstream.flush();
        printstream.close();
      }
    }
    catch (Exception ex)
    {
      log("Failed to process " + inFile, Project.MSG_INFO);
      if (outFile != null)
        outFile.delete();

      if (ex instanceof ParserException)
      {
        log(ex.toString());
        throw new BuildException("Parsing faild");
      }
      else
      {
        ex.printStackTrace();
        throw new BuildException(ex);
      }
    }
  }

  /**
   * Processes the given input XML file and stores the result
   * in the given resultFile.
   *
   * @param inFile The text file, which should parsed
   * @param outFile The output file
   * @param parsertableFile Parser table file
   *
   * @throws BuildException
   */
  private void process(File inFile, File outFile,
                       File parsertableFile) throws BuildException
  {
    try
    {
      long parsertableLastModified = parsertableFile.lastModified();

      log("In file " + inFile + " time: " + inFile.lastModified(),
          Project.MSG_DEBUG);
      log("Out file " + outFile + " time: " + outFile.lastModified(),
          Project.MSG_DEBUG);
      log("Parsertable file " + parsertableFile + " time: "
          + parsertableLastModified, Project.MSG_DEBUG);

      if (!inFile.exists())
      {
        log("File " + inFile + " doesn't exists");
        return;
      }

      if (!parsertableFile.exists())
      {
        log("File " + parsertableFile + " doesn't exists");
        return;
      }

      if ((inFile.lastModified() > outFile.lastModified())
              || (parsertableLastModified > outFile.lastModified()))
      {
        ensureDirectoryFor(outFile);
        log("Parsing file " + inFile + " to " + outFile, Project.MSG_INFO);

        ObjectInputStream in = new ObjectInputStream(new FileInputStream(parsertableFile));
       
        EventQueue queue = parser.parse((ParserTable)in.readObject(), new FileInputStream(inFile), encoding);
        in.close();

        OutputFormat format = new OutputFormat(Method.XML, "ASCII", indent); // Serialize DOM

        if (indent)
        {
          format.setIndenting(true);
          format.setIndent(1);
        }
        else
          format.setPreserveSpace(true);

        StringWriter stringOut = new StringWriter(); // Writer will be a String
        XMLSerializer serial = new XMLSerializer(stringOut, format);

        SAXEventAdapter adapter = new SAXEventAdapter(serial.asContentHandler(), ignorableTokens, false);
        adapter.enableLogging(new AntLogger(this, msgLevel));
        queue.fireEvents(adapter);

        FileOutputStream outputstream = new FileOutputStream(outFile);
        PrintWriter printstream = new PrintWriter(outputstream);

        printstream.println(stringOut.toString());
        printstream.flush();
        printstream.close();
      }
    }
    catch (Exception ex)
    {
      log("Failed to process " + inFile, Project.MSG_INFO);
      if (outFile != null)
        outFile.delete();

      if (ex instanceof ParserException)
      {
        log(ex.toString());
        throw new BuildException("Parsing faild");
      }
      else
      {
        ex.printStackTrace();
        throw new BuildException(ex);
      }
    }
  }

  /**
   * Ensures the directory for the output
   *
   * @param targetFile The directory
   *
   * @throws BuildException
   */
  private void ensureDirectoryFor(File targetFile) throws BuildException
  {
    File directory = new File(targetFile.getParent());

    if ((!directory.exists()) && (!directory.mkdirs()))
      throw new BuildException("Unable to create directory: "
                               + directory.getAbsolutePath());
  }
}
TOP

Related Classes of net.sourceforge.chaperon.ant.ChaperonParse

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.