You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ad...@apache.org on 2002/08/21 15:10:58 UTC

cvs commit: jakarta-commons-sandbox/vfs/src/test-data/code ClassToLoad.java

adammurdoch    2002/08/21 06:10:58

  Modified:    vfs      maven.xml
               vfs/src/java/org/apache/commons/vfs FileContent.java
                        FileObject.java package.html
               vfs/src/java/org/apache/commons/vfs/impl
                        Resources.properties
               vfs/src/java/org/apache/commons/vfs/provider
                        AbstractFileObject.java AbstractFileSystem.java
                        DefaultFileContent.java FileSystem.java
                        Resources.properties
               vfs/src/java/org/apache/commons/vfs/provider/ftp
                        FtpFileSystem.java
               vfs/src/java/org/apache/commons/vfs/provider/local
                        LocalFileSystem.java
               vfs/src/java/org/apache/commons/vfs/provider/smb
                        SmbFileSystem.java
               vfs/src/java/org/apache/commons/vfs/provider/url
                        UrlFileSystem.java
               vfs/src/java/org/apache/commons/vfs/provider/zip
                        ParsedZipUri.java ZipFileSystem.java
                        ZipFileSystemProvider.java
               vfs/src/test/org/apache/commons/vfs/test
                        AbstractFileSystemTestCase.java
               vfs/src/test-data test.policy
  Added:       vfs/src/java/org/apache/commons/vfs/impl Resource.java
                        VFSClassLoader.java
               vfs/src/test-data/code ClassToLoad.java
  Log:
  - Added VFSClassLoader, and test cases.
  
  - API Changes:
      - FileObject.getContent() can now be called for folders.
      - Added FileObject.getParentLayer()
      - Added FileContent.getCertificates()
  
  - Implemented FileContent.getLastModifiedTime(), setLastModifiedTime(),
    getAttribute(), and setAttribute().
  
  Patch submitted by Brian Olsen.
  
  Revision  Changes    Path
  1.4       +13 -0     jakarta-commons-sandbox/vfs/maven.xml
  
  Index: maven.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/maven.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- maven.xml	21 Aug 2002 01:46:38 -0000	1.3
  +++ maven.xml	21 Aug 2002 13:10:56 -0000	1.4
  @@ -10,6 +10,19 @@
           <exclude name="*.policy"/>
         </fileset>
       </copy>
  +    
  +    <!-- Compile the code for the class loader test -->
  +    <javac
  +      destdir="${test.data}/basedir"
  +      debug="${maven.compile.debug}"
  +      deprecation="${maven.compile.deprecation}"
  +      optimize="${maven.compile.optimize}">
  +      <src>
  +        <path>
  +          <pathelement location="${test.data.src}"/>
  +        </path>
  +      </src>
  +    </javac>
   
       <mkdir dir="${test.data}/basedir/emptydir"/>
   
  
  
  
  1.3       +11 -0     jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileContent.java
  
  Index: FileContent.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileContent.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FileContent.java	21 Aug 2002 07:00:10 -0000	1.2
  +++ FileContent.java	21 Aug 2002 13:10:56 -0000	1.3
  @@ -9,6 +9,7 @@
   
   import java.io.InputStream;
   import java.io.OutputStream;
  +import java.security.cert.Certificate;
   
   /**
    * This interface is used to access the data content of a file.
  @@ -108,6 +109,16 @@
        */
       void setAttribute( String attrName, Object value )
           throws FileSystemException;
  +
  +    /**
  +     * Retrives the certificates if any used to sign this file or folder.
  +     * This will return null if there is no certificates or the file system
  +     * does not support signing.
  +     *
  +     * @throws FileSystemException
  +     *      If the file does not exist, or is being written.
  +     */
  +    Certificate[] getCertificates() throws FileSystemException;
   
       /**
        * Returns an input stream for reading the file's content.
  
  
  
  1.3       +13 -6     jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileObject.java
  
  Index: FileObject.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileObject.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FileObject.java	21 Aug 2002 07:00:10 -0000	1.2
  +++ FileObject.java	21 Aug 2002 13:10:56 -0000	1.3
  @@ -95,6 +95,19 @@
        *      If the file does not exist, or on error determining the file's type.
        */
       FileType getType() throws FileSystemException;
  +    
  +    /**
  +     * Returns the parent layer if this file resides in a layered file
  +     * system.
  +     *
  +     * @return
  +     *      The file object that this file is layered on top. Returns null
  +     *      if this file is not from a layered file system.
  +     *
  +     * @throws FileSystemException
  +     *      In case of errors finding the parent layer.
  +     */
  +    FileObject getParentLayer() throws FileSystemException;
   
       /**
        * Returns the folder that contains this file.
  @@ -241,12 +254,6 @@
        * <p>This method can be called if the file does not exist, and
        * the returned {@link FileContent} can be used to create the file
        * by writing its content.
  -     *
  -     * @todo Do not throw an exception if this file is a folder.  Instead,
  -     *       throw the exceptions when (if) any methods on the returned object
  -     *       are called.  This is to hand 2 cases: when the folder is deleted
  -     *       and recreated as a file, and to allow attributes of the folder
  -     *       to be set (last modified time, permissions, etc).
        *
        * @return
        *      This file's content.
  
  
  
  1.2       +4 -4      jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/package.html
  
  Index: package.html
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/package.html,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- package.html	16 Jul 2002 17:18:58 -0000	1.1
  +++ package.html	21 Aug 2002 13:10:56 -0000	1.2
  @@ -1,10 +1,10 @@
   <body>
   <p>This package contains the interfaces used to access the VFS.</p>
   
  -<p>A {@link vfs.filesystem.FileSystemManager} is the starting point for
  -all file system access.  It is used to locate a {@link vfs.filesystem.FileObject}
  -by name.  Files are accessed using the {@link vfs.filesystem.FileObject}
  +<p>A {@link FileSystemManager} is the starting point for
  +all file system access.  It is used to locate a {@link FileObject}
  +by name.  Files are accessed using the {@link FileObject}
   interface.  This interface allows a file's structure and content to be
   accessed.</p>
   
  -</body>
  \ No newline at end of file
  +</body>
  
  
  
  1.3       +5 -1      jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/impl/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/impl/Resources.properties,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Resources.properties	21 Aug 2002 06:21:25 -0000	1.2
  +++ Resources.properties	21 Aug 2002 13:10:57 -0000	1.3
  @@ -6,4 +6,8 @@
   no-local-file-provider.error=Could not find a file system provider which can handle local files.
   no-replicator.error=No file replicator configured.
   replicate-file.error=Could not replicate "{0}".
  -delete-temp.warn=Could not clean up temporary file "{0}".
  \ No newline at end of file
  +delete-temp.warn=Could not clean up temporary file "{0}".
  +#VFSClassLoader
  +class-not-found.error=Class "{0}" was not found.
  +pkg-sealing-unsealed=Trying to seal package "{0}" that exists as unsealed.
  +pkg-sealed-other-url=Package "{0}" exists and is sealed with other URL.
  
  
  
  1.1                  jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/impl/Resource.java
  
  Index: Resource.java
  ===================================================================
  package org.apache.commons.vfs.impl;
  
  import java.net.MalformedURLException;
  import java.net.ProtocolException;
  import java.net.URL;
  import java.io.IOException;
  import java.io.InputStream;
  import org.apache.commons.vfs.FileObject;
  import org.apache.commons.vfs.FileContent;
  import org.apache.commons.vfs.FileSystemException;
  
  /**
   * Helper class for VFSClassLoader. This represents a resource loaded with
   * the classloader.
   *
   * @see VFSClassLoader
   *
   * @author <a href="mailto:brian@mmmanager.org">Brian Olsen</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/21 13:10:57 $
   */
  class Resource
  {
      private FileObject root;
      private FileObject resource;
  
      /**
       * Creates a new instance.
       *
       * @param root The code source FileObject.
       * @param resource The resource of the FileObject.
       */
      Resource( FileObject root, FileObject resource )
      {
          this.root = root;
          this.resource = resource;
      }
      
      /**
       * Returns the URL of the resource.
       */
      URL getURL() throws MalformedURLException
      {
          return resource.getURL();
      }
  
      /**
       * Returns the FileObject of the resource.
       */
      FileObject getFileObject()
      {
          return resource;
      }
  
      /**
       * Returns the code source as an URL.
       */
      URL getCodeSourceURL() throws MalformedURLException
      {
          return root.getURL();
      }
  
      /**
       * Returns the data for this resource as a byte array.
       */
      byte[] getBytes() throws IOException
      {
          try
          {
              FileContent content = resource.getContent();
              final int size = (int) content.getSize();
              byte[] buf = new byte[ size ];
          
              InputStream in = content.getInputStream();
              int read = in.read( buf );
  
              while ( read < size )
              {
                  read += in.read( buf, read, size - read );
              }
  
              return buf;
          }
          catch ( FileSystemException fse )
          {
              throw new ProtocolException( fse.getMessage() );
          }
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/impl/VFSClassLoader.java
  
  Index: VFSClassLoader.java
  ===================================================================
  package org.apache.commons.vfs.impl;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.Enumeration;
  import java.security.SecureClassLoader;
  import java.security.cert.Certificate;
  import java.security.CodeSource;
  import java.security.PermissionCollection;
  import java.security.Permissions;
  import java.security.Permission;
  import java.util.jar.Attributes.Name;
  import java.net.URL;
  import java.net.MalformedURLException;
  import java.io.IOException;
  import org.apache.commons.vfs.FileSystemManager;
  import org.apache.commons.vfs.FileObject;
  import org.apache.commons.vfs.FileContent;
  import org.apache.commons.vfs.FileSystemException;
  import org.apache.commons.vfs.FileType;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  
  
  /**
   *
   * A class loader that can load classes and resources from a search path
   * VFS FileObjects refering both to folders and JAR files. Any FileObject
   * of type {@link FileType#FILE} is asumed to be a JAR and is opened
   * by creating a layered file system with the "jar" scheme.
   * </p><p>
   * TODO - Test this with signed Jars and a SecurityManager.
   *
   * @see FileSystemManager#createFileSystem
   * @author <a href="mailto:brian@mmmanager.org">Brian Olsen</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/21 13:10:57 $
   */
  public class VFSClassLoader
      extends SecureClassLoader
  {
      private static final Resources REZ
          = ResourceManager.getPackageResources( VFSClassLoader.class );
  
      private ArrayList resources;
      private FileSystemManager manager;
     
      /**
       * Constructors a new VFSClassLoader for the given FileObjects.
       * The FileObjects will be searched in the order specified.
       *
       * @param files the FileObjects to load the classes and resources from.
       *
       * @param manager
       *      the FileManager to use when trying create a layered Jar file
       *      system.
       */
      public VFSClassLoader( FileObject[] files,
                             FileSystemManager manager )
      {
          super();
  
          this.manager = manager;
          resources = new ArrayList( files.length );
          for ( int i = 0; i < files.length; i++ )
          {
              addFileObject( files[i] );
          }
      }
  
      /**
       * Constructors a new VFSClassLoader for the given FileObjects.
       * The FileObjects will be searched in the order specified.
       *
       * @param files the FileObjects to load the classes and resources from.
       *
       * @param manager
       *      the FileManager to use when trying create a layered Jar file
       *      system.
       *
       * @param parent the parent class loader for delegation.
       */
      public VFSClassLoader( FileObject[] files,
                             FileSystemManager manager,
                             ClassLoader parent )
      {
          super( parent );
  
          this.manager = manager;
          resources = new ArrayList( files.length );
          for ( int i = 0; i < files.length; i++ )
          {
              addFileObject( files[i] );
          }
      }
      
      /**
       * Appends the specified FileObject to the list of FileObjects to search
       * for classes and resources.
       *
       * @param file the FileObject to append to the search path.
       */
      protected void addFileObject( FileObject file )
      {
          resources.add( file );
      }
      
      /**
       * Finds and loads the class with the specified name from the search
       * path.
       * @throws ClassNotFoundException if the class is not found.
       */
      protected Class findClass( String name ) throws ClassNotFoundException
      {
          try
          {
              String path = name.replace( '.', '/' ).concat( ".class" );
              Resource res = loadResource( path );
              if ( res == null )
              {
                  final String message =
                      REZ.getString( "class-not-found.error", name );
                  throw new ClassNotFoundException( message );
              }
              return defineClass( name, res );
          }
          catch ( FileSystemException fse )
          {
              throw new ClassNotFoundException( name, fse );
          }
          catch ( IOException ioe )
          {
              throw new ClassNotFoundException( name, ioe );
          }
      }
  
      /**
       * Loads and verifies the class with name and located with res.
       */
      private Class defineClass( String name, Resource res )
          throws IOException, FileSystemException
      {
          URL url = res.getCodeSourceURL();
  
          int i = name.lastIndexOf( "." );
          if ( i != -1 )
          {
              String pkgName = name.substring( 0, i );
              Package pkg = getPackage( pkgName );
              if ( pkg != null )
              {
                  if ( pkg.isSealed() )
                  {
                      if ( !pkg.isSealed( url ) )
                      {
                          final String message = REZ.getString(
                              "pkg-sealed-other-url", pkgName );
                          throw new SecurityException( message );
                      }
                  }
                  else
                  {
                      if ( isSealed( res ) )
                      {
                          final String message = REZ.getString(
                              "pkg-sealing-unsealed", pkgName );
                          throw new SecurityException( message );
                      }
                  }
              }
              else
              {
                  definePackage( pkgName, res, url );
              }
          }
  
          byte[] bytes = res.getBytes();
          Certificate[] certs =
              res.getFileObject().getContent().getCertificates();
          CodeSource cs = new CodeSource( url, certs );
          return defineClass( name, bytes, 0, bytes.length, cs );
      }
  
      /**
       * Reads attributes for the package and defines it.
       */
      private Package definePackage( String name, Resource res, URL url )
          throws IOException, FileSystemException
      {
          URL sealBase = null;
          final FileContent content =
              res.getFileObject().getParent().getContent();
          String specTitle = (String) content.getAttribute(
              Name.SPECIFICATION_TITLE.toString() );
  
          String specVersion = (String) content.getAttribute(
              Name.SPECIFICATION_VERSION.toString() );
          String specVendor = (String) content.getAttribute(
              Name.SPECIFICATION_VENDOR.toString() );
          String implTitle = (String) content.getAttribute(
              Name.IMPLEMENTATION_TITLE.toString() );
          String implVersion = (String) content.getAttribute(
              Name.IMPLEMENTATION_VERSION.toString() );
          String implVendor = (String) content.getAttribute(
              Name.IMPLEMENTATION_VENDOR.toString() );
          String seal = (String) content.getAttribute( Name.SEALED.toString() );
  
          if( "true".equalsIgnoreCase( seal ) )
          {
              sealBase = url;
          }
          return definePackage( name, specTitle, specVersion, specVendor,
                                implTitle, implVersion, implVendor, sealBase );
      }
  
      /**
       * Returns true if the we should seal the package where res resides.
       */
      private boolean isSealed( Resource res )
          throws IOException, FileSystemException
      {
          final FileContent content =
              res.getFileObject().getParent().getContent();
          String sealed = (String) content.getAttribute( Name.SEALED.toString() );
          
          return "true".equalsIgnoreCase( sealed );
      }
  
  
      /**
       * Calls super.getPermissions both for the code source and also
       * adds the permissions granted to the parent layers.
       */
      protected PermissionCollection getPermissions( CodeSource cs )
      {
          try
          {
              String url = cs.getLocation().toString();
              FileObject file = lookupFileObject( url );
              if ( file == null )
              {
                  return super.getPermissions( cs );
              }
  
              FileObject parentLayer = file.getParentLayer();
              if ( parentLayer == null )
              {
                  return super.getPermissions( cs );
              }
          
              Permissions combi = new Permissions();
              PermissionCollection permCollect = super.getPermissions( cs );
              copyPermissions( permCollect, combi );
  
              for ( FileObject parent = parentLayer;
                    parent != null;
                    parent = parent.getParentLayer() )
              {
                  cs = new CodeSource( parent.getURL(),
                                       parent.getContent().getCertificates() );
                  permCollect = super.getPermissions( cs );
                  copyPermissions( permCollect, combi );
              }
  
              return combi;
          }
          catch ( FileSystemException fse )
          {
              throw new SecurityException( fse.getMessage() );
          }
          catch ( MalformedURLException mue )
          {
              throw new SecurityException( mue.getMessage() );
          }
      }
  
      /**
       * Copies the permissions from src to dest.
       */
      protected void copyPermissions( PermissionCollection src,
                                      PermissionCollection dest )
      {
          for ( Enumeration elem = src.elements(); elem.hasMoreElements(); )
          {
              final Permission permission = (Permission) elem.nextElement();
              dest.add( permission );
          }
      }
  
      /**
       * Does a reverse lookup to find the FileObject when we only have the
       * URL.
       */
      private FileObject lookupFileObject( String name )
      {
          Iterator it = resources.iterator();
          while ( it.hasNext() )
          {
              final FileObject object = (FileObject) it.next();
              if ( name.equals( object.getName().getURI() ) )
              {
                  return object;
              }
          }
          return null;
      }
         
      /**
       * Finds the resource with the specified name from the search path.
       * This returns null if the resource is not found.
       */
      protected URL findResource( String name )
      {
          try
          {
              Resource res = loadResource( name );
              return res != null ? res.getURL() : null;
          }
          catch ( MalformedURLException mue )
          {
              return null;
          }
      }
  
      /**
       * Returns an Enumeration of all the resources in the search path
       * with the specified name.
       * TODO - Implement this.
       */
      protected Enumeration findResources( String name )
      {
          return null;
      }
  
      /**
       * Searches through the search path of for the first class or resource
       * with specified name.
       */
      private Resource loadResource( String name )
      {
          Iterator it = resources.iterator();
          while ( it.hasNext() )
          {
              try
              {
                  Resource res = null;
                  final FileObject object = (FileObject)it.next();
                  if ( object.getType() == FileType.FILE )
                  {
                      res = loadJarResource( object, name );
                  }
                  else if ( object.getType() == FileType.FOLDER )
                  {
                      res = loadFolderResource( object, name );
                  }
                  if ( res != null )
                  {
                      return res;
                  }
              }
              catch ( FileSystemException fse )
              {
              }
          }
          return null;
      }
  
      Resource loadJarResource( FileObject jarFile, String name )
          throws FileSystemException
      {
          FileObject base = manager.createFileSystem( "jar", jarFile );
          FileObject file = base.resolveFile( name );
          if ( file.exists() )
          {
              return new Resource( jarFile, file );
          }
          return null;
      }
  
      Resource loadFolderResource( FileObject base, String name )
          throws FileSystemException
      {
          FileObject file = base.resolveFile( name );
          if ( file.exists() )
          {
              return new Resource( base, file );
          }
          return null;
      }
  }
  
  
  
  1.5       +73 -5     jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/AbstractFileObject.java
  
  Index: AbstractFileObject.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/AbstractFileObject.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- AbstractFileObject.java	21 Aug 2002 07:00:11 -0000	1.4
  +++ AbstractFileObject.java	21 Aug 2002 13:10:57 -0000	1.5
  @@ -12,6 +12,7 @@
   import java.io.OutputStream;
   import java.net.MalformedURLException;
   import java.net.URL;
  +import java.security.cert.Certificate;
   import java.security.AccessController;
   import java.security.PrivilegedActionException;
   import java.security.PrivilegedExceptionAction;
  @@ -150,6 +151,62 @@
       }
   
       /**
  +     * Called from {@link DefaultFileContent#getLastModifiedTime}.
  +     * The default is to just throw an exception so filesystems must
  +     * override it to use it.
  +     */
  +    protected long doGetLastModifiedTime() throws FileSystemException
  +    {
  +        final String message = REZ.getString( "get-last-modified-not-supported.error" );
  +        throw new FileSystemException( message ); 
  +    }
  +
  +    /**
  +     * Called from {@link DefaultFileContent#setLastModifiedTime}.
  +     * The default is to just throw an exception so filesystems must
  +     * override it to use it.
  +     */
  +    protected void doSetLastModifiedTime( long modtime )
  +        throws FileSystemException
  +    {
  +        final String message = REZ.getString( "set-last-modified-not-supported.error" );
  +        throw new FileSystemException( message ); 
  +    }
  +
  +    /**
  +     * Called from {@link DefaultFileContent#getAttribute}.
  +     * The default implementation just returns null so filesystems must
  +     * override it to use it.
  +     */
  +    protected Object doGetAttribute( String atttrName )
  +        throws FileSystemException
  +    {
  +        return null;
  +    }
  +
  +    /**
  +     * Called from {@link DefaultFileContent#setAttribute}.
  +     * The default is to just throw an exception so filesystems must
  +     * override it to use it.
  +     */
  +    protected void doSetAttribute( String atttrName, Object value )
  +        throws FileSystemException
  +    {
  +        final String message = REZ.getString( "set-attribute-not-supported.error" );
  +        throw new FileSystemException( message ); 
  +    }
  +
  +    /**
  +     * Called from {@link DefaultFileContent#getCertificates}.
  +     * The default implementation just returns null so filesystems must
  +     * override it to use it.
  +     */
  +    protected Certificate[] doGetCertificates() throws FileSystemException
  +    {
  +        return null;
  +    }
  +
  +    /**
        * Returns the size of the file content (in bytes).  Is only called if
        * {@link #doGetType} returns {@link FileType#FILE}.
        */
  @@ -286,6 +343,14 @@
       }
   
       /**
  +     * Returns the parent layer of the file system containing the file.
  +     */
  +    public FileObject getParentLayer() throws FileSystemException
  +    {
  +        return fs.getParentLayer();
  +    }
  +
  +    /**
        * Returns the root of the file system containing the file.
        */
       public FileObject getRoot() throws FileSystemException
  @@ -607,16 +672,19 @@
       }
   
       /**
  +     * Returns true if this is a Folder.
  +     */
  +    boolean isFolder()
  +    {
  +        return type == FileType.FOLDER;
  +    }
  +
  +    /**
        * Returns the file's content.
        */
       public FileContent getContent() throws FileSystemException
       {
           attach();
  -        if ( type == FileType.FOLDER )
  -        {
  -            final String message = REZ.getString( "get-folder-content.error", name );
  -            throw new FileSystemException( message );
  -        }
           if ( content == null )
           {
               content = new DefaultFileContent( this );
  
  
  
  1.4       +39 -1     jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/AbstractFileSystem.java
  
  Index: AbstractFileSystem.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/AbstractFileSystem.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- AbstractFileSystem.java	21 Aug 2002 07:00:11 -0000	1.3
  +++ AbstractFileSystem.java	21 Aug 2002 13:10:57 -0000	1.4
  @@ -9,6 +9,8 @@
   
   import java.util.HashMap;
   import java.util.Map;
  +import org.apache.avalon.excalibur.i18n.ResourceManager;
  +import org.apache.avalon.excalibur.i18n.Resources;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   import org.apache.commons.vfs.FileName;
  @@ -24,6 +26,10 @@
   public abstract class AbstractFileSystem
       implements FileSystem
   {
  +    private static final Resources REZ =
  +        ResourceManager.getPackageResources( AbstractFileSystem.class );
  +        
  +    private FileObject parentLayer;
       private FileObject root;
       private final FileName rootName;
       private final FileSystemProviderContext context;
  @@ -32,8 +38,10 @@
       private final Map files = new HashMap();
   
       protected AbstractFileSystem( final FileSystemProviderContext context,
  -                                  final FileName rootName )
  +                                  final FileName rootName,
  +                                  final FileObject parentLayer )
       {
  +        this.parentLayer = parentLayer;
           this.rootName = rootName;
           this.context = context;
       }
  @@ -44,6 +52,7 @@
           files.clear();
       }
   
  +
       /**
        * Creates a file object.  This method is called only if the requested
        * file is not cached.
  @@ -72,6 +81,35 @@
       public FileSystemProviderContext getContext()
       {
           return context;
  +    }
  +    
  +    /**
  +     * Retrives the attribute with the specified name. The default
  +     * implementation simply throws an exception.
  +     */
  +    public Object getAttribute( String attrName ) throws FileSystemException
  +    {
  +        final String message = REZ.getString( "get-attribute-not-supported.error" );
  +        throw new FileSystemException( message ); 
  +    }
  +
  +    /**
  +     * Sets the attribute with the specified name. The default
  +     * implementation simply throws an exception.
  +     */
  +    public void setAttribute( String attrName, Object value )
  +        throws FileSystemException
  +    {
  +        final String message = REZ.getString( "set-attribute-not-supported.error" );
  +        throw new FileSystemException( message ); 
  +    }
  +
  +    /**
  +     * Returns the parent layer if this is a layered file system.
  +     */
  +    public FileObject getParentLayer() throws FileSystemException
  +    {
  +        return parentLayer;
       }
   
       /**
  
  
  
  1.3       +44 -8     jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/DefaultFileContent.java
  
  Index: DefaultFileContent.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/DefaultFileContent.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DefaultFileContent.java	21 Aug 2002 07:00:11 -0000	1.2
  +++ DefaultFileContent.java	21 Aug 2002 13:10:57 -0000	1.3
  @@ -12,6 +12,7 @@
   import java.io.IOException;
   import java.io.InputStream;
   import java.io.OutputStream;
  +import java.security.cert.Certificate;
   import org.apache.avalon.excalibur.i18n.ResourceManager;
   import org.apache.avalon.excalibur.i18n.Resources;
   import org.apache.commons.vfs.FileContent;
  @@ -57,6 +58,12 @@
        */
       public long getSize() throws FileSystemException
       {
  +        if( file.isFolder() )
  +        {
  +            final String message = REZ.getString( "get-size-folder.error", file );
  +            throw new FileSystemException( message );
  +        }
  +
           // Do some checking
           if ( !file.exists() )
           {
  @@ -86,8 +93,12 @@
        */
       public long getLastModifiedTime() throws FileSystemException
       {
  -        // TODO - implement this
  -        throw new FileSystemException( "Not implemented." );
  +        if( !file.exists() )
  +        {
  +            final String message = REZ.getString( "get-last-modified-no-exist.error", file );
  +            throw new FileSystemException( message );
  +        }
  +        return file.doGetLastModifiedTime();
       }
   
       /**
  @@ -95,8 +106,12 @@
        */
       public void setLastModifiedTime( long modTime ) throws FileSystemException
       {
  -        // TODO - implement this
  -        throw new FileSystemException( "Not implemented." );
  +        if( !file.exists() )
  +        {
  +            final String message = REZ.getString( "set-last-modified-no-exist.error", file );
  +            throw new FileSystemException( message );
  +        }
  +        file.doSetLastModifiedTime( modTime );
       }
   
       /**
  @@ -104,8 +119,7 @@
        */
       public Object getAttribute( String attrName ) throws FileSystemException
       {
  -        // TODO - implement this
  -        throw new FileSystemException( "Not implemented." );
  +        return file.doGetAttribute( attrName );
       }
   
       /**
  @@ -113,8 +127,20 @@
        */
       public void setAttribute( String attrName, Object value ) throws FileSystemException
       {
  -        // TODO - implement this
  -        throw new FileSystemException( "Not implemented." );
  +        file.doSetAttribute( attrName, value );
  +    }
  +
  +    /**
  +     * Returns the certificates used to sign this file.
  +     */
  +    public Certificate[] getCertificates() throws FileSystemException
  +    {
  +        if( !file.exists() )
  +        {
  +            final String message = REZ.getString( "get-certificates-no-exist.error", file );
  +            throw new FileSystemException( message );
  +        }
  +        return file.doGetCertificates();
       }
   
       /**
  @@ -122,6 +148,11 @@
        */
       public InputStream getInputStream() throws FileSystemException
       {
  +        if( file.isFolder() )
  +        {
  +            final String message = REZ.getString( "read-folder.error", file );
  +            throw new FileSystemException( message );
  +        }
           if ( !file.exists() )
           {
               final String message = REZ.getString( "read-no-exist.error", file );
  @@ -156,6 +187,11 @@
        */
       public OutputStream getOutputStream() throws FileSystemException
       {
  +        if( file.isFolder() )
  +        {
  +            final String message = REZ.getString( "write-folder.error", file );
  +            throw new FileSystemException( message );
  +        }
           if ( state != STATE_NONE )
           {
               final String message = REZ.getString( "write-in-use.error", file );
  
  
  
  1.3       +46 -0     jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/FileSystem.java
  
  Index: FileSystem.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/FileSystem.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FileSystem.java	20 Aug 2002 06:10:50 -0000	1.2
  +++ FileSystem.java	21 Aug 2002 13:10:57 -0000	1.3
  @@ -25,6 +25,52 @@
       FileObject getRoot() throws FileSystemException;
   
       /**
  +     * Returns the parent layerer if this is a layered file system.
  +     * This returns null if this is not a layered file system.
  +     */
  +    FileObject getParentLayer() throws FileSystemException;
  +
  +    /**
  +     * Gets the value of an attribute of the file system.
  +     *
  +     * <p>TODO - change to <code>Map getAttributes()</code> instead?
  +     *
  +     * <p>TODO - define the standard attribute names, and define which attrs
  +     * are guaranteed to be present.
  +     *
  +     * @see org.apache.commons.vfs.FileContent#getAttribute
  +     *
  +     * @param attrName
  +     *      The name of the attribute.
  +     *
  +     * @return
  +     *      The value of the attribute.
  +     *
  +     * @throws FileSystemException
  +     *      If the file does not exist, or is being written, or if the
  +     *      attribute is unknown.
  +     */
  +    Object getAttribute( String attrName ) throws FileSystemException;
  +
  +    /**
  +     * Sets the value of an attribute of the file's content.  Creates the
  +     * file if it does not exist.
  +     *
  +     * @see org.apache.commons.vfs.FileContent#setAttribute
  +     *
  +     * @param attrName
  +     *      The name of the attribute.
  +     *
  +     * @param value
  +     *      The value of the attribute.
  +     *
  +     * @throws FileSystemException
  +     *      If the file is read-only, or is being read, or if the attribute
  +     *      is not supported, or on error setting the attribute.
  +     */
  +    void setAttribute( String attrName, Object value ) throws FileSystemException;
  +
  +    /**
        * Finds a file in this file system.
        *
        * @param name
  
  
  
  1.2       +10 -3     jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/Resources.properties,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Resources.properties	16 Jul 2002 17:18:57 -0000	1.1
  +++ Resources.properties	21 Aug 2002 13:10:57 -0000	1.2
  @@ -1,6 +1,9 @@
   # AbstractFileObject
   delete-not-supported.error=This file type does not support delete.
  -create-folder-not-supported.error=This file type does not support folder creation.
  +create-folder-not-supported.error=this file type does not support folder creation.
  +get-last-modified-not-supported.error=this file type does not support retriving last modified time.
  +set-last-modified-not-supported.error=this file type does not support setting last modified time.
  +set-attribute-not-supported.error=this file type does not support setting attributes.
   write-not-supported.error=This file type cannot be written to.
   get-type-no-exist.error=Could not determine the type of file "{0}" because it does not exist.
   get-type.error=Could not determine the type of file "{0}".
  @@ -12,7 +15,6 @@
   create-mismatched-type.error=Could not create {0} "{1}" because it already exists and is a {2}.
   create-read-only.error=Could not create {0} "{1}" because the file system is read-only.
   create.error=Could not create {0} "{1}".
  -get-folder-content.error=Could not get the content of "{0}" because it is a folder.
   write-read-only.error=Could not write to "{0}" because it is read-only.
   write-folder.error=Could not write to "{0}" because it is a folder.
   write-in-use.error=Could not write to "{0}" because it is already in use.
  @@ -22,12 +24,17 @@
   copy-missing-file.error=Could not copy "{0}" because is does not exist.
   
   # DefaultFileContent
  +get-size-folder.error=Could not determine the size of "{0}" because it is a folder.
   get-size-no-exist.error=Could not determine the size of file "{0}" because it does not exist.
   get-size-write.error=Could not determine the size of file "{0}" because it is being written to.
   get-size.error=Could not determine the size of file "{0}".
  +read-folder.error=Could not read from "{0}" because it is a folder.
   read-no-exist.error=Could not read file "{0}" because it does not exist.
   read-in-use.error=Could not read file "{0}" because it is already being used.
   read.error=Could not read file "{0}".
  +get-last-modified-no-exist.error=Could not determine the last modified timestamp of "{0}" because it does not exist.
  +set-last-modified-no-exist.error=Could not set the last modified timestamp of "{0}" because it does not exist.
  +get-certificates-no-exist.error=Could not retrive the certificates of "{0}" because it does not exist.
   close-instr.error=Could not close file input stream.
   close-outstr.error=Could not close file output stream.
   
  @@ -43,4 +50,4 @@
   invalid-childname.error=Invalid file base-name "{0}".
   invalid-descendent-name.error=Invalid descendent file name "{0}".
   invalid-escape-sequence.error=Invalid URI escape sequence "{0}".
  -invalid-relative-path.error=Invalid relative file name.
  \ No newline at end of file
  +invalid-relative-path.error=Invalid relative file name.
  
  
  
  1.5       +1 -1      jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/ftp/FtpFileSystem.java
  
  Index: FtpFileSystem.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/ftp/FtpFileSystem.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- FtpFileSystem.java	21 Aug 2002 07:00:12 -0000	1.4
  +++ FtpFileSystem.java	21 Aug 2002 13:10:57 -0000	1.5
  @@ -40,7 +40,7 @@
                             final String password )
           throws FileSystemException
       {
  -        super( context, rootName );
  +        super( context, rootName, null );
           try
           {
               client = new FTPClient();
  
  
  
  1.3       +1 -1      jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/local/LocalFileSystem.java
  
  Index: LocalFileSystem.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/local/LocalFileSystem.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- LocalFileSystem.java	21 Aug 2002 07:00:12 -0000	1.2
  +++ LocalFileSystem.java	21 Aug 2002 13:10:57 -0000	1.3
  @@ -31,7 +31,7 @@
                               final DefaultFileName rootName,
                               final String rootFile )
       {
  -        super( context, rootName );
  +        super( context, rootName, null );
           this.rootFile = rootFile;
       }
   
  
  
  
  1.3       +1 -1      jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/smb/SmbFileSystem.java
  
  Index: SmbFileSystem.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/smb/SmbFileSystem.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SmbFileSystem.java	21 Aug 2002 06:11:32 -0000	1.2
  +++ SmbFileSystem.java	21 Aug 2002 13:10:57 -0000	1.3
  @@ -27,7 +27,7 @@
       public SmbFileSystem( final FileSystemProviderContext context,
                             final FileName rootName )
       {
  -        super( context, rootName );
  +        super( context, rootName, null );
       }
   
       /**
  
  
  
  1.4       +2 -2      jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/url/UrlFileSystem.java
  
  Index: UrlFileSystem.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/url/UrlFileSystem.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- UrlFileSystem.java	21 Aug 2002 07:00:12 -0000	1.3
  +++ UrlFileSystem.java	21 Aug 2002 13:10:57 -0000	1.4
  @@ -29,7 +29,7 @@
       public UrlFileSystem( final FileSystemProviderContext context,
                             final FileName rootName )
       {
  -        super( context, rootName );
  +        super( context, rootName, null );
       }
   
       /**
  
  
  
  1.4       +13 -1     jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/zip/ParsedZipUri.java
  
  Index: ParsedZipUri.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/zip/ParsedZipUri.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ParsedZipUri.java	21 Aug 2002 07:00:13 -0000	1.3
  +++ ParsedZipUri.java	21 Aug 2002 13:10:57 -0000	1.4
  @@ -11,7 +11,7 @@
   import org.apache.commons.vfs.provider.ParsedUri;
   
   /**
  - * A parsed Zip URI.
  + * A parsed Zip URI. These have the form "<scheme>:<zip-file>!/<path>".
    *
    * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
    * @version $Revision$ $Date$
  @@ -22,21 +22,33 @@
       private String zipFileName;
       private FileObject zipFile;
   
  +    /**
  +     * Returns the zip-file part of the URI.
  +     */
       public String getZipFileName()
       {
           return zipFileName;
       }
   
  +    /**
  +     * Sets the zip-file part of the URI.
  +     */
       public void setZipFileName( final String zipFileName )
       {
           this.zipFileName = zipFileName;
       }
   
  +    /**
  +     * Returns the FileObject representing the zip-file part.
  +     */
       public FileObject getZipFile()
       {
           return zipFile;
       }
   
  +    /**
  +     * Sets the FileObject representing the zip-file part.
  +     */
       public void setZipFile( final FileObject zipFile )
       {
           this.zipFile = zipFile;
  
  
  
  1.5       +7 -2      jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/zip/ZipFileSystem.java
  
  Index: ZipFileSystem.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/zip/ZipFileSystem.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ZipFileSystem.java	21 Aug 2002 07:00:13 -0000	1.4
  +++ ZipFileSystem.java	21 Aug 2002 13:10:57 -0000	1.5
  @@ -17,6 +17,7 @@
   import org.apache.commons.vfs.FileName;
   import org.apache.commons.vfs.FileObject;
   import org.apache.commons.vfs.FileSystemException;
  +import org.apache.commons.vfs.FileConstants;
   import org.apache.commons.vfs.provider.AbstractFileSystem;
   import org.apache.commons.vfs.provider.DefaultFileName;
   import org.apache.commons.vfs.provider.FileSystem;
  @@ -40,10 +41,14 @@
   
       public ZipFileSystem( final FileSystemProviderContext context,
                             final DefaultFileName rootName,
  -                          final File file )
  +                          final FileObject parentLayer )
           throws FileSystemException
       {
  -        super( context, rootName );
  +        super( context, rootName, parentLayer );
  +
  +        // Make a local copy of the file
  +        final File file = parentLayer.replicateFile( FileConstants.SELECT_SELF );
  +
           this.file = file;
   
           // Open the Zip file
  
  
  
  1.4       +1 -4      jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/zip/ZipFileSystemProvider.java
  
  Index: ZipFileSystemProvider.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/zip/ZipFileSystemProvider.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ZipFileSystemProvider.java	21 Aug 2002 07:00:13 -0000	1.3
  +++ ZipFileSystemProvider.java	21 Aug 2002 13:10:57 -0000	1.4
  @@ -87,9 +87,6 @@
           // Create the file system
           final DefaultFileName name = new DefaultFileName( parser, zipUri.getRootUri(), "/" );
   
  -        // Make a local copy of the file
  -        final File zipFile = file.replicateFile( FileConstants.SELECT_SELF );
  -
           try
           {
               return (ZipFileSystem)AccessController.doPrivileged(
  @@ -97,7 +94,7 @@
                   {
                       public Object run() throws FileSystemException
                       {
  -                        return new ZipFileSystem( getContext(), name, zipFile );
  +                        return new ZipFileSystem( getContext(), name, file );
                       }
                   } );
           }
  
  
  
  1.6       +29 -5     jakarta-commons-sandbox/vfs/src/test/org/apache/commons/vfs/test/AbstractFileSystemTestCase.java
  
  Index: AbstractFileSystemTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/test/org/apache/commons/vfs/test/AbstractFileSystemTestCase.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- AbstractFileSystemTestCase.java	21 Aug 2002 06:21:26 -0000	1.5
  +++ AbstractFileSystemTestCase.java	21 Aug 2002 13:10:57 -0000	1.6
  @@ -27,6 +27,7 @@
   import org.apache.commons.vfs.FileType;
   import org.apache.commons.vfs.NameScope;
   import org.apache.commons.vfs.impl.DefaultFileSystemManager;
  +import org.apache.commons.vfs.impl.VFSClassLoader;
   import org.apache.commons.vfs.impl.PrivilegedFileReplicator;
   import org.apache.commons.vfs.impl.DefaultFileReplicator;
   import org.apache.commons.vfs.provider.AbstractFileObject;
  @@ -52,7 +53,7 @@
       protected DefaultFileSystemManager m_manager;
   
       // Contents of "file1.txt"
  -    private String m_charContent;
  +    protected String m_charContent;
   
       public AbstractFileSystemTestCase( String name )
       {
  @@ -100,6 +101,10 @@
           dir.addChild( "file1.txt", FileType.FILE );
           dir.addChild( "file2.txt", FileType.FILE );
           dir.addChild( "file3.txt", FileType.FILE );
  +        
  +        final FileInfo code = new FileInfo( "code", FileType.FOLDER );
  +        base.addChild( code );
  +        code.addChild( "ClassToLoad.class", FileType.FILE );
           return base;
       }
   
  @@ -746,6 +751,25 @@
       }
   
       /**
  +     * Tests VFSClassLoader.
  +     */
  +    public void testVFSClassLoader() throws Exception
  +    {
  +        final FileObject[] objects = { m_baseFolder };
  +        VFSClassLoader loader =
  +            new VFSClassLoader( objects, m_manager );
  +
  +        Class testClass = loader.loadClass( "code.ClassToLoad" );
  +        Object testObject = testClass.newInstance();
  +        assertSame( "**PRIVATE**", testObject.toString() );
  +
  +        URL resource = loader.getResource( "file1.txt" );
  +        assertNotNull( resource );
  +        URLConnection urlCon = resource.openConnection();
  +        assertSameURLContent( m_charContent, urlCon );
  +    }
  +
  +    /**
        * Tests url.
        */
       public void testURL() throws Exception
  @@ -826,12 +850,12 @@
           FileObject folder = m_baseFolder.resolveFile( "dir1" );
           try
           {
  -            folder.getURL().openConnection();
  +            folder.getURL().openConnection().getInputStream();
               fail();
           }
           catch( IOException e )
           {
  -            final String message = REZ.getString( "get-folder-content.error", folder );
  +            final String message = REZ.getString( "read-folder.error", folder );
               assertSameMessage( message, e );
           }
   
  @@ -915,12 +939,12 @@
           FileObject folder = m_baseFolder.resolveFile( "dir1" );
           try
           {
  -            folder.getContent();
  +            folder.getContent().getInputStream();
               fail();
           }
           catch( FileSystemException e )
           {
  -            final String message = REZ.getString( "get-folder-content.error", folder );
  +            final String message = REZ.getString( "read-folder.error", folder );
               assertSameMessage( message, e );
           }
   
  
  
  
  1.3       +4 -0      jakarta-commons-sandbox/vfs/src/test-data/test.policy
  
  Index: test.policy
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/test-data/test.policy,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- test.policy	21 Aug 2002 06:21:26 -0000	1.2
  +++ test.policy	21 Aug 2002 13:10:57 -0000	1.3
  @@ -23,6 +23,10 @@
       permission java.io.FilePermission "${test.basedir}/write-tests/-", "read, write, delete";
       permission java.io.FilePermission "${test.basedir}/-", "read";
       permission java.io.FilePermission "${test.basedir}", "read";
  +
  +    //This is needed for the ClassLoader tests.
  +    permission java.lang.RuntimePermission "createClassLoader";
  +
   	// Allows any thread to stop itself using the java.lang.Thread.stop()
   	// method that takes no argument.
   	// Note that this permission is granted by default only to remain
  
  
  
  1.1                  jakarta-commons-sandbox/vfs/src/test-data/code/ClassToLoad.java
  
  Index: ClassToLoad.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package code;
  
  /**
   * The test class for the VFS classloader.
   *
   * @author <a href="mailto:brian@mmmanager.org">Brian Olsen</a>
   * @version $Revision: 1.1 $ $Date: 2002/08/21 13:10:57 $
   */
  public class ClassToLoad
  {
      private String m_message = "**PRIVATE**";
  
      public String toString()
      {
          return m_message;
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>