You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2003/10/30 23:00:38 UTC

cvs commit: avalon/merlin/kernel/loader/src/test/org/apache/avalon/merlin/env EnvTest.java

mcconnell    2003/10/30 14:00:38

  Modified:    merlin/kernel/loader project.xml
               merlin/kernel/loader/src/java/org/apache/avalon/merlin
                        KernelConfig.java KernelDefaults.java
                        merlin.properties
               merlin/kernel/loader/src/java/org/apache/avalon/merlin/env
                        Env.java
               merlin/kernel/loader/src/test/org/apache/avalon/merlin/env
                        EnvTest.java
  Log:
  Pathch from Alex - updating the kernel loader to move from user-repo terminology to app-repo, enhancements relative to proxy management, and updates to the env handling.
  
  Revision  Changes    Path
  1.3       +10 -0     avalon/merlin/kernel/loader/project.xml
  
  Index: project.xml
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/kernel/loader/project.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- project.xml	27 Oct 2003 23:50:47 -0000	1.2
  +++ project.xml	30 Oct 2003 22:00:38 -0000	1.3
  @@ -23,6 +23,16 @@
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
       </dependency>
  +    <dependency>
  +      <groupId>avalon-repository</groupId>
  +      <artifactId>avalon-repository-spi</artifactId>
  +      <version>1.0b1</version>
  +    </dependency>
  +    <dependency>
  +      <groupId>avalon-repository</groupId>
  +      <artifactId>avalon-repository-impl</artifactId>
  +      <version>1.0b1</version>
  +    </dependency>
   
     </dependencies>
     
  
  
  
  1.3       +153 -23   avalon/merlin/kernel/loader/src/java/org/apache/avalon/merlin/KernelConfig.java
  
  Index: KernelConfig.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/kernel/loader/src/java/org/apache/avalon/merlin/KernelConfig.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- KernelConfig.java	28 Oct 2003 09:02:40 -0000	1.2
  +++ KernelConfig.java	30 Oct 2003 22:00:38 -0000	1.3
  @@ -1,45 +1,110 @@
  +/*
  +
  + ============================================================================
  +                   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 apache@apache.org.
  +
  + 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.merlin ;
   
  +import org.apache.avalon.repository.ProxyContext;
   
   /**
    * Kernel configuration parameters.
    * 
  + * @todo finish and double check javadocs - ask Steve to take a look at em.
  + * 
    * @author <a href="mailto:aok123@bellsouth.net">Alex Karasulu</a>
    * @author $Author$
    * @version $Revision$
    */
   public class KernelConfig 
   {
  -    /** @todo confirm default value */
  +    /** flag for the kernel's server mode */
       private boolean m_isServer = KernelDefaults.isServer() ;
  -    /** @todo confirm default value */
  +    
  +    /** flag for the kernel's debug mode */
       private boolean m_isDebug = KernelDefaults.isDebugEnabled() ; 
  -    /** @todo confirm default value */
  +
  +    /** flag for the kernel's info mode */
       private boolean m_isInfo = KernelDefaults.isInfoEnabled() ;
       
  -    /** @todo confirm default value */
  -    private String[] m_remoteRepositoryUrls = 
  -        KernelDefaults.getRemoteRepositoryUrls() ;
  +    /** Returns a set of remote repositories to pull jars from */
  +    private String [] m_remoteRepositoryUrls = 
  +         KernelDefaults.getRemoteRepositoryUrls() ;
  +
       /** @todo confirm default value */
       private String m_systemRepositoryPath = 
           KernelDefaults.getSystemRepositoryPath() ;
  -    /** @todo confirm default value */
  -    private String m_userRepositoryPath =
  -        KernelDefaults.getUserRepositoryPath() ;
  +
  +    /** the path to the application specific repository */
  +    private String m_applicationRepositoryPath =
  +        KernelDefaults.getApplicationRepositoryPath() ;
  +
       /** @todo confirm default value */
       private String m_configUrl = KernelDefaults.getConfigUrl() ;
  +
       /** @todo confirm default value */
       private String m_homePath = KernelDefaults.getHomePath() ;
  +
       /** @todo confirm default value */
       private String m_kernelUrl = KernelDefaults.getKernelUrl() ;
  +
       /** @todo confirm default value */
       private String m_libraryPath = KernelDefaults.getLibraryPath() ;
  +
       /** @todo confirm default value */
       private String m_tempPath = KernelDefaults.getTempPath() ;
       
       /** @todo confirm default value */
       private String [] m_blockUrls = KernelDefaults.getBlockUrls() ;
       
  +    /** descriptor for proxy used by the kernel to access remote repositories */
  +    private ProxyContext m_proxyCtx = KernelDefaults.getProxyContext() ;
  +    
       
      /**
       * Return TRUE if the kernel is launched in server model.
  @@ -69,44 +134,97 @@
       {
           return m_isInfo ;
       }
  -
       
  +    /**
  +     * Gets the ProxyContext used by the Kernel to access remote repositories.
  +     * 
  +     * @return the proxy context used by the Kernel
  +     */
  +    public ProxyContext getProxyContext()
  +    {
  +        return m_proxyCtx ;
  +    }
  +
  +    /**
  +     * Gets the set of remote repositories used to download artifacts.
  +     * 
  +     * @return the remote repositories to use
  +     */
       public String[] getRemoteRepositoryUrls()
       {
           return m_remoteRepositoryUrls ;
       }
   
       
  -    public String getUserRepositoryPath()
  +    /**
  +     * Gets the path to the application repository directory.  This directory 
  +     * will be used during the retrival of resources such as jar files 
  +     * referenced by block include directives and classloader resource 
  +     * references.  It is not used to for Kernel bootstrapping however at the
  +     * discretion of the user this and the system repository may be one and the 
  +     * same.
  +     * 
  +     * @return the local application repository path
  +     */
  +    public String getApplicationRepositoryPath()
       {
  -        return m_userRepositoryPath ;
  +        return m_applicationRepositoryPath ;
       }
   
  -    
  +    /**
  +     * The local system repository used to access artifacts used to bootstrap 
  +     * the Kernel.
  +     * 
  +     * @return the local system repository path
  +     */
       public String getSystemRepositoryPath()
       {
           return m_systemRepositoryPath ;
       }
   
       
  +    /**
  +     * Gets the path to the directory used as the base anchor for resolution of 
  +     * relative path references for jar extension library directory statements 
  +     * in classloader directives.  If not supplied the value defaults to the 
  +     * current working directory or a file system root.
  +     * 
  +     * @return the path to the library directory
  +     */
       public String getLibraryPath()
       {
           return m_libraryPath ;
       }
   
       
  +    /**
  +     * The path to the root working directory for the kernel.  This config
  +     * parameter determines the paths of some key Context properties obtained 
  +     * during the Contextualizable life-cycle phase.
  +     * 
  +     * @return the path to the kernel root
  +     */
       public String getHomePath()
       {
           return m_homePath ;
       }
   
  -    
  +    /**
  +     * Gets the path to a temporary directory.
  +     * 
  +     * @return path to temororary directory
  +     */
       public String getTempPath()
       {
           return m_tempPath ;
       }
   
  -    
  +    /**
  +     * Gets the url for a configuration file.  This file is for the block target
  +     * configuration overrides.
  +     * 
  +     * @return the url to a config file
  +     */
       public String getConfigUrl()
       {
           return m_configUrl ;
  @@ -118,14 +236,28 @@
           return m_blockUrls ;
       }
   
  -    
  +    /**
  +     * Gets the url for a Kernel XML configuration file.
  +     * 
  +     * @return the path to a Kernel XML configuration file
  +     */
       public String getKernelUrl()
       {
           return m_kernelUrl ;
       }
   
  -    
       /**
  +     * Sets the ProxyContext for this KernelConfig.
  +     * 
  +     * @param a_proxyCtx sets the proxy context
  +     */
  +    public void setProxyContext( ProxyContext a_proxyCtx )
  +    {
  +        m_proxyCtx = a_proxyCtx ;
  +    }
  +
  +    /**
  +     * Set the configuration url.
        * @param a_configUrl The configUrl to set.
        */
       public void setConfigUrl( String a_configUrl )
  @@ -133,7 +265,6 @@
           m_configUrl = a_configUrl ;
       }
   
  -    
       /**
        * @param a_homePath The homePath to set.
        */
  @@ -222,13 +353,12 @@
       {
           m_tempPath = a_tempPath ;
       }
  -
       
       /**
  -     * @param a_userRepositoryPath The userRepositoryPath to set.
  +     * @param path the path to the application repository
        */
  -    public void setUserRepositoryPath( String a_userRepositoryPath )
  +    public void setApplicationRepositoryPath( String path )
       {
  -        m_userRepositoryPath = a_userRepositoryPath ;
  +        m_applicationRepositoryPath = path ;
       }
   }
  
  
  
  1.6       +294 -79   avalon/merlin/kernel/loader/src/java/org/apache/avalon/merlin/KernelDefaults.java
  
  Index: KernelDefaults.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/kernel/loader/src/java/org/apache/avalon/merlin/KernelDefaults.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- KernelDefaults.java	28 Oct 2003 12:53:49 -0000	1.5
  +++ KernelDefaults.java	30 Oct 2003 22:00:38 -0000	1.6
  @@ -55,21 +55,23 @@
   import java.io.IOException ;
   import java.io.InputStream ;
   import java.io.FileInputStream ;
  -
  +import java.net.Authenticator ;
  +import java.net.PasswordAuthentication ;
   import java.util.ArrayList ;
   import java.util.Properties ;
   import java.util.Enumeration ;
   
   import org.apache.avalon.merlin.env.Env ;
   import org.apache.avalon.merlin.env.EnvAccessException ;
  +import org.apache.avalon.repository.ProxyContext ;
   
   
   /**
  - * Maintains algorithms for determining default values to kernel parameters.  
  + * Contains search policy for discovering default values to kernel parameters.
    * This involves searching classpaths, finding variables in the environment in
    * an operating system dependent fashion, and finding variables within the 
  - * system properties.  Basically the policy of finding the values to these
  - * kernel parameters are maintained here.
  + * system properties.  The expansion of macro values for properties are also
  + * handled by this class.
    * 
    * @todo document the property keys and make sure they reflect those defined by
    * Steve in his emails
  @@ -80,83 +82,144 @@
    */
   public class KernelDefaults
   {
  -    private static final String MERLIN_HOME_ENV = "MERLIN_HOME";
  -    private static final String MERLIN_REPO_LOCAL_ENV = "MERLIN_REPO_LOCAL";
  +    // ------------------------------------------------------------------------
  +    // Environment Variable Names 
  +    // ------------------------------------------------------------------------
  +
  +    /** Merlin home environment variable name */
  +    public static final String MERLIN_HOME_ENV = "MERLIN_HOME" ;
  +    /** Merlin local application repository environment variable name */
  +    public static final String MERLIN_REPO_LOCAL_ENV = "MERLIN_REPO_LOCAL" ;
  +
  +
  +    // ------------------------------------------------------------------------
  +    // Single Valued Kernel Configuration Properties
  +    // ------------------------------------------------------------------------
   
  +    /** Array for all single valued property keys */
       private static final String [] s_keys =
       {
  -        "merlin.policy.server",
  -        "merlin.policy.info",
  -        "merlin.policy.debug",
  -        "merlin.repository.remote.urls",
  -        "merlin.repository.user.path",
  -        "merlin.repository.system.path",
  -        "merlin.work.path",
  -        "merlin.config.url",
  -        "merlin.kernel.url",
  -        "java.io.tmpdir",
  -        "merlin.library.path"
  +        "merlin.policy.server",                     // 0 IS_SERVER_KEY
  +        "merlin.policy.info",                       // 1 IS_INFO_KEY
  +        "merlin.policy.debug",                      // 2 IS_DEBUG_KEY
  +        "merlin.repository.application.path",       // 3 APPLICATION_REPO_KEY
  +        "merlin.repository.system.path",            // 4 SYSTEM_REPO_KEY 
  +        "merlin.work.path",                         // 5 HOME_PATH_KEY
  +        "merlin.config.url",                        // 6 CONFIG_URL_KEY
  +        "merlin.kernel.url",                        // 7 KERNEL_URL_KEY
  +        "java.io.tmpdir",                           // 8 TEMP_PATH_KEY
  +        "merlin.library.path",                      // 9 LIBRARY_PATH_KEY
  +        "merlin.proxy.host",                        // 10 MERLIN_PROXY_HOST      
  +        "merlin.proxy.port",                        // 11 MERLIN_PROXY_PORT      
  +        "merlin.proxy.username",                    // 12 MERLIN_PROXY_USERNAME  
  +        "merlin.proxy.password"                     // 13 MERLIN_PROXY_PASSWORD
       } ;
       
       
  -    public static final String IS_SERVER_KEY = 
  -        s_keys[0] ;
  -    public static final String IS_INFO_KEY =
  -        s_keys[1] ;
  -    public static final String IS_DEBUG_KEY =
  -        s_keys[2] ;
  -    
  -    public static final String REMOTE_REPO_KEY =
  -        s_keys[3] ;
  -    public static final String USER_REPO_KEY =
  -        s_keys[4] ;
  -    public static final String SYSTEM_REPO_KEY =
  -        s_keys[5] ;
  -    public static final String HOME_PATH_KEY =
  -        s_keys[6] ;
  -    public static final String CONFIG_URL_KEY =
  -        s_keys[7] ;
  -    public static final String KERNEL_URL_KEY =
  -        s_keys[8] ;
  -    public static final String TEMP_PATH_KEY =
  -        s_keys[9] ;
  -    public static final String LIBRARY_PATH_KEY =
  -        s_keys[10] ;
  -    
  -    public static final String BLOCK_URLS_BASE =
  -        "merlin.kernel.targeturls" ;
  +    /** Property to determine if the kernel runs in server mode */
  +    public static final String IS_SERVER_KEY = s_keys[0] ;
  +    /** Property to determine if all logging channels log at the info level */
  +    public static final String IS_INFO_KEY = s_keys[1] ;
  +    /** Property to determine if all logging channels log debugging info */
  +    public static final String IS_DEBUG_KEY = s_keys[2] ;
  +    /**
  +     * The key to the root directory for the local application repository.  This
  +     * directory will be used during the retrival of resources such as jar files
  +     * referenced by block include directives and classloader resource 
  +     * references.
  +     */
  +    public static final String APPLICATION_REPO_KEY = s_keys[3] ;
  +    public static final String SYSTEM_REPO_KEY = s_keys[4] ;
  +    /**
  +     * The key to the working base directory.  Component working directories
  +     * are created relative to this root directory.
  +     */
  +    public static final String HOME_PATH_KEY = s_keys[5] ;
  +    /** url to the config.xml */     
  +    public static final String CONFIG_URL_KEY = s_keys[6] ;
  +    /** The key to a kernel configuration. */
  +    public static final String KERNEL_URL_KEY = s_keys[7] ;
  +    /** A temporary directory */
  +    public static final String TEMP_PATH_KEY = s_keys[8] ;
  +    /**
  +     * The key to the directory used as the base anchor for resolution of 
  +     * relative path references for jar extension library directory statements 
  +     * in classloader directives.
  +     */
  +    public static final String LIBRARY_PATH_KEY = s_keys[9] ;
  +    /** the remote repository proxy port */
  +    public static final String MERLIN_PROXY_HOST = s_keys[10] ;
  +    /** the remote repository proxy host */
  +    public static final String MERLIN_PROXY_PORT = s_keys[11] ;
  +    /** the remote repository proxy username if required */
  +    public static final String MERLIN_PROXY_USERNAME = s_keys[12] ;
  +    /** the remote repository proxy password if required */
  +    public static final String MERLIN_PROXY_PASSWORD = s_keys[13] ;
  +
  +    // ------------------------------------------------------------------------
  +    // Multivalued Kernel Configuration Property Bases
  +    // ------------------------------------------------------------------------
  +
  +    /** key base used for enumerating the remote repositories */
  +    public static final String REMOTE_REPO_KEYBASE =
  +        "merlin.repository.remote.url" ;
  +    /** key base used for enumerating block.xml file urls */
  +    public static final String BLOCK_URLS_KEYBASE =
  +        "merlin.kernel.blockurl" ;
  +
  +    // ------------------------------------------------------------------------
  +    // Misc. Constants
  +    // ------------------------------------------------------------------------
  +
  +    /** file name base for the Merlin default properties using in phase I */
       public static final String MERLIN_FILE_BASE =
           "merlin.properties" ;
       
  -    /** Overlay of default properties discovered */
  +    // ------------------------------------------------------------------------
  +    // Static Variables, Blocks and Functions
  +    // ------------------------------------------------------------------------
  +     
  +    /** Overlay of system wide default properties discovered */
       private static final Properties s_defaults = new Properties() ;
  -    
  -    
  +     
  +
  +    /*
  +     * Discover and cache defaults first then apply macro expansion right after 
  +     * this class is loaded into the VM.
  +     */
       static 
       {
  -        loadDefaults() ;
  +        discoverDefaults( s_defaults ) ;
  +        macroExpand( s_defaults, null ) ;
       }
       
  -    
       /**
  -     * Loads the defaults for the kernel configuration.  Not fail fast meaning
  -     * if it fails at one stage it continues to gather defaults rather than
  -     * bombing out. 
  +     * Discovers default values for the kernel configuration.  Not fail fast 
  +     * meaning if it fails at one stage it continues to gather defaults rather 
  +     * than bombing out.
  +     * 
  +     * Note that discovery does not entail macro expansion and that property 
  +     * value overrides downstream of a macro will overwrite macros before they
  +     * have a chance to expand.
  +     * 
  +     * @param a_props the Properties to populate with discovered defaults
        */
  -    private static void loadDefaults()
  +    private static void discoverDefaults( Properties a_props )
       {
  +        // --------------------------------------------------------------------
           //
           // Stage I - load the default properties bundled with this
           // jar under the resource name MERLIN_FILE_BASE.  This set the 
           // primative defaults.
           //
  +        // --------------------------------------------------------------------
           
           InputStream l_in = 
               KernelDefaults.class.getResourceAsStream( MERLIN_FILE_BASE ) ;
           
           try
           {
  -            s_defaults.load( l_in ) ;
  +            a_props.load( l_in ) ;
           }
           catch ( IOException e )
           {
  @@ -164,33 +227,51 @@
           }
           
           //
  +        // If no library path is defined and the user directory is unknown as
  +        // is the case in environments like a servlet container then we default
  +        // to the the first root within the file system.
  +        //
  +
  +        String l_userDir = System.getProperty( "user.dir" ) ;
  +        if ( null == l_userDir && null == getLibraryPath() )
  +        {
  +            File [] l_roots = File.listRoots() ; 
  +            l_userDir = l_roots[0].getAbsolutePath() ;
  +            a_props.setProperty( LIBRARY_PATH_KEY, l_userDir ) ;
  +        }        
  +        
  +        // --------------------------------------------------------------------
  +        //
           // Stage II - get some properties from the environment.
           //
  +        // --------------------------------------------------------------------
   
  -        File l_merlinHome = getMerlinHome();
  +        File l_merlinHome = getMerlinHome() ;
           
           if ( null != l_merlinHome && l_merlinHome.exists() )
           {    
               File l_sysRepo = new File( l_merlinHome, "system" ) ;
               if ( l_sysRepo.exists() )
               {    
  -                s_defaults.setProperty( SYSTEM_REPO_KEY, 
  +                a_props.setProperty( SYSTEM_REPO_KEY, 
                       l_sysRepo.getAbsolutePath() ) ;
               }
               
  -            File l_userRepo = getMerlinUserRepository( l_merlinHome );
  +            File l_applRepo = getMerlinApplicationRepository( l_merlinHome ) ;
   
  -            if ( l_userRepo.exists() )
  +            if ( l_applRepo.exists() )
               {
  -                s_defaults.setProperty( USER_REPO_KEY, 
  -                    l_userRepo.getAbsolutePath() ) ;
  +                a_props.setProperty( APPLICATION_REPO_KEY, 
  +                    l_applRepo.getAbsolutePath() ) ;
               }
           }
           
  +        // --------------------------------------------------------------------
           //
           // Stage III - check for overriding values of .merlin.properties within
           // the user's home directory.
           //
  +        // --------------------------------------------------------------------
   
           String l_userHome = System.getProperty( "user.home" ) ;
           File l_userProps = new File( l_userHome, "." + MERLIN_FILE_BASE ) ;
  @@ -198,7 +279,7 @@
           {
               try 
               {
  -                s_defaults.load( new FileInputStream( l_userProps ) ) ;
  +                a_props.load( new FileInputStream( l_userProps ) ) ;
               }
               catch ( IOException e )
               {
  @@ -206,21 +287,23 @@
               }
           }
           
  +        // --------------------------------------------------------------------
           //
           // Stage IV - Check for overriding values within the System properties.
           //
  +        // --------------------------------------------------------------------
   
           for( int ii = 0; ii < s_keys.length; ii++ )
           {
               /*
  -             * If s_defaults has the property use it as default in case property
  +             * If a_props has the property use it as default in case property
                * does not exist in the system properties.
                */
               String l_default = System.getProperty( s_keys[ii], 
  -                    s_defaults.getProperty( s_keys[ii] ) ) ;
  +                    a_props.getProperty( s_keys[ii] ) ) ;
               if ( null != l_default )
               {    
  -                s_defaults.setProperty( s_keys[ii], l_default ) ;
  +                a_props.setProperty( s_keys[ii], l_default ) ;
               }
           }
   
  @@ -232,14 +315,34 @@
           while ( l_list.hasMoreElements() )
           {
               String l_key = ( String ) l_list.nextElement() ;
  -            if ( l_key.startsWith( BLOCK_URLS_BASE ) )
  +            if ( l_key.startsWith( BLOCK_URLS_KEYBASE ) )
  +            {
  +                String l_default = System.getProperty( l_key,
  +                        a_props.getProperty( l_key ) ) ;
  +                
  +                if ( null != l_default )
  +                {
  +                    a_props.setProperty( l_key, l_default ) ;
  +                }
  +            }
  +        }
  +
  +        //
  +        // Now we overlay all the remote repo url properties defined
  +        //
  +
  +        l_list = System.getProperties().keys() ;
  +        while ( l_list.hasMoreElements() )
  +        {
  +            String l_key = ( String ) l_list.nextElement() ;
  +            if ( l_key.startsWith( REMOTE_REPO_KEYBASE ) )
               {
                   String l_default = System.getProperty( l_key,
  -                        s_defaults.getProperty( l_key ) ) ;
  +                        a_props.getProperty( l_key ) ) ;
                   
                   if ( null != l_default )
                   {
  -                    s_defaults.setProperty( l_key, l_default ) ;
  +                    a_props.setProperty( l_key, l_default ) ;
                   }
               }
           }
  @@ -247,6 +350,83 @@
   
       
       /**
  +     * Expands out a set of property key macros in the following format 
  +     * ${foo.bar} where foo.bar is a property key, by dereferencing the value 
  +     * of the key using the original source Properties and other optional 
  +     * Properties.
  +     * 
  +     * If the original expanded Properties contain the value for the macro key 
  +     * foo.bar then dereferencing stops by using the value in the expanded 
  +     * Properties: the other optional Properties are NOT used at all.
  +     * 
  +     * If the original expanded Properties do NOT contain the value for the 
  +     * macro key, then the optional Properties are used in order.  The first of
  +     * the optionals to contain the value for the macro key (foo.bar) shorts the
  +     * search.  Hence the first optional Properties in the array to contain a 
  +     * value for the macro key (foo.bar) is used to set the expanded value.
  +     * 
  +     * If a macro cannot be expanded because it's key was not defined within the 
  +     * expanded Properties or one of the optional Properties then it is left as
  +     * is.
  +     * 
  +     * @param a_expanded the Properties to perform the macro expansion upon
  +     * @param a_optionals null or an optional set of Properties to use for 
  +     * dereferencing macro keys (foo.bar)
  +     */
  +    public static void macroExpand( Properties a_expanded, 
  +                                    Properties [] a_optionals )
  +    {
  +        // Handle null optionals
  +        if ( null == a_optionals )
  +        {
  +            a_optionals = new Properties [ 0 ] ;
  +        }
  +        
  +        Enumeration l_list = a_expanded.propertyNames() ;
  +        while ( l_list.hasMoreElements() )
  +        {
  +            String l_key = ( String ) l_list.nextElement() ;
  +            String l_macro = a_expanded.getProperty( l_key ) ;
  +            
  +            /*
  +             * Skip all regular properties that are not macros: used de Morgans
  +             * to convert ! l_key.startsWith( "${" ) && l_key.endsWith( "}" )
  +             * to conditional below since it is faster.
  +             */
  +            if ( ! l_macro.startsWith( "${" ) || ! l_macro.endsWith( "}" ) )
  +            {
  +                continue ;
  +            }
  +            
  +            /*
  +             * Check if the macro key exists within the expanded Properties. If
  +             * so we continue onto the next macro skipping the optional props.
  +             */
  +            String l_macroKey = l_macro.substring( 2, l_macro.length() - 1 ) ;
  +            if ( a_expanded.containsKey( l_macroKey ) )
  +            {
  +                a_expanded.put( l_key, a_expanded.getProperty( l_macroKey ) ) ;
  +                continue ;
  +            }
  +            
  +            /*
  +             * Check if the macro key exists within the array of optional 
  +             * Properties.  Set expanded value to first Properties with the 
  +             * key and break out of the loop.
  +             */
  +            for ( int ii = 0; ii < a_optionals.length; ii++ )
  +            {
  +                if ( a_optionals[ii].containsKey( l_macroKey ) )
  +                {
  +                    String l_value = a_optionals[ii].getProperty( l_macroKey ) ;
  +                    a_expanded.put( l_key, l_value ) ;
  +                    break ;
  +                }
  +            }
  +        }
  +    }
  +    
  +    /**
        * Gets a default value for the server flag property for the KernelConfig.
        * 
        * @return true if the IS_SERVER_KEY property value is set to 1, true, yes 
  @@ -296,7 +476,7 @@
           while ( l_list.hasMoreElements() )
           {
               String l_key = ( String ) l_list.nextElement() ;
  -            if ( l_key.startsWith( REMOTE_REPO_KEY ) )
  +            if ( l_key.startsWith( REMOTE_REPO_KEYBASE ) )
               {
                   l_urlArray.add( s_defaults.getProperty( l_key ) ) ;
               }
  @@ -306,14 +486,14 @@
   
       
       /**
  -     * Gets the default value for the user repository path.
  +     * Gets the default value for the application repository path.
        *  
        * @see org.apache.avalon.merlin.kernel.KernelConfig#
  -     * getUserRepositoryPath()
  +     * getApplicationRepositoryPath()
        */
  -    public static String getUserRepositoryPath()
  +    public static String getApplicationRepositoryPath()
       {
  -        return s_defaults.getProperty( USER_REPO_KEY ) ;
  +        return s_defaults.getProperty( APPLICATION_REPO_KEY ) ;
       }
   
       
  @@ -389,7 +569,7 @@
           while ( l_list.hasMoreElements() )
           {
               String l_key = ( String ) l_list.nextElement() ;
  -            if ( l_key.startsWith( BLOCK_URLS_BASE ) )
  +            if ( l_key.startsWith( BLOCK_URLS_KEYBASE ) )
               {
                   l_urlArray.add( s_defaults.getProperty( l_key ) ) ;
               }
  @@ -408,8 +588,42 @@
       {
           return s_defaults.getProperty( KERNEL_URL_KEY ) ;
       }
  -
       
  +    /**
  +     * Creates and returns a new ProxyContext every time using default property
  +     * settings.  If criticial proxy parameters are not set then null is 
  +     * returned.
  +     * 
  +     * @return null if defaults do not exist or a ProxyContext representing 
  +     * default values
  +     */
  +    public static ProxyContext getProxyContext()
  +    {
  +        String l_host = s_defaults.getProperty( MERLIN_PROXY_HOST ) ;
  +        String l_port = s_defaults.getProperty( MERLIN_PROXY_PORT ) ;
  +        
  +        if ( null == l_host || null == l_port )
  +        {
  +            return null ;
  +        }
  +        
  +        Authenticator l_authenticator = new Authenticator()
  +        {
  +            protected PasswordAuthentication getPasswordAuthentication()
  +            {
  +                PasswordAuthentication l_pwdAuth = new PasswordAuthentication(
  +                    s_defaults.getProperty( MERLIN_PROXY_USERNAME ),
  +                    s_defaults.getProperty( MERLIN_PROXY_PASSWORD )
  +                        .toCharArray() ) ;
  +                return l_pwdAuth ;
  +            }
  +        } ;
  +        
  +        ProxyContext l_ctx = new ProxyContext( l_host, Integer.parseInt( 
  +            s_defaults.getProperty( MERLIN_PROXY_PORT ) ), l_authenticator ) ;
  +        return l_ctx ;
  +    }
  +
       // ------------------------------------------------------------------------
       // Private Utility Methods
       // ------------------------------------------------------------------------
  @@ -438,6 +652,7 @@
           return false ;
       }
   
  +
      /**
       * Return the default value of the merlin installation home. The 
       * value returned corresponds to the environment variable MERLIN_HOME.
  @@ -464,7 +679,7 @@
                   }
                   else
                   {
  -                    return null;
  +                    return null ;
                   }
               }
           }
  @@ -476,12 +691,12 @@
       }
   
      /**
  -    * Return the default value of the merlin local user repository. The 
  +    * Return the default value of the merlin local application repository. The 
       * value returned corresponds to the environment variable MERLIN_REPO_LOCAL.
       * If the env variable is undefined, return ${merlin.home}/repository
       * @return the default merlin local user repository path
       */ 
  -    private static File getMerlinUserRepository( File home )
  +    private static File getMerlinApplicationRepository( File home )
       {
           try 
           {
  @@ -492,13 +707,13 @@
               }
               else
               {
  -                return new File( home, "repository" );
  +                return new File( home, "repository" ) ;
               }
           }
           catch( EnvAccessException e )
           {
               e.printStackTrace( System.err ) ;
  -            return null;
  +            return null ;
           }
       }
   }
  
  
  
  1.3       +7 -7      avalon/merlin/kernel/loader/src/java/org/apache/avalon/merlin/merlin.properties
  
  Index: merlin.properties
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/kernel/loader/src/java/org/apache/avalon/merlin/merlin.properties,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- merlin.properties	28 Oct 2003 10:34:26 -0000	1.2
  +++ merlin.properties	30 Oct 2003 22:00:38 -0000	1.3
  @@ -12,29 +12,29 @@
   
   #
   # A comma seperated list of urls to remote repositories.
  -#merlin.repository.remote.urls
  +#merlin.repository.remote.urls=
   
   #
   # The user repository path - defaults to ${merlin.home}/repository
  -#merlin.repository.user.path
  +#merlin.repository.application.path=
   
   #
   # The system repository path - defaults to ${merlin.home}/system
  -#merlin.repository.system.path
  +#merlin.repository.system.path=
   
   #
   # The working directory path - defaults to ${user.dir}
  -#merlin.work.path
  +#merlin.work.path=
   
   #
   # URL to a configuration override - no default
  -#merlin.config.url
  +#merlin.config.url=
   
   #
   # URL to the kernel defintion - defaults to ${merlin.home}/config/kernel.xml
  -merlin.kernel.url
  +merlin.kernel.url=
   
   #
   # Path to the library anchor directory - defaults to ${user.dir}
  -#merlin.library.path
  +#merlin.library.path=
   
  
  
  
  1.3       +36 -34    avalon/merlin/kernel/loader/src/java/org/apache/avalon/merlin/env/Env.java
  
  Index: Env.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/kernel/loader/src/java/org/apache/avalon/merlin/env/Env.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Env.java	29 Oct 2003 22:37:54 -0000	1.2
  +++ Env.java	30 Oct 2003 22:00:38 -0000	1.3
  @@ -135,41 +135,40 @@
           throws EnvAccessException
       {
           File l_etcpasswd = new File( "/etc/passwd" ) ;
  -    
  -        if ( l_etcpasswd.exists() && l_etcpasswd.canRead() )
  +    	  if ( l_etcpasswd.exists() && l_etcpasswd.canRead() )
           {
               String l_username = System.getProperty( "user.name" ) ;
               BufferedReader l_in = null ;
       
  -            try 
  -            {
  -                String l_entry = null ;
  -                l_in = new BufferedReader( new FileReader( l_etcpasswd ) ) ;
  +    	      try 
  +    	      {
  +        		String l_entry = null ;
  +        		l_in = new BufferedReader( new FileReader( l_etcpasswd ) ) ;
           
  -                while( null != ( l_entry = l_in.readLine() ) )
  -                {
  -                    // Skip entries other than the one for this username
  -                    if ( ! l_entry.startsWith( l_username ) ) 
  -                    {
  -                        continue ;
  -                    }
  +        		while( null != ( l_entry = l_in.readLine() ) )
  +        		{
  +        		    // Skip entries other than the one for this username
  +        		    if ( ! l_entry.startsWith( l_username ) ) 
  +        		    {
  +        		        continue ;
  +        		    }
           
  -                    // Get the shell part of the passwd entry
  -                    int l_index = l_entry.lastIndexOf( ':' ) ;
  -                    if ( l_index == -1 )
  -                    {
  -                        throw new EnvAccessException( a_varName,
  -                            "/etc/passwd contains malformed user entry for " 
  -                            + l_username ) ;
  -                    }
  +        		    // Get the shell part of the passwd entry
  +        		    int l_index = l_entry.lastIndexOf( ':' ) ;
  +        		    if ( l_index == -1 )
  +        		    {
  +            			throw new EnvAccessException( a_varName,
  +            			    "/etc/passwd contains malformed user entry for " 
  +            			    + l_username ) ;
  +        		    }
           
  -                    return l_entry.substring( l_index + 1 ) ;
  -                }
  -            } 
  -            catch ( IOException e )
  -            {
  -                throw new EnvAccessException( a_varName, e ) ;
  -            }
  +        		    return l_entry.substring( l_index + 1 ) ;
  +        		}
  +    	      } 
  +    	      catch ( IOException e )
  +    	      {
  +    	          throw new EnvAccessException( a_varName, e ) ;
  +    	      }
       
               throw new EnvAccessException( a_varName, "User " + l_username 
                       + " does not seem to exist in /etc/passwd" ) ;
  @@ -180,8 +179,10 @@
       }
   
       /**
  -     * Gets a UNIX shell environment parameter by forking a call to echo. This
  -     * should work on all UNIX shells like sh, ksh, csh, zsh and bash.
  +     * Gets a UNIX shell environment parameter by forking the user's default 
  +     * shell based on /etc/passwd and running echo on the environment variable
  +     * within the shell.  This should work on all UNIX shells like sh, ksh, csh,
  +     * zsh and bash accross all the supported platforms.
        * 
        * @param a_name the name of the variable accessed
        * @return the value of the variable 
  @@ -248,6 +249,7 @@
               }
           }
           
  +        // Check that we exited normally before returning an invalid output
           if ( 0 == l_proc.exitValue() )
           {
               // Handle situations where the env property does not exist.
  
  
  
  1.2       +3 -2      avalon/merlin/kernel/loader/src/test/org/apache/avalon/merlin/env/EnvTest.java
  
  Index: EnvTest.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/kernel/loader/src/test/org/apache/avalon/merlin/env/EnvTest.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- EnvTest.java	27 Oct 2003 23:50:47 -0000	1.1
  +++ EnvTest.java	30 Oct 2003 22:00:38 -0000	1.2
  @@ -54,6 +54,7 @@
           EnvAccessException l_error = null ;
           try 
           {
  +            // All shells and their echo's will freak out when they see this
               Env.getVariable( "--*&^%^%$" ) ;
           }
           catch( EnvAccessException e )
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org