ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From co...@apache.org
Subject cvs commit: jakarta-ant/src/main/org/apache/tools/ant/util LoaderUtils.java FileUtils.java
Date Mon, 11 Mar 2002 09:40:21 GMT
conor       02/03/11 01:40:21

  Modified:    src/main/org/apache/tools/ant AntClassLoader.java
                        ProjectHelper.java
               src/main/org/apache/tools/ant/taskdefs XSLTProcess.java
               src/main/org/apache/tools/ant/types defaults.properties
               src/main/org/apache/tools/ant/util FileUtils.java
  Added:       src/main/org/apache/tools/ant/types XMLCatalog.java
               src/main/org/apache/tools/ant/util LoaderUtils.java
  Removed:     src/main/org/apache/tools/ant/types XCatalog.java
  Log:
  Restore 1.1 operation
  Refactor context class loader methods into a utility class
  Add URL method to FileUtils (still need to pick that up in Project)
  Rename xcatalog to XMLCatalog
  
  Revision  Changes    Path
  1.45      +80 -83    jakarta-ant/src/main/org/apache/tools/ant/AntClassLoader.java
  
  Index: AntClassLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/AntClassLoader.java,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -u -w -u -r1.44 -r1.45
  --- AntClassLoader.java	8 Mar 2002 11:16:14 -0000	1.44
  +++ AntClassLoader.java	11 Mar 2002 09:40:20 -0000	1.45
  @@ -70,6 +70,7 @@
   import java.net.URL;
   import java.net.MalformedURLException;
   import org.apache.tools.ant.types.Path;
  +import org.apache.tools.ant.util.LoaderUtils;
   
   /**
    * Used to load classes within ant with a different claspath from 
  @@ -181,8 +182,7 @@
        * The components of the classpath that the classloader searches
        * for classes.
        */
  -    // XXX: Any reason this shouldn't be private?
  -    Vector pathComponents  = new Vector();
  +    private Vector pathComponents  = new Vector();
   
       /**
        * The project to which this class loader belongs.
  @@ -228,7 +228,8 @@
       private Hashtable zipFiles = new Hashtable();
   
       /**
  -     * The context loader saved when setting the thread's current context loader.
  +     * The context loader saved when setting the thread's current 
  +     * context loader.
        */
       private ClassLoader savedContextLoader = null;
       /**
  @@ -248,29 +249,18 @@
        */
       private static Method defineClassProtectionDomain = null;
   
  -    /**
  -     * Reflection method reference for getContextClassLoader;
  -     * used to avoid 1.1-compatibility problems.
  -     */
  -    private static Method getContextClassLoader = null;
  -
  -    /**
  -     * Reflection method reference for setContextClassLoader;
  -     * used to avoid 1.1-compatibility problems.
  -     */
  -    private static Method setContextClassLoader = null;
       
       // Set up the reflection-based Java2 methods if possible
       static {
           try {
  -            getProtectionDomain = Class.class.getMethod("getProtectionDomain", new Class[0]);
  -            Class protectionDomain = Class.forName("java.security.ProtectionDomain");
  -            Class[] args = new Class[] {String.class, byte[].class, Integer.TYPE, Integer.TYPE,
protectionDomain};
  -            defineClassProtectionDomain = ClassLoader.class.getDeclaredMethod("defineClass",
args);
  -
  -            getContextClassLoader = Thread.class.getMethod("getContextClassLoader", new
Class[0]);
  -            args = new Class[] {ClassLoader.class};
  -            setContextClassLoader = Thread.class.getMethod("setContextClassLoader", args);
  +            getProtectionDomain 
  +                = Class.class.getMethod("getProtectionDomain", new Class[0]);
  +            Class protectionDomain 
  +                = Class.forName("java.security.ProtectionDomain");
  +            Class[] args = new Class[] {String.class, byte[].class, 
  +                Integer.TYPE, Integer.TYPE, protectionDomain};
  +            defineClassProtectionDomain 
  +                = ClassLoader.class.getDeclaredMethod("defineClass", args);
           }
           catch (Exception e) {}
       }
  @@ -299,7 +289,8 @@
                       addPathElement(pathElements[i]);
                   }
                   catch (BuildException e) {
  -                    // ignore path elements which are invalid relative to the project
  +                    // ignore path elements which are invalid 
  +                    // relative to the project
                   }
               }
           }
  @@ -345,7 +336,8 @@
        *                    classloader should be consulted before trying to 
        *                    load the a class through this loader.
        */
  -    public AntClassLoader(Project project, Path classpath, boolean parentFirst) {
  +    public AntClassLoader(Project project, Path classpath, 
  +                          boolean parentFirst) {
           this(null, project, classpath, parentFirst);
       }
   
  @@ -398,49 +390,23 @@
           if (isContextLoaderSaved) {
               throw new BuildException("Context loader has not been reset");
           }
  -        if (getContextClassLoader != null && setContextClassLoader != null) {
  -            try {
  -                savedContextLoader
  -                    = (ClassLoader)getContextClassLoader.invoke(Thread.currentThread(),
new Object[0]);
  -                Object[] args = null;
  -                if ("only".equals(project.getProperty("build.sysclasspath"))) {
  -                    args = new Object[] {this.getClass().getClassLoader()};
  -                } else {
  -                    args = new Object[] {this};
  -                }
  -                setContextClassLoader.invoke(Thread.currentThread(), args);
  +        if (LoaderUtils.isContextLoaderAvailable()) {
  +            savedContextLoader = LoaderUtils.getContextClassLoader();
  +            LoaderUtils.setContextClassLoader(this);
                   isContextLoaderSaved = true;
               }
  -            catch (InvocationTargetException ite) {
  -                Throwable t = ite.getTargetException();
  -                throw new BuildException(t.toString());
  -            }
  -            catch (Exception e) {
  -                throw new BuildException(e.toString());
  -            }
  -        }
       }
   
       /**
        * Resets the current thread's context loader to its original value.
        */
       public void resetThreadContextLoader() {
  -        if (isContextLoaderSaved &&
  -                getContextClassLoader != null && setContextClassLoader != null)
{
  -            try {
  -                Object[] args = new Object[] {savedContextLoader};
  -                setContextClassLoader.invoke(Thread.currentThread(), args);
  +        if (LoaderUtils.isContextLoaderAvailable() 
  +            && isContextLoaderSaved) {
  +            LoaderUtils.setContextClassLoader(savedContextLoader);
                   savedContextLoader = null;
                   isContextLoaderSaved = false;
               }
  -            catch (InvocationTargetException ite) {
  -                Throwable t = ite.getTargetException();
  -                throw new BuildException(t.toString());
  -            }
  -            catch (Exception e) {
  -                throw new BuildException(e.toString());
  -            }
  -        }
       }
   
   
  @@ -575,7 +541,8 @@
        * @exception ClassNotFoundException if the requested class does not exist
        *                                   on this loader's classpath.
        */
  -    public Class forceLoadClass(String classname) throws ClassNotFoundException {
  +    public Class forceLoadClass(String classname) 
  +         throws ClassNotFoundException {
           log("force loading " + classname, Project.MSG_DEBUG);
   
           Class theClass = findLoadedClass(classname);
  @@ -603,7 +570,8 @@
        * @exception ClassNotFoundException if the requested class does not exist
        * on this loader's classpath.
        */
  -    public Class forceLoadSystemClass(String classname) throws ClassNotFoundException {
  +    public Class forceLoadSystemClass(String classname) 
  +         throws ClassNotFoundException {
           log("force system loading " + classname, Project.MSG_DEBUG);
   
           Class theClass = findLoadedClass(classname);
  @@ -674,8 +642,8 @@
        *         the resource cannot be found on the loader's classpath.
        */
       private InputStream loadResource(String name) {
  -        // we need to search the components of the path to see if we can find the
  -        // class we want.
  +        // we need to search the components of the path to see if we can 
  +        // find the class we want.
           InputStream stream = null;
   
           for (Enumeration e = pathComponents.elements(); e.hasMoreElements() &&
stream == null; ) {
  @@ -743,8 +711,9 @@
               }
           }
           catch (Exception e) {
  -            log("Ignoring Exception " + e.getClass().getName() + ": " + e.getMessage()
+
  -                " reading resource " + resourceName + " from " + file, Project.MSG_VERBOSE);
  +            log("Ignoring Exception " + e.getClass().getName() 
  +                + ": " + e.getMessage() + " reading resource " + resourceName 
  +                + " from " + file, Project.MSG_VERBOSE);
           }
   
           return null;
  @@ -765,7 +734,8 @@
       private boolean isParentFirst(String resourceName) {
           // default to the global setting and then see
           // if this class belongs to a package which has been
  -        // designated to use a specific loader first (this one or the parent one)
  +        // designated to use a specific loader first 
  +        // (this one or the parent one)
           
           // XXX - shouldn't this always return false in isolated mode?
           
  @@ -803,11 +773,12 @@
        *         adequate privileges to get the resource.
        */
       public URL getResource(String name) {
  -        // we need to search the components of the path to see if we can find the
  -        // class we want.
  +        // we need to search the components of the path to see if 
  +        // we can find the class we want.
           URL url = null;
           if (isParentFirst(name)) {
  -            url = (parent == null) ? super.getResource(name) : parent.getResource(name);
  +            url = (parent == null) ? super.getResource(name) 
  +                                   : parent.getResource(name);
           }
   
           if (url != null) {
  @@ -897,7 +868,8 @@
                   ZipEntry entry = zipFile.getEntry(resourceName);
                   if (entry != null) {
                       try {
  -                        return new URL("jar:file:"+file.toString()+"!/"+entry);
  +                        return new URL("jar:file:" + file.toString() 
  +                            + "!/" + entry);
                       } catch (MalformedURLException ex) {
                           return null;
                       }
  @@ -931,7 +903,8 @@
        * on the system classpath (when not in isolated mode) or this loader's 
        * classpath.
        */
  -    protected Class loadClass(String classname, boolean resolve) throws ClassNotFoundException
{
  +    protected Class loadClass(String classname, boolean resolve) 
  +         throws ClassNotFoundException {
   
           Class theClass = findLoadedClass(classname);
           if (theClass != null) {
  @@ -941,24 +914,28 @@
           if (isParentFirst(classname)) {
               try {
                   theClass = findBaseClass(classname);
  -                log("Class " + classname + " loaded from parent loader", Project.MSG_DEBUG);
  +                log("Class " + classname + " loaded from parent loader", 
  +                    Project.MSG_DEBUG);
               }
               catch (ClassNotFoundException cnfe) {
                   theClass = findClass(classname);
  -                log("Class " + classname + " loaded from ant loader", Project.MSG_DEBUG);
  +                log("Class " + classname + " loaded from ant loader", 
  +                    Project.MSG_DEBUG);
               }
           }
           else {
               try {
                   theClass = findClass(classname);
  -                log("Class " + classname + " loaded from ant loader", Project.MSG_DEBUG);
  +                log("Class " + classname + " loaded from ant loader", 
  +                    Project.MSG_DEBUG);
               }
               catch (ClassNotFoundException cnfe) {
                   if (ignoreBase) {
                       throw cnfe;
                   }
                   theClass = findBaseClass(classname);
  -                log("Class " + classname + " loaded from parent loader", Project.MSG_DEBUG);
  +                log("Class " + classname + " loaded from parent loader", 
  +                    Project.MSG_DEBUG);
               }
           }
   
  @@ -1008,12 +985,16 @@
           byte[] classData = baos.toByteArray();
   
           // Simply put:
  -        // defineClass(classname, classData, 0, classData.length, Project.class.getProtectionDomain());
  +        // defineClass(classname, classData, 0, classData.length, 
  +        //             Project.class.getProtectionDomain());
           // Made more elaborate to be 1.1-safe.
           if (defineClassProtectionDomain != null) {
               try {
  -                Object domain = getProtectionDomain.invoke(Project.class, new Object[0]);
  -                Object[] args = new Object[] {classname, classData, new Integer(0), new
Integer(classData.length), domain};
  +                Object domain 
  +                    = getProtectionDomain.invoke(Project.class, new Object[0]);
  +                Object[] args 
  +                    = new Object[] {classname, classData, new Integer(0), 
  +                                    new Integer(classData.length), domain};
                   return (Class)defineClassProtectionDomain.invoke(this, args);
               }
               catch (InvocationTargetException ite) {
  @@ -1066,9 +1047,10 @@
        * @exception ClassNotFoundException if the requested class does not exist
        * on this loader's classpath.
        */
  -    private Class findClassInComponents(String name) throws ClassNotFoundException {
  -        // we need to search the components of the path to see if we can find the
  -        // class we want.
  +    private Class findClassInComponents(String name) 
  +         throws ClassNotFoundException {
  +        // we need to search the components of the path to see if 
  +        // we can find the class we want.
           InputStream stream = null;
           String classFilename = getClassFilename(name);
           try {
  @@ -1082,7 +1064,8 @@
                   }
                   catch (IOException ioe) {
                       // ioe.printStackTrace();
  -                    log("Exception reading component " + pathComponent , Project.MSG_VERBOSE);
  +                    log("Exception reading component " + pathComponent , 
  +                        Project.MSG_VERBOSE);
                   }
               }
   
  @@ -1143,6 +1126,8 @@
   
       /**
        * Empty implementation to satisfy the BuildListener interface.
  +     *
  +     * @param event the buildStarted event
        */
       public void buildStarted(BuildEvent event) {
       }
  @@ -1150,6 +1135,8 @@
       /**
        * Cleans up any resources held by this classloader at the end
        * of a build.
  +     *
  +     * @param event the buildFinished event
        */
       public void buildFinished(BuildEvent event) {
           cleanup();
  @@ -1157,30 +1144,40 @@
   
       /**
        * Empty implementation to satisfy the BuildListener interface.
  +     *
  +     * @param event the targetStarted event
        */
       public void targetStarted(BuildEvent event) {
       }
   
       /**
        * Empty implementation to satisfy the BuildListener interface.
  +     *
  +     * @param event the targetFinished event
        */
       public void targetFinished(BuildEvent event) {
       }
   
       /**
        * Empty implementation to satisfy the BuildListener interface.
  +     *
  +     * @param event the taskStarted event
        */
       public void taskStarted(BuildEvent event) {
       }
   
       /**
        * Empty implementation to satisfy the BuildListener interface.
  +     *
  +     * @param event the taskFinished event
        */
       public void taskFinished(BuildEvent event) {
       }
   
       /**
        * Empty implementation to satisfy the BuildListener interface.
  +     *
  +     * @param event the messageLogged event
        */
       public void messageLogged(BuildEvent event) {
       }
  
  
  
  1.78      +5 -23     jakarta-ant/src/main/org/apache/tools/ant/ProjectHelper.java
  
  Index: ProjectHelper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/ProjectHelper.java,v
  retrieving revision 1.77
  retrieving revision 1.78
  diff -u -w -u -r1.77 -r1.78
  --- ProjectHelper.java	6 Mar 2002 16:36:12 -0000	1.77
  +++ ProjectHelper.java	11 Mar 2002 09:40:20 -0000	1.78
  @@ -70,6 +70,7 @@
   
   import org.xml.sax.AttributeList;
   import org.apache.tools.ant.helper.ProjectHelperImpl;
  +import org.apache.tools.ant.util.LoaderUtils;
   
   /**
    * Configures a Project (complete with Targets and Tasks) based on
  @@ -236,30 +237,11 @@
       public static ClassLoader getContextClassLoader()
           throws BuildException
       {
  -        // Are we running on a JDK 1.2 or later system?
  -        Method method = null;
  -        try {
  -            method = Thread.class.getMethod("getContextClassLoader", null);
  -        } catch (NoSuchMethodException e) {
  -            // we are running on JDK 1.1
  +        if (!LoaderUtils.isContextLoaderAvailable()) {
               return null; 
           }
   
  -        // Get the thread context class loader (if there is one)
  -        ClassLoader classLoader = null;
  -        try {
  -            classLoader = (ClassLoader)
  -                method.invoke(Thread.currentThread(), null);
  -        } catch (IllegalAccessException e) {
  -            throw new BuildException
  -                ("Unexpected IllegalAccessException", e);
  -        } catch (InvocationTargetException e) {
  -            throw new BuildException
  -                ("Unexpected InvocationTargetException", e);
  -        }
  -
  -        // Return the selected class loader
  -        return (classLoader);
  +        return LoaderUtils.getContextClassLoader();
       }
   
       // -------------------- Static utils, used by most helpers -------------------- 
  
  
  
  1.39      +10 -10    jakarta-ant/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java
  
  Index: XSLTProcess.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -w -u -r1.38 -r1.39
  --- XSLTProcess.java	5 Mar 2002 13:49:46 -0000	1.38
  +++ XSLTProcess.java	11 Mar 2002 09:40:21 -0000	1.39
  @@ -65,7 +65,7 @@
   import org.apache.tools.ant.types.Path;
   import org.apache.tools.ant.types.Reference;
   import org.apache.tools.ant.util.FileUtils;
  -import org.apache.tools.ant.types.XCatalog;
  +import org.apache.tools.ant.types.XMLCatalog;
   import org.xml.sax.EntityResolver;
   
   /**
  @@ -86,7 +86,7 @@
    * such as images, or html files in the source directory will be
    * copied into the destination directory.
    *
  - * @version $Revision: 1.38 $ 
  + * @version $Revision: 1.39 $ 
    *
    * @author <a href="mailto:kvisco@exoffice.com">Keith Visco</a>
    * @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a>
  @@ -142,7 +142,7 @@
       private String outputtype = null;
       
       /** for resolving entities such as dtds */
  -    private XCatalog xcatalog;
  +    private XMLCatalog xmlCatalog;
       
       /** Name of the TRAX Liason class */
       private static final String TRAX_LIAISON_CLASS =
  @@ -344,12 +344,12 @@
       }
       
       /**
  -     * store the xcatalog for resolving entities
  +     * store the xml catalog for resolving entities
        * 
  -     * @param xcatalog the xcatalog instance to use to look up DTDs
  +     * @param xmlCatalog the XMLCatalog instance to use to look up DTDs
        */
  -    public void addXcatalog(XCatalog xcatalog) {
  -        this.xcatalog = xcatalog;
  +    public void addXMLcatalog(XMLCatalog xmlCatalog) {
  +        this.xmlCatalog = xmlCatalog;
       }
       
       /**
  @@ -660,16 +660,16 @@
                   Param p = (Param)e.nextElement();
                   liaison.addParam( p.getName(), p.getExpression() );
               }
  -            // if liaison is a TraxLiason, use XCatalog as the entity
  +            // if liaison is a TraxLiason, use XMLCatalog as the entity
               // resolver
               if (liaison.getClass().getName().equals(TRAX_LIAISON_CLASS) &&
  -                xcatalog != null) {
  +                xmlCatalog != null) {
                   log("Configuring TraxLiaison and calling entity resolver",
                       Project.MSG_DEBUG);
                   Method resolver = liaison.getClass()
                                       .getDeclaredMethod("setEntityResolver", 
                                           new Class[] {EntityResolver.class});
  -                resolver.invoke(liaison, new Object[] {xcatalog});
  +                resolver.invoke(liaison, new Object[] {xmlCatalog});
               }
           } catch (Exception ex) {
               log("Failed to read stylesheet " + stylesheet, Project.MSG_INFO);
  
  
  
  1.10      +1 -1      jakarta-ant/src/main/org/apache/tools/ant/types/defaults.properties
  
  Index: defaults.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/types/defaults.properties,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -w -u -r1.9 -r1.10
  --- defaults.properties	5 Mar 2002 13:49:47 -0000	1.9
  +++ defaults.properties	11 Mar 2002 09:40:21 -0000	1.10
  @@ -8,5 +8,5 @@
   classfileset=org.apache.tools.ant.types.optional.depend.ClassfileSet
   substitution=org.apache.tools.ant.types.Substitution
   regexp=org.apache.tools.ant.types.RegularExpression
  -xcatalog=org.apache.tools.ant.types.XCatalog
  +xmlcatalog=org.apache.tools.ant.types.XMLCatalog
   
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/types/XMLCatalog.java
  
  Index: XMLCatalog.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.tools.ant.types;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.InputStream;
  import java.io.IOException;
  import java.net.URL;
  import java.util.Iterator;
  import java.util.Vector;
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.Project;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  import org.apache.tools.ant.util.LoaderUtils;
  import org.apache.tools.ant.util.FileUtils;
  
  /**
   * This data type provides a catalog of DTD locations
   * <p>
   * <code>
   * &lt;catalog&gt;<br>
   * &nbsp;&nbsp;&lt;dtd publicId="" location="/path/to/file.jar" /&gt;<br>
   * &nbsp;&nbsp;&lt;dtd publicId location="/path/to/file2.jar" /gt;<br>
   * &nbsp;&nbsp;&lt;entity publicId="" location="/path/to/file3.jar" /&gt;<br>
   * &nbsp;&nbsp;&lt;entity publicId="" location="/path/to/file4.jar" /&gt;<br>
   * &lt;/catalog&gt;<br>
   * </code>
   * <p>
   * The object implemention <code>sometask</code> must provide a method called
   * <code>createCatalog</code> which returns an instance of <code>XCatalog</code>.
   * Nested dtd and entity definitions are handled by the XCatalog object and
   * must be labeled <code>dtd</code> and <code>entity</code> respectively.</p>
   *
   * <p>Possible future extension could allow a catalog file instead of nested
   * elements, or use Norman Walsh's entity resolver from xml-commons</p>
   *
   * @author  dIon Gillard
   * @version $Id: XMLCatalog.java,v 1.1 2002/03/11 09:40:21 conor Exp $
   */
  public class XMLCatalog extends DataType implements Cloneable, EntityResolver {
      
      private FileUtils fileUtils = FileUtils.newFileUtils();
      
      //-- Fields ----------------------------------------------------------------
      
      /** holds dtd/entity objects until needed */
      private Vector elements = new Vector();
      
      //-- Methods ---------------------------------------------------------------
      
      /**
       * @return the elements of the catalog - DTDLocation objects
       */
      private Vector getElements() {
          return elements;
      }
      
      /**
       * Set the list of DTDLocation object sin the catalog
       *
       * @param aVector the new list of DTD Locations to use in the catalog.
       */
      private void setElements(Vector aVector) {
          elements = aVector;
      }
      
      /**
       * Add a DTD Location to the catalog
       *
       * @param aDTD the DTDLocation instance to be aded to the catalog
       */
      private void addElement(DTDLocation aDTD) {
          getElements().add(aDTD);
      }
      
      /**
       * Creates the nested <code>&lt;dtd&gt;</code> element.
       *
       * @param dtd the infromation about the DTD to be added to the catalog
       * @exception BuildException if this is a reference and no nested 
       *       elements are allowed.
       */
      public void addDTD(DTDLocation dtd) throws BuildException {
          if (isReference()) {
              throw noChildrenAllowed();
          }
          getElements().add(dtd);
      }
      
      /**
       * Creates the nested <code>&lt;entity&gt;</code> element
       *
       * @param dtd the infromation about the DTD to be added to the catalog
       * @exception BuildException if this is a reference and no nested 
       *       elements are allowed.
       */
      public void addEntity(DTDLocation dtd) throws BuildException {
          addDTD(dtd);
      }
  
      /**
       * Makes this instance in effect a reference to another XCatalog instance.
       *
       * <p>You must not set another attribute or nest elements inside
       * this element if you make it a reference.</p>
       *
       * @param r the reference to which this catalogi instance is associated
       * @exception BuildException if this instance already has been configured.
       */
      public void setRefid(Reference r) throws BuildException {
          if (!elements.isEmpty()) {
              throw tooManyAttributes();
          }
          // change this to get the objects from the other reference
          Object o = r.getReferencedObject(getProject());
          // we only support references to other XCatalogs
          if (o instanceof XMLCatalog) {
              // set all elements from referenced catalog to this one
              XMLCatalog catalog = (XMLCatalog) o;
              setElements(catalog.getElements());
          } else {
              String msg = r.getRefId() + " doesn\'t refer to an XCatalog";
              throw new BuildException(msg);
          }
  
          super.setRefid(r);
      }
  
      /**
       * @see org.xml.sax.EntityResolver#resolveEntity
       */
      public InputSource resolveEntity(String publicId, String systemId)
          throws SAXException, IOException {
          InputSource source = null;
          DTDLocation matchingDTD = findMatchingDTD(publicId);
          if (matchingDTD != null) {
              // check if publicId is mapped to a file
              log("Matching DTD found for publicId: '" + publicId +
                  "' location: '" + matchingDTD.getLocation() + "'",
                  Project.MSG_DEBUG);
              File dtdFile = new File(matchingDTD.getLocation());
              if (dtdFile.exists() && dtdFile.canRead()) {
                  source = new InputSource(new FileInputStream(dtdFile));
                  URL dtdFileURL = fileUtils.getFileURL(dtdFile);
                  source.setSystemId(dtdFileURL.toExternalForm());
                  log("matched a readable file", Project.MSG_DEBUG);
              } else {
                  // check if publicId is a resource
                  // FIXME: ClassLoader: should this be context?
                  ClassLoader loader = LoaderUtils.getContextClassLoader();
                  if (loader == null) {
                      loader = getClass().getClassLoader();
                  }
                  
                  InputStream is 
                      = loader.getResourceAsStream(matchingDTD.getLocation());
                  if (is != null) {
                      source = new InputSource(is);
                      source.setSystemId(loader.getResource(
                          matchingDTD.getLocation()).toExternalForm());
                      log("matched a resource", Project.MSG_DEBUG);
                  } else {
                      // check if it's a URL
                      try {
                          URL dtdUrl = new URL(matchingDTD.getLocation());
                          InputStream dtdIs = dtdUrl.openStream();
                          if (dtdIs != null) {
                              source = new InputSource(dtdIs);
                              source.setSystemId(dtdUrl.toExternalForm());
                              log("matched as a URL", Project.MSG_DEBUG);
                          } else {
                              log("No match, parser will use: '" + systemId + "'",
                                  Project.MSG_DEBUG);
                          }
                      } catch ( IOException ioe) {
                          //ignore
                      }
                  }
              }
          } else {
              log("No match, parser will use: '" + systemId + "'",
                  Project.MSG_DEBUG);
          }
          // else let the parser handle it as a URI as we don't know what to
          // do with it
          return source;
      }
      
      /**
       * Find a DTDLocation instance for the given publicId.
       *
       * @param publicId the publicId of the DTD for which local information is 
       *        required
       * @return a DTDLocation instance with information on the local location 
       *         of the DTD or null if no such information is available
       */
      private DTDLocation findMatchingDTD(String publicId) {
          Iterator elements = getElements().iterator();
          DTDLocation element = null;
          while (elements.hasNext()) {
              element = (DTDLocation)elements.next();
              if (element.getPublicId().equals(publicId)) {
                  return element;
              }
          }
          return null;
      }
        
  }
  
  
  
  
  1.18      +22 -1     jakarta-ant/src/main/org/apache/tools/ant/util/FileUtils.java
  
  Index: FileUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/util/FileUtils.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -w -u -r1.17 -r1.18
  --- FileUtils.java	8 Mar 2002 08:20:15 -0000	1.17
  +++ FileUtils.java	11 Mar 2002 09:40:21 -0000	1.18
  @@ -74,6 +74,8 @@
   import java.util.Stack;
   import java.util.StringTokenizer;
   import java.util.Vector;
  +import java.net.URL;
  +import java.net.MalformedURLException;
   
   import org.apache.tools.ant.BuildException;
   import org.apache.tools.ant.Project;
  @@ -93,7 +95,7 @@
    * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
    * @author <a href="mailto:jtulley@novell.com">Jeff Tulley</a> 
    *
  - * @version $Revision: 1.17 $
  + * @version $Revision: 1.18 $
    */
   
   public class FileUtils {
  @@ -115,6 +117,25 @@
        */
       protected FileUtils() {}
   
  +    /**
  +     * Get the URL for a file taking into account # characters
  +     *
  +     * @param file the file whose URL representation is required.
  +     * @return The FileURL value
  +     * @throws MalformedURLException if the URL representation cannot be
  +     *      formed.
  +     */
  +    public URL getFileURL(File file) throws MalformedURLException {
  +        String uri = "file:" + file.getAbsolutePath().replace('\\', '/');
  +        for (int i = uri.indexOf('#'); i != -1; i = uri.indexOf('#')) {
  +            uri = uri.substring(0, i) + "%23" + uri.substring(i + 1);
  +        }
  +        if (file.isDirectory()) {
  +            uri += "/";
  +        }
  +        return new URL(uri);
  +    }
  +    
       /**
        * Convienence method to copy a file from a source to a destination.
        * No filtering is performed.
  
  
  
  1.1                  jakarta-ant/src/main/org/apache/tools/ant/util/LoaderUtils.java
  
  Index: LoaderUtils.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.tools.ant.util;
  
  import java.lang.reflect.InvocationTargetException;
  
  import java.lang.reflect.Method;
  import org.apache.tools.ant.BuildException;
  
  /**
   * ClassLoader utility methods
   *
   * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
   * @created 11 March 2002
   */
  public class LoaderUtils {
      /** The getContextClassLoader method */
      private static Method getContextClassLoader;
      /** The setContextClassLoader method */
      private static Method setContextClassLoader;
  
      // Set up the reflection-based Java2 methods if possible
      static {
          try {
              getContextClassLoader
                   = Thread.class.getMethod("getContextClassLoader",
                  new Class[0]);
              Class[] setContextArgs = new Class[]{ClassLoader.class};
              setContextClassLoader
                   = Thread.class.getMethod("setContextClassLoader",
                  setContextArgs);
          } catch (Exception e) {
              // ignore any problems accessing the methods - probably JDK 1.1
          }
      }
  
      /**
       * JDK1.1 compatible access to get the context class loader. Has no
       * effect on JDK 1.1
       *
       * @param loader the ClassLoader to be used as the context class loader
       *      on the current thread.
       */
      public static void setContextClassLoader(ClassLoader loader) {
          if (setContextClassLoader == null) {
              return;
          }
  
          try {
              Thread currentThread = Thread.currentThread();
              setContextClassLoader.invoke(currentThread,
                  new Object[]{loader});
          } catch (IllegalAccessException e) {
              throw new BuildException
                  ("Unexpected IllegalAccessException", e);
          } catch (InvocationTargetException e) {
              throw new BuildException
                  ("Unexpected InvocationTargetException", e);
          }
  
      }
  
  
      /**
       * JDK1.1 compatible access to set the context class loader.
       *
       * @return the ClassLoader instance being used as the context
       *      classloader on the current thread. Returns null on JDK 1.1
       */
      public static ClassLoader getContextClassLoader() {
          if (getContextClassLoader == null) {
              return null;
          }
  
          try {
              Thread currentThread = Thread.currentThread();
              return (ClassLoader)getContextClassLoader.invoke(currentThread,
                  new Object[0]);
          } catch (IllegalAccessException e) {
              throw new BuildException
                  ("Unexpected IllegalAccessException", e);
          } catch (InvocationTargetException e) {
              throw new BuildException
                  ("Unexpected InvocationTargetException", e);
          }
      }
  
      /**
       * Indicates if the context class loader methods are available
       *
       * @return true if the get and set methods dealing with the context
       *      classloader are available.
       */
      public static boolean isContextLoaderAvailable() {
          return getContextClassLoader != null &&
              setContextClassLoader != null;
      }
  }
  
  
  
  

--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message