all classes. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268332 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -4,6 +4,7 @@ | |||
| import java.io.*; | |||
| import java.util.*; | |||
| import java.util.jar.*; | |||
| import java.util.zip.*; | |||
| /** | |||
| @@ -161,31 +162,46 @@ public class Bootstrap2 { | |||
| private static void jarDir(File dir, File jarfile) throws IOException { | |||
| String[] files = dir.list(); | |||
| if (files.length > 0) { | |||
| System.out.println("Jaring: " + jarfile); | |||
| System.out.println("Jaring: " + jarfile); | |||
| FileOutputStream fos = new FileOutputStream(jarfile); | |||
| ZipOutputStream zos = new ZipOutputStream(fos); | |||
| jarDir(dir, "", zos); | |||
| zos.close(); | |||
| JarOutputStream jos = new JarOutputStream(fos, new Manifest()); | |||
| jarDir(dir, "", jos); | |||
| jos.close(); | |||
| } | |||
| } | |||
| private static void jarDir(File dir, String prefix, ZipOutputStream zos) throws | |||
| private static void jarDir(File dir, String prefix, JarOutputStream jos) 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); | |||
| String zipEntryName; | |||
| if (!prefix.equals("")) { | |||
| zipEntryName = prefix + "/" + files[i]; | |||
| } else { | |||
| zipEntryName = files[i]; | |||
| } | |||
| ZipEntry ze = new ZipEntry(zipEntryName); | |||
| jos.putNextEntry(ze); | |||
| jarDir(f, zipEntryName, jos); | |||
| } else { | |||
| ZipEntry ze = new ZipEntry(prefix + "/" + files[i]); | |||
| zos.putNextEntry(ze); | |||
| String zipEntryName; | |||
| if (!prefix.equals("")) { | |||
| zipEntryName = prefix + "/" + files[i]; | |||
| } else { | |||
| zipEntryName = files[i]; | |||
| } | |||
| ZipEntry ze = new ZipEntry(zipEntryName); | |||
| jos.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); | |||
| jos.write(buf, 0, count); | |||
| count = fis.read(buf, 0, buf.length); | |||
| } | |||
| fis.close(); | |||
| @@ -1,4 +1,4 @@ | |||
| # taskdef.properties for Echo task | |||
| tasks=echo | |||
| echo.class=org.apache.ant.echo.EchoTask | |||
| task.echo.class=org.apache.ant.echo.EchoTask | |||
| @@ -28,13 +28,18 @@ public class Ant { | |||
| /** | |||
| * | |||
| */ | |||
| private Vector taskPathNodes = new Vector(); | |||
| private File buildfile; | |||
| /** | |||
| * | |||
| * Manager of tasks. | |||
| */ | |||
| private File buildfile; | |||
| private TaskManager taskManager = new TaskManager(); | |||
| /** | |||
| * | |||
| */ | |||
| private Vector taskPathNodes = new Vector(); | |||
| /** | |||
| * | |||
| */ | |||
| @@ -61,18 +66,13 @@ public class Ant { | |||
| */ | |||
| public void addTaskPathNode(File node) { | |||
| taskPathNodes.insertElementAt(node, 0); | |||
| taskManager.addTaskPathNode(node); | |||
| } | |||
| /** | |||
| * | |||
| */ | |||
| public void buildTarget(String targetName) throws AntException { | |||
| try { | |||
| loadTasks(); | |||
| } catch (IOException ioe) { | |||
| throw new AntException(ioe.getMessage()); | |||
| } | |||
| Target target = project.getTarget(targetName); | |||
| @@ -81,24 +81,18 @@ public class Ant { | |||
| 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); | |||
| 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"); | |||
| } | |||
| } else { | |||
| throw new AntException("Don't have a class for task type: " + task); | |||
| } catch (Exception e) { | |||
| // XXX yes yes yes, this shouldn't be a catch all... | |||
| throw new AntException("ERR: " + e); | |||
| } | |||
| } | |||
| } | |||
| @@ -147,53 +141,6 @@ public class Ant { | |||
| // 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, | |||
| @@ -211,13 +158,13 @@ public class Ant { | |||
| // generic unix | |||
| f = new File(userHome + ".ant", "tasks"); | |||
| if (f.exists() && f.isDirectory()) { | |||
| taskPathNodes.addElement(f); | |||
| taskManager.addTaskPathNode(f); | |||
| } | |||
| // macos x | |||
| f = new File(userHome + "/Library/Ant", "Tasks"); | |||
| if (f.exists() && f.isDirectory()) { | |||
| taskPathNodes.addElement(f); | |||
| taskManager.addTaskPathNode(f); | |||
| } | |||
| // windows -- todo | |||
| @@ -227,13 +174,13 @@ public class Ant { | |||
| // generic unix | |||
| f = new File("/usr/local/ant/tasks"); | |||
| if (f.exists() && f.isDirectory()) { | |||
| taskPathNodes.addElement(f); | |||
| taskManager.addTaskPathNode(f); | |||
| } | |||
| // macos x | |||
| f = new File("/Library/Ant/Tasks"); | |||
| if (f.exists() && f.isDirectory()) { | |||
| taskPathNodes.addElement(f); | |||
| taskManager.addTaskPathNode(f); | |||
| } | |||
| // windows -- todo | |||
| @@ -1,103 +0,0 @@ | |||
| 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); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,196 @@ | |||
| // ------------------------------------------------------------------------------- | |||
| // Copyright (c)2000 Apache Software Foundation | |||
| // ------------------------------------------------------------------------------- | |||
| package org.apache.ant; | |||
| import java.io.*; | |||
| import java.net.*; | |||
| import java.util.*; | |||
| import java.util.zip.*; | |||
| /** | |||
| * Manager of tasks and all things related to tasks. Tasks can be found in a | |||
| * wide number of locations -- and most of these locations require class loading | |||
| * help. As well, new nodes on the task search path may be added at any time. | |||
| * When these are added, new tasks should be scanned for. | |||
| * | |||
| * @author James Duncan Davidson (duncan@apache.org) | |||
| */ | |||
| class TaskManager { | |||
| // ----------------------------------------------------------------- | |||
| // PRIVATE DATA MEMBERS | |||
| // ----------------------------------------------------------------- | |||
| /** | |||
| * Data structure where all the Class definition for all known tasks are | |||
| * held. | |||
| */ | |||
| private Hashtable taskClasses = new Hashtable(); | |||
| /** | |||
| * Data structure that holds all the nodes where tasks are picked up from. | |||
| */ | |||
| private Vector taskPathNodes = new Vector(); | |||
| // ----------------------------------------------------------------- | |||
| // CONSTRUCTORS | |||
| // ----------------------------------------------------------------- | |||
| /** | |||
| * Creates a new TaskManager. | |||
| */ | |||
| TaskManager() { | |||
| } | |||
| // ----------------------------------------------------------------- | |||
| // PACKAGE METHODS | |||
| // ----------------------------------------------------------------- | |||
| /** | |||
| * Adds a node to the task path | |||
| */ | |||
| void addTaskPathNode(File file) { | |||
| taskPathNodes.addElement(file); | |||
| processTaskPathNode(file); | |||
| } | |||
| /** | |||
| * | |||
| */ | |||
| AbstractTask getTaskInstance(String taskName) { | |||
| 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 | |||
| } | |||
| return null; | |||
| } | |||
| // ----------------------------------------------------------------- | |||
| // PRIVATE METHODS | |||
| // ----------------------------------------------------------------- | |||
| /** | |||
| * Returns an enum of the task names that are defined in a given | |||
| * properties file. | |||
| */ | |||
| private Enumeration getTaskNames(Properties props) { | |||
| Vector v = new Vector(); | |||
| String s = props.getProperty("tasks"); | |||
| StringTokenizer tok = new StringTokenizer(s, ",", false); | |||
| while (tok.hasMoreTokens()) { | |||
| String taskName = tok.nextToken().trim(); | |||
| v.addElement(taskName); | |||
| } | |||
| return v.elements(); | |||
| } | |||
| /** | |||
| * Processes a directory to get class defintions from it | |||
| */ | |||
| private void processDir(File dir) { | |||
| System.out.println("Scanning " + dir + " for tasks"); | |||
| File file = new File(dir, "taskdef.properties"); | |||
| if (file.exists()) { | |||
| try { | |||
| InputStream in = new FileInputStream(file); | |||
| Properties props = new Properties(); | |||
| props.load(in); | |||
| in.close(); | |||
| Enumeration enum = getTaskNames(props); | |||
| while (enum.hasMoreElements()) { | |||
| String taskName = (String)enum.nextElement(); | |||
| String taskClass = props.getProperty("task." + taskName + ".class"); | |||
| URLClassLoader loader = new URLClassLoader(new URL[] {dir.toURL()}); | |||
| try { | |||
| Class clazz = loader.loadClass(taskClass); | |||
| System.out.println("Got task: " + taskName + " " + clazz); | |||
| taskClasses.put(taskName, clazz); | |||
| } catch (ClassNotFoundException cnfe) { | |||
| System.out.println("Couldn't load task: " + taskName); | |||
| System.out.println(cnfe); | |||
| // XXX error out and stop.... | |||
| } | |||
| } | |||
| } catch (IOException ioe) { | |||
| System.out.println("Could not work with dir: " + dir); | |||
| System.out.println(ioe); | |||
| // XXX error out and stop the build | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Processes a jar file to get class definitions from it | |||
| */ | |||
| private void processJar(File file) { | |||
| System.out.println("Scanning " + file + " for tasks"); | |||
| try { | |||
| ZipFile zipFile = new ZipFile(file); | |||
| ZipEntry zipEntry = zipFile.getEntry("taskdef.properties"); | |||
| if (zipEntry != null) { | |||
| InputStream in = zipFile.getInputStream(zipEntry); | |||
| Properties props = new Properties(); | |||
| props.load(in); | |||
| in.close(); | |||
| Enumeration enum = getTaskNames(props); | |||
| while (enum.hasMoreElements()) { | |||
| String taskName = (String)enum.nextElement(); | |||
| String taskClass = props.getProperty("task." + taskName + ".class"); | |||
| URLClassLoader loader = new URLClassLoader(new URL[] {file.toURL()}); | |||
| try { | |||
| Class clazz = loader.loadClass(taskClass); | |||
| System.out.println("Got Task: " + taskName + " " + clazz); | |||
| taskClasses.put(taskName, clazz); | |||
| } catch (ClassNotFoundException cnfe) { | |||
| System.out.println("Couldn't load task: " + taskName); | |||
| System.out.println(cnfe); | |||
| // XXX error out and stop.... | |||
| } | |||
| } | |||
| } | |||
| // make sure to not leave resources hanging | |||
| zipFile.close(); | |||
| } catch (IOException ioe) { | |||
| System.out.println("Couldn't work with file: " + file); | |||
| System.out.println(ioe); | |||
| // XXX need to exception out of here properly to stop things | |||
| } | |||
| } | |||
| /** | |||
| * Processes a node of the task path searching for task definitions there | |||
| * and adding them to the list of known tasks | |||
| */ | |||
| private void processTaskPathNode(File file) { | |||
| // task path nodes can be any of the following: | |||
| // * jar file | |||
| // * directory of jar files | |||
| // * directory holding class files | |||
| if(file.isDirectory()) { | |||
| // first look for all jar files here | |||
| // second look for a taskdefs.properties here to see if we should | |||
| // treat the directory as a classpath | |||
| String[] files = file.list(); | |||
| for (int i = 0; i < files.length; i++) { | |||
| if (files[i].endsWith(".jar")) { | |||
| processJar(new File(file, files[i])); | |||
| } else if (files[i].equals("taskdef.properties")) { | |||
| processDir(file); | |||
| } | |||
| } | |||
| } else if (file.getName().endsWith(".jar")) { | |||
| processJar(file); | |||
| } | |||
| } | |||
| } | |||