akarasulu    2003/11/05 20:03:49

  Added:       repository/impl/src/java/org/apache/avalon/repository/impl
                        DefaultAuthenticator.java DefaultBlockManifest.java
                        DefaultFactory.java DefaultFileRepository.java
                        HttpController.java package.html
  Log:
  Checking in a snapshot of the repository
  
  Revision  Changes    Path
  1.1                  
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultAuthenticator.java
  
  Index: DefaultAuthenticator.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" 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 [EMAIL PROTECTED]
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.repository.impl;
  
  import java.net.Authenticator;
  import java.net.PasswordAuthentication;
  
  /**
   * Default authenticator that provides support for username password
   * based authentication in conjunction with the repository proxy settings.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2003/11/06 04:03:49 $
   */
  public final class DefaultAuthenticator extends Authenticator
  {
      /**
       * Proxy username.
       */
       private String m_username;
  
      /**
       * Proxy password.
       */
       private char[] m_password;
  
      /**
       * Creation of a new simple authenticator.
       * @param username the username
       * @param password a passsword
       * @exception NullPointerException if the supplied username or password is null
       */
       public DefaultAuthenticator( String username, String password ) throws 
NullPointerException 
       {
           if( username == null ) throw new NullPointerException( "username" );
           if( password == null ) throw new NullPointerException( "password" );
           m_username = username;
           m_password = password.toCharArray();
       }
  
      /**
       * Returns the password authenticator.
       * @return the password authenticator
       */
       protected PasswordAuthentication getPasswordAuthentication()
       {
            return new PasswordAuthentication( m_username, m_password );
       }
  }
  
  
  
  1.1                  
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultBlockManifest.java
  
  Index: DefaultBlockManifest.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" 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 [EMAIL PROTECTED]
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.repository.impl;
  
  import java.util.jar.Manifest;
  import org.apache.avalon.repository.BlockManifest;
  
  /**
   * An extended manifest that provides a set of convinience operations
   * to access block related attributes.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2003/11/06 04:03:49 $
   */
  public final class DefaultBlockManifest implements BlockManifest
  {
  
     /**
      * Group identifier.
      */
      private final String m_group;
  
     /**
      * Name.
      */
      private final String m_name;
  
     /**
      * Version identifier.
      */
      private final String m_version;
  
     /**
      * Creation of a new block manifest
      * @param manifest the jar manifest
      */
      public DefaultBlockManifest( Manifest manifest ) throws NullPointerException 
      {
          m_group = (String) manifest.getMainAttributes().getValue( BLOCK_GROUP_KEY );
          m_name = (String) manifest.getMainAttributes().getValue( BLOCK_NAME_KEY );
          m_version = (String) manifest.getMainAttributes().getValue( 
BLOCK_VERSION_KEY );
      }
  
      public String getBlockGroup()
      {
          return m_group;
      }
  
      public String getBlockName()
      {
          return m_name;
      }
  
      public String getBlockVersion()
      {
          return m_version;
      }
  }
  
  
  
  1.1                  
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultFactory.java
  
  Index: DefaultFactory.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" 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 [EMAIL PROTECTED]
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.repository.impl ;
  
  
  import java.io.File ;
  import java.io.IOException ;
  import java.io.InputStream ;
  import java.io.FileInputStream ;
  
  import java.util.Properties ;
  import java.net.Authenticator ;
  import java.net.MalformedURLException ;
  import java.net.PasswordAuthentication ;
  
  import org.apache.avalon.defaults.Defaults ;
  import org.apache.avalon.defaults.DefaultsFinder ;
  import org.apache.avalon.defaults.SimpleDefaultsFinder ;
  import org.apache.avalon.defaults.SystemDefaultsFinder ;
  
  import org.apache.avalon.repository.Repository ;
  import org.apache.avalon.repository.ProxyContext ;
  import org.apache.avalon.repository.RepositoryConfig ;
  import org.apache.avalon.repository.RepositoryFactory ;
  import org.apache.avalon.repository.RepositoryException ;
  
  
  /**
   * The default repository factory implementation.
   * 
   * @author <a href="mailto:[EMAIL PROTECTED]">Alex Karasulu</a>
   * @author $Author: akarasulu $
   * @version $Revision: 1.1 $
   */
  public class DefaultFactory implements RepositoryFactory
  {
      /** properties file where we pull defaults from */
      public static final String DEFAULTS = "repository.properties" ;
      /** single valued properties */
      private static final String [] s_singles = {
          "cache.dir",
          "proxyHost",
          "proxyPort",
          "proxyUsername",
          "proxyPassword"
      } ;
      /** the local repository base key where we download files into */
      public static final String CACHE_DIR = s_singles[0] ;
      /** the proxy host key */
      public static final String PROXY_HOST = s_singles[1] ;
      /** the proxy port key */
      public static final String PROXY_PORT = s_singles[2] ;
      /** the proxy username key */
      public static final String PROXY_USERNAME = s_singles[3] ;
      /** the proxy password key */
      public static final String PROXY_PASSWORD = s_singles[4] ;
  
      /** enumerated (multivalued) properties */
      public static final String [] s_multiple = {
          "remote.repository.url"
      } ;
      
      /** the key base for the remote repo enumerated property */
      public static final String REMOTE_REPO_BASE = s_multiple[0] ;
  
  
      /**
       * Creates a repository configuration and populates it with parameters 
       * obtained from a default bootstrap properties file, a hidden form of the
       * same properties file (dot '.' prefixed), and the system properties in 
       * that order.  Support property key macro expansion.
       * 
       * @see org.apache.avalon.repository.RepositoryFactory#getDefaultConfig()
       */
      public RepositoryConfig getDefaultConfig()
          throws RepositoryException
      {
          Properties l_bootstrap = new Properties() ;
          ProxyContext l_proxy = null ;
          RepositoryConfig l_config = new RepositoryConfig() ;
          InputStream l_in = Repository.class.getResourceAsStream( DEFAULTS ) ;
          
          /*
           * Load the jar relative default properties file first.  Then load into
           * the same properties the dot prefixed version of the defaults file 
           * within the user's home directory.
           */
          try 
          {
              l_bootstrap.load( l_in ) ;
              String l_userHome = System.getProperty( "user.home" ) ;
              File l_user = new File( l_userHome, "." + DEFAULTS ) ;
              
              if ( l_user.exists() ) 
              {    
                  l_in = new FileInputStream( l_user ) ;
                  l_bootstrap.load( l_in ) ;
              }
          }
          catch( IOException e )
          {
              throw new RepositoryException( "Failed to load defaults", e ) ;
          }
  
          /*
           * Create the finder (discovery policy), construct the defaults, and
           * macro expand the values.
           */
          final DefaultsFinder [] l_finders = {
              new SimpleDefaultsFinder( new Properties[] { l_bootstrap }, false ),
              new SystemDefaultsFinder()
          } ;
          
          final Defaults l_defaults = 
              new Defaults( s_singles, s_multiple, l_finders ) ;
          Defaults.macroExpand( l_defaults, null ) ;
          
          /*
           * Here we start to populate the empty repository configuration using
           * the values stored in the defaults.
           */
          
          l_config.setCacheDir( l_defaults.getProperty( CACHE_DIR ) ) ;
          
          try
          {
              l_config.setRemoteRepositoryUrls( 
                      l_defaults.getEnumerated( REMOTE_REPO_BASE ) ) ;
          }
          catch ( MalformedURLException e )
          {
              throw new RepositoryException( "Failed to set remote repos", e ) ;
          }
  
          if ( l_defaults.containsKey( PROXY_HOST ) )
          {    
              int l_port = Integer
                  .parseInt( l_defaults.getProperty( PROXY_PORT ) ) ;
              String l_host = l_defaults.getProperty( PROXY_HOST ) ;
      
              Authenticator l_authenticator = new Authenticator()
              {
                  protected PasswordAuthentication getPasswordAuthentication()
                  {
                      PasswordAuthentication l_pwdAuth = 
                          new PasswordAuthentication(
                          l_defaults.getProperty( PROXY_USERNAME ),
                          l_defaults.getProperty( PROXY_PASSWORD )
                              .toCharArray() ) ;
                      return l_pwdAuth ;
                  }
              } ;
              
              l_proxy = new ProxyContext( l_host, l_port, l_authenticator) ;
          }
          
          l_config.setProxyContext( l_proxy ) ;
          
          return l_config ;
      }
  
  
      /**
       * Creates a file repository using the properties of a configuration bean.
       * 
       * @see org.apache.avalon.repository.RepositoryFactory
       * create(org.apache.avalon.repository.RepositoryConfig)
       */
      public Repository create( RepositoryConfig a_config )
      {
          Repository l_repository = null ;
          File l_base = new File( a_config.getCacheDir() ) ;
          
          if ( null == a_config.getProxyContext() && 
               null == a_config.getRemoteRepositories() )
          {
              l_repository = new DefaultFileRepository( l_base ) ;
          }
          else if ( null == a_config.getProxyContext() )
          {
              l_repository = new DefaultFileRepository( l_base, 
                      a_config.getRemoteRepositories() ) ;
          }
          
          l_repository = new DefaultFileRepository( l_base, 
                  a_config.getProxyContext(), 
                  a_config.getRemoteRepositories() ) ;
          
          return l_repository ;
      }
  }
  
  
  
  1.1                  
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultFileRepository.java
  
  Index: DefaultFileRepository.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" 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 [EMAIL PROTECTED]
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.repository.impl;
   
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.InputStream;
  import java.io.IOException;
  import java.net.URL;
  import java.net.Authenticator;
  import java.net.JarURLConnection;
  import java.util.jar.JarFile;
  import java.util.zip.ZipEntry;
  import java.util.Enumeration;
  
  import org.apache.avalon.repository.Repository;
  import org.apache.avalon.repository.RepositoryException;
  import org.apache.avalon.repository.ProxyContext;
  import org.apache.avalon.repository.BlockManifest;
  
  /**
   * A component that provides access to versioned resources based on 
   * an underlying file system.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2003/11/06 04:03:49 $
   */
  public class DefaultFileRepository implements Repository
  {
      //------------------------------------------------------------------
      // immutable state 
      //------------------------------------------------------------------
  
     /**
      * The directory referencing the local repository cache.
      */
      private final File m_base;
  
     /**
      * Sequence of remote hosts.
      */
      private final URL[] m_hosts;
  
      //------------------------------------------------------------------
      // constructor 
      //------------------------------------------------------------------
  
      public DefaultFileRepository( File base )
      {
         this( base, null, new URL[0] );
      }
  
      public DefaultFileRepository( File base, URL[] hosts )
      {
         this( base, null, hosts );
      }
  
      public DefaultFileRepository( File base, ProxyContext context, URL[] hosts )
      {
          if( base == null ) throw new NullPointerException( "base" );
  
          m_base = base;
  
          if( hosts == null )
          {
              m_hosts = new URL[0];
          }
          else
          {
              m_hosts = new URL[ hosts.length ];
              for( int i=0; i<hosts.length; i++ )
              {
                  URL url = hosts[i];
                  final String path = url.toString();
                  if( !path.endsWith( "/" ) ) 
                  {
                      try
                      {
                          m_hosts[i] = new URL( path + "/" );
                      }
                      catch( Throwable e )
                      {
                          final String error = 
                            "Could not coerce supplied URL to a directory reference: " 
                            + path;
                          throw new IllegalArgumentException( error );
                      }
                  }
                  else
                  {
                      m_hosts[i] = hosts[i];
                  }
              }
          }
  
          if( context != null )
          {
              System.getProperties().put( "proxySet", "true" );
              System.getProperties().put( "proxyHost", context.getHost() );
              System.getProperties().put( "proxyPort", context.getPort() );
              if( context.getAuthenticator() != null )
              {
                  Authenticator.setDefault( context.getAuthenticator() );
              }
          }
      } 
  
      //------------------------------------------------------------------
      // implementation 
      //------------------------------------------------------------------
  
     /**
      * Return the repository location.
      * 
      * @return the location
      */
      public String getLocation()
      {
          return m_base.toString();
      }
  
  
     /**
      * Install a block archive into the repository.
      * @param url the block archive url
      * @param buffer a string buffer against which messages may be logged
      * @return the block manifest
      */
      public BlockManifest install( URL url, StringBuffer buffer ) throws 
RepositoryException
      {
          String path = url.getFile();
  
          try
          {
              File temp = File.createTempFile( "avalon-", "-bar" );
              temp.delete();
              HttpController.getFile( url.toString(), temp, true );
              temp.deleteOnExit();
              return expand( temp.toURL(), buffer );
          }
          catch( RepositoryException e )
          {
              throw e;
          }
          catch( Throwable e )
          {
              final String error = 
                "Cannot install target: " + url;
              throw new RepositoryException( error, e );
          }
      }
  
     /**
      * Expand a block archive into the repository.
      * @param url the block archive url
      * @param buffer a string buffer against which messages may be logged
      * @return the block manifest
      */
      private BlockManifest expand( URL url, StringBuffer buffer ) throws 
RepositoryException
      {
          try
          {
              URL jurl = new URL( "jar:" + url.toString() + "!/" );
              JarURLConnection connection = (JarURLConnection) jurl.openConnection();
              BlockManifest manifest = 
                new DefaultBlockManifest( connection.getManifest() );
              final String group = manifest.getBlockGroup();
  
              buffer.append( "\nBlock Group: " + group );
              final File root = new File( m_base, group );
              buffer.append( "\nLocal target: " + root );
              JarFile jar = connection.getJarFile();
              Enumeration entries = jar.entries();
              while( entries.hasMoreElements() )
              {
                  ZipEntry entry = (ZipEntry) entries.nextElement();
                  if( !entry.getName().startsWith( "META-INF" ) )
                  {
                      installEntry( buffer, root, jar, entry );
                  }
              }
              buffer.append( "\nInstall successful." );
              return manifest;
          }
          catch( Throwable e )
          {
              final String error = 
                "Could not install block: " + url;
              throw new RepositoryException( error, e );
          }
      }
  
     /**
      * Get a resource relative to the supplied artifact name where the artifact name
      * is equivalent to the group and resource name seperated by a colon.
      * 
      * @param artifact the artifact name
      * @param version the version identifier
      * @param type the resource type
      * @return the resource
      */
      public URL getArtifact( 
        final String artifact, final String version, final String type )
        throws RepositoryException
      {
          int n = verify( artifact );
          final String group = getGroupName( artifact, n );
          final String name = getResourceName( artifact, n );
          return getArtifact( group, name, version, type );
      }
  
     /**
      * Get a resource relative to the supplied application name, 
      * resource name, version and resource type.
      * 
      * @param group the application or group name
      * @param name the resource name
      * @param version the version identifier
      * @param type the resource type
      * @return the resource
      */
      public URL getArtifact( 
        final String group, final String name, final String version, final String type 
)
        throws RepositoryException
      {
          if( m_hosts == null )
          {
              throw new IllegalStateException( "hosts" );
          }
          if( group == null )
          {
              throw new NullPointerException( "group" );
          }
          if( name == null )
          {
              throw new NullPointerException( "name" );
          }
          if( type == null )
          {
              throw new NullPointerException( "type" );
          }
          String path = group + "/" + type + "s/" + name;
          if( ( version != null ) && ( version.length() != 0 ) ) 
          {
              path = path + "-" + version;
          }
          path = path + "." + type;
  
          RepositoryException repositoryException = null;
          try
          {
              return getLocalArtifact( group, name, version, type );
          }
          catch( RepositoryException e )
          {
              repositoryException = e;
              for( int i=0; i<m_hosts.length; i++ )
              {
                  final URL source = m_hosts[i];
                  final String host = source.toString();
                  final File local = new File( m_base, path );
                  final String url = host + path;
  
                  try
                  {
                      if( HttpController.getFile( url, local, true ) )
                      {
                          return getLocalArtifact( group, name, version, type );
                      }
                  }
                  catch( Throwable anything )
                  {
                      // continue
                  }
              }
          }
          catch( Throwable e )
          {
              final String error =
                "Unexpected error while attempting to resolve artifact: " + path;
              throw new RepositoryException( error, e );
          }
  
          //
          // fallback to throwing a local repository error
          //
  
          throw repositoryException;
  
      }
  
     /**
      * Get a resource relative to the supplied application name, 
      * resource name, version and resource type from the local cache.
      * 
      * @param group the application or group name
      * @param name the resource name
      * @param version the version identifier
      * @param type the resource type
      * @return the resource
      */
      private URL getLocalArtifact( 
        final String group, final String name, 
        final String version, final String type )
        throws RepositoryException
      {
          File application = new File( m_base, group );
          if( !application.exists() )
          {
              final String error = 
                "Unknown group: '" + group
                + "' relative to the repository base: '" + m_base + "'.";
              throw new RepositoryException( error );
          }
  
          File types = new File( application, type + "s" );
          if( !types.exists() )
          {
              final String error = 
                "No resources of the type: '" + type 
                + "' in the group: '" + group 
                + "'. File: '" + types + "'.";
              throw new RepositoryException( error );
          }
  
          //
          // we only append the version identifier if the version
          // value is not null and more than 0 characters
          //
  
          String resourceName = name;
          if( ( version != null ) && ( version.length() != 0 ) ) 
          {
              resourceName = resourceName + "-" + version;
          }
          File resource = new File( types, resourceName + "." + type );
  
          if( !resource.exists() )
          {
              final String error = 
                "No resources of the type: '" + type 
                + "' in the group: '" + group 
                + "' with the name: '" + name 
                + "' and version: '" + version 
                + ". File: '" + resource + "'.";
              throw new RepositoryException( error );
          }
  
          try
          {
              return resource.toURL();
          }
          catch( Throwable e )
          {
              final String error = 
                "Unable to resolve URL for resource: " + resource;
              throw new RepositoryException( error );
          }
      }
  
      private int verify( final String artifact ) throws RepositoryException
      {
          int n = artifact.indexOf( SEPERATOR );
          if( n < 1 )
          {
              final String error = 
                "Invalid artifact name: " + artifact;
              throw new RepositoryException( error );
          }
          return n;
      }
  
      private String getGroupName( String artifact, int index )
      {
          return artifact.substring( 0, index );
      }
  
      private String getResourceName( String artifact, int index )
      {
          return artifact.substring( index + 1 );
      }
  
     /**
      * Internal utility to install a entry from a jar file into the local repository.
      * @param buffer the buffer to log messages to
      * @param root the root directory corresponding to the bar group
      * @param jar the block archive
      * @param entry the entry from the archive to install
      */
      private void installEntry( 
        StringBuffer buffer, File root, JarFile jar, ZipEntry entry ) throws Exception
      {
          if( entry.isDirectory() ) return;
          
          final String name = entry.getName();
          File file = new File( root, name );
  
          long timestamp = entry.getTime();
          if( file.exists() )
          {
              if( file.lastModified() == timestamp )
              {
                  buffer.append( "\nEntry: " + name + " (already exists)" );
                  return;
              }
              else if( file.lastModified() > timestamp )
              {
                  buffer.append( "\nEntry: " + name + " (local version is more 
recent)" );
                  return;
              }
              else
              {
                  buffer.append( "\nEntry: " + name + " (updating local version)" );
              }
          }
          else
          {
              buffer.append( "\nEntry: " + name );
          }       
  
          InputStream is = jar.getInputStream( entry );
          if ( is == null )
          {
              final String error = 
                "Entry returned a null input stream: " + name;
              buffer.append( "\n  " + error );
              throw new IOException( error );
          }
  
          file.getParentFile().mkdirs();
          FileOutputStream fos = new FileOutputStream( file );
          byte[] buf = new byte[100 * 1024];
          int length;
          while ( ( length = is.read( buf ) ) >= 0 )
          {
              fos.write( buf, 0, length );
          }
          fos.close();
          is.close();
  
          if ( timestamp < 0 )
          {
              file.setLastModified( System.currentTimeMillis() );
          }
          else
          {
              file.setLastModified( timestamp );
          }
      }
  }
  
  
  
  1.1                  
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/HttpController.java
  
  Index: HttpController.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" 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 [EMAIL PROTECTED]
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.repository.impl;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.HttpURLConnection;
  import java.net.URL;
  import java.net.URLConnection;
  
  /**
   * Class supporting the retrival of remotely located resources.
   * Implementation is based on original code from the Maven project
   * refactored to seperate static proxy establishment from transport
   * concerns.
   *
   * @author [EMAIL PROTECTED]
   * @author [EMAIL PROTECTED] (Added Java 1.1 style HTTP basic auth)
   * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
   * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2003/11/06 04:03:49 $
   */
  class HttpController
  {
  
      /**
       * Retrieve a remote file.  Returns true if the file was updated, false
       * if the existing cached resource was not modified.
       *
       * @param url the of the file to retrieve
       * @param destinationFile where to store it
       * @param useTimestamp whether to check the modified timestamp on the
       *      <code>destinationFile</code> against the remote <code>source</code>
       * @param useChecksum Flag to indicate the use of the checksum for the retrieved
       *        artifact if it is available.
       */
      public static boolean getFile( 
        String url, File destinationFile, boolean useTimestamp, boolean useChecksum )
          throws Exception
      {
          // Get the requested file.
          boolean result = getFile( url, destinationFile, useTimestamp );
  
          // Get the checksum if requested.
          if ( useChecksum )
          {
              File checksumFile = new File( destinationFile + ".md5" );
              try
              {
                  getFile( url + ".md5", checksumFile, useTimestamp );
              }
              catch ( Exception e )
              {
                  // do nothing we will check later in the process
                  // for the checksums.
              }
          }
  
          return result;
      }
  
      /**
       * Retrieve a remote file.  Returns true if the file was successfully
       * retrieved or if it is up to date (when the useTimestamp flag is set).
       *
       * @param url the of the file to retrieve
       * @param destinationFile where to store it
       * @param useTimestamp whether to check the modified timestamp on the
       *      <code>destinationFile</code> against the remote <code>source</code>
       * @return TRUE if the file was updated else FALSE
       */
      public static boolean getFile( String url,
                                  File destinationFile,
                                  boolean useTimestamp )
          throws Exception
      {
          String[] s = parseUrl( url );
          String username = s[0];
          String password = s[1];
          String parsedUrl = s[2];
  
          URL source = new URL( parsedUrl );
  
          //set the timestamp to the file date.
          long timestamp = 0;
          boolean hasTimestamp = false;
          if ( useTimestamp && destinationFile.exists() )
          {
              timestamp = destinationFile.lastModified();
              hasTimestamp = true;
          }
  
          //set up the URL connection
          URLConnection connection = source.openConnection();
  
          //modify the headers
          //NB: things like user authentication could go in here too.
          if ( useTimestamp && hasTimestamp )
          {
              connection.setIfModifiedSince( timestamp );
          }
  
          //connect to the remote site (may take some time)
          connection.connect();
          //next test for a 304 result (HTTP only)
          if ( connection instanceof HttpURLConnection )
          {
              HttpURLConnection httpConnection = (HttpURLConnection) connection;
              if ( httpConnection.getResponseCode() == 
HttpURLConnection.HTTP_NOT_MODIFIED )
              {
                  return false;
              }
              // test for 401 result (HTTP only)
              if ( httpConnection.getResponseCode() == 
HttpURLConnection.HTTP_UNAUTHORIZED )
              {
                  throw new Exception( "Not authorized." );
              }
          }
  
          // REVISIT: at this point even non HTTP connections may support the
          // if-modified-since behaviour - we just check the date of the
          // content and skip the write if it is not newer.
          // Some protocols (FTP) dont include dates, of course.
  
          InputStream is = null;
          for ( int i = 0; i < 3; i++ )
          {
              try
              {
                  is = connection.getInputStream();
                  break;
              }
              catch ( IOException ex )
              {
                  // do nothing
              }
          }
          if ( is == null )
          {
              final String error = 
                "Connection returned a null input stream: " + url;
              throw new IOException( error );
          }
  
          File parent = destinationFile.getParentFile();
          parent.mkdirs();
  
          FileOutputStream fos = new FileOutputStream( destinationFile );
  
          byte[] buffer = new byte[100 * 1024];
          int length;
  
          System.out.print( "Source: " + source + "\n");
          while ( ( length = is.read( buffer ) ) >= 0 )
          {
              fos.write( buffer, 0, length );
              System.out.print( "." );
          }
  
          System.out.println( "" );
          fos.close();
          is.close();
  
          // if (and only if) the use file time option is set, then the
          // saved file now has its timestamp set to that of the downloaded
          // file
  
          if ( useTimestamp )
          {
              long remoteTimestamp = connection.getLastModified();
  
              if ( remoteTimestamp != 0 )
              {
                  touchFile( destinationFile, remoteTimestamp );
              }
          }
          return true;
      }
  
      /**
       * Parse an url which might contain a username and password. If the
       * given url doesn't contain a username and password then return the
       * origin url unchanged.
       *
       * @param url The url to parse.
       * @return The username, password and url.
       */
      static String[] parseUrl( String url )
      {
          String[] parsedUrl = new String[3];
          parsedUrl[0] = null;
          parsedUrl[1] = null;
          parsedUrl[2] = url;
  
          // We want to be able to deal with Basic Auth where the username
          // and password are part of the URL. An example of the URL string
          // we would like to be able to parse is like the following:
          //
          // http://username:[EMAIL PROTECTED]
  
          int i = url.indexOf( "@" );
          if ( i > 0 )
          {
              String s = url.substring( 7, i );
              int j = s.indexOf( ":" );
              parsedUrl[0] = s.substring( 0, j );
              parsedUrl[1] = s.substring( j + 1 );
              parsedUrl[2] = "http://"; + url.substring( i + 1 );
          }
  
          return parsedUrl;
      }
  
      /**
       * set the timestamp of a named file to a specified time.
       *
       * @param file the file to touch
       * @param timemillis in milliseconds since the start of the era
       * @return true if it succeeded. False means that this is a java1.1 system
       *      and that file times can not be set
       * @exception Exception Thrown in unrecoverable error. Likely this
       *      comes from file access failures.
       */
      private static boolean touchFile( File file, long timemillis )
          throws Exception
      {
          long modifiedTime;
  
          if ( timemillis < 0 )
          {
              modifiedTime = System.currentTimeMillis();
          }
          else
          {
              modifiedTime = timemillis;
          }
  
          file.setLastModified( modifiedTime );
          return true;
      }
  }
  
  
  
  1.1                  
avalon-sandbox/repository/impl/src/java/org/apache/avalon/repository/impl/package.html
  
  Index: package.html
  ===================================================================
  
  <body>
  <p>
  The repository impl package contains an implementation of a file based repository.
  </p>
  
  </body>
  
  
  

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

Reply via email to