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); | |||
} | |||
} | |||
} |