You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by ru...@locus.apache.org on 2000/04/26 21:09:19 UTC

cvs commit: jakarta-ant/src/main/org/apache/tools/ant BuildException.java Main.java ProjectHelper.java Target.java Task.java ApacheParser.java Parser.java SunParser.java parser.properties

rubys       00/04/26 12:09:18

  Modified:    .        bootstrap.bat bootstrap.sh build.bat build.sh
                        build.xml
               src/main/org/apache/tools/ant BuildException.java Main.java
                        ProjectHelper.java Target.java Task.java
  Removed:     lib      xml.jar
               src/main/org/apache/tools/ant ApacheParser.java Parser.java
                        SunParser.java parser.properties
  Log:
  Support JAXP and SAX1.0
  Submitted by: Matt Foemmel
  
  Revision  Changes    Path
  1.8       +1 -2      jakarta-ant/bootstrap.bat
  
  Index: bootstrap.bat
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/bootstrap.bat,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- bootstrap.bat	2000/03/17 23:15:35	1.7
  +++ bootstrap.bat	2000/04/26 19:09:15	1.8
  @@ -17,7 +17,7 @@
   echo.
   echo ... Bootstrapping Ant Distribution
   
  -set CLASSPATH=src\main;classes;lib\xml.jar
  +set CLASSPATH=src\main;classes;%CLASSPATH%
   if exist %JAVA_HOME%\lib\tools.jar set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\lib\tools.jar
   
   echo JAVA_HOME=%JAVA_HOME%
  @@ -40,7 +40,6 @@
   echo ... Copying Required Files
   
   copy %TOOLS%\ant\taskdefs\*.properties classes\org\apache\tools\ant\taskdefs
  -copy %TOOLS%\ant\*.properties          classes\org\apache\tools\ant
   
   echo.
   echo ... Building Ant Distribution
  
  
  
  1.9       +1 -2      jakarta-ant/bootstrap.sh
  
  Index: bootstrap.sh
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/bootstrap.sh,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- bootstrap.sh	2000/02/10 18:04:28	1.8
  +++ bootstrap.sh	2000/04/26 19:09:15	1.9
  @@ -5,7 +5,7 @@
   SRCDIR=src/main/org/apache/tools
   CLASSDIR=classes
   CLASSPATH=${CLASSPATH}:${JAVA_HOME}/lib/classes.zip:${JAVA_HOME}/lib/tools.jar
  -CLASSPATH=${CLASSPATH}:lib/xml.jar:src/main:${CLASSDIR}
  +CLASSPATH=${CLASSPATH}:src/main:${CLASSDIR}
   
   mkdir -p ${CLASSDIR}
   
  @@ -17,7 +17,6 @@
   javac  -d ${CLASSDIR} ${SRCDIR}/ant/taskdefs/*.java
   
   cp src/main/org/apache/tools/ant/taskdefs/defaults.properties ${CLASSDIR}/org/apache/tools/ant/taskdefs
  -cp src/main/org/apache/tools/ant/parser.properties ${CLASSDIR}/org/apache/tools/ant
   
   java org.apache.tools.ant.Main main
   java org.apache.tools.ant.Main clean 
  
  
  
  1.4       +1 -1      jakarta-ant/build.bat
  
  Index: build.bat
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/build.bat,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- build.bat	2000/01/14 13:50:24	1.3
  +++ build.bat	2000/04/26 19:09:15	1.4
  @@ -1,3 +1,3 @@
   @echo off
   REM convience bat file to build with
  -java -classpath "%CLASSPATH%;lib\ant.jar;lib\xml.jar" org.apache.tools.ant.Main %1 %2 %3 %4 %5
  +java -classpath "%CLASSPATH%;lib\ant.jar" org.apache.tools.ant.Main %1 %2 %3 %4 %5
  
  
  
  1.4       +1 -1      jakarta-ant/build.sh
  
  Index: build.sh
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/build.sh,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- build.sh	2000/01/14 13:50:24	1.3
  +++ build.sh	2000/04/26 19:09:15	1.4
  @@ -1,6 +1,6 @@
   #!/bin/sh
   
  -ADDL_CLASSPATH=./lib/ant.jar:./lib/xml.jar
  +ADDL_CLASSPATH=./lib/ant.jar
   
   if [ "$CLASSPATH" != "" ] ; then
     CLASSPATH=$CLASSPATH:$ADDL_CLASSPATH
  
  
  
  1.17      +1 -1      jakarta-ant/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/build.xml,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- build.xml	2000/04/01 15:17:29	1.16
  +++ build.xml	2000/04/26 19:09:15	1.17
  @@ -21,7 +21,7 @@
     <property name="build.javadocs" value="build/javadocs"/>
     <property name="ant.dist.dir" value="dist"/>
   
  -  <property name="classpath" value="lib/xml.jar"/>
  +  <property name="classpath" value=""/>
     <property name="packages" value="org.apache.tools.*"/>
     <property name="manifest" value="src/etc/manifest"/>
   
  
  
  
  1.4       +59 -10    jakarta-ant/src/main/org/apache/tools/ant/BuildException.java
  
  Index: BuildException.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/BuildException.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- BuildException.java	2000/03/19 01:22:23	1.3
  +++ BuildException.java	2000/04/26 19:09:17	1.4
  @@ -1,7 +1,7 @@
   /*
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 1999 The Apache Software Foundation.  All rights 
  + * Copyright (c) 1999 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -9,7 +9,7 @@
    * are met:
    *
    * 1. Redistributions of source code must retain the above copyright
  - *    notice, this list of conditions and the following disclaimer. 
  + *    notice, this list of conditions and the following disclaimer.
    *
    * 2. Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in
  @@ -17,15 +17,15 @@
    *    distribution.
    *
    * 3. The end-user documentation included with the redistribution, if
  - *    any, must include the following acknowlegement:  
  - *       "This product includes software developed by the 
  + *    any, must include the following acknowlegement:
  + *       "This product includes software developed by the
    *        Apache Software Foundation (http://www.apache.org/)."
    *    Alternately, this acknowlegement may appear in the software itself,
    *    if and wherever such third-party acknowlegements normally appear.
    *
    * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
    *    Foundation" must not be used to endorse or promote products derived
  - *    from this software without prior written permission. For written 
  + *    from this software without prior written permission. For written
    *    permission, please contact apache@apache.org.
    *
    * 5. Products derived from this software may not be called "Apache"
  @@ -50,7 +50,7 @@
    * individuals on behalf of the Apache Software Foundation.  For more
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
  - */ 
  + */
   
   package org.apache.tools.ant;
   
  @@ -65,10 +65,13 @@
       /** Exception that might have caused this one. */
       private Exception cause;
   
  +    /** Location in the build file where the exception occured */
  +    private Location location = Location.UNKNOWN_LOCATION;
  +
       /**
        * Constructs a build exception with no descriptive information.
        */
  -    
  +
       public BuildException() {
   	super();
       }
  @@ -77,7 +80,7 @@
        * Constructs an exception with the given descriptive message.
        * @param msg Description of or information about the exception.
        */
  -    
  +
       public BuildException(String msg) {
   	super(msg);
       }
  @@ -93,14 +96,60 @@
   	super(msg);
   	this.cause = cause;
       }
  -    
  +
       /**
  +     * Constructs an exception with the given message and exception as
  +     * a root cause and a location in a file.
  +     * @param msg Description of or information about the exception.
  +     * @param cause Exception that might have cause this one.
  +     * @param location Location in the project file where the error occured.
  +     */
  +
  +    public BuildException(String msg, Exception cause, Location location) {
  +        this(msg, cause);
  +	this.location = location;
  +    }
  +
  +    /**
        * Constructs an exception with the given exception as a root cause.
        * @param cause Exception that might have caused this one.
        */
  -    
  +
       public BuildException(Exception cause) {
   	super(cause.toString());
   	this.cause = cause;
  +    }
  +
  +    /**
  +     * Constructs an exception with the given descriptive message and a location
  +     * in a file.
  +     * @param msg Description of or information about the exception.
  +     * @param location Location in the project file where the error occured.
  +     */
  +
  +    public BuildException(String msg, Location location) {
  +	super(msg);
  +	this.location = location;
  +    }
  +
  +    /**
  +     * Returns the nested exception.
  +     */
  +    public Exception getException() {
  +        return cause;
  +    }
  +
  +    /**
  +     * Returns the location of the error and the error message.
  +     */
  +    public String toString() {
  +        return location.toString() + getMessage();
  +    }
  +
  +    /**
  +     * Sets the file location where the error occured.
  +     */
  +    public void setLocation(Location location) {
  +        this.location = location;
       }
   }
  
  
  
  1.6       +16 -8     jakarta-ant/src/main/org/apache/tools/ant/Main.java
  
  Index: Main.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/Main.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Main.java	2000/02/24 00:57:42	1.5
  +++ Main.java	2000/04/26 19:09:17	1.6
  @@ -141,7 +141,7 @@
   
                   /* Interestingly enough, we get to here when a user
                    * uses -Dname=value. However, in some cases, the JDK
  -                 * goes ahead * and parses this out to args 
  +                 * goes ahead * and parses this out to args
                    *   {"-Dname", "value"}
                    * so instead of parsing on "=", we just make the "-D"
                    * characters go away and skip one argument forward.
  @@ -189,7 +189,7 @@
   
           // ok, so if we've made it here, let's run the damn build allready
           runBuild();
  -        
  +
           return;
       }
   
  @@ -216,15 +216,23 @@
               project.setUserProperty(arg, value);
           }
   	project.setUserProperty( "ant.file" , buildFile.getAbsolutePath() );
  -	
  +
           // first use the ProjectHelper to create the project object
           // from the given build file.
           try {
  +            try {
  +                Class.forName("javax.xml.parsers.SAXParserFactory");
  +            } catch (ClassNotFoundException cnfe) {
  +                throw new BuildException(cnfe);
  +            }
               ProjectHelper.configureProject(project, buildFile);
           } catch (BuildException be) {
  -            String msg = "BUILD CONFIG ERROR: ";
  -            System.out.println(msg + be.getMessage());
  -            be.printStackTrace();
  +            System.out.println("\nBUILD CONFIG ERROR\n");
  +            if (be.getException() == null) {
  +                System.out.println(be.toString());
  +            } else {
  +                be.getException().printStackTrace();
  +	    }
               System.exit(1);
           }
   
  @@ -240,8 +248,8 @@
                   project.executeTarget((String) en.nextElement());
               }
           } catch (BuildException be) {
  -            String msg = "BUILD FATAL ERROR: ";
  -            System.out.println(msg + be.getMessage());
  +            String msg = "\nBUILD FATAL ERROR\n\n";
  +            System.out.println(msg + be.toString());
               if (msgOutputLevel > Project.MSG_INFO) {
                   be.printStackTrace();
               }
  
  
  
  1.12      +307 -212  jakarta-ant/src/main/org/apache/tools/ant/ProjectHelper.java
  
  Index: ProjectHelper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/ProjectHelper.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- ProjectHelper.java	2000/04/01 22:35:25	1.11
  +++ ProjectHelper.java	2000/04/26 19:09:17	1.12
  @@ -55,13 +55,13 @@
   package org.apache.tools.ant;
   
   import java.beans.*;
  -import java.io.File;
  -import java.io.IOException;
  +import java.io.*;
   import java.lang.reflect.*;
   import java.util.*;
  -import org.xml.sax.SAXException;
  +import org.xml.sax.*;
   import org.w3c.dom.*;
   import org.apache.tools.ant.taskdefs.*;
  +import javax.xml.parsers.*;
   
   /**
    * Configures a Project (complete with Targets and Tasks) based on
  @@ -72,228 +72,332 @@
   
   public class ProjectHelper {
   
  -    public static void configureProject(Project project, File buildFile)
  -        throws BuildException
  -    {
  +    private static SAXParserFactory parserFactory = null;
   
  -        // XXX
  -        // need to get rid of the DOM layer and use SAX
  +    private org.xml.sax.Parser parser;
  +    private Project project;
  +    private File buildFile;
  +    private Locator locator;
   
  -        Document doc;
  +    /**
  +     * Configures the Project with the contents of the specified XML file.
  +     */
  +    public static void configureProject(Project project, File buildFile) throws BuildException {
  +        new ProjectHelper(project, buildFile).parse();
  +    }
   
  +    /**
  +     * Constructs a new Ant parser for the specified XML file.
  +     */
  +    private ProjectHelper(Project project, File buildFile) {
  +        this.project = project;
  +        this.buildFile = buildFile;
  +    }
  +
  +    /**
  +     * Parses the project file.
  +     */
  +    private void parse() throws BuildException {
           try {
  -            doc=Parser.getParser(project).parse(buildFile);
  -        } catch (IOException ioe) {
  -            String msg = "Can't open config file: " + buildFile +
  -                " due to: " + ioe;
  -            throw new BuildException(msg);
  -        } catch (SAXException se) {
  -            String msg = "Can't open config file: " + buildFile +
  -                " due to: " + se;
  -            throw new BuildException(msg);
  +            parser = getParserFactory().newSAXParser().getParser();
  +            parser.setDocumentHandler(new RootHandler());
  +            parser.parse(new InputSource(new FileReader(buildFile)));
  +        }
  +        catch(ParserConfigurationException exc) {
  +            throw new BuildException("Parser has not been configured correctly", exc);
  +        }
  +        catch(SAXParseException exc) {
  +            Location location =
  +                new Location(buildFile.toString(), exc.getLineNumber(), exc.getColumnNumber());
  +            throw new BuildException(exc.getMessage(), exc.getException(), location);
  +        }
  +        catch(SAXException exc) {
  +            throw new BuildException(exc.getMessage(), exc.getException());
  +        }
  +        catch(FileNotFoundException exc) {
  +            throw new BuildException("File \"" + buildFile.toString() + "\" not found");
           }
  +        catch(IOException exc) {
  +            throw new BuildException("Error reading project file", exc);
  +        }
  +    }
   
  -        Element root = doc.getDocumentElement();
  +    /**
  +     * The common superclass for all sax event handlers in Ant. Basically
  +     * throws an exception in each method, so subclasses should override
  +     * what they can handle.
  +     *
  +     * Each type of xml element (task, target, etc) in ant will
  +     * have its own subclass of AbstractHandler.
  +     *
  +     * In the constructor, this class    takes over the handling of sax
  +     * events from the parent handler, and returns
  +     * control back to the parent in the endElement method.
  +     */
  +    private class AbstractHandler extends HandlerBase {
  +        protected DocumentHandler parentHandler;
   
  -        // sanity check, make sure that we have the right element
  -        // as we aren't validating the input
  +        public AbstractHandler(DocumentHandler parentHandler) {
  +            this.parentHandler = parentHandler;
   
  -        if (!root.getTagName().equals("project")) {
  -            String msg = "Config file is not of expected XML type";
  -            throw new BuildException(msg);
  +            // Start handling SAX events
  +            parser.setDocumentHandler(this);
           }
   
  -        project.setDefaultTarget(root.getAttribute("default"));
  +        public void startElement(String tag, AttributeList attrs) throws SAXParseException {
  +            throw new SAXParseException("Unexpected element \"" + tag + "\"", locator);
  +        }
   
  -        String name = root.getAttribute("name");
  -        project.setName(name);
  -        if (name != null) project.addReference(name, project);
  +        public void characters(char[] buf, int start, int end) throws SAXParseException {
  +            String s = new String(buf, start, end).trim();
   
  -        String id = root.getAttribute("id");
  -        if (id != null) project.addReference(id, project);
  +            if (s.length() > 0) {
  +                throw new SAXParseException("Unexpected text \"" + s + "\"", locator);
  +            }
  +        }
   
  -        String baseDir = project.getProperty("basedir");
  -        if (baseDir == null) {
  -            baseDir = root.getAttribute("basedir");
  -            if (baseDir.equals("")) {
  -                // Using clunky JDK1.1 methods here
  -                baseDir = new File(buildFile.getAbsolutePath()).getParent();
  +        public void endElement(String name) throws SAXException {
  +
  +            // Let parent resume handling SAX events
  +            parser.setDocumentHandler(parentHandler);
  +        }
  +    }
  +
  +    /**
  +     * Handler for the root element. It's only child must be the "project" element.
  +     */
  +    private class RootHandler extends HandlerBase {
  +        public void startElement(String tag, AttributeList attrs) throws SAXParseException {
  +            if (tag.equals("project")) {
  +                new ProjectHandler(this).init(tag, attrs);
  +            } else {
  +                throw new SAXParseException("Config file is not of expected XML type", locator);
               }
           }
  -        project.setBasedir(baseDir);
   
  -        // set up any properties that may be in the config file
  +        public void setDocumentLocator(Locator locator) {
  +            ProjectHelper.this.locator = locator;
  +        }
  +    }
  +
  +    /**
  +     * Handler for the top level "project" element.
  +     */
  +    private class ProjectHandler extends AbstractHandler {
  +        public ProjectHandler(DocumentHandler parentHandler) {
  +            super(parentHandler);
  +        }
  +
  +        public void init(String tag, AttributeList attrs) throws SAXParseException {
  +            String def = null;
  +            String name = null;
  +            String id = null;
  +            String baseDir = new File(buildFile.getAbsolutePath()).getParent();
  +
  +            for (int i = 0; i < attrs.getLength(); i++) {
  +                String key = attrs.getName(i);
  +                String value = attrs.getValue(i);
  +
  +                if (key.equals("default")) {
  +                    def = value;
  +                } else if (key.equals("name")) {
  +                    name = value;
  +                } else if (key.equals("id")) {
  +                    id = value;
  +                } else if (key.equals("basedir")) {
  +                    baseDir = value;
  +                } else {
  +                    throw new SAXParseException("Unexpected attribute \"" + attrs.getName(i) + "\"", locator);
  +                }
  +            }
  +
  +            project.setDefaultTarget(def);
  +
  +            project.setName(name);
  +            if (name != null) project.addReference(name, project);
  +
  +            if (id != null) project.addReference(id, project);
  +
  +            if (project.getProperty("basedir") != null) {
  +                project.setBasedir(project.getProperty("basedir"));
  +            } else {
  +                project.setBasedir(baseDir);
  +            }
  +
  +        }
   
  -        //      configureProperties(project, root);
  +        public void startElement(String name, AttributeList attrs) throws SAXParseException {
  +            if (name.equals("taskdef")) {
  +                handleTaskdef(name, attrs);
  +            } else if (name.equals("property")) {
  +                handleProperty(name, attrs);
  +            } else if (name.equals("target")) {
  +                handleTarget(name, attrs);
  +            } else {
  +                throw new SAXParseException("Unexpected element \"" + name + "\"", locator);
  +            }
  +        }
   
  -        // set up any task defs that may be in the config file
  +        private void handleTaskdef(String name, AttributeList attrs) throws SAXParseException {
  +            new TaskHandler(this, null).init(name, attrs);
  +        }
   
  -        //      configureTaskDefs(project, root);
  +        private void handleProperty(String name, AttributeList attrs) throws SAXParseException {
  +            new TaskHandler(this, null).init(name, attrs);
  +        }
   
  -        // set up the taskdefs, properties, and targets into the project
  -        configureProject(project, root);
  +        private void handleTarget(String tag, AttributeList attrs) throws SAXParseException {
  +            new TargetHandler(this).init(tag, attrs);
  +        }
       }
   
  -    private static void configureProject(Project project, Element root)
  -        throws BuildException
  -    {
  -        // configure taskdefs
  -        NodeList list = root.getElementsByTagName("taskdef");
  -        for (int i = 0; i < list.getLength(); i++) {
  -            Task taskdef = new Taskdef();
  -            configure(project, taskdef, (Element)list.item(i));
  -            taskdef.setProject(project);
  -            taskdef.init();
  -        }
  -
  -        // configure properties
  -        list = root.getElementsByTagName("property");
  -        for (int i = 0; i < list.getLength(); i++) {
  -            Task property = new Property();
  -            configure(project, property, (Element)list.item(i));
  -            property.setProject(project);
  -            property.init();
  -        }
  -
  -        // configure targets
  -        list = root.getElementsByTagName("target");
  -        for (int i = 0; i < list.getLength(); i++) {
  -            Element element = (Element)list.item(i);
  -            String targetName = element.getAttribute("name");
  -            String targetDep = element.getAttribute("depends");
  -            String targetCond = element.getAttribute("if");
  -            String targetId = element.getAttribute("id");
  -
  -            // all targets must have a name
  -            if (targetName.equals("")) {
  -                String msg = "target element appears without a name attribute";
  -                throw new BuildException(msg);
  +    /**
  +     * Handler for "target" elements.
  +     */
  +    private class TargetHandler extends AbstractHandler {
  +        private Target target;
  +
  +        public TargetHandler(DocumentHandler parentHandler) {
  +            super(parentHandler);
  +        }
  +
  +        public void init(String tag, AttributeList attrs) throws SAXParseException {
  +            String name = null;
  +            String depends = "";
  +            String cond = null;
  +            String id = null;
  +
  +            for (int i = 0; i < attrs.getLength(); i++) {
  +                String key = attrs.getName(i);
  +                String value = attrs.getValue(i);
  +
  +                if (key.equals("name")) {
  +                    name = value;
  +                } else if (key.equals("depends")) {
  +                    depends = value;
  +                } else if (key.equals("if")) {
  +                    cond = value;
  +                } else if (key.equals("id")) {
  +                    id = value;
  +                } else {
  +                    throw new SAXParseException("Unexpected attribute \"" + key + "\"", locator);
  +                }
  +            }
  +
  +            if (name == null) {
  +                throw new SAXParseException("target element appears without a name attribute", locator);
               }
   
  -            Target target = new Target();
  -            target.setName(targetName);
  -            target.setCondition(targetCond);
  -            project.addTarget(targetName, target);
  +            target = new Target();
  +            target.setName(name);
  +            target.setCondition(cond);
  +            project.addTarget(name, target);
   
  -            if (targetId != null && !targetId.equals("")) 
  -                project.addReference(targetId,target);
  +            if (id != null && !id.equals(""))
  +                project.addReference(id, target);
   
               // take care of dependencies
   
  -            if (targetDep.length() > 0) {
  -                StringTokenizer tok =
  -                    new StringTokenizer(targetDep, ",", false);
  +            if (depends.length() > 0) {
  +                StringTokenizer tok = 
  +                    new StringTokenizer(depends, ",", false);
                   while (tok.hasMoreTokens()) {
                       target.addDependency(tok.nextToken().trim());
                   }
               }
  -
  -            // populate target with tasks
  +        }
   
  -            configureTasks(project, target, element);
  +        public void startElement(String name, AttributeList attrs) throws SAXParseException {
  +            new TaskHandler(this, target).init(name, attrs);
           }
       }
   
  -    private static void configureTasks(Project project,
  -                                       Target target,
  -                                       Element targetElement)
  -        throws BuildException
  -    {
  -        NodeList list = targetElement.getChildNodes();
  -        for (int i = 0; i < list.getLength(); i++) {
  -            Node node = list.item(i);
  -
  -            // right now, all we are interested in is element nodes
  -            // not quite sure what to do with others except drop 'em
  -
  -            if (node.getNodeType() == Node.ELEMENT_NODE) {
  -                Element element = (Element)node;
  -                String taskType = element.getTagName();
  +    /**
  +     * Handler for all task elements.
  +     */
  +    private class TaskHandler extends AbstractHandler {
  +        private Target target;
  +        private Task task;
   
  -                // XXX
  -                // put in some sanity checking
  +        public TaskHandler(DocumentHandler parentHandler, Target target) {
  +            super(parentHandler);
   
  -                Task task = project.createTask(taskType);
  +            this.target = target;
  +        }
   
  -                // get the attributes of this element and reflect them
  -                // into the task
  +        public void init(String tag, AttributeList attrs) throws SAXParseException {
  +            task = project.createTask(tag);
  +            configure(task, attrs);
  +            task.setLocation(new Location(buildFile.toString(), locator.getLineNumber(), locator.getColumnNumber()));
  +            task.init();
   
  -                configure(project, task, element);
  -                task.init();
  +            // Top level tasks don't have associated targets
  +            if (target != null) {
                   task.setTarget(target);
                   target.addTask(task);
  +            }
  +        }
   
  -                processNestedProperties(project, task, element);
  +        public void characters(char[] buf, int start, int end) throws SAXParseException {
  +            String text = new String(buf, start, end).trim();
  +            if (text.length() == 0) return;
  +
  +            try {
  +                Method addProp = task.getClass().getMethod("addText", new Class[]{String.class});
  +                Object child = addProp.invoke(task, new Object[] {text});
  +            } catch(NoSuchMethodException exc) {
  +                throw new SAXParseException(task.getClass() + " does not support nested text elements", locator);
  +            } catch(InvocationTargetException exc) {
  +                throw new SAXParseException("Error invoking \"addText\" method", locator, exc);
  +            } catch(IllegalAccessException exc) {
  +                throw new SAXParseException("Unable to access \"addText\" method", locator, exc);
               }
           }
  +
  +        public void startElement(String name, AttributeList attrs) throws SAXParseException {
  +            new NestedPropertyHandler(this, task).init(name, attrs);
  +        }
       }
   
  -    private static void processNestedProperties(Project project,
  -                                                Object target,
  -                                                Element targetElement)
  -        throws BuildException
  -    {
  -        Class targetClass = target.getClass();
  -        NodeList list = targetElement.getChildNodes();
  +    /**
  +     * Handler for all nested properties.
  +     */
  +    private class NestedPropertyHandler extends AbstractHandler {
  +        private DocumentHandler parentHandler;
   
  -        for (int i = 0; i < list.getLength(); i++) {
  -            Node node = list.item(i);
  +        private Object target;
  +        private Object child;
   
  -            // right now, all we are interested in is element nodes
  -            // not quite sure what to do with others except drop 'em
  +        public NestedPropertyHandler(DocumentHandler parentHandler, Object target) {
  +            super(parentHandler);
   
  -            if (node.getNodeType() == Node.TEXT_NODE) {
  -                String text = ((Text)node).getData();
  -                try {
  -                    Method addProp = targetClass.getMethod(
  -                        "addText", new Class[]{"".getClass()});
  -                    Object child = addProp.invoke(target, new Object[] {text});
  -                } catch (NoSuchMethodException nsme) {
  -                    if (text.trim().length() > 0)
  -                        throw new BuildException(targetClass + 
  -                            " does not support nested text elements");
  -                } catch (InvocationTargetException ite) {
  -                    throw new BuildException(ite.getMessage());
  -                } catch (IllegalAccessException iae) {
  -                    throw new BuildException(iae.getMessage());
  -                }
  -            }
  +            this.target = target;
  +        }
   
  -            if (node.getNodeType() == Node.ELEMENT_NODE) {
  -                Element element = (Element)node;
  -                String propType = element.getTagName();
  -                String methodName = "create" +
  -		    Character.toUpperCase(propType.charAt(0)) +
  -                    propType.substring(1);
  -
  -                try {
  -                    Method addProp =
  -                        targetClass.getMethod(methodName, new Class[]{});
  -                    Object child = addProp.invoke(target, new Object[] {});
  -
  -                    configure(project, child, element);
  -
  -                    processNestedProperties(project, child, element);
  -                } catch (NoSuchMethodException nsme) {
  -                    throw new BuildException(targetClass + 
  -                        " does not support nested " + propType + " properties");
  -                } catch (InvocationTargetException ite) {
  -                    throw new BuildException(ite.getMessage());
  -                } catch (IllegalAccessException iae) {
  -                    throw new BuildException(iae.getMessage());
  -                }
  +        public void init(String propType, AttributeList attrs) throws SAXParseException {
  +            Class targetClass = target.getClass();
   
  +            String methodName = "create" + Character.toUpperCase(propType.charAt(0)) + propType.substring(1);
  +
  +            try {
  +                Method addProp = targetClass.getMethod(methodName, new Class[]{});
  +                child = addProp.invoke(target, new Object[] {});
  +                configure(child, attrs);
  +            } catch(NoSuchMethodException exc) {
  +                throw new SAXParseException(targetClass + " does not support nested " + propType + " properties", locator);
  +            } catch(InvocationTargetException exc) {
  +                throw new SAXParseException(exc.getMessage(), locator);
  +            } catch(IllegalAccessException exc) {
  +                throw new SAXParseException(exc.getMessage(), locator);
               }
           }
  -    }
   
  -    private static void configure(Project project,
  -                                  Object target,
  -                                  Element element)
  -        throws BuildException
  -    {
  -        NamedNodeMap nodeMap = element.getAttributes();
  +        public void startElement(String name, AttributeList attrs) throws SAXParseException {
  +            new NestedPropertyHandler(this, child).init(name, attrs);
  +        }
  +    }
   
  +    private void configure(Object target, AttributeList attrs) throws BuildException {
           if( target instanceof TaskAdapter )
               target=((TaskAdapter)target).getProxy();
   
  @@ -331,49 +435,41 @@
                   }
               }
           }
  -
  -        for (int i = 0; i < nodeMap.getLength(); i++) {
  -            Node node = nodeMap.item(i);
   
  -            // these should only be attribs, we won't see anything
  -            // else here.
  -
  -            if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
  -                Attr attr = (Attr)node;
  -
  -                // reflect these into the target
  -
  -                Method setMethod = (Method)propertySetters.get(attr.getName());
  -                if (setMethod == null) {
  -                    if (attr.getName().equals("id")) {
  -                        project.addReference(attr.getValue(), target);
  -                        continue;
  -                    }
  +        for (int i = 0; i < attrs.getLength(); i++) {
  +            // reflect these into the target
   
  -                    String msg = "Configuration property \"" + attr.getName() +
  -                        "\" does not have a setMethod in " + target.getClass();
  -                    throw new BuildException(msg);
  +            Method setMethod = (Method)propertySetters.get(attrs.getName(i));
  +            if (setMethod == null) {
  +                if (attrs.getName(i).equals("id")) {
  +                    project.addReference(attrs.getValue(i), target);
  +                    continue;
                   }
   
  -                String value=replaceProperties(  attr.getValue(), project.getProperties() );
  -                try {
  -                    setMethod.invoke(target, new String[] {value});
  -                } catch (IllegalAccessException iae) {
  -                    String msg = "Error setting value for attrib: " +
  -                        attr.getName();
  -                    iae.printStackTrace();
  -                    throw new BuildException(msg);
  -                } catch (InvocationTargetException ie) {
  -                    String msg = "Error setting value for attrib: " +
  -                        attr.getName() + " in " + target.getClass().getName();
  -                    ie.printStackTrace();
  -                    ie.getTargetException().printStackTrace();
  -                    throw new BuildException(msg);
  -                }
  +                String msg = "Class " + target.getClass() +
  +                    " doesn't support the \"" + attrs.getName(i) + "\" property";
  +                throw new BuildException(msg);
  +            }
  +
  +            String value=replaceProperties(attrs.getValue(i), project.getProperties() );
  +            try {
  +                setMethod.invoke(target, new String[] {value});
  +            } catch (IllegalAccessException iae) {
  +                String msg = "Error setting value for attrib: " +
  +                    attrs.getName(i);
  +                iae.printStackTrace();
  +                throw new BuildException(msg);
  +            } catch (InvocationTargetException ie) {
  +                String msg = "Error setting value for attrib: " +
  +                    attrs.getName(i) + " in " + target.getClass().getName();
  +                ie.printStackTrace();
  +                ie.getTargetException().printStackTrace();
  +                throw new BuildException(msg);
               }
           }
       }
   
  +
       /** Replace ${NAME} with the property value
        */
       public static String replaceProperties( String value, Hashtable keys )
  @@ -411,13 +507,12 @@
           // System.out.println("Before replace: " + value);
           return sb.toString();
       }
  -}
  -
  -
  -
  -
   
  -
  -
  -
  +    private static SAXParserFactory getParserFactory() {
  +        if (parserFactory == null) {
  +            parserFactory = SAXParserFactory.newInstance();
  +        }
   
  +        return parserFactory;
  +    }
  +}
  
  
  
  1.4       +7 -1      jakarta-ant/src/main/org/apache/tools/ant/Target.java
  
  Index: Target.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/Target.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Target.java	2000/02/13 18:19:59	1.3
  +++ Target.java	2000/04/26 19:09:17	1.4
  @@ -117,7 +117,13 @@
               Enumeration enum = tasks.elements();
               while (enum.hasMoreElements()) {
                   Task task = (Task) enum.nextElement();
  -                task.execute();
  +
  +                try {
  +               	    task.execute();
  +		} catch(BuildException exc) {
  +		    exc.setLocation(task.getLocation());
  +		    throw exc;
  +		}
               }
           } else {
               project.log("Skipped because property '" + this.condition + "' not set.", this.name, Project.MSG_VERBOSE);
  
  
  
  1.5       +18 -4     jakarta-ant/src/main/org/apache/tools/ant/Task.java
  
  Index: Task.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/Task.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Task.java	2000/02/24 21:57:20	1.4
  +++ Task.java	2000/04/26 19:09:17	1.5
  @@ -57,13 +57,14 @@
   /**
    * Base class for all tasks.
    */
  - 
  +
   public abstract class Task {
   
       protected Project project = null;
       protected Target target = null;
       protected String description=null;
  -    
  +    protected Location location = Location.UNKNOWN_LOCATION;
  +
       /**
        * Sets the project object of this task. This method is used by
        * project when a task is added to it so that the task has
  @@ -87,7 +88,7 @@
   
       /** Sets a description of the current action. It will be usefull in commenting
        *  what we are doing.
  -     */ 
  +     */
       public void setDescription( String desc ) {
   	description=desc;
       }
  @@ -95,7 +96,7 @@
       public String getDescription() {
   	return description;
       }
  -    
  +
       /**
        * Called by the project to let the task initialize properly. Normally it does nothing.
        *
  @@ -110,5 +111,18 @@
        */
       public void execute() throws BuildException {};
   
  +    /**
  +     * Returns the file location where this task was defined.
  +     */
  +    public Location getLocation() {
  +        return location;
  +    }
  +
  +    /**
  +     * Sets the file location where this task was defined.
  +     */
  +    public void setLocation(Location location) {
  +        this.location = location;
  +    }
   }
   
  
  
  

Re: cvs commit: jakarta-ant/src/main/org/apache/tools/ant BuildException.java Main.java ProjectHelper.java Target.java Task.java ApacheParser.java Parser.java SunParser.java parser.properties

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
rubys@locus.apache.org wrote:

> rubys       00/04/26 12:09:18
>
>   Modified:    .        bootstrap.bat bootstrap.sh build.bat build.sh
>                         build.xml
>                src/main/org/apache/tools/ant BuildException.java Main.java
>                         ProjectHelper.java Target.java Task.java
>   Removed:     lib      xml.jar
>                src/main/org/apache/tools/ant ApacheParser.java Parser.java
>                         SunParser.java parser.properties
>   Log:
>   Support JAXP and SAX1.0
>   Submitted by: Matt Foemmel
>

While we are messing around with the build process for Ant, how about taking this opportunity to conform to the place other
Jakarta projects create their "build" and "dist" outputs?  For Taglibs/Tomcat/Watchdog, they go to ../build/xxxx and ../dist/xxxx
rather than embedded in the project directory like Ant currently does.

Craig McClanahan