blob: ef561d7710145f5d04528fc968e920903f9c3117 [file] [log] [blame]
/* Copyright (c) 2000 The Apache Software Foundation */
package org.apache.tools.ant.xml;
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import org.apache.tools.ant.*;
import org.xml.sax.*;
import org.xml.sax.ext.*;
import org.xml.sax.helpers.*;
/**
* This class populates a Project object via SAX events.
*/
public class ProjectHandler extends DefaultHandler /* implements LexicalHandler */ {
private Workspace workspace;
private Project project;
private Locator locator;
/**
* The top of this stack represents the "current" event handler.
*/
private Stack handlers;
/**
* Constructs a SAX handler for the specified project.
*/
public ProjectHandler(Project project) {
this.project = project;
this.workspace = project.getWorkspace();
this.handlers = new Stack();
this.handlers.push(new RootHandler());
}
public Project getProject() {
return project;
}
public void setDocumentLocator(Locator locator) {
this.locator = locator;
}
protected String getLocation() {
return locator.getPublicId() + ":" + locator.getLineNumber();
}
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
// Delegate to the current handler
((ContentHandler)handlers.peek()).startElement(namespaceURI, localName, qName, atts);
}
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
// Delegate to the current handler
((ContentHandler)handlers.peek()).endElement(namespaceURI, localName, qName);
}
public void characters(char[] ch, int start, int length) {
//XXX need to implement text content
}
public void processingInstruction(String target, String data) {
System.out.println("@" + target + "@" + data + "@");
}
/*
public void comment(char[] ch, int start, int length) {)
public void endCDATA() {}
public void endDTD() {}
public void endEntity(java.lang.String name) {}
public void startCDATA() {}
public void startDTD(String name, String publicId, String systemId) {}
public void startEntity(java.lang.String name) {}
*/
/**
* This class handles any top level SAX events.
*/
private class RootHandler extends DefaultHandler {
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if (isAntNamespace(namespaceURI) && localName.equals("project")) {
handlers.push(new ProjectElemHandler(qName, atts));
}
else {
throw new SAXParseException("Unexpected element \"" + qName + "\"", locator);
}
}
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
handlers.pop();
}
}
/**
* This class handles events that occur with a "project" element.
*/
private class ProjectElemHandler extends DefaultHandler {
public ProjectElemHandler(String qName, Attributes atts) throws SAXException {
String projectName = null;
for (int i = 0; i < atts.getLength(); i++) {
if (!isAntNamespace(atts.getURI(i))) {
continue;
}
String name = atts.getQName(i);
String value = atts.getValue(i);
if (name.equals("name")) {
projectName = value;
}
else {
throw new SAXParseException("Unexpected attribute \"" + name + "\"", locator);
}
}
if (projectName == null) {
throw new SAXParseException("Missing attribute \"name\"", locator);
}
if (!projectName.equals(project.getName())) {
throw new SAXParseException("A project named \"" + projectName + "\" must be located in a file called \"" + projectName + ".ant\"", locator);
}
}
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if (isAntNamespace(namespaceURI) && localName.equals("target")) {
handlers.push(new TargetElemHandler(project, qName, atts));
}
else if (isAntNamespace(namespaceURI) && localName.equals("import")) {
handlers.push(new ImportElemHandler(project, qName, atts));
}
else {
throw new SAXParseException("Unexpected element \"" + qName + "\"", locator);
}
}
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
handlers.pop();
}
}
/**
* This class handles events that occur with a "target" element.
*/
private class TargetElemHandler extends DefaultHandler {
private Target target;
public TargetElemHandler(Project project, String qName, Attributes atts) throws SAXException {
String targetName = null;
String dependencies = "";
for (int i = 0; i < atts.getLength(); i++) {
if (!isAntNamespace(atts.getURI(i))) {
continue;
}
String name = atts.getQName(i);
String value = atts.getValue(i);
if (name.equals("name")) {
targetName = value;
}
else if (name.equals("depends")) {
dependencies = value;
}
else {
throw new SAXParseException("Unexpected attribute \"" + name + "\"", locator);
}
}
if (targetName == null) {
throw new SAXParseException("Missing attribute \"name\"", locator);
}
try {
target = project.createTarget(targetName);
target.setLocation(getLocation());
parseDepends(dependencies);
}
catch(BuildException exc) {
throw new SAXException(exc);
}
}
/**
* Parses the list of space-separated project names.
*/
private void parseDepends(String depends) {
StringTokenizer tokenizer = new StringTokenizer(depends);
while (tokenizer.hasMoreTokens()) {
String targetName = tokenizer.nextToken();
target.addDepend(targetName);
}
}
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if (!isAntNamespace(namespaceURI)) {
throw new SAXParseException("Unexpected attribute \"" + qName + "\"", locator);
}
TaskProxy proxy = target.createTaskProxy(qName);
proxy.setLocation(getLocation());
handlers.push(new TaskElemHandler(proxy.getData(), qName, atts));
}
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
handlers.pop();
}
}
/**
* This class handles events that occur with a "import" element.
*/
private class ImportElemHandler extends DefaultHandler {
public ImportElemHandler(Project project, String qName, Attributes atts) throws SAXException {
String importName = null;
for (int i = 0; i < atts.getLength(); i++) {
if (!isAntNamespace(atts.getURI(i))) {
continue;
}
String name = atts.getQName(i);
String value = atts.getValue(i);
if (name.equals("name")) {
importName = value;
}
else {
throw new SAXParseException("Unexpected attribute \"" + name + "\"", locator);
}
}
if (importName == null) {
throw new SAXParseException("Missing attribute \"name\"", locator);
}
Import imp = project.createImport(importName);
imp.setLocation(getLocation());
}
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
throw new SAXParseException("Unexpected element \"" + qName + "\"", locator);
}
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
handlers.pop();
}
}
/**
* This class handles events that occur with a task element.
*/
private class TaskElemHandler extends DefaultHandler {
private TaskData data;
public TaskElemHandler(TaskData data, String qName, Attributes atts) throws SAXException {
this.data = data;
for (int i = 0; i < atts.getLength(); i++) {
if (!isAntNamespace(atts.getURI(i))) {
continue;
}
String name = atts.getQName(i);
String value = atts.getValue(i);
TaskData child = data.addProperty(name);
child.setLocation(getLocation());
child.setText(value);
}
}
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if (!isAntNamespace(namespaceURI)) {
throw new SAXParseException("Unexpected element \"" + qName + "\"", locator);
}
TaskData child = data.addProperty(qName);
child.setLocation(getLocation());
handlers.push(new TaskElemHandler(child, qName, atts));
}
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
handlers.pop();
}
}
private static boolean isAntNamespace(String uri) {
return uri == null ? false : uri.equals("");
}
}