ends use core... In order for a front end to run a build, it first creates a ProjectBuilder, loads a Project from it, then can run a build on that Project. What still needs a bit of looking after is creating a project from scratch (such as a GUI might do) and then executing it. Later. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268339 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -70,12 +70,6 @@ public class Bootstrap { | |||||
| */ | */ | ||||
| static void runCommand(String[] command) throws IOException { | static void runCommand(String[] command) throws IOException { | ||||
| System.out.print("Exec'ing: "); | |||||
| for (int i = 0; i < command.length; i++) { | |||||
| System.out.print(command[i] + " "); | |||||
| } | |||||
| System.out.println(); | |||||
| Runtime runtime = Runtime.getRuntime(); | Runtime runtime = Runtime.getRuntime(); | ||||
| Process process = runtime.exec(command); | Process process = runtime.exec(command); | ||||
| @@ -42,11 +42,14 @@ public class Bootstrap2 { | |||||
| } | } | ||||
| // ------------------------------------------------------------ | // ------------------------------------------------------------ | ||||
| // build crimson | |||||
| // build crimson, but only if it hasn't been built yet since | |||||
| // 127 class files takes more seconds than I like to wait. | |||||
| // ------------------------------------------------------------ | // ------------------------------------------------------------ | ||||
| Vector v1 = getSources(base + crimsonSources); | |||||
| doCompile(base + "bootstrap/temp/crimson", v1); | |||||
| if (!(new File(base + "bootstrap/temp/crimson/javax").exists())) { | |||||
| Vector v1 = getSources(base + crimsonSources); | |||||
| doCompile(base + "bootstrap/temp/crimson", v1); | |||||
| } | |||||
| // ------------------------------------------------------------ | // ------------------------------------------------------------ | ||||
| // build the main thing | // build the main thing | ||||
| @@ -75,7 +78,7 @@ public class Bootstrap2 { | |||||
| System.out.println("-------------------------------------------"); | System.out.println("-------------------------------------------"); | ||||
| System.out.println(); | System.out.println(); | ||||
| String[] cmdarray = new String[9]; | |||||
| String[] cmdarray = new String[10]; | |||||
| cmdarray[0] = "java"; | cmdarray[0] = "java"; | ||||
| cmdarray[1] = "-cp"; | cmdarray[1] = "-cp"; | ||||
| cmdarray[2] = base + "bootstrap/temp/main" + File.pathSeparator + | cmdarray[2] = base + "bootstrap/temp/main" + File.pathSeparator + | ||||
| @@ -84,8 +87,9 @@ public class Bootstrap2 { | |||||
| cmdarray[4] = "-taskpath"; | cmdarray[4] = "-taskpath"; | ||||
| cmdarray[5] = base + "bootstrap/temp/taskjars"; | cmdarray[5] = base + "bootstrap/temp/taskjars"; | ||||
| cmdarray[6] = "-buildfile"; | cmdarray[6] = "-buildfile"; | ||||
| cmdarray[7] = base + "source/main.ant"; | |||||
| cmdarray[8] = "default"; | |||||
| cmdarray[7] = base + "source/main.ant"; | |||||
| cmdarray[8] = "-target"; | |||||
| cmdarray[9] = "default"; | |||||
| Bootstrap.runCommand(cmdarray, args); | Bootstrap.runCommand(cmdarray, args); | ||||
| @@ -1,12 +1,12 @@ | |||||
| package org.apache.ant.echo; | package org.apache.ant.echo; | ||||
| import java.io.*; | |||||
| import java.util.*; | |||||
| import org.apache.ant.*; | import org.apache.ant.*; | ||||
| /** | /** | ||||
| * Basic echo task that just spits out whatever it is supposed to... | |||||
| * A very simple task that takes a bit of text and echos it back out | |||||
| * when it is executed. This is useful for troubleshooting properties | |||||
| * in buildfiles, letting the user know that something is going to happen | |||||
| * and as a very simple example that can be copied to create other tasks. | |||||
| * | * | ||||
| * @author James Duncan Davidson (duncan@apache.org) | * @author James Duncan Davidson (duncan@apache.org) | ||||
| */ | */ | ||||
| @@ -19,26 +19,24 @@ public class EchoTask extends AbstractTask { | |||||
| /** | /** | ||||
| * Data to echo | * Data to echo | ||||
| */ | */ | ||||
| private String data; | |||||
| private String text; | |||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| // PUBLIC METHODS | // PUBLIC METHODS | ||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| /** | /** | ||||
| * | |||||
| * Executes this task. | |||||
| */ | */ | ||||
| public boolean execute() throws AntException { | public boolean execute() throws AntException { | ||||
| PrintStream out = project.getOutput(); | |||||
| out.println("ECHOING: " + data); | |||||
| project.getFrontEnd().writeMessage(text); | |||||
| return true; | return true; | ||||
| } | } | ||||
| /** | /** | ||||
| * | |||||
| * Sets the text that this task will echo. | |||||
| */ | */ | ||||
| public void setData(String data) { | |||||
| this.data = data; | |||||
| public void setText(String text) { | |||||
| this.text = text; | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,13 +1,21 @@ | |||||
| <?xml version="1.0"?> | <?xml version="1.0"?> | ||||
| <project name="Ant"> | |||||
| <!-- Comment outside of project --> | |||||
| <target name="default"> | |||||
| <echo data="Echo In Default"/> | |||||
| <project name="Ant" default="default"> | |||||
| <!-- Comment inside of project --> | |||||
| <description>Primary buildfile for building Ant itself</description> | |||||
| <property name="foo" value="bar"/> | |||||
| <target name="default" depends="main"> | |||||
| <echo text="Default Target is Executing"/> | |||||
| </target> | </target> | ||||
| <target name="main"> | <target name="main"> | ||||
| <echo data="Echo In Main"/> | |||||
| <echo text="Main Target is Executing"/> | |||||
| </target> | </target> | ||||
| </project> | |||||
| </project> | |||||
| @@ -71,7 +71,19 @@ public class Project { | |||||
| /** | /** | ||||
| * TaskManager for this project. | * TaskManager for this project. | ||||
| */ | */ | ||||
| private TaskManager taskManager = new TaskManager(this); | |||||
| private TaskManager taskManager; | |||||
| // ----------------------------------------------------------------- | |||||
| // CONSTRUCTORS | |||||
| // ----------------------------------------------------------------- | |||||
| /** | |||||
| * Creates a new Project object with the given FrontEnd and TaskManager | |||||
| */ | |||||
| public Project(FrontEnd frontEnd, TaskManager taskManager) { | |||||
| this.frontEnd = frontEnd; | |||||
| this.taskManager = taskManager; | |||||
| } | |||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| // PUBLIC METHODS | // PUBLIC METHODS | ||||
| @@ -225,7 +237,6 @@ public class Project { | |||||
| frontEnd.notifyProjectStart(this); | frontEnd.notifyProjectStart(this); | ||||
| Target target = getTarget(targetName); | Target target = getTarget(targetName); | ||||
| //TaskManager taskManager = ant.getTaskManager(); | |||||
| frontEnd.notifyTargetStart(target); | frontEnd.notifyTargetStart(target); | ||||
| @@ -26,17 +26,17 @@ public class ProjectBuilder { | |||||
| /** | /** | ||||
| * | * | ||||
| */ | */ | ||||
| //private Ant ant; | |||||
| private FrontEnd frontEnd; | |||||
| /** | /** | ||||
| * | * | ||||
| */ | */ | ||||
| private FrontEnd frontEnd; | |||||
| private SAXParserFactory parserFactory; | |||||
| /** | /** | ||||
| * | * | ||||
| */ | */ | ||||
| private SAXParserFactory parserFactory; | |||||
| private TaskManager taskManager; | |||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| // CONSTRUCTORS | // CONSTRUCTORS | ||||
| @@ -49,10 +49,15 @@ public class ProjectBuilder { | |||||
| */ | */ | ||||
| public ProjectBuilder(FrontEnd frontEnd) { | public ProjectBuilder(FrontEnd frontEnd) { | ||||
| this.frontEnd = frontEnd; | this.frontEnd = frontEnd; | ||||
| taskManager = new TaskManager(frontEnd); | |||||
| parserFactory = SAXParserFactory.newInstance(); | parserFactory = SAXParserFactory.newInstance(); | ||||
| parserFactory.setValidating(false); | parserFactory.setValidating(false); | ||||
| } | } | ||||
| // ----------------------------------------------------------------- | |||||
| // PUBLIC METHODS | |||||
| // ----------------------------------------------------------------- | |||||
| /** | /** | ||||
| * Builds a project from the given file. | * Builds a project from the given file. | ||||
| */ | */ | ||||
| @@ -79,6 +84,18 @@ public class ProjectBuilder { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Returns the TaskManager associated with this ProjectBuilder and | |||||
| * the projects that it builds | |||||
| */ | |||||
| public TaskManager getTaskManager() { | |||||
| return taskManager; | |||||
| } | |||||
| // ----------------------------------------------------------------- | |||||
| // INNER CLASSES | |||||
| // ----------------------------------------------------------------- | |||||
| /** | /** | ||||
| * Inner class that implements the needed SAX methods to get all the | * Inner class that implements the needed SAX methods to get all the | ||||
| * data needed out of a build file. | * data needed out of a build file. | ||||
| @@ -100,7 +117,7 @@ public class ProjectBuilder { | |||||
| private Target currentTarget; | private Target currentTarget; | ||||
| private Task currentTask; | private Task currentTask; | ||||
| Project project = new Project(); | |||||
| Project project = new Project(frontEnd, taskManager); | |||||
| Project getProject() { | Project getProject() { | ||||
| return project; | return project; | ||||
| @@ -17,21 +17,16 @@ import java.util.zip.*; | |||||
| * | * | ||||
| * @author James Duncan Davidson (duncan@apache.org) | * @author James Duncan Davidson (duncan@apache.org) | ||||
| */ | */ | ||||
| class TaskManager { | |||||
| public class TaskManager { | |||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| // PRIVATE DATA MEMBERS | // PRIVATE DATA MEMBERS | ||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| /** | /** | ||||
| * Reference to Ant that holds this TaskManager | |||||
| * FrontEnd that this TaskManager can communicate through. | |||||
| */ | */ | ||||
| //private Ant ant; | |||||
| /** | |||||
| * Project to which this task manger belongs. | |||||
| */ | |||||
| private Project project; | |||||
| private FrontEnd frontEnd; | |||||
| /** | /** | ||||
| * Data structure where all the Class definition for all known tasks are | * Data structure where all the Class definition for all known tasks are | ||||
| @@ -51,21 +46,26 @@ class TaskManager { | |||||
| /** | /** | ||||
| * Creates a new TaskManager. | * Creates a new TaskManager. | ||||
| */ | */ | ||||
| TaskManager(Project project) { | |||||
| this.project = project; | |||||
| TaskManager(FrontEnd frontEnd) { | |||||
| System.out.println("CREATING TM"); | |||||
| this.frontEnd = frontEnd; | |||||
| } | } | ||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| // PACKAGE METHODS | |||||
| // PUBLIC METHODS | |||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| /** | /** | ||||
| * Adds a node to the task path | * Adds a node to the task path | ||||
| */ | */ | ||||
| void addTaskPathNode(File file) { | |||||
| public void addTaskPathNode(File file) { | |||||
| taskPathNodes.addElement(file); | taskPathNodes.addElement(file); | ||||
| processTaskPathNode(file); | processTaskPathNode(file); | ||||
| } | } | ||||
| // ----------------------------------------------------------------- | |||||
| // PACKAGE METHODS | |||||
| // ----------------------------------------------------------------- | |||||
| /** | /** | ||||
| * | * | ||||
| @@ -104,7 +104,7 @@ class TaskManager { | |||||
| * Processes a directory to get class defintions from it | * Processes a directory to get class defintions from it | ||||
| */ | */ | ||||
| private void processDir(File dir) { | private void processDir(File dir) { | ||||
| project.getFrontEnd().writeMessage("Scanning " + dir + " for tasks", | |||||
| frontEnd.writeMessage("Scanning " + dir + " for tasks", | |||||
| FrontEnd.MSG_LEVEL_LOW); | FrontEnd.MSG_LEVEL_LOW); | ||||
| File file = new File(dir, "taskdef.properties"); | File file = new File(dir, "taskdef.properties"); | ||||
| if (file.exists()) { | if (file.exists()) { | ||||
| @@ -121,7 +121,7 @@ class TaskManager { | |||||
| URLClassLoader loader = new URLClassLoader(new URL[] {dir.toURL()}); | URLClassLoader loader = new URLClassLoader(new URL[] {dir.toURL()}); | ||||
| try { | try { | ||||
| Class clazz = loader.loadClass(taskClass); | Class clazz = loader.loadClass(taskClass); | ||||
| project.getFrontEnd().writeMessage("Got Task: " + taskName + | |||||
| frontEnd.writeMessage("Got Task: " + taskName + | |||||
| clazz, FrontEnd.MSG_LEVEL_LOW); | clazz, FrontEnd.MSG_LEVEL_LOW); | ||||
| taskClasses.put(taskName, clazz); | taskClasses.put(taskName, clazz); | ||||
| } catch (ClassNotFoundException cnfe) { | } catch (ClassNotFoundException cnfe) { | ||||
| @@ -142,7 +142,7 @@ class TaskManager { | |||||
| * Processes a jar file to get class definitions from it | * Processes a jar file to get class definitions from it | ||||
| */ | */ | ||||
| private void processJar(File file) { | private void processJar(File file) { | ||||
| project.getFrontEnd().writeMessage("Scanning " + file + " for tasks", | |||||
| frontEnd.writeMessage("Scanning " + file + " for tasks", | |||||
| FrontEnd.MSG_LEVEL_LOW); | FrontEnd.MSG_LEVEL_LOW); | ||||
| try { | try { | ||||
| ZipFile zipFile = new ZipFile(file); | ZipFile zipFile = new ZipFile(file); | ||||
| @@ -160,7 +160,7 @@ class TaskManager { | |||||
| URLClassLoader loader = new URLClassLoader(new URL[] {file.toURL()}); | URLClassLoader loader = new URLClassLoader(new URL[] {file.toURL()}); | ||||
| try { | try { | ||||
| Class clazz = loader.loadClass(taskClass); | Class clazz = loader.loadClass(taskClass); | ||||
| project.getFrontEnd().writeMessage("Got Task: " + taskName + | |||||
| frontEnd.writeMessage("Got Task: " + taskName + | |||||
| clazz, FrontEnd.MSG_LEVEL_LOW); | clazz, FrontEnd.MSG_LEVEL_LOW); | ||||
| taskClasses.put(taskName, clazz); | taskClasses.put(taskName, clazz); | ||||
| } catch (ClassNotFoundException cnfe) { | } catch (ClassNotFoundException cnfe) { | ||||
| @@ -207,4 +207,57 @@ class TaskManager { | |||||
| processJar(file); | processJar(file); | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * 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()) { | |||||
| addTaskPathNode(f); | |||||
| } | |||||
| // macos x | |||||
| f = new File(userHome + "/Library/Ant", "Tasks"); | |||||
| if (f.exists() && f.isDirectory()) { | |||||
| addTaskPathNode(f); | |||||
| } | |||||
| // windows -- todo | |||||
| // 2nd, add system local dir. | |||||
| // generic unix | |||||
| f = new File("/usr/local/ant/tasks"); | |||||
| if (f.exists() && f.isDirectory()) { | |||||
| addTaskPathNode(f); | |||||
| } | |||||
| // macos x | |||||
| f = new File("/Library/Ant/Tasks"); | |||||
| if (f.exists() && f.isDirectory()) { | |||||
| 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. | |||||
| } | |||||
| } | } | ||||
| @@ -23,18 +23,23 @@ public class CLIFrontEnd extends FrontEnd { | |||||
| /** | /** | ||||
| * | * | ||||
| */ | */ | ||||
| //private Ant ant; | |||||
| private String[] args; | |||||
| /** | /** | ||||
| * | |||||
| * ProjectBuilder that is associated with this frontEnd. | |||||
| */ | */ | ||||
| private String[] args; | |||||
| private ProjectBuilder projectBuilder; | |||||
| /** | /** | ||||
| * | * | ||||
| */ | */ | ||||
| private int msgLevelFilter = MSG_LEVEL_MED; | private int msgLevelFilter = MSG_LEVEL_MED; | ||||
| /** | |||||
| * TaskManager instance that we can set taskpaths and such on. | |||||
| */ | |||||
| private TaskManager taskManager; | |||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| // CONSTRUCTORS | // CONSTRUCTORS | ||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| @@ -44,7 +49,8 @@ public class CLIFrontEnd extends FrontEnd { | |||||
| * Line. | * Line. | ||||
| */ | */ | ||||
| public CLIFrontEnd() { | public CLIFrontEnd() { | ||||
| //ant = new Ant(this); | |||||
| projectBuilder = new ProjectBuilder(this); | |||||
| taskManager = projectBuilder.getTaskManager(); | |||||
| } | } | ||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| @@ -135,7 +141,7 @@ public class CLIFrontEnd extends FrontEnd { | |||||
| return; | return; | ||||
| } else { | } else { | ||||
| // XXX need to separate on path seps so that real paths can be taken | // XXX need to separate on path seps so that real paths can be taken | ||||
| // ant.addTaskPathNode(new File(argTaskpath)); | |||||
| taskManager.addTaskPathNode(new File(argTaskpath)); | |||||
| } | } | ||||
| } | } | ||||
| @@ -164,16 +170,15 @@ public class CLIFrontEnd extends FrontEnd { | |||||
| // like get the default... | // like get the default... | ||||
| try { | try { | ||||
| ProjectBuilder projectBuilder = new ProjectBuilder(this); | |||||
| Project project = projectBuilder.buildFromFile(buildFile); | Project project = projectBuilder.buildFromFile(buildFile); | ||||
| //Project project = ant.getProject(); | |||||
| // XXX | |||||
| // get taskmanager from project and set taskpath nodes on it! | |||||
| project.setFrontEnd(this); | project.setFrontEnd(this); | ||||
| project.startBuild(target); | project.startBuild(target); | ||||
| } catch (AntException ae) { | |||||
| } catch (AntException ae) { | |||||
| //XXX this whole write a string at a time message handling | |||||
| // sucks and needs to be improved... | |||||
| writeMessage("Build Stopped"); | writeMessage("Build Stopped"); | ||||
| writeMessage(" Project: " + ae.getProject().getName()); | writeMessage(" Project: " + ae.getProject().getName()); | ||||
| writeMessage(" Target: " + ae.getTarget().getName()); | writeMessage(" Target: " + ae.getTarget().getName()); | ||||
| @@ -182,6 +187,13 @@ public class CLIFrontEnd extends FrontEnd { | |||||
| writeMessage(""); | writeMessage(""); | ||||
| writeMessage(ae.getMessage()); | writeMessage(ae.getMessage()); | ||||
| ae.printStackTrace(System.out); | ae.printStackTrace(System.out); | ||||
| Throwable t = ae.getCause(); | |||||
| if (t != null) { | |||||
| writeMessage(""); | |||||
| writeMessage("Cause Exception: " + t.toString()); | |||||
| writeMessage(t.getMessage()); | |||||
| t.printStackTrace(System.out); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||