You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by du...@locus.apache.org on 2000/12/06 09:08:41 UTC

cvs commit: jakarta-ant/proposal/anteater/source/main/org/apache/ant/cli Main.java

duncan      00/12/06 00:08:40

  Added:       proposal/anteater README
               proposal/anteater/bootstrap Bootstrap.java README
               proposal/anteater/lib crimson.jar jaxp.jar
               proposal/anteater/source main.ant
               proposal/anteater/source/coretasks/echo taskdef.properties
               proposal/anteater/source/coretasks/echo/org/apache/ant/echo
                        EchoTask.java
               proposal/anteater/source/main/org/apache/ant
                        AbstractTask.java Ant.java AntException.java
                        Project.java ProjectBuilder.java Target.java
                        Task.java TaskClassLoader.java
               proposal/anteater/source/main/org/apache/ant/cli Main.java
  Log:
  Initial checkin
  
  Revision  Changes    Path
  1.1                  jakarta-ant/proposal/anteater/README
  
  Index: README
  ===================================================================
  README for Ant(Eater)
  ---------------------------------------------------------------------------------
  
  Execution:
  
      ant [args] target
      
  Args:
  
      -help
      -quiet
      -verbose
      -taskpath [path]
      -antfile [file]
  
  
  1.1                  jakarta-ant/proposal/anteater/bootstrap/Bootstrap.java
  
  Index: Bootstrap.java
  ===================================================================
  // -------------------------------------------------------------------------------
  // Copyright (c)2000 Apache Software Foundation
  // -------------------------------------------------------------------------------
  
  import java.io.*;
  import java.util.*;
  import java.util.zip.*;
  
  /**
   * Quick and dirty single class bootstrap utility for getting Ant off
   * the ground when in need. To use, compile this file in the directory
   * where the source code is in the repository, then execute it. That's
   * it.<p>
   *
   * No pretense is made that this is an elegant peice of code. This code
   * only exists to do a ground zero build of Ant. Any other building of
   * Ant should be done with itself whenever possible.
   *
   * @author James Duncan Davidson (duncan@apache.org)
   */
  public class Bootstrap {
     
      private static String base = "../";
      private static String[] modules = new String[]{"copy", "echo", "jar", "javac"};
  
      /**
       * Command line entry point.
       */
      public static void main(String[] args) {
      
          // check for secret sugar left by MRJ startup script...
      
          if (args.length > 0) {
              if (args[0].equals("osx")) {
                  base = "";
              }
          }
      
          long startTime = System.currentTimeMillis();
      
          System.out.println("Starting Bootstrap....");
  
          // ------------------------------------------------------------
          // first create dirs that we need for strapping
          // ------------------------------------------------------------
  
          mkdir(base + "bootstrap/temp");
          mkdir(base + "bootstrap/temp/main");
          mkdir(base + "bootstrap/temp/tasks");
          mkdir(base + "bootstrap/temp/taskjars");
          
          for (int i = 0; i < modules.length; i++) {
              mkdir(base + "bootstrap/temp/tasks/" + modules[i]);
          }
          
          // ------------------------------------------------------------
          // build the main thing
          // ------------------------------------------------------------        
          
          Vector v = getSources(base + "source/main");
          doCompile(base + "bootstrap/temp/main", v);
          
          // ------------------------------------------------------------
          // now build each of the needed peices into their
          // areas within the strapping area
          // ------------------------------------------------------------
  
          for (int i = 0; i < modules.length; i++) {
              buildModule(modules[i]);
          }
  
          // ------------------------------------------------------------
          // now, set classpaths and launch an Ant build to
          // have Ant build itself nicely
          // ------------------------------------------------------------
  
          System.out.println();
          System.out.println("-------------------------------------------");
          System.out.println("STARTING REAL BUILD");
          System.out.println("-------------------------------------------");
          System.out.println();     
          
          String[] cmdarray = new String[9];
          cmdarray[0] = "java";
          cmdarray[1] = "-cp";
          cmdarray[2] = base + "bootstrap/temp/main:" + base + "lib/jaxp.jar:" +
                        base + "lib/crimson.jar";
          cmdarray[3] = "org.apache.ant.cli.Main";
          cmdarray[4] = "-taskpath";
          cmdarray[5] = base + "bootstrap/temp/taskjars";
          cmdarray[6] = "-buildfile";
          cmdarray[7] = base + "source/main.ant"; 
          cmdarray[8] = "default";
          
          try {
              Runtime runtime = Runtime.getRuntime();
              Process process = runtime.exec(cmdarray);
              
              // echo output from process
              
              InputStream in = process.getInputStream();
              byte[] buf = new byte[80];
              int count = 0;
              count = in.read(buf, 0, buf.length);
              while (count != -1) {
                  System.out.write(buf, 0, count);
                  count = in.read(buf, 0, buf.length);
              }
              
              in = process.getErrorStream();
              count = in.read(buf, 0, buf.length);          
              if (count > 0) {
                  System.out.println();
                  System.out.println("Error Stream Output:");
               
                  while (count != -1) {
                      System.out.write(buf, 0, count);
                      count = in.read(buf, 0, buf.length);
                  }
              }
          } catch (Exception e) {
              System.out.println("OUCHY: " + e);
              return;
          }
          
          System.out.println();
          System.out.println("-------------------------------------------");
          System.out.println("FINISHED WITH REAL BUILD");
          System.out.println("-------------------------------------------");
          System.out.println();
          
          // ------------------------------------------------------------
          // Remove Temporary classes
          // ------------------------------------------------------------
  
          // delete(tempDirName);
  
          // ------------------------------------------------------------
          // Print Closer
          // ------------------------------------------------------------
  
          long endTime = System.currentTimeMillis();
          long elapsd = endTime - startTime;
          System.out.println("Bootstrap Time: " + (elapsd/1000) + "." + (elapsd%1000) + 
                             " seconds");
      }
  
      private static void mkdir(String arg) {
          File dir = new File(arg);
          if (dir.exists() && !dir.isDirectory()) {
              System.out.println("Oh, horrors! Dir " + arg + " " +
                                 "doesn't seem to be a dir... Stop!");
              System.exit(1);
          }
          if (!dir.exists()) {
              System.out.println("Making dir: " + arg);
              dir.mkdir();
          }
      }
  
      private static void buildModule(String arg) {
          System.out.println("Building " + arg);
       
          // get all sources and hand them off to the compiler to
          // build over into destination
  
          Vector v = getSources(base + "source/coretasks/" + arg);
          if (v.size() > 0) {
              doCompile(base + "bootstrap/temp/tasks/" + arg, v);
          }
          
  
          // move taskdef.properties for the module
  
          copyfile(base + "source/coretasks/" + arg + "/taskdef.properties",
                   base + "bootstrap/temp/tasks/" + arg + "/taskdef.properties");
                   
          // jar up tasks
          try {
              jarDir(new File(base + "bootstrap/temp/tasks/" + arg), 
                  new File(base + "bootstrap/temp/taskjars/" + arg + ".jar"));
          } catch(IOException ioe) {
              System.out.println("problem jar'ing: " + arg);
          }
      }
  
      private static Vector getSources(String arg) {
  
          File sourceDir = new File(arg);
          
          Vector v = new Vector();
          scanDir(sourceDir, v, ".java");
          return v;
      }
  
      private static void jarDir(File dir, File jarfile) throws IOException {
          String[] files = dir.list();
          if (files.length > 0) {
              System.out.println("Jaring: " + jarfile);
              FileOutputStream fos = new FileOutputStream(jarfile);
              ZipOutputStream zos = new ZipOutputStream(fos);
              jarDir(dir, "", zos);
              zos.close();      
          }
      }
      
      private static void jarDir(File dir, String prefix, ZipOutputStream zos) throws 
          IOException 
      {
          String[] files = dir.list();
          for (int i = 0; i < files.length; i++) {
              File f = new File(dir, files[i]);
              if (f.isDirectory()) {
                  jarDir(f, prefix + "/" + files[i], zos);
              } else {
                  ZipEntry ze = new ZipEntry(prefix + "/" + files[i]);
                  zos.putNextEntry(ze);
                  FileInputStream fis = new FileInputStream(f);
                  int count = 0;
                  byte[] buf = new byte[8 * 1024];
                  count = fis.read(buf, 0, buf.length);
                  while (count != -1) {
                      zos.write(buf, 0, count);
                      count = fis.read(buf, 0, buf.length);
                  }
                  fis.close();
              }
          }
      }
  
      private static void scanDir(File dir, Vector v, String endsWith) {
          // System.out.println("user.dir=" + System.getProperty("user.dir"));
          // System.out.println("Scanning: " + dir);
          String[] files = dir.list();
          // System.out.println("Files: " + files);
          for (int i = 0; i < files.length; i++) {
              File f = new File(dir, files[i]);
              if (f.isDirectory()) {
                  scanDir(f, v, endsWith);
              } else {
                  if (files[i].endsWith(endsWith)) {
                      v.addElement(f);
                  }
              }
          }
      }
  
      private static void doCompile(String dest, Vector sources) {
          System.out.println("   Compiling " + sources.size() + " files to " + dest);
          
          // XXX This should be more forgiving about compiling wherever
          // under whatever compiler, but this works so...
          
          sun.tools.javac.Main compiler = new sun.tools.javac.Main(System.out, 
                                                                   "javac");        
          String[] args = new String[sources.size() + 4];
          args[0] = "-classpath";
          args[1] = base + "bootstrap/temp/main:" + base + "lib/jaxp.jar:" + 
                    base + "lib/crimson.jar";
          args[2] = "-d";
          args[3] = dest;
          for (int i = 0; i < sources.size(); i++) {
              args[4+i] = ((File)sources.elementAt(i)).toString();
          }
          
          // System.out.print("javac ");
          // for (int i = 0; i < args.length; i++) {
          //     System.out.print(args[i] + " ");
          // }
          // System.out.println();
          
          compiler.compile(args);
      }
  
      private static void copyfile(String from, String dest) {
          File fromF = new File(from);
          File destF = new File(dest);
          if (fromF.exists()) {
              System.out.println("   Copying " + from);
              try {
                  FileInputStream in = new FileInputStream(fromF);
                  FileOutputStream out = new FileOutputStream(destF);
                  byte[] buf = new byte[1024 * 16];
                  int count = 0;
                  count = in.read(buf, 0, buf.length);
                  if (count != -1) {
                      out.write(buf, 0, count);
                      count = in.read(buf, 0, buf.length);
                  }
                  
                  in.close();
                  out.close();
              } catch (IOException ioe) {
                  System.out.println("OUCH: " + from);
                  System.out.println(ioe);
              }
          }
      }
  }
  
  
  1.1                  jakarta-ant/proposal/anteater/bootstrap/README
  
  Index: README
  ===================================================================
  BOOTSTRAP FOLDER README
  ---------------------------------------------------------------------
  
  The utilities provided here are used by the developers of Ant to 
  bootstrap builds of Ant and will be used by the nightly build process
  to build Ant from a zero state.
  
  That said, there is no reason for most folks -- even hard core Ant
  developers -- to use the files here on a regular basis. You should
  really have the latest stable version of Ant installed somewhere so
  that you can easily build Ant using itself. Check out the 
  installation guidelines in the documentation for suggestions on how
  Ant can be installed as a full time program of your system. 
  
  HOW TO USE
  
  So, you really want to use the bootstrap facilities instead of just
  downloading a build from somewhere? Ok. Here's how it works:
  
    * Make sure that sun.tools.javac.Main is on your classpath. 
      Sometimes it is, sometimes it isn't -- it depends on the JDK
      installed on your machine. You can do a quick check using
      the 'javap sun.tools.javac.Main' command to see if it is.
  
    * Make sure that you have a JAXP 1.1 compliant parser in your
      classpath. The Bootstrap itself doesn't need XML parsing
      classes, but Ant itself does. A good test for this is
      'javap javax.xml.parsers.DocumentBuilder'
  
    * Compile Bootstrap.java. You should end up with Bootstrap.class
      and maybe a few other classes (depending).
      
    * Execute the Bootstrap class.
    
  How this will work in practice is:
  
    % javac Bootstrap.java
    % java Bootstrap
  
  The Bootstrap class will grind out a preliminary build in the directory
  'temp/' which will be placed in this directory, then use that build to
  build a real copy of Ant into '../Build' using Ant's own makefile. After
  doing this, the Boostrap class will remove the intermediate build in
  the 'temp/' directory.
  
  HISTORICAL NOTE
  
  The Bootstrap class is somewhat the same rough hack as the first sketch
  of Ant itself -- a proof of concept that a Java based build system
  could work out halfway decently. Of course, Ant has expanded much past
  the capabilities of this, but this little start serves as a useful
  tool to bootstrap builds.
  
  
  1.1                  jakarta-ant/proposal/anteater/lib/crimson.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-ant/proposal/anteater/lib/jaxp.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-ant/proposal/anteater/source/main.ant
  
  Index: main.ant
  ===================================================================
  <?xml version="1.0"?>
  
  <project name="Ant">
  
    <target name="default">
      <echo data="Echo In Default"/>
    </target>
  
    <target name="main">
      <echo data="Echo In Main"/>
    </target>
  
  </project>
  
  
  
  1.1                  jakarta-ant/proposal/anteater/source/coretasks/echo/taskdef.properties
  
  Index: taskdef.properties
  ===================================================================
  # taskdef.properties for Echo task
  
  tasks=echo
  echo.class=org.apache.ant.echo.EchoTask
  
  
  1.1                  jakarta-ant/proposal/anteater/source/coretasks/echo/org/apache/ant/echo/EchoTask.java
  
  Index: EchoTask.java
  ===================================================================
  package org.apache.ant.echo;
  
  import java.io.*;
  import java.util.*;
  
  import org.apache.ant.*;
  
  /**
   * Basic echo task that just spits out whatever it is supposed to...
   *
   * @author James Duncan Davidson (duncan@apache.org)
   */
  public class EchoTask extends AbstractTask {
      
      // -----------------------------------------------------------------
      // PRIVATE DATA MEMBERS
      // -----------------------------------------------------------------
      
      /**
       * Data to echo
       */
      private String data;
      
      // -----------------------------------------------------------------
      // PUBLIC METHODS
      // -----------------------------------------------------------------    
      
      /**
       *
       */
      public boolean execute() throws AntException {
      
          PrintStream out = project.getOutput();
          out.println("ECHOING: " + data);
          return true;
      } 
      
      /**
       *
       */
      public void setData(String data) {
          this.data = data;
      }
  }
  
  
  1.1                  jakarta-ant/proposal/anteater/source/main/org/apache/ant/AbstractTask.java
  
  Index: AbstractTask.java
  ===================================================================
  package org.apache.ant;
  
  import java.io.*;
  import java.util.*;
  import java.lang.reflect.*;
  import java.beans.*;
  
  /**
   * Superclass of all Tasks. All tasks extend from this.
   *
   * @author James Duncan Davidson (duncan@apache.org)
   */
  public abstract class AbstractTask {
      
      // -----------------------------------------------------------------
      // PROTECTED DATA MEMBERS
      // -----------------------------------------------------------------
      
      /**
       *
       */
      protected Project project;
      
      // -----------------------------------------------------------------
      // ABSTRACT PUBLIC METHODS
      // -----------------------------------------------------------------     
      
      /**
       *
       */
      public abstract boolean execute() throws AntException;
      
      // -----------------------------------------------------------------
      // PUBLIC METHODS
      // -----------------------------------------------------------------  
      
      /**
       * Used by the system to set the attributes which then get reflected
       * into the particular implementation class
       */
      public void setAttributes(Hashtable attributes) {
          Class clazz = this.getClass();
          BeanInfo bi;
          try {
              bi = Introspector.getBeanInfo(clazz);
          } catch (IntrospectionException ie) {
              System.out.println("Can't reflect on: " + clazz);
              // XXX exception out
              return;
          }
          PropertyDescriptor[] pda = bi.getPropertyDescriptors();
          for (int i = 0; i < pda.length; i++) {
              PropertyDescriptor pd = pda[i];
              String property = pd.getName();
              Object o = attributes.get(property);
              if (o != null) {
                  String value = (String)o;
                  Method setMethod = pd.getWriteMethod();
                  if (setMethod != null) {
                      Class[] ma = setMethod.getParameterTypes();
                      if (ma.length == 1) {
                          Class c = ma[0];
                          if (c.getName().equals("java.lang.String")) {
                              try {
                                  setMethod.invoke(this, new String[] {value});
                              } catch (Exception e) {
                                  // XXX bad bad bad -- narrow to exact exceptions
                                  System.out.println("OUCH: " + e);
                                  // XXX exception out.
                              }
                          }
                      }
                  }
              }
          }
      }
      
      /**
       * Used by system to set the project.
       */  
      public void setProject(Project project) {
          this.project = project;
      }
    
  }
  
  
  1.1                  jakarta-ant/proposal/anteater/source/main/org/apache/ant/Ant.java
  
  Index: Ant.java
  ===================================================================
  // -------------------------------------------------------------------------------
  // 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 Hashtable abstractTaskClasses = new Hashtable();
      
      /**
       *
       */
      private Vector taskPathNodes = new Vector();
      
      /**
       *
       */
      private File buildfile;
      
      /**
       *
       */
      private Project project;
      
      // -----------------------------------------------------------------
      // CONSTRUCTORS
      // -----------------------------------------------------------------
      
      /**
       * Constructs a new Ant instance.
       */
      public Ant() {
          setUpTaskPath();
      }
      
      // -----------------------------------------------------------------
      // PUBLIC METHODS
      // ----------------------------------------------------------------- 
      
      /**
       * Sets additional path nodes onto the task lookup path. These nodes
       * take precendence over all previously set path nodes.
       */   
      public void addTaskPathNode(File node) {
          taskPathNodes.insertElementAt(node, 0);
      }
      
      /**
       *
       */
      public void buildTarget(String targetName) throws AntException {
      
          try {
              loadTasks();
          } catch (IOException ioe) {
              throw new AntException(ioe.getMessage());
          }
          
          Target target = project.getTarget(targetName);
          
          // XXX don't forget to execute dependancies first!
          
          Enumeration enum = target.getTasks().elements();
          while (enum.hasMoreElements()) {
              Task task = (Task)enum.nextElement();
              Object o = abstractTaskClasses.get(task.getType());
              if (o != null) {
                  Class c = (Class)o;
                  try {
                      AbstractTask aTask = (AbstractTask)c.newInstance();
                      aTask.setAttributes(task.getAttributes());
                      aTask.setProject(project);
                      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);
                  }
              } else {
                  throw new AntException("Don't have a class for task type: " + task);
              }
          }
      }
      
      /**
       *
       */
      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
      // ----------------------------------------------------------------- 
      
      /**
       * Searches through the taskpath and loads up the taskImpl hashtable
       *
       * XXX we also need to lookup a taskdef.properties file out of a few
       * strategic locations on disk to allow generic classes to be pulled
       * from the classpath
       */
      private void loadTasks() throws IOException {
          Enumeration enum = taskPathNodes.elements();
          while (enum.hasMoreElements()) {
              File dir = (File)enum.nextElement();
              String[] files = dir.list();
              for (int i = 0; i < files.length; i++) {
                  if (files[i].endsWith(".jar")) {
                      File f = new File(dir, files[i]);
                      ZipFile zf = new ZipFile(f);
                      ZipEntry ze = zf.getEntry("/taskdef.properties");
                      if (ze != null) {
                          InputStream is = zf.getInputStream(ze);
                          Properties props = new Properties();
                          props.load(is);
                          is.close();
                          //System.out.println("Props: " + props);
                          String s = props.getProperty("tasks");
                          StringTokenizer tok = new StringTokenizer(s, ",", false);
                          while (tok.hasMoreTokens()) {
                              String taskType = tok.nextToken();
                              String taskClassName = props.getProperty(taskType + 
                                                                       ".class");
                              //System.out.println("TASK: " + taskType + " class: " +
                              //                taskClassName);
                              ClassLoader pcl = this.getClass().getClassLoader();
                              TaskClassLoader tcl = new TaskClassLoader(pcl, zf);
                              try {
                                  Class clazz = tcl.findClass(taskClassName);
                                  abstractTaskClasses.put(taskType, clazz);
                              } catch (ClassNotFoundException cnfe) {
                                  System.out.println(cnfe);
                                  System.out.println(cnfe.getMessage());
                              }
                          }
                      }
                  }
              }
          }
      }
  
      /**
       * 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()) {
              taskPathNodes.addElement(f);
          }
          
          // macos x
          f = new File(userHome + "/Library/Ant", "Tasks");
          if (f.exists() && f.isDirectory()) {
              taskPathNodes.addElement(f);
          }
          
          // windows -- todo
          
          // 2nd, add system local dir.
          
          // generic unix
          f = new File("/usr/local/ant/tasks");
          if (f.exists() && f.isDirectory()) {
              taskPathNodes.addElement(f);
          }
          
          // macos x
          f = new File("/Library/Ant/Tasks");
          if (f.exists() && f.isDirectory()) {
              taskPathNodes.addElement(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.
      }
  
  }
  
  
  1.1                  jakarta-ant/proposal/anteater/source/main/org/apache/ant/AntException.java
  
  Index: AntException.java
  ===================================================================
  // -------------------------------------------------------------------------------
  // Copyright (c)2000 Apache Software Foundation
  // -------------------------------------------------------------------------------
  
  package org.apache.ant;
  
  /**
   * Signals a problem.
   *
   * @author James Duncan Davidson (duncan@apache.org)
   */
  public class AntException extends Exception {
  
      public AntException() {
          super();
      }
      
      public AntException(String msg) {
          super(msg);
      }
  }
  
  
  1.1                  jakarta-ant/proposal/anteater/source/main/org/apache/ant/Project.java
  
  Index: Project.java
  ===================================================================
  // ---------------------------------------------------------------------
  // (c)2000 Apache Software Foundation
  //
  // ---------------------------------------------------------------------
  
  package org.apache.ant;
  
  import java.io.*;
  import java.util.*;
  
  /**
   * In memory container for an Ant project.
   *
   * @author James Duncan Davidson (duncan@apache.org)
   */
  public class Project {
  
      // -----------------------------------------------------------------
      // PRIVATE DATA MEMBERS
      // -----------------------------------------------------------------
  
      /**
       *
       */
      private Ant ant;
      
      /**
       *
       */
      private PrintStream out;
  
      /**
       * Parent project to this project, if one exists.
       */
      private Project parentProject = null;
  
      /**
       *
       */
      private String name;
  
      /**
       * Hashtable containing all of the targets that are part of this
       * project. Targets are stored in this hashtable using the name
       * of the target as the key and the Target object for the target
       * as the value.
       */
      private Hashtable targets = new Hashtable();
  
      // -----------------------------------------------------------------
      // PUBLIC ACCESSOR METHODS
      // -----------------------------------------------------------------
  
      /**
       *
       */
      public void addTarget(Target target) {
          // XXX check out for name, if null, reject!
          targets.put(target.getName(), target);
      }
  
      /**
       *
       */
      public PrintStream getOutput() {
          // XXX check if null!!!!????
          return out;
      }
  
      /**
       * Returns the parent Project object to this Project if a parent
       * project exists. If there is not a parent Project object, null
       * is returned.
       */
      public Project getParent() {
          return parentProject;
      }
  
      /**
       * Returns the target identified with the given name. If no target
       * is known by the given name, then null is returned.
       */
      public Target getTarget(String name) {
          return (Target)targets.get(name);
      }
      
      /**
       *
       */
      public Enumeration getTargets() {
          return targets.elements();
      }
      
      /**
       *
       */
      public String getName() {
          return name;
      }
      
      /**
       *
       */
      public void setAnt(Ant ant) {
          this.ant = ant;
      }
      
      /**
       *
       */
      public void setOutput(PrintStream out) {
          this.out = out;
      }
      
      /**
       *
       */
      public void setName(String name) {
          this.name = name;
      }
      
      /**
       *
       */
      public String toString() {
          return "Project name=" + name;
      }
  }
  
  
  1.1                  jakarta-ant/proposal/anteater/source/main/org/apache/ant/ProjectBuilder.java
  
  Index: ProjectBuilder.java
  ===================================================================
  // -------------------------------------------------------------------------------
  // Copyright (c)2000 Apache Software Foundation
  // -------------------------------------------------------------------------------
  
  package org.apache.ant;
  
  import java.io.*;
  import javax.xml.parsers.*;
  import org.xml.sax.*;
  
  /**
   * Helper class to build Project object trees.
   *
   * XXX right now this class only deals with the primary levels (project/target/task)
   * and nothing else. Also, it only supports attributes....
   *
   * @author James Duncan Davidson (duncan@apache.org)
   */
  class ProjectBuilder {
  
      private SAXParserFactory parserFactory;
          
      // -----------------------------------------------------------------
      // CONSTRUCTORS
      // -----------------------------------------------------------------
     
      ProjectBuilder() {
          parserFactory = SAXParserFactory.newInstance();
          parserFactory.setValidating(false);  
      }
  
      Project buildFromFile(File file) throws AntException {
          try {
              SAXParser parser = parserFactory.newSAXParser();
              BuilderHandlerBase bhb = new BuilderHandlerBase();
              parser.parse(file, bhb);
              return bhb.getProject();
          } catch (ParserConfigurationException pce) {
              throw new AntException(pce.getMessage());
          } catch (SAXException se) {
              System.out.println(se);
              System.out.println(se.getMessage());
              throw new AntException(se.getMessage());
          } catch (IOException ioe) {
              throw new AntException(ioe.getMessage());
          }
      }
      
      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_FINISHED = 99;
      
          private int state = STATE_START;
          
          private Target currentTarget;
          private Task currentTask;
      
          Project project = new Project();
      
          Project getProject() {
              return project;
          }
          
          public void startElement(String name, AttributeList atts) throws SAXException {
              //System.out.println("element: " + name);
              
              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
                      }
                      project.setName(projectName);
                  } else {
                      System.out.println("Expecting project, got: " + name);
                      // XXX exception out
                  }
                  break;
                case STATE_PROJECT:
                  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
                      }
                      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:
                  state = STATE_TASK;
                  //System.out.println("Getting task: " + name + " for target " + 
                  //                   currentTarget);
                  // XXX need to validate that task type (name) exists in system
                  // else exception out.
                  currentTask = new Task(name);
                  currentTarget.addTask(currentTask);
                  for (int i = 0; i < atts.getLength(); i++) {
                      String atName = atts.getName(i);
                      String atValue = atts.getValue(i);
                      currentTask.addAttribute(atName, atValue);
                  }
                  break;
                default:
                  System.out.println("I'm not sure, but we're off base here: " + name);
                  // XXX exception out
              }
          }
          
          public void characters(char ch[], int start, int length) throws SAXException {
          }
          
          public void endElement(String name) throws SAXException {
              // System.out.println("end: " + name);
              switch (state) {
                case STATE_TASK:
                  state = STATE_TARGET;
                  break;
                case STATE_TARGET:
                  if (name.equals("target")) {
                      state = STATE_PROJECT;
                  } else {
                      System.out.println("Expecting to get an end of target, got: " + name);
                      // XXX exception out.
                  }
                  break;
                case STATE_PROJECT:
                  if (name.equals("project")) {
                      state = STATE_FINISHED;
                  } else {
                      System.out.println("Expecting to get end of project, got: " + name);
                      // XXX exception out;
                  }
                  break;
                default:
                  System.out.println("I'm not sure what we are ending here: " + name);
                  // XXX exception out;
              }
          }
      }
  }
  
  
  1.1                  jakarta-ant/proposal/anteater/source/main/org/apache/ant/Target.java
  
  Index: Target.java
  ===================================================================
  // ---------------------------------------------------------------------
  // (c)2000 Apache Software Foundation
  //
  // ---------------------------------------------------------------------
  
  package org.apache.ant;
  
  import java.util.*;
  
  /**
   * In memory container for an Ant target.
   */
  public class Target {
  
      // -----------------------------------------------------------------
      // PRIVATE DATA MEMBERS
      // -----------------------------------------------------------------
  
      /**
       * String containing the name of the target. This name must be
       * unique withing a project.
       */
      private String name;
  
      /**
       * Vector containing the tasks that are part of this target.
       */
      private Vector tasks = new Vector();
  
      // -----------------------------------------------------------------
      // CONSTRUCTORS
      // -----------------------------------------------------------------
  
      /**
       * Constructs a new Target object with the given name.
       */
      public Target(String name) {
          this.name = name;
      }
  
      // -----------------------------------------------------------------
      // PUBLIC ACCESSOR METHODS
      // -----------------------------------------------------------------
      
      /**
       *
       */
      public void addTask(Task task) {
          tasks.addElement(task);
      }
      
      /**
       * Returns a String containing the name of this Target.
       */
      public String getName() {
          return name;
      }
      
      /**
       *
       */
      public String toString() {
          return "TARGET: " + name;
      }
  
      /**
       * Returns a Vector of Tasks contained in this Target. 
       * <p>
       * Please use caution when using this method. I am not happy
       * about exposing this data as something other than a 
       * Collection, but don't want to use 1.1 collections. So, 
       * this method may change in the future. You have been warned.
       */
      public Vector getTasks() {
          return tasks;
      }
  }
  
  
  1.1                  jakarta-ant/proposal/anteater/source/main/org/apache/ant/Task.java
  
  Index: Task.java
  ===================================================================
  // ---------------------------------------------------------------------
  // (c)2000 Apache Software Foundation
  //
  // ---------------------------------------------------------------------
  
  package org.apache.ant;
  
  import java.util.*;
  
  /**
   * In memory container for an Ant target.
   *
   * XXX need a way to query which attributes are valid for this particular
   * task type... Like into Ant object to do this?
   */
  public class Task {
  
      // -----------------------------------------------------------------
      // PRIVATE DATA MEMBERS
      // -----------------------------------------------------------------
      
      /**
       *
       */
      private Hashtable attributes = new Hashtable();
      
      /**
       * String containing the type of the task.
       */
      private String type;
  
      // -----------------------------------------------------------------
      // CONSTRUCTORS
      // -----------------------------------------------------------------
  
      /**
       * Constructs a new Target object with the given name.
       */
      public Task(String type) {
          this.type = type;
      }
  
      // -----------------------------------------------------------------
      // PUBLIC ACCESSOR METHODS
      // -----------------------------------------------------------------
      
      /**
       *
       */
      public void addAttribute(String name, String value) {
          attributes.put(name, value);
      }
      
      public String getAttribute(String name) {
          return (String)attributes.get(name);
      }
      
      /**
       *
       */
      public Hashtable getAttributes() {
          return attributes;
      }
      
      /**
       *
       */
      public Enumeration getAttributeNames() {
          return attributes.keys();
      }
       
      /**
       * Returns a String containing the name of this Target.
       */
      public String getType() {
          return type;
      }
      
      /**
       *
       */
      public String toString() {
          return "TASK: " + type;
      }
  
  }
  
  
  1.1                  jakarta-ant/proposal/anteater/source/main/org/apache/ant/TaskClassLoader.java
  
  Index: TaskClassLoader.java
  ===================================================================
  package org.apache.ant;
  
  import java.io.*;
  import java.util.*;
  import java.util.zip.*;
  
  /**
   *
   *
   * @author James Duncan Davidson (duncan@apache.org)
   */
  class TaskClassLoader extends ClassLoader {
  
      // -----------------------------------------------------------------
      // PRIVATE MEMBERS
      // -----------------------------------------------------------------
  
      /**
       *
       */
      private Hashtable cache = new Hashtable();
  
      /**
       *
       */
      private ZipFile zf;
  
      // -----------------------------------------------------------------
      // CONSTRUCTORS
      // ----------------------------------------------------------------- 
      
      /**
       * Constructs a classloader that loads classes from the specified
       * zip file.
       */
      TaskClassLoader(ClassLoader parent, ZipFile zf) {
          super(parent);
          this.zf = zf;
      }
       
      // -----------------------------------------------------------------
      // PUBLIC METHODS
      // ----------------------------------------------------------------- 
      
      /**
       *
       */
      public Class findClass(String name) 
      throws ClassNotFoundException 
      {
          Class c;
          try {
              return findSystemClass(name);
          } catch (ClassNotFoundException cnfe) {
          }
          try {
              return this.getClass().getClassLoader().loadClass(name);
          } catch (Exception e) {
          }
          Object o = cache.get(name);
          if (o != null) {
              c = (Class)o;
          } else {
              byte[] data = loadClassData(name);
              c = defineClass(data, 0, data.length);
              cache.put(name, c);
          }
          //if (resolve) {
          //    resolveClass(c);
          //}
          return c;
      }
      
      /**
       *
       */
      private byte[] loadClassData(String name) throws ClassNotFoundException {
          String newName = name.replace('.', '/');
          ZipEntry ze = zf.getEntry("/" + newName + ".class");
          //System.out.println("/" + newName + ".class");
          //System.out.println("ZE: " + ze);
          if (ze != null) {
              byte[] buf = new byte[((int)ze.getSize())];
              // System.out.println("ZE SIZE " + ze.getSize());
              try {
                  InputStream in = zf.getInputStream(ze);
                  int count = 0;
                  int thisRead = 0;
                  while (count < buf.length && thisRead != -1) {
                      thisRead = in.read(buf, count, buf.length - count);
                      count += thisRead;
                  }
                  in.close();
              } catch (IOException ioe) {
                  throw new ClassNotFoundException("Can't load class: " + name + " " +
                                                   ioe.getMessage());
              }
              return buf;
          } else {
              throw new ClassNotFoundException("Can't find class for: " + name);
          }
      }
  }
  
  
  1.1                  jakarta-ant/proposal/anteater/source/main/org/apache/ant/cli/Main.java
  
  Index: Main.java
  ===================================================================
  // -------------------------------------------------------------------------------
  // Copyright (c)2000 Apache Software Foundation
  // -------------------------------------------------------------------------------
  
  package org.apache.ant.cli;
  
  import java.io.*;
  import java.util.*;
  import org.apache.ant.*;
  
  /**
   * Entry point for Ant on the Command Line Interface.
   *
   * @author James Duncan Davidson (duncan@apache.org)
   */
  public class Main {
  
      /**
       * Command line entry point.
       */
      public static void main(String[] args) {
          Ant ant = new Ant();
          String target = "";
          
          System.out.println("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) {
                          System.out.println("ICK: " + ae);
                          System.out.println(ae.getMessage());
                          return;
                      }
                  }
              } else {
                  target = arg;
              }
          }
          
          // 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);
  
          System.out.println();
          System.out.println("Executing Target: " + target);
          
          try {
              ant.buildTarget(target);
          } catch (AntException ae) {
              System.out.println("Problem while building: " + ae);
              System.out.println(ae.getMessage());
          }
      }
  
      // -----------------------------------------------------------------
      // PRIVATE METHODS
      // -----------------------------------------------------------------  
      
      /**
       * Prints help to System.out
       */  
      private static void printHelp() {
          System.out.println("Usage: ant [args] [target]");
          System.out.println("   Arguments:");
          System.out.println("       -help");
          System.out.println("       -taskpath [path]");
          System.out.println("       -buildfile [file]");
      }
  }