Browse Source

Support JAXP and SAX1.0

Submitted by: Matt Foemmel


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@267656 13f79535-47bb-0310-9956-ffa450edef68
master
Sam Ruby 25 years ago
parent
commit
fe4a5cb029
14 changed files with 415 additions and 536 deletions
  1. +1
    -2
      bootstrap.bat
  2. +1
    -2
      bootstrap.sh
  3. +1
    -1
      build.bat
  4. +1
    -1
      build.sh
  5. +1
    -1
      build.xml
  6. +0
    -98
      src/main/org/apache/tools/ant/ApacheParser.java
  7. +59
    -10
      src/main/org/apache/tools/ant/BuildException.java
  8. +16
    -8
      src/main/org/apache/tools/ant/Main.java
  9. +0
    -111
      src/main/org/apache/tools/ant/Parser.java
  10. +310
    -215
      src/main/org/apache/tools/ant/ProjectHelper.java
  11. +0
    -81
      src/main/org/apache/tools/ant/SunParser.java
  12. +7
    -1
      src/main/org/apache/tools/ant/Target.java
  13. +18
    -4
      src/main/org/apache/tools/ant/Task.java
  14. +0
    -1
      src/main/org/apache/tools/ant/parser.properties

+ 1
- 2
bootstrap.bat View File

@@ -17,7 +17,7 @@ if "" == "%JAVAC%" set JAVAC=%JAVA_HOME%\bin\javac
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.
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
- 2
bootstrap.sh View File

@@ -5,7 +5,7 @@ fi
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/*.java
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
- 1
build.bat View File

@@ -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
- 1
build.sh View File

@@ -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
- 1
build.xml View File

@@ -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"/>



+ 0
- 98
src/main/org/apache/tools/ant/ApacheParser.java View File

@@ -1,98 +0,0 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* 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
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* 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
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
* ITS 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* 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;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.lang.reflect.Method;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* Implementation of Parser using Apache Xerces-J.
*
* @author pier@apache.org
*/
public class ApacheParser extends Parser {

Class DOMParser = null;
Method parse;
Method getDocument;

/**
* Parse the specified file and return a DOM Document.
*/
public Document parse(File buildFile)
throws SAXException, IOException {
try {
if (DOMParser == null) {
DOMParser = Class.forName("org.apache.xerces.parsers.DOMParser");
parse = DOMParser.getMethod("parse", new Class[]{String.class});
getDocument = DOMParser.getMethod("getDocument", new Class[]{});
}

Object p=DOMParser.newInstance();
URL url=new URL("file","",buildFile.getAbsolutePath());
parse.invoke(p, new Object[]{url.toExternalForm()});
return(org.w3c.dom.Document)getDocument.invoke(p, new Object[]{});
} catch (Exception e) {
if (e instanceof IOException) throw (IOException)e;
if (e instanceof SAXException) throw (SAXException)e;
throw new IOException(e.toString());
}
}
}

+ 59
- 10
src/main/org/apache/tools/ant/BuildException.java View File

@@ -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 @@ public class BuildException extends RuntimeException {
/** 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 @@ public class BuildException extends RuntimeException {
* 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 @@ public class BuildException extends RuntimeException {
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;
}
}

+ 16
- 8
src/main/org/apache/tools/ant/Main.java View File

@@ -141,7 +141,7 @@ public class Main {

/* 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 @@ public class Main {

// ok, so if we've made it here, let's run the damn build allready
runBuild();
return;
}

@@ -216,15 +216,23 @@ public class Main {
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 @@ public class Main {
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();
}


+ 0
- 111
src/main/org/apache/tools/ant/Parser.java View File

@@ -1,111 +0,0 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* 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
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* 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
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
* ITS 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* 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;

import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.util.Properties;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
* Dummy parser abstraction class for ANT to be used until the Java API for
* XML Parsing are released.
*
* @author pier@apache.org
*/
public abstract class Parser {
// The properties file to be loaded
private static String properties="org/apache/tools/ant/parser.properties";

/**
* Create a working instance of a parser
*/
public static Parser getParser(Project project)
throws BuildException {
InputStream in=project.getClass().getResourceAsStream("parser.properties");
if (in==null) throw new BuildException("Cannot find properties file");

String name;
try {
Properties prop=new Properties();
prop.load(in);
name=prop.getProperty("parser");
if (name==null) throw new BuildException("Parser name not found");
} catch(IOException e) {
throw new BuildException("Cannot load properties file");
}
try {
return((Parser)Class.forName(name).newInstance());
} catch (ClassNotFoundException e) {
throw new BuildException("Class "+name+" cannot be found");
} catch (InstantiationException e) {
throw new BuildException("Class "+name+" cannot be instantiated");
} catch (IllegalAccessException e) {
throw new BuildException("Class "+name+" cannot be accessed");
} catch (ClassCastException e) {
throw new BuildException("Class "+name+" doesn't extend Parser");
}
}
/**
* Parse the specified file and return a DOM Document.
*/
public abstract Document parse(File f)
throws SAXException, IOException;
}


+ 310
- 215
src/main/org/apache/tools/ant/ProjectHelper.java View File

@@ -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 @@ import org.apache.tools.ant.taskdefs.*;

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);
}

public void startElement(String tag, AttributeList attrs) throws SAXParseException {
throw new SAXParseException("Unexpected element \"" + tag + "\"", locator);
}

project.setDefaultTarget(root.getAttribute("default"));
public void characters(char[] buf, int start, int end) throws SAXParseException {
String s = new String(buf, start, end).trim();

String name = root.getAttribute("name");
project.setName(name);
if (name != null) project.addReference(name, project);
if (s.length() > 0) {
throw new SAXParseException("Unexpected text \"" + s + "\"", locator);
}
}

String id = root.getAttribute("id");
if (id != null) project.addReference(id, project);
public void endElement(String name) throws SAXException {

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();
// 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);

// configureProperties(project, root);
project.setName(name);
if (name != null) project.addReference(name, project);

// set up any task defs that may be in the config file
if (id != null) project.addReference(id, project);

// configureTaskDefs(project, root);
if (project.getProperty("basedir") != null) {
project.setBasedir(project.getProperty("basedir"));
} else {
project.setBasedir(baseDir);
}

// set up the taskdefs, properties, and targets into the project
configureProject(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);
}
}

private void handleTaskdef(String name, AttributeList attrs) throws SAXParseException {
new TaskHandler(this, null).init(name, attrs);
}

private void handleProperty(String name, AttributeList attrs) throws SAXParseException {
new TaskHandler(this, null).init(name, attrs);
}

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);
}
}

Target target = new Target();
target.setName(targetName);
target.setCondition(targetCond);
project.addTarget(targetName, target);
if (name == null) {
throw new SAXParseException("target element appears without a name attribute", locator);
}

if (targetId != null && !targetId.equals(""))
project.addReference(targetId,target);
target = new Target();
target.setName(name);
target.setCondition(cond);
project.addTarget(name, 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();

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.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());
}
}
/**
* Handler for all nested properties.
*/
private class NestedPropertyHandler extends AbstractHandler {
private DocumentHandler parentHandler;

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());
}
private Object target;
private Object child;

public NestedPropertyHandler(DocumentHandler parentHandler, Object target) {
super(parentHandler);

this.target = target;
}

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();

@@ -332,48 +436,40 @@ public class ProjectHelper {
}
}

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
for (int i = 0; i < attrs.getLength(); i++) {
// 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;
}

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 @@ public class ProjectHelper {
// System.out.println("Before replace: " + value);
return sb.toString();
}
}








private static SAXParserFactory getParserFactory() {
if (parserFactory == null) {
parserFactory = SAXParserFactory.newInstance();
}

return parserFactory;
}
}

+ 0
- 81
src/main/org/apache/tools/ant/SunParser.java View File

@@ -1,81 +0,0 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* 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
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* 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
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
* ITS 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* 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;

import java.io.File;
import java.io.IOException;
import com.sun.xml.parser.Resolver;
import com.sun.xml.tree.XmlDocument;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* Implementation of Parser using Sun ProjectX.
*
* @author pier@apache.org
*/
public class SunParser extends Parser {
/**
* Parse the specified file and return a DOM Document.
*/
public Document parse(File buildFile)
throws SAXException, IOException {
InputSource input = Resolver.createInputSource(buildFile);
return XmlDocument.createXmlDocument(input, false);
}
}


+ 7
- 1
src/main/org/apache/tools/ant/Target.java View File

@@ -117,7 +117,13 @@ public class Target {
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);


+ 18
- 4
src/main/org/apache/tools/ant/Task.java View File

@@ -57,13 +57,14 @@ package org.apache.tools.ant;
/**
* 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 @@ public abstract class Task {

/** 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 abstract class Task {
public String getDescription() {
return description;
}
/**
* Called by the project to let the task initialize properly. Normally it does nothing.
*
@@ -110,5 +111,18 @@ public abstract class Task {
*/
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;
}
}


+ 0
- 1
src/main/org/apache/tools/ant/parser.properties View File

@@ -1 +0,0 @@
parser=org.apache.tools.ant.SunParser

Loading…
Cancel
Save