There is the task:
I  am not too sure if I am using the new ResourceCollection stuff
correctly!

Peter


/*
* Copyright  2006 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*/
package org.apache.tools.ant.taskdefs;


import java.lang.reflect.Method;

import java.util.Set;
import java.util.HashSet;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.URLResource;
import org.apache.tools.ant.util.FileUtils;

/**
* A Task to extend the project class path.
* This task works by assuming that the project
* classloader is a URLClassLoader (or derives
* from URLClassloader), and by using reflection
* to make the addURL method public.
*/
public class AppendProjectPath extends Task {
   private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();

   /**
    * URLS in the attributes and the nested elements
    */
   private List urls = new ArrayList();

   //  ---    fields used in the execute method ---

   /**
    * Set used to ensure that a URL is only used once
    */
   private Set urlSet;

   /**
    * The addURL method on URLClassLoader
    */
   private Method addURLMethod;

   /**
    * The classloader of the project class
    */
   private URLClassLoader projectLoader;

   /**
    * A nested element class. The element is "url" and
    * it has one attribute - "url", this is a required
    * attribute.
    */
   public static class URLElement {
       private String urlString;

       /**
        * Set the url.
        *
        * @param urlString the value to set.
        */
       public void setURL(String urlString) {
           this.urlString = urlString;
       }

       /**
        * Get the url.
        *
        * @return the url string.
        */
       public String getURL() {
           if (urlString == null) {
               throw new BuildException(
                       "Missing required attribute url "
                               + "for nested url element");
           }
           return urlString;
       }
   }

   /**
    * Add a url to the list of urls.
    * This is an attribute of the task.
    *
    * @param urlString the value.
    */
   public void setURL(String urlString) {
       URL url;
       try {
           url = new URL(urlString);
       } catch (Exception ex) {
           throw new BuildException(
                   "Unable to convert to URL " + urlString);
       }
       urls.add(url);
   }

   /**
    * Handle a nested url element.
    * Get the url from it and call setURL to add to the
    * list of URLs.
    *
    * @param el the nested url element.
    */
   public void addConfiguredURL(URLElement el) {
       String urlString = el.getURL();
       setURL(urlString);
   }


   /**
    * Handle a nested resource collection.
    * Get the pathelements for the path, convert
    * them to url strings and call setURL to add
    * them to the list of urls.
    *
    * @param collection a nested path element.
    */
   public void addConfigured(ResourceCollection collection) {
       for (Iterator iter = collection.iterator(); iter.hasNext();) {
           Resource r = (Resource) iter.next();
           if (r instanceof FileResource) {
               FileResource file = (FileResource) r;
               String filePath = file.toString();
               try {
                   setURL(FILE_UTILS.toURI(file.toString()));
               } catch (Exception ex) {
                   throw new BuildException(
                       "Unable to convert to URL " + filePath);
               }
           } else if (r instanceof URLResource) {
               URLResource urlResource = (URLResource) r;
               urls.add(urlResource.getURL());
           } else if (r.isReference()) {
               addConfigured(r);
           } else {
               throw new BuildException(
                       "Do not know how do deal with " + r.getClass());
           }
       }
   }

   /**
    * Handle the "path" attribute.
    * This converts the path string to a Path object
    * and uses addConfigured(Path) to add the URLs.
    *
    * @param path a path string.
    */
   public void setPath(String path) {
       addConfigured(new Path(getProject(), path));
   }

   /**
    * Handle the "pathref" attribute.
    * This method adds the path referenced by the reference.
    *
    * @param ref a reference to an existing path.
    */

   public void setPathRef(Reference ref) {
       Path path = new Path(getProject());
       path.setRefid(ref);
       addConfigured(path);
   }

  /**
    * The execute method for the task.
    * This gets the addURL method, gets the project classloader,
    * iterates over the urls and appends them to the project classloader.
    */
   public void execute() {
       this.urlSet = new HashSet();
       this.addURLMethod = findAddURLMethod();
       this.projectLoader = findProjectLoader();
       populateCurrentURLS();
       for (Iterator iter = urls.iterator(); iter.hasNext();) {
           appendURLToProject((URL) iter.next());
       }
   }

   /**
    * Get the addURL method of the URLClassLoader class.
    * Change the accessiblity to true and return the method.
    * @return the addURL method.
    */
   private Method findAddURLMethod() {
       try {
           addURLMethod = URLClassLoader.class.getDeclaredMethod("addURL",
                   new Class[]{URL.class});
           addURLMethod.setAccessible(true);
       } catch (SecurityException ex) {
           throw new BuildException(
                   "Unable to setAccessible(true) for method addURL", ex);
        } catch (NoSuchMethodException ex) {
           throw new BuildException(
                   "Unable to find the addURL method", ex);
       }
       return addURLMethod;
   }

   /**
    * Append a url to the project classloader using the
    * addURL method. If the url is alreaded added, do nothing.
    * @param url the url to append to the classloader.
    */
   private void appendURLToProject(URL url) {
       if (!urlSet.add(url)) {
           return;
       }
       try {
           addURLMethod.invoke(projectLoader, new Object[]{url});
       } catch (Exception ex) {
           throw new BuildException(
                   "Unable to add URL " + url + " to the project
classpath",
                   ex);
       }
   }

   /**
    * Populate the set of urls in the project classloader.
    */
   private void populateCurrentURLS() {
       URL[] urls = projectLoader.getURLs();
       for (int i = 0; i < urls.length; ++i) {
           urlSet.add(urls[i]);
       }
   }

   /**
    * Get the classloader of the Project class
    * and check that it is a URLClassLoader.
    * @return the project classloader.
    * @throws BuildException if the project classlaoder is not a
URLClassLoader.
    */
   private URLClassLoader findProjectLoader() {
       ClassLoader loader = getProject().getClass().getClassLoader();
       if (!(loader instanceof URLClassLoader)) {
           throw new BuildException(
                   "project classloader is not a URLClassLoader");
       }
       return (URLClassLoader) loader;
   }
}


On 9/12/06, Matt Benson <[EMAIL PROTECTED]> wrote:

The subject line is manually entered b/c I no longer
have the mails from the original thread; I'm hoping
the mail archive will do the right thing anyway.  So
(and I make no pretense that this isn't DIRECTLY
related to my other thread)...

Peter, what's the status of your simplified extension
task prototype described here:

http://marc.theaimsgroup.com/?l=ant-dev&m=115695299516537&w=2

?

Thanks,
Matt

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Reply via email to