that its becoming a bit more clear how FrontEnds should interace with the core. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268338 13f79535-47bb-0310-9956-ffa450edef68master
@@ -1,201 +0,0 @@ | |||
// ------------------------------------------------------------------------------- | |||
// Copyright (c)2000 Apache Software Foundation | |||
// ------------------------------------------------------------------------------- | |||
package org.apache.ant; | |||
import java.io.*; | |||
import java.util.*; | |||
import java.util.zip.*; | |||
/** | |||
* Central class of Ant. This is the core 'kernel' of ant. Interfaces into | |||
* ant talk to Ant through this class. | |||
* | |||
* @author James Duncan Davidson (duncan@apache.org) | |||
*/ | |||
public class Ant { | |||
// ----------------------------------------------------------------- | |||
// PRIVATE DATA MEMBERS | |||
// ----------------------------------------------------------------- | |||
/** | |||
* | |||
*/ | |||
private File buildfile; | |||
/** | |||
* The front end running this. | |||
*/ | |||
private AntFrontEnd frontEnd; | |||
/** | |||
* Manager of tasks. | |||
*/ | |||
private TaskManager taskManager = new TaskManager(); | |||
/** | |||
* | |||
*/ | |||
private Project project; | |||
// ----------------------------------------------------------------- | |||
// CONSTRUCTORS | |||
// ----------------------------------------------------------------- | |||
/** | |||
* Constructs a new Ant instance. | |||
*/ | |||
public Ant(AntFrontEnd frontEnd) { | |||
this.frontEnd = frontEnd; | |||
setUpTaskPath(); | |||
} | |||
// ----------------------------------------------------------------- | |||
// PUBLIC METHODS | |||
// ----------------------------------------------------------------- | |||
/** | |||
* Sets additional path nodes onto the task lookup path. | |||
*/ | |||
public void addTaskPathNode(File node) { | |||
taskManager.addTaskPathNode(node); | |||
} | |||
/** | |||
* Builds a target. | |||
*/ | |||
public void buildTarget(String targetName) throws AntException { | |||
// notify FrontEnd that we are starting a build on a project | |||
frontEnd.notifyProjectStart(project); | |||
Target target = project.getTarget(targetName); | |||
frontEnd.notifyTargetStart(target); | |||
// XXX don't forget to execute dependancies first! | |||
Enumeration enum = target.getTasks().elements(); | |||
while (enum.hasMoreElements()) { | |||
Task task = (Task)enum.nextElement(); | |||
frontEnd.notifyTaskStart(task); | |||
AbstractTask aTask = taskManager.getTaskInstance(task.getType()); | |||
try { | |||
aTask.setProject(project); | |||
aTask.setAttributes(task.getAttributes()); | |||
boolean b = aTask.execute(); | |||
if (!b) { | |||
throw new AntException("STOP: Task " + task + | |||
" did not succeed"); | |||
} | |||
} catch (Exception e) { | |||
// XXX yes yes yes, this shouldn't be a catch all... | |||
throw new AntException("ERR: " + e); | |||
} | |||
frontEnd.notifyTaskEnd(task); | |||
} | |||
// notify frontEnd that we are done | |||
frontEnd.notifyTargetEnd(target); | |||
frontEnd.notifyProjectEnd(project); | |||
} | |||
/** | |||
* | |||
*/ | |||
public Project getProject() { | |||
return project; | |||
} | |||
/** | |||
* Sets the buildfile to be used. This action triggers a parse of | |||
* the build file and assembles a Project object from it. | |||
*/ | |||
public void setBuildfile(File file) throws AntException { | |||
buildfile = file; | |||
ProjectBuilder builder = new ProjectBuilder(); | |||
project = builder.buildFromFile(file); | |||
project.setAnt(this); | |||
System.out.println("Loaded Project: " + project.getName()); | |||
// XXX remove the dump after comfort level is reached | |||
System.out.println("Dump of Project:"); | |||
Enumeration enum = project.getTargets(); | |||
while (enum.hasMoreElements()) { | |||
Target target = (Target)enum.nextElement(); | |||
System.out.println(" Target: " + target.getName()); | |||
Enumeration enum2 = target.getTasks().elements(); | |||
while (enum2.hasMoreElements()) { | |||
Task task = (Task)enum2.nextElement(); | |||
System.out.println(" Task: " + task.getType()); | |||
Enumeration enum3 = task.getAttributeNames(); | |||
while (enum3.hasMoreElements()) { | |||
String atName = (String)enum3.nextElement(); | |||
String atValue = task.getAttribute(atName); | |||
System.out.println(" Att: " + atName + " = " + | |||
atValue); | |||
} | |||
} | |||
} | |||
} | |||
// ----------------------------------------------------------------- | |||
// PRIVATE METHODS | |||
// ----------------------------------------------------------------- | |||
/** | |||
* Sets up the taskpath based on the currently running operating | |||
* system. In general, the ordering of the taskpath is: user directory, | |||
* system directory, and then installation. This allows users or | |||
* system admins to override or add tasks. | |||
*/ | |||
private void setUpTaskPath() { | |||
// 1st, add user's home dir. | |||
File f; | |||
String userHome = System.getProperty("user.home"); | |||
// generic unix | |||
f = new File(userHome + ".ant", "tasks"); | |||
if (f.exists() && f.isDirectory()) { | |||
taskManager.addTaskPathNode(f); | |||
} | |||
// macos x | |||
f = new File(userHome + "/Library/Ant", "Tasks"); | |||
if (f.exists() && f.isDirectory()) { | |||
taskManager.addTaskPathNode(f); | |||
} | |||
// windows -- todo | |||
// 2nd, add system local dir. | |||
// generic unix | |||
f = new File("/usr/local/ant/tasks"); | |||
if (f.exists() && f.isDirectory()) { | |||
taskManager.addTaskPathNode(f); | |||
} | |||
// macos x | |||
f = new File("/Library/Ant/Tasks"); | |||
if (f.exists() && f.isDirectory()) { | |||
taskManager.addTaskPathNode(f); | |||
} | |||
// windows -- todo | |||
// 3rd, add installation local dir. | |||
//System.out.println("BASE: " + this.getClass().getResource("/")); | |||
// XXX ---- not really sure how the best way of getting this info is... | |||
// hafta think about it. | |||
} | |||
} |
@@ -22,12 +22,33 @@ public class Project { | |||
/** | |||
* | |||
*/ | |||
private Ant ant; | |||
//private Ant ant; | |||
/** | |||
* Base directory of this project. Usually this value is the directory | |||
* where the project file was found, but can be different. | |||
*/ | |||
private File baseDir; | |||
/** | |||
* | |||
*/ | |||
private PrintStream out; | |||
private String defaultTargetName; | |||
/** | |||
* Short description of the project. | |||
*/ | |||
private String description; | |||
/** | |||
* Front end that this project communicates to. | |||
*/ | |||
private FrontEnd frontEnd; | |||
/** | |||
* Properties of this project. | |||
*/ | |||
private Properties properties = new Properties(); | |||
/** | |||
* Parent project to this project, if one exists. | |||
@@ -46,13 +67,18 @@ public class Project { | |||
* as the value. | |||
*/ | |||
private Hashtable targets = new Hashtable(); | |||
/** | |||
* TaskManager for this project. | |||
*/ | |||
private TaskManager taskManager = new TaskManager(this); | |||
// ----------------------------------------------------------------- | |||
// PUBLIC ACCESSOR METHODS | |||
// PUBLIC METHODS | |||
// ----------------------------------------------------------------- | |||
/** | |||
* | |||
* Adds a target to this project. | |||
*/ | |||
public void addTarget(Target target) { | |||
// XXX check out for name, if null, reject! | |||
@@ -60,11 +86,33 @@ public class Project { | |||
} | |||
/** | |||
* | |||
* Returns the base directory of this project. | |||
*/ | |||
public File getBaseDir() { | |||
return baseDir; | |||
} | |||
/** | |||
* Returns the default target for this project, if there is one. Otherwise | |||
* it returns null. | |||
*/ | |||
public PrintStream getOutput() { | |||
// XXX check if null!!!!???? | |||
return out; | |||
public String getDefaultTargetName() { | |||
return defaultTargetName; | |||
} | |||
/** | |||
* Returns a short description of this project, if any. If not, returns | |||
* null. | |||
*/ | |||
public String getDescription() { | |||
return description; | |||
} | |||
/** | |||
* Gets the front end that is running this project. | |||
*/ | |||
public FrontEnd getFrontEnd() { | |||
return frontEnd; | |||
} | |||
/** | |||
@@ -85,42 +133,140 @@ public class Project { | |||
} | |||
/** | |||
* | |||
* Gets an exumeration of all the targets that are part of this project. | |||
*/ | |||
public Enumeration getTargets() { | |||
return targets.elements(); | |||
} | |||
/** | |||
* | |||
* Gets the name of this project. | |||
*/ | |||
public String getName() { | |||
return name; | |||
} | |||
/** | |||
* | |||
* Returns the value of a property. Returns null if the property does | |||
* not exist. | |||
*/ | |||
public void setAnt(Ant ant) { | |||
this.ant = ant; | |||
public String getProperty(String propertyName) { | |||
return properties.getProperty(propertyName); | |||
} | |||
/** | |||
* | |||
*/ | |||
public void setOutput(PrintStream out) { | |||
this.out = out; | |||
//public void setAnt(Ant ant) { | |||
// this.ant = ant; | |||
//} | |||
/** | |||
* Sets the base dir for this project. | |||
*/ | |||
public void setBaseDir(File dir) { | |||
// XXX should check this to make sure it's a dir! | |||
baseDir = dir; | |||
} | |||
/** | |||
* | |||
* Sets the default target for this project. | |||
*/ | |||
public void setDefaultTargetName(String targetName) { | |||
defaultTargetName = targetName; | |||
} | |||
/** | |||
* Sets the description for this project. | |||
*/ | |||
public void setDescription(String description) { | |||
this.description = description; | |||
} | |||
/** | |||
* Sets the front end for this project. | |||
*/ | |||
public void setFrontEnd(FrontEnd frontEnd) { | |||
this.frontEnd = frontEnd; | |||
} | |||
/** | |||
* Sets the name of this project. | |||
*/ | |||
public void setName(String name) { | |||
this.name = name; | |||
} | |||
/** | |||
* Sets a property on this project. If the property is already | |||
* set, this method will override it. | |||
*/ | |||
public void setProperty(String propertyName, String propertyValue) { | |||
properties.put(propertyName, propertyValue); | |||
} | |||
/** | |||
* | |||
* Starts a build of this project using the default target if one | |||
* is set. | |||
*/ | |||
public void startBuild() throws AntException { | |||
// XXX need to do something if the default target isn't set.. | |||
// maybe look for target name 'default', then bail? | |||
startBuild(defaultTargetName); | |||
} | |||
/** | |||
* Starts a build of this project with the entry point at the given | |||
* target. | |||
*/ | |||
public void startBuild(String targetName) throws AntException { | |||
// notify FrontEnd that we are starting a build on a project | |||
frontEnd.notifyProjectStart(this); | |||
Target target = getTarget(targetName); | |||
//TaskManager taskManager = ant.getTaskManager(); | |||
frontEnd.notifyTargetStart(target); | |||
// XXX don't forget to execute dependancies first! | |||
Enumeration enum = target.getTasks().elements(); | |||
while (enum.hasMoreElements()) { | |||
Task task = (Task)enum.nextElement(); | |||
frontEnd.notifyTaskStart(task); | |||
try { | |||
AbstractTask aTask = taskManager.getTaskInstance(task.getType()); | |||
aTask.setProject(this); | |||
aTask.setAttributes(task.getAttributes()); | |||
boolean b = aTask.execute(); | |||
if (!b) { | |||
String msg = "Task " + task.getType() + " failed"; | |||
AntException ae = new AntException(msg); | |||
throw ae; | |||
} | |||
} catch (Exception e) { | |||
AntException ae; | |||
if (!(e instanceof AntException)) { | |||
ae = new AntException(e); | |||
} else { | |||
ae = (AntException)e; | |||
} | |||
ae.setProject(this); | |||
ae.setTarget(target); | |||
ae.setTask(task); | |||
throw ae; | |||
} | |||
frontEnd.notifyTaskEnd(task); | |||
} | |||
// notify frontEnd that we are done | |||
frontEnd.notifyTargetEnd(target); | |||
frontEnd.notifyProjectEnd(this); | |||
} | |||
/** | |||
* Givens a string representation of this object. Useful for debugging. | |||
*/ | |||
public String toString() { | |||
return "Project name=" + name; | |||
@@ -5,6 +5,7 @@ | |||
package org.apache.ant; | |||
import java.io.*; | |||
import java.util.*; | |||
import javax.xml.parsers.*; | |||
import org.xml.sax.*; | |||
@@ -16,46 +17,86 @@ import org.xml.sax.*; | |||
* | |||
* @author James Duncan Davidson (duncan@apache.org) | |||
*/ | |||
class ProjectBuilder { | |||
public class ProjectBuilder { | |||
// ----------------------------------------------------------------- | |||
// PRIVATE MEMBERS | |||
// ----------------------------------------------------------------- | |||
/** | |||
* | |||
*/ | |||
//private Ant ant; | |||
/** | |||
* | |||
*/ | |||
private FrontEnd frontEnd; | |||
/** | |||
* | |||
*/ | |||
private SAXParserFactory parserFactory; | |||
// ----------------------------------------------------------------- | |||
// CONSTRUCTORS | |||
// ----------------------------------------------------------------- | |||
ProjectBuilder() { | |||
/** | |||
* Creates a new project builder that will build projects for the given | |||
* Ant. | |||
*/ | |||
public ProjectBuilder(FrontEnd frontEnd) { | |||
this.frontEnd = frontEnd; | |||
parserFactory = SAXParserFactory.newInstance(); | |||
parserFactory.setValidating(false); | |||
} | |||
Project buildFromFile(File file) throws AntException { | |||
/** | |||
* Builds a project from the given file. | |||
*/ | |||
public Project buildFromFile(File file) throws AntException { | |||
try { | |||
SAXParser parser = parserFactory.newSAXParser(); | |||
BuilderHandlerBase bhb = new BuilderHandlerBase(); | |||
bhb.setProjectFileLocation(file); | |||
parser.parse(file, bhb); | |||
return bhb.getProject(); | |||
Project project = bhb.getProject(); | |||
project.setFrontEnd(frontEnd); | |||
return project; | |||
} catch (ParserConfigurationException pce) { | |||
throw new AntException(pce.getMessage()); | |||
throw new AntException(pce); | |||
} catch (SAXException se) { | |||
System.out.println(se); | |||
System.out.println(se.getMessage()); | |||
throw new AntException(se.getMessage()); | |||
Exception e = se.getException(); | |||
if (e != null && e instanceof AntException) { | |||
// it's one of our own thrown from inside the parser to stop it | |||
throw (AntException)e; | |||
} | |||
throw new AntException(se); | |||
} catch (IOException ioe) { | |||
throw new AntException(ioe.getMessage()); | |||
throw new AntException(ioe); | |||
} | |||
} | |||
/** | |||
* Inner class that implements the needed SAX methods to get all the | |||
* data needed out of a build file. | |||
*/ | |||
class BuilderHandlerBase extends HandlerBase { | |||
private static final int STATE_START = 0; | |||
private static final int STATE_PROJECT = 1; | |||
private static final int STATE_TARGET = 2; | |||
private static final int STATE_TASK = 3; | |||
private static final int STATE_DESCRIPTION = 4; | |||
private static final int STATE_PROPERTY = 5; | |||
private static final int STATE_FINISHED = 99; | |||
private int state = STATE_START; | |||
private Vector tagCharDataStack = new Vector(); | |||
private Target currentTarget; | |||
private Task currentTask; | |||
@@ -65,42 +106,98 @@ class ProjectBuilder { | |||
return project; | |||
} | |||
void setProjectFileLocation(File file) { | |||
project.setBaseDir(file.getParentFile()); | |||
} | |||
public void startElement(String name, AttributeList atts) throws SAXException { | |||
//System.out.println("element: " + name); | |||
StringBuffer tagCharData = new StringBuffer(); | |||
tagCharDataStack.insertElementAt(tagCharData, 0); | |||
switch (state) { | |||
case STATE_START: | |||
if (name.equals("project")) { | |||
state = STATE_PROJECT; | |||
String projectName = atts.getValue("name"); | |||
if (projectName == null) { | |||
System.out.println("Projects *must* have names"); | |||
// XXX exception out | |||
if (projectName != null) { | |||
project.setName(projectName); | |||
} else { | |||
String msg = "Project element doesn't contain a name attribute"; | |||
AntException ae = new AntException(msg); | |||
throw new SAXException(ae); | |||
} | |||
String defaultTarget = atts.getValue("default"); | |||
if (defaultTarget != null) { | |||
project.setDefaultTargetName(defaultTarget); | |||
} | |||
String baseDirName = atts.getValue("basedir"); | |||
if (baseDirName != null) { | |||
// XXX need to check to see if base dir exists | |||
project.setBaseDir(new File(baseDirName)); | |||
} | |||
project.setName(projectName); | |||
} else { | |||
System.out.println("Expecting project, got: " + name); | |||
// XXX exception out | |||
String msg = "Project file doesn't contain a project element as " + | |||
"its root node"; | |||
AntException ae = new AntException(msg); | |||
throw new SAXException(ae); | |||
} | |||
break; | |||
case STATE_PROJECT: | |||
if (name.equals("target")) { | |||
// valid tags in a project object are: description, property, and target | |||
if (name.equals("description")) { | |||
state = STATE_DESCRIPTION; | |||
} else if (name.equals("property")) { | |||
state = STATE_PROPERTY; | |||
String propertyName = atts.getValue("name"); | |||
String propertyValue = atts.getValue("value"); | |||
if (propertyName == null) { | |||
String msg = "Name attribute must be present on property"; | |||
AntException ae = new AntException(msg); | |||
throw new SAXException(ae); | |||
} else if (propertyValue == null) { | |||
String msg = "Value attribute must be present on property"; | |||
AntException ae = new AntException(msg); | |||
throw new SAXException(ae); | |||
} else { | |||
project.setProperty(propertyName, propertyValue); | |||
} | |||
} else if (name.equals("target")) { | |||
state = STATE_TARGET; | |||
String targetName = atts.getValue("name"); | |||
if (targetName == null) { | |||
System.out.println("Targets *must* have names"); | |||
// XXX exception out | |||
if (targetName != null) { | |||
currentTarget = new Target(targetName); | |||
project.addTarget(currentTarget); | |||
} else { | |||
// XXX figure out which target we're talking about! | |||
// Like a location | |||
String msg = "Target element doesn't contain a name attribute"; | |||
AntException ae = new AntException(msg); | |||
throw new SAXException(ae); | |||
} | |||
String depends = atts.getValue("depends"); | |||
if (depends != null) { | |||
StringTokenizer tok = new StringTokenizer(depends, ",", false); | |||
while(tok.hasMoreTokens()) { | |||
currentTarget.addDependancy(tok.nextToken().trim()); | |||
} | |||
} | |||
currentTarget = new Target(targetName); | |||
project.addTarget(currentTarget); | |||
// XXX add dependency checks | |||
} else { | |||
System.out.println("Expecting target, got: " + name); | |||
// XXX exception out | |||
} | |||
break; | |||
case STATE_TARGET: | |||
// Valid tags inside target: task | |||
state = STATE_TASK; | |||
//System.out.println("Getting task: " + name + " for target " + | |||
// currentTarget); | |||
@@ -114,6 +211,16 @@ class ProjectBuilder { | |||
currentTask.addAttribute(atName, atValue); | |||
} | |||
break; | |||
case STATE_TASK: | |||
// data in here needs to be reflected into tasks | |||
System.out.println("Not yet supporting tags inside of tasks!"); | |||
System.out.println("The project build will probably bust right here"); | |||
break; | |||
default: | |||
System.out.println("I'm not sure, but we're off base here: " + name); | |||
// XXX exception out | |||
@@ -121,14 +228,21 @@ class ProjectBuilder { | |||
} | |||
public void characters(char ch[], int start, int length) throws SAXException { | |||
StringBuffer buf = (StringBuffer)tagCharDataStack.elementAt(0); | |||
buf.append(ch, start, length); | |||
} | |||
public void endElement(String name) throws SAXException { | |||
// System.out.println("end: " + name); | |||
StringBuffer elementData = (StringBuffer)tagCharDataStack.elementAt(0); | |||
tagCharDataStack.removeElementAt(0); | |||
switch (state) { | |||
case STATE_TASK: | |||
state = STATE_TARGET; | |||
break; | |||
case STATE_TARGET: | |||
if (name.equals("target")) { | |||
state = STATE_PROJECT; | |||
@@ -137,6 +251,27 @@ class ProjectBuilder { | |||
// XXX exception out. | |||
} | |||
break; | |||
case STATE_DESCRIPTION: | |||
if (name.equals("description")) { | |||
state = STATE_PROJECT; | |||
project.setDescription(elementData.toString().trim()); | |||
} else { | |||
System.out.println("Expecting to get an end of description, got: " + | |||
name); | |||
// XXX exception out. | |||
} | |||
break; | |||
case STATE_PROPERTY: | |||
if (name.equals("property")) { | |||
state = STATE_PROJECT; | |||
} else { | |||
System.out.println("Expecting to get end of property, got: " + name); | |||
// XXX exception out | |||
} | |||
break; | |||
case STATE_PROJECT: | |||
if (name.equals("project")) { | |||
state = STATE_FINISHED; | |||
@@ -145,6 +280,7 @@ class ProjectBuilder { | |||
// XXX exception out; | |||
} | |||
break; | |||
default: | |||
System.out.println("I'm not sure what we are ending here: " + name); | |||
// XXX exception out; | |||
@@ -22,6 +22,12 @@ public class Target { | |||
*/ | |||
private String name; | |||
/** | |||
* Vector containing the names of the targets that this target | |||
* depends on. | |||
*/ | |||
private Vector dependsList = new Vector(); | |||
/** | |||
* Vector containing the tasks that are part of this target. | |||
*/ | |||
@@ -42,6 +48,13 @@ public class Target { | |||
// PUBLIC ACCESSOR METHODS | |||
// ----------------------------------------------------------------- | |||
/** | |||
* Adds a dependancy to this task. | |||
*/ | |||
public void addDependancy(String targetName) { | |||
dependsList.addElement(targetName); | |||
} | |||
/** | |||
* | |||
*/ | |||
@@ -23,6 +23,16 @@ class TaskManager { | |||
// PRIVATE DATA MEMBERS | |||
// ----------------------------------------------------------------- | |||
/** | |||
* Reference to Ant that holds this TaskManager | |||
*/ | |||
//private Ant ant; | |||
/** | |||
* Project to which this task manger belongs. | |||
*/ | |||
private Project project; | |||
/** | |||
* Data structure where all the Class definition for all known tasks are | |||
* held. | |||
@@ -41,7 +51,8 @@ class TaskManager { | |||
/** | |||
* Creates a new TaskManager. | |||
*/ | |||
TaskManager() { | |||
TaskManager(Project project) { | |||
this.project = project; | |||
} | |||
// ----------------------------------------------------------------- | |||
@@ -59,16 +70,15 @@ class TaskManager { | |||
/** | |||
* | |||
*/ | |||
AbstractTask getTaskInstance(String taskName) { | |||
AbstractTask getTaskInstance(String taskName) throws AntException { | |||
Class clazz = (Class)taskClasses.get(taskName); | |||
try { | |||
return (AbstractTask)clazz.newInstance(); | |||
} catch (Exception e) { | |||
System.out.println("Can't instantiate task: " + taskName); | |||
System.out.println(e); | |||
// XXX error out and stop | |||
} catch (Exception e) { | |||
String msg = "Can't instantiate task: " + taskName; | |||
AntException ae = new AntException(msg, e); | |||
throw ae; | |||
} | |||
return null; | |||
} | |||
// ----------------------------------------------------------------- | |||
@@ -94,7 +104,8 @@ class TaskManager { | |||
* Processes a directory to get class defintions from it | |||
*/ | |||
private void processDir(File dir) { | |||
System.out.println("Scanning " + dir + " for tasks"); | |||
project.getFrontEnd().writeMessage("Scanning " + dir + " for tasks", | |||
FrontEnd.MSG_LEVEL_LOW); | |||
File file = new File(dir, "taskdef.properties"); | |||
if (file.exists()) { | |||
try { | |||
@@ -110,7 +121,8 @@ class TaskManager { | |||
URLClassLoader loader = new URLClassLoader(new URL[] {dir.toURL()}); | |||
try { | |||
Class clazz = loader.loadClass(taskClass); | |||
System.out.println("Got task: " + taskName + " " + clazz); | |||
project.getFrontEnd().writeMessage("Got Task: " + taskName + | |||
clazz, FrontEnd.MSG_LEVEL_LOW); | |||
taskClasses.put(taskName, clazz); | |||
} catch (ClassNotFoundException cnfe) { | |||
System.out.println("Couldn't load task: " + taskName); | |||
@@ -130,7 +142,8 @@ class TaskManager { | |||
* Processes a jar file to get class definitions from it | |||
*/ | |||
private void processJar(File file) { | |||
System.out.println("Scanning " + file + " for tasks"); | |||
project.getFrontEnd().writeMessage("Scanning " + file + " for tasks", | |||
FrontEnd.MSG_LEVEL_LOW); | |||
try { | |||
ZipFile zipFile = new ZipFile(file); | |||
ZipEntry zipEntry = zipFile.getEntry("taskdef.properties"); | |||
@@ -147,7 +160,8 @@ class TaskManager { | |||
URLClassLoader loader = new URLClassLoader(new URL[] {file.toURL()}); | |||
try { | |||
Class clazz = loader.loadClass(taskClass); | |||
System.out.println("Got Task: " + taskName + " " + clazz); | |||
project.getFrontEnd().writeMessage("Got Task: " + taskName + | |||
clazz, FrontEnd.MSG_LEVEL_LOW); | |||
taskClasses.put(taskName, clazz); | |||
} catch (ClassNotFoundException cnfe) { | |||
System.out.println("Couldn't load task: " + taskName); | |||
@@ -14,7 +14,7 @@ import org.apache.ant.*; | |||
* | |||
* @author James Duncan Davidson (duncan@apache.org) | |||
*/ | |||
public class CLIFrontEnd extends AntFrontEnd { | |||
public class CLIFrontEnd extends FrontEnd { | |||
// ----------------------------------------------------------------- | |||
// PRIVATE MEMBERS | |||
@@ -23,22 +23,28 @@ public class CLIFrontEnd extends AntFrontEnd { | |||
/** | |||
* | |||
*/ | |||
private Ant ant; | |||
//private Ant ant; | |||
/** | |||
* | |||
*/ | |||
private int msgLevel = MSG_LEVEL_MED; | |||
private String[] args; | |||
/** | |||
* | |||
*/ | |||
private int msgLevelFilter = MSG_LEVEL_MED; | |||
// ----------------------------------------------------------------- | |||
// CONSTRUCTORS | |||
// ----------------------------------------------------------------- | |||
/** | |||
* | |||
* Creates a new CLIFrontEnd that can drive an Ant build from the Command | |||
* Line. | |||
*/ | |||
public CLIFrontEnd() { | |||
ant = new Ant(this); | |||
//ant = new Ant(this); | |||
} | |||
// ----------------------------------------------------------------- | |||
@@ -98,74 +104,84 @@ public class CLIFrontEnd extends AntFrontEnd { | |||
writeMessage("Task End: " + task.getType(), MSG_LEVEL_LOW); | |||
} | |||
/** | |||
* Prints help to System.out | |||
*/ | |||
private void printHelp() { | |||
String ls = System.getProperty("line.separator"); | |||
String msg = "Usage: ant [args] [target]" + ls + | |||
" Arguments can be any of the following:" + ls + | |||
" -help" + ls + | |||
" -taskpath [path]" + ls + | |||
" -buildfile [file]" +ls + | |||
" -verbose" + ls + | |||
" -quiet" + ls + ls + | |||
" Note that if no buildfile argument is given, Ant will"+ls+ | |||
" try to find one in the current directory. If there are"+ls+ | |||
" two or more buildfiles in the current directory, it" +ls+ | |||
" will bail."; | |||
writeMessage(msg); | |||
} | |||
/** | |||
* | |||
*/ | |||
public void run(String[] args) { | |||
this.args = args; | |||
String target = ""; | |||
File buildFile = null; | |||
writeMessage("Ant(Eater) -- Proposed Ant 2.0"); | |||
// flip through args and set things accordingly | |||
for (int i = 0; i < args.length; i++) { | |||
String arg = args[i]; | |||
// scan through -- all -aaa args come first. | |||
if (arg.startsWith("-")) { | |||
if (arg.equals("-help")) { | |||
printHelp(); | |||
return; | |||
} else if (arg.equals("-taskpath")) { | |||
// XXX | |||
// need to seperate on pathsep, but not today | |||
ant.addTaskPathNode(new File(args[++i])); | |||
} else if (arg.equals("-buildfile")) { | |||
// XXX | |||
// need to check file to make sure it exists! | |||
try { | |||
ant.setBuildfile(new File(args[++i])); | |||
} catch (AntException ae) { | |||
writeMessage("ICK: " + ae); | |||
writeMessage(ae.getMessage()); | |||
return; | |||
} | |||
} | |||
// process through the args set | |||
if (isArg("help")) { | |||
printHelp(); | |||
return; | |||
} | |||
if (isArg("quiet")) { | |||
msgLevelFilter = MSG_LEVEL_HIGH; | |||
} | |||
if (isArg("verbose")) { | |||
msgLevelFilter = MSG_LEVEL_LOW; | |||
} | |||
String argTaskpath = getArgValue("taskpath"); | |||
if (argTaskpath != null) { | |||
if (argTaskpath.equals("")) { | |||
writeMessage("Must give a value for -taskpath"); | |||
return; | |||
} else { | |||
target = arg; | |||
// XXX need to separate on path seps so that real paths can be taken | |||
// ant.addTaskPathNode(new File(argTaskpath)); | |||
} | |||
} | |||
String argBuildfile = getArgValue("buildfile"); | |||
if (argBuildfile != null) { | |||
if (argBuildfile.equals("")) { | |||
writeMessage("Must give a value for -buildfile"); | |||
return; | |||
} else { | |||
//try { | |||
buildFile = new File(argBuildfile); | |||
//ant.setBuildfile(new File(argBuildfile)); | |||
//} catch (AntException ae) { | |||
// writeMessage("Can't set buildfile"); | |||
// writeMessage(ae.toString()); | |||
// return; | |||
//} | |||
} | |||
} | |||
target = getTargetArg(); | |||
// XXX do something if we dont' have a buildfile set! | |||
// XXX really should check to make sure that the target is set to something | |||
// set our listeners on the project | |||
Project project = ant.getProject(); | |||
project.setOutput(System.out); | |||
// like get the default... | |||
try { | |||
ant.buildTarget(target); | |||
} catch (AntException ae) { | |||
writeMessage("Problem while building: " + ae); | |||
ProjectBuilder projectBuilder = new ProjectBuilder(this); | |||
Project project = projectBuilder.buildFromFile(buildFile); | |||
//Project project = ant.getProject(); | |||
// XXX | |||
// get taskmanager from project and set taskpath nodes on it! | |||
project.setFrontEnd(this); | |||
project.startBuild(target); | |||
} catch (AntException ae) { | |||
writeMessage("Build Stopped"); | |||
writeMessage(" Project: " + ae.getProject().getName()); | |||
writeMessage(" Target: " + ae.getTarget().getName()); | |||
writeMessage(" Task Type: " + ae.getTask().getType()); | |||
writeMessage("Details Follow"); | |||
writeMessage(""); | |||
writeMessage(ae.getMessage()); | |||
ae.printStackTrace(System.out); | |||
} | |||
} | |||
@@ -173,10 +189,100 @@ public class CLIFrontEnd extends AntFrontEnd { | |||
* Writes a message to the front end. | |||
*/ | |||
public void writeMessage(String message, int level) { | |||
if (level >= msgLevel) { | |||
if (level >= msgLevelFilter) { | |||
System.out.println(message); | |||
} | |||
} | |||
// ----------------------------------------------------------------- | |||
// PRIVATE METHODS | |||
// ----------------------------------------------------------------- | |||
/** | |||
* Returns the value for a given argument name, null if the argument | |||
* name isn't in the argument set, or "" if the argument doesn't have | |||
* a value. | |||
*/ | |||
private String getArgValue(String argName) { | |||
for (int i = 0; i < args.length; i++) { | |||
if (args[i].equals("-" + argName)) { | |||
if (i != args.length - 1) { | |||
return args[i + 1]; | |||
} else { | |||
return ""; | |||
} | |||
} | |||
} | |||
return null; | |||
} | |||
/** | |||
* Returns the target that was requested to be built, if any. If no | |||
* target is determined, returns null. | |||
*/ | |||
public String getTargetArg() { | |||
String possibleTarget = getArgValue("target"); | |||
if (possibleTarget != null) { | |||
if (possibleTarget.equals("")) { | |||
writeMessage("Must give a value for -target"); | |||
} else { | |||
return possibleTarget; | |||
} | |||
} | |||
possibleTarget = args[args.length - 1]; | |||
if (possibleTarget.startsWith("-")) { | |||
return null; | |||
} | |||
if (args[args.length - 2].startsWith("-")) { | |||
// our possible target might be an arg value instead of a target | |||
// XXX ugh -- there has to be a better way here. We need to hold | |||
// a list of all args that don't have values somewhere. | |||
if (args[args.length - 2].equals("-help") || | |||
args[args.length - 2].equals("-verbose") || | |||
args[args.length - 2].equals("-quiet")) { | |||
// we're ok, the arg before the possible target doesn't have a value | |||
return possibleTarget; | |||
} else { | |||
return null; | |||
} | |||
} else { | |||
return possibleTarget; | |||
} | |||
} | |||
/** | |||
* Indicates whether or not a given argument name exists in the argument | |||
* set. | |||
*/ | |||
private boolean isArg(String argName) { | |||
for (int i = 0; i < args.length; i++) { | |||
if (args[i].equals("-" + argName)) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
/** | |||
* Prints help to System.out | |||
*/ | |||
private void printHelp() { | |||
// XXX resource bundle this. | |||
String ls = System.getProperty("line.separator"); | |||
String msg = "Usage: ant [args] [target]" + ls + | |||
" Arguments can be any of the following:" + ls + | |||
" -help" + ls + | |||
" -taskpath [path]" + ls + | |||
" -buildfile [file]" +ls + | |||
" -verbose" + ls + | |||
" -quiet" + ls + ls + | |||
" Note that if no buildfile argument is given, Ant will"+ls+ | |||
" try to find one in the current directory. If there are"+ls+ | |||
" two or more buildfiles in the current directory, it" +ls+ | |||
" will bail."; | |||
writeMessage(msg); | |||
} | |||
} |