|
- // -------------------------------------------------------------------------------
- // 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)
- */
- public class TaskManager {
-
- // -----------------------------------------------------------------
- // PRIVATE DATA MEMBERS
- // -----------------------------------------------------------------
-
- /**
- * FrontEnd that this TaskManager can communicate through.
- */
- private AntFrontEnd frontEnd;
-
- /**
- * 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(AntFrontEnd frontEnd) {
- this.frontEnd = frontEnd;
- }
-
- // -----------------------------------------------------------------
- // PUBLIC METHODS
- // -----------------------------------------------------------------
-
- /**
- * Adds a node to the task path
- */
- public void addTaskPathNode(File file) throws AntException {
- taskPathNodes.addElement(file);
- processTaskPathNode(file);
- }
-
- // -----------------------------------------------------------------
- // PACKAGE METHODS
- // -----------------------------------------------------------------
-
- /**
- *
- */
- AbstractTask getTaskInstance(String taskName) throws AntException {
- Class clazz = (Class)taskClasses.get(taskName);
- try {
- return (AbstractTask)clazz.newInstance();
- } catch (Exception e) {
- String msg = "Can't instantiate task: " + taskName;
- AntException ae = new AntException(msg, e);
- throw ae;
- }
- }
-
- // -----------------------------------------------------------------
- // 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) {
- frontEnd.writeMessage("Scanning " + dir + " for tasks",
- AntFrontEnd.MSG_LEVEL_LOW);
- 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);
- frontEnd.writeMessage("Got Task: " + taskName +
- clazz, AntFrontEnd.MSG_LEVEL_LOW);
- 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) throws AntException {
- frontEnd.writeMessage("Scanning " + file + " for tasks",
- AntFrontEnd.MSG_LEVEL_LOW);
- 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");
- if (taskClass == null) {
- String msg = "No class definition for task " + taskName +
- "in jar file " + file;
- throw new AntException(msg);
- }
- URLClassLoader loader = new URLClassLoader(new URL[] {file.toURL()});
- try {
- Class clazz = loader.loadClass(taskClass);
- frontEnd.writeMessage("Got Task: " + taskName +
- clazz, AntFrontEnd.MSG_LEVEL_LOW);
- 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) throws AntException {
-
- // 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);
- }
- }
-
- /**
- * 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() throws AntException {
-
- // 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.
- }
-
- }
|