ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From adammurd...@apache.org
Subject cvs commit: jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/workspace PropertyResolver.java
Date Sat, 09 Mar 2002 02:04:26 GMT
adammurdoch    02/03/08 18:04:26

  Modified:    proposal/myrmidon/src/testcases/org/apache/myrmidon/components
                        AbstractComponentTest.java
               proposal/myrmidon/src/java/org/apache/antlib/file
                        Delete.java
               proposal/myrmidon/src/java/org/apache/aut/bzip2
                        CBZip2InputStream.java
               proposal/myrmidon/src/java/org/apache/aut/tar
                        TarOutputStream.java
               proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor
                        DefaultEmbeddor.java
               proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace
                        DefaultTaskContext.java Resources.properties
  Added:       proposal/myrmidon/src/testcases/org/apache/myrmidon/components/workspace
                        ClassicPropertyResolverTest.java
                        DefaultPropertyResolverTest.java
               proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace
                        ClassicPropertyResolver.java
                        DefaultPropertyResolver.java
               proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/workspace
                        PropertyResolver.java
  Removed:     proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace
                        PropertyUtil.java
  Log:
  * Added PropertyResolver service interface, together with 2 implementations.
    (One implementation mimics Ant1 behaviour). These are added in the
    "workspace" packages, since that's where PropertyUtil was. Not sure if this
    is the right place.
  * DefaultTaskContext now implements Context interface, used by
    PropertyResolver. This avoids having the PropertyResolver dependent on
    TaskContext, avoiding a potential circularity problem. (since TaskContext has
    a "resolve" method of it's own).
  * Removed PropertyUtil.
  * Tests for PropertyResolver implementations.
  
  Submitted by Darrell DeBoer [darrell@apache.org]
  
  Revision  Changes    Path
  1.12      +6 -0      jakarta-ant/proposal/myrmidon/src/testcases/org/apache/myrmidon/components/AbstractComponentTest.java
  
  Index: AbstractComponentTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/testcases/org/apache/myrmidon/components/AbstractComponentTest.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- AbstractComponentTest.java	6 Mar 2002 10:09:10 -0000	1.11
  +++ AbstractComponentTest.java	9 Mar 2002 02:04:25 -0000	1.12
  @@ -27,6 +27,7 @@
   import org.apache.myrmidon.components.extensions.DefaultExtensionManager;
   import org.apache.myrmidon.components.role.DefaultRoleManager;
   import org.apache.myrmidon.components.type.DefaultTypeManager;
  +import org.apache.myrmidon.components.workspace.DefaultPropertyResolver;
   import org.apache.myrmidon.interfaces.configurer.Configurer;
   import org.apache.myrmidon.interfaces.converter.ConverterRegistry;
   import org.apache.myrmidon.interfaces.deployer.Deployer;
  @@ -36,6 +37,7 @@
   import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;
   import org.apache.myrmidon.interfaces.type.TypeException;
   import org.apache.myrmidon.interfaces.type.TypeManager;
  +import org.apache.myrmidon.interfaces.workspace.PropertyResolver;
   
   /**
    * A base class for tests for the default components.
  @@ -118,6 +120,10 @@
   
           component = new DefaultRoleManager();
           m_serviceManager.put( RoleManager.ROLE, component );
  +        components.add( component );
  +
  +        component = new DefaultPropertyResolver();
  +        m_serviceManager.put( PropertyResolver.ROLE, component );
           components.add( component );
   
           // Log enable the components
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/testcases/org/apache/myrmidon/components/workspace/ClassicPropertyResolverTest.java
  
  Index: ClassicPropertyResolverTest.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 org.apache.myrmidon.components.workspace;
  
  import org.apache.myrmidon.interfaces.workspace.PropertyResolver;
  
  /**
   * A test for {@link ClassicPropertyResolver}
   *
   * @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a>
   * @version $Revision: 1.1 $ $Date: 2002/03/09 02:04:25 $
   */
  public class ClassicPropertyResolverTest
      extends DefaultPropertyResolverTest
  {
      public ClassicPropertyResolverTest( String name )
      {
          super( name );
      }
  
      protected PropertyResolver createResolver()
      {
          return new ClassicPropertyResolver();
      }
  
      /**
       * Tests handing undefined property.
       */
      public void testUndefinedProp() throws Exception
      {
          String undefinedProp = "undefinedProperty";
  
          final String propRef = "${" + undefinedProp + "}";
          doTestResolution( propRef, propRef, m_context );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/testcases/org/apache/myrmidon/components/workspace/DefaultPropertyResolverTest.java
  
  Index: DefaultPropertyResolverTest.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 org.apache.myrmidon.components.workspace;
  
  import java.io.File;
  import java.util.Date;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.context.Context;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.components.AbstractComponentTest;
  import org.apache.myrmidon.interfaces.workspace.PropertyResolver;
  
  /**
   * Functional tests for {@link DefaultPropertyResolver}.
   *
   * @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a>
   * @version $Revision: 1.1 $ $Date: 2002/03/09 02:04:25 $
   */
  public class DefaultPropertyResolverTest
      extends AbstractComponentTest
  {
      protected final static Resources REZ
          = ResourceManager.getPackageResources( DefaultPropertyResolver.class );
  
      protected PropertyResolver m_resolver;
      protected DefaultTaskContext m_context;
  
      public DefaultPropertyResolverTest( String name )
      {
          super( name );
      }
  
      protected void setUp() throws Exception
      {
          super.setUp();
  
          m_resolver = createResolver();
  
          m_context = new DefaultTaskContext( null, getServiceManager(), getLogger() );
          m_context.setProperty( "intProp", new Integer( 333 ) );
          m_context.setProperty( "stringProp", "String property" );
      }
  
      protected PropertyResolver createResolver()
      {
          return new DefaultPropertyResolver();
      }
  
      /**
       * Test property resolution with various different typed properties.
       */
      public void testPropertyTypes() throws Exception
      {
          testPropertyValue( new String( "String value" ) );
          testPropertyValue( new Date() );
          testPropertyValue( new Integer( Integer.MIN_VALUE ) );
          testPropertyValue( new Double( 24234.98453 ) );
          testPropertyValue( this.getClass() );
          testPropertyValue( File.createTempFile( "PropertyResolverTest", null ) );
      }
  
      /**
       * Simple tests with property on it's own, and accompanied by text.
       */
      private void testPropertyValue( Object propObject )
          throws Exception
      {
          m_context.setProperty( "typedProp", propObject );
          String propString = propObject.toString();
  
          doTestResolution( "${typedProp}", propObject, m_context );
          doTestResolution( "${typedProp} with following text",
                            propString + " with following text", m_context );
          doTestResolution( "Preceding text with ${typedProp}",
                            "Preceding text with " + propString, m_context );
      }
  
      /**
       * Tests multiple property declarations in a single value.
       */
      public void testMultipleProperties() throws Exception
      {
          m_context.setProperty( "prop1", "value1" );
          m_context.setProperty( "prop2", "value2" );
          m_context.setProperty( "int1", new Integer( 123 ) );
  
          doTestResolution( "${prop1}${prop2}", "value1value2", m_context );
          doTestResolution( "${prop1}${prop1}${prop1}", "value1value1value1", m_context );
          doTestResolution( "before ${prop2} between ${prop1} after",
                            "before value2 between value1 after", m_context );
          doTestResolution( "${prop1}-${int1}-${prop2}", "value1-123-value2", m_context );
  
      }
  
      /**
       * Tests handing undefined property.
       */
      public void testUndefinedProp() throws Exception
      {
          String undefinedProp = "undefinedProperty";
          doTestFailure( "${" + undefinedProp + "}",
                         REZ.getString( "prop.missing-value.error", undefinedProp ),
                         m_context );
  
          //TODO - "" should be disallowed as a property name
          doTestFailure( "${}",
                         REZ.getString( "prop.missing-value.error", "" ),
                         m_context );
      }
  
      /**
       * Tests illegal property syntax.
       */
      public void testInvalidTypeDeclarations() throws Exception
      {
  
          doTestFailure( "${unclosed",
                         REZ.getString( "prop.mismatched-braces.error" ),
                         m_context );
          doTestFailure( "${",
                         REZ.getString( "prop.mismatched-braces.error" ),
                         m_context );
  
          /* TODO - need to handle these cases. */
          //        testFailure( "${bad${}", "", m_context );
          //        testFailure( "${ }", "", m_context );
  
      }
  
      /**
       * Resolves the property using the supplied context, and checks the result.
       */
      protected void doTestResolution( String value,
                                       Object expected,
                                       Context context )
          throws Exception
      {
          Object resolved = m_resolver.resolveProperties( value, context );
  
          assertEquals( expected, resolved );
      }
  
      /**
       * Attempts to resolve the value using the supplied context, expecting to
       * fail with the supplied error message.
       */
      protected void doTestFailure( String value,
                                    String expectedErrorMessage,
                                    Context context )
      {
          try
          {
              m_resolver.resolveProperties( value, context );
              fail( "Unexpected sucess - test should have failed." );
          }
          catch( TaskException e )
          {
              assertSameMessage( expectedErrorMessage, e );
          }
      }
  }
  
  
  
  1.3       +2 -2      jakarta-ant/proposal/myrmidon/src/java/org/apache/antlib/file/Delete.java
  
  Index: Delete.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/antlib/file/Delete.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Delete.java	3 Feb 2002 10:29:06 -0000	1.2
  +++ Delete.java	9 Mar 2002 02:04:26 -0000	1.3
  @@ -26,7 +26,7 @@
    * @author <a href="mailto:tad1@cornell.edu">Tom Dimock</a>
    * @author <a href="mailto:glennm@ca.ibm.com">Glenn McAllister</a>
    * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
  - * @version $Revision: 1.2 $ $Date: 2002/02/03 10:29:06 $
  + * @version $Revision: 1.3 $ $Date: 2002/03/09 02:04:26 $
    */
   public class Delete
       extends AbstractTask
  @@ -237,4 +237,4 @@
               }
           }
       }
  -}
  \ No newline at end of file
  +}
  
  
  
  1.5       +1 -1      jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/bzip2/CBZip2InputStream.java
  
  Index: CBZip2InputStream.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/bzip2/CBZip2InputStream.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- CBZip2InputStream.java	6 Feb 2002 13:34:45 -0000	1.4
  +++ CBZip2InputStream.java	9 Mar 2002 02:04:26 -0000	1.5
  @@ -958,4 +958,4 @@
               }
           }
       }
  -}
  \ No newline at end of file
  +}
  
  
  
  1.3       +1 -1      jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/tar/TarOutputStream.java
  
  Index: TarOutputStream.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/tar/TarOutputStream.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TarOutputStream.java	27 Jan 2002 01:24:59 -0000	1.2
  +++ TarOutputStream.java	9 Mar 2002 02:04:26 -0000	1.3
  @@ -338,4 +338,4 @@
   
           m_buffer.writeRecord( m_recordBuf );
       }
  -}
  \ No newline at end of file
  +}
  
  
  
  1.31      +3 -1      jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java
  
  Index: DefaultEmbeddor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/embeddor/DefaultEmbeddor.java,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- DefaultEmbeddor.java	25 Feb 2002 10:42:43 -0000	1.30
  +++ DefaultEmbeddor.java	9 Mar 2002 02:04:26 -0000	1.31
  @@ -41,6 +41,7 @@
   import org.apache.myrmidon.interfaces.service.MultiSourceServiceManager;
   import org.apache.myrmidon.interfaces.type.TypeFactory;
   import org.apache.myrmidon.interfaces.type.TypeManager;
  +import org.apache.myrmidon.interfaces.workspace.PropertyResolver;
   import org.apache.myrmidon.interfaces.workspace.Workspace;
   import org.apache.myrmidon.listeners.ProjectListener;
   
  @@ -49,7 +50,7 @@
    * Instantiate this to embed inside other applications.
    *
    * @author <a href="mailto:peter@apache.org">Peter Donald</a>
  - * @version $Revision: 1.30 $ $Date: 2002/02/25 10:42:43 $
  + * @version $Revision: 1.31 $ $Date: 2002/03/09 02:04:26 $
    */
   public class DefaultEmbeddor
       extends AbstractLogEnabled
  @@ -254,6 +255,7 @@
           createComponent( Deployer.class, PREFIX + "deployer.DefaultDeployer" );
           createComponent( ClassLoaderManager.class, PREFIX + "deployer.DefaultClassLoaderManager"
);
           createComponent( Executor.class, PREFIX + "executor.AspectAwareExecutor" );
  +        createComponent( PropertyResolver.class, PREFIX + "workspace.DefaultPropertyResolver"
);
   
           // Setup the components
           for( Iterator iterator = m_components.iterator(); iterator.hasNext(); )
  
  
  
  1.19      +36 -6     jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultTaskContext.java
  
  Index: DefaultTaskContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultTaskContext.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- DefaultTaskContext.java	6 Mar 2002 10:09:45 -0000	1.18
  +++ DefaultTaskContext.java	9 Mar 2002 02:04:26 -0000	1.19
  @@ -13,20 +13,23 @@
   import org.apache.avalon.excalibur.i18n.ResourceManager;
   import org.apache.avalon.excalibur.i18n.Resources;
   import org.apache.avalon.excalibur.io.FileUtil;
  +import org.apache.avalon.framework.context.Context;
  +import org.apache.avalon.framework.context.ContextException;
   import org.apache.avalon.framework.logger.Logger;
   import org.apache.avalon.framework.service.ServiceException;
   import org.apache.avalon.framework.service.ServiceManager;
   import org.apache.myrmidon.api.TaskContext;
   import org.apache.myrmidon.api.TaskException;
  +import org.apache.myrmidon.interfaces.workspace.PropertyResolver;
   
   /**
    * Default implementation of TaskContext.
    *
    * @author <a href="mailto:peter@apache.org">Peter Donald</a>
  - * @version $Revision: 1.18 $ $Date: 2002/03/06 10:09:45 $
  + * @version $Revision: 1.19 $ $Date: 2002/03/09 02:04:26 $
    */
   public class DefaultTaskContext
  -    implements TaskContext
  +    implements TaskContext, Context
   {
       private final static Resources REZ =
           ResourceManager.getPackageResources( DefaultTaskContext.class );
  @@ -35,6 +38,7 @@
       private final TaskContext m_parent;
       private ServiceManager m_serviceManager;
       private Logger m_logger;
  +    private PropertyResolver m_propertyResolver;
   
       /**
        * Constructor that takes both parent context and a service directory.
  @@ -55,7 +59,7 @@
        */
       public String getName()
       {
  -        return (String)m_contextData.get( NAME );
  +        return (String)getProperty( NAME );
       }
   
       /**
  @@ -65,7 +69,7 @@
        */
       public File getBaseDirectory()
       {
  -        return (File)m_contextData.get( BASE_DIRECTORY );
  +        return (File)getProperty( BASE_DIRECTORY );
       }
   
       /**
  @@ -133,10 +137,17 @@
       public Object resolveValue( final String value )
           throws TaskException
       {
  +
           try
           {
  +            // Lazy lookup of the PropertyResolver
  +            if( m_propertyResolver == null )
  +            {
  +                m_propertyResolver = (PropertyResolver)getService( PropertyResolver.class
);
  +            }
  +
               final Object object =
  -                PropertyUtil.resolveProperty( value, this, false );
  +                m_propertyResolver.resolveProperties( value, this );
   
               if( null == object )
               {
  @@ -161,7 +172,12 @@
        */
       public Object getProperty( final String name )
       {
  -        return m_contextData.get( name );
  +        Object value = m_contextData.get( name );
  +        if( value == null && m_parent != null )
  +        {
  +            value = m_parent.getProperty( name );
  +        }
  +        return value;
       }
   
       /**
  @@ -330,6 +346,20 @@
           context.setProperty( TaskContext.BASE_DIRECTORY, getBaseDirectory() );
   
           return context;
  +    }
  +
  +    /**
  +     * Returns a property.
  +     */
  +    public Object get( final Object key ) throws ContextException
  +    {
  +        final Object value = getProperty( (String)key );
  +        if( value == null )
  +        {
  +            final String message = REZ.getString( "unknown-property.error", key );
  +            throw new ContextException( message );
  +        }
  +        return value;
       }
   
       /**
  
  
  
  1.8       +2 -6      jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/Resources.properties,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Resources.properties	25 Feb 2002 10:42:44 -0000	1.7
  +++ Resources.properties	9 Mar 2002 02:04:26 -0000	1.8
  @@ -11,17 +11,13 @@
   exec-task.notice=Executing task {0}.
   
   #DefaultTaskContext
  -no-version.error=No JavaVersion in Context.
  -no-name.error=No Name in Context.
  -no-dir.error=No Base Directory in Context.
  -no-parent.error=Can't set a property with parent scope when context has no parent.
  -bad-scope.error=Unknown property scope! ({0}).
  +unknown-prop.error=Unknown property {0}.
   bad-property.error=Property {0} must have a value of type {1}.
   null-resolved-value.error=Value "{0}" resolved to null.
   bad-resolve.error=Unable to resolve value "{0}".
   bad-find-service.error=Could not find service "{0}".
   bad-service-class.error=Find service "{0}" but it was of type {1} where it was expected
to be of type {2}.
   
  -#PropertyUtil
  +#AbstractPropertyResolver
   prop.mismatched-braces.error=Malformed property with mismatched }'s.
   prop.missing-value.error=Unable to find "{0}" to expand during property resolution.
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/ClassicPropertyResolver.java
  
  Index: ClassicPropertyResolver.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 org.apache.myrmidon.components.workspace;
  
  import org.apache.myrmidon.interfaces.workspace.PropertyResolver;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.context.ContextException;
  
  /**
   * A {@link PropertyResolver} implementation which resolves properties
   * as per Ant1, ignoring undefined properties.
   *
   * @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a>
   * @version $Revision: 1.1 $ $Date: 2002/03/09 02:04:26 $
   */
  public class ClassicPropertyResolver
      extends DefaultPropertyResolver
      implements PropertyResolver
  {
      /**
       * Retrieve a value from the specified context using the specified key.
       * If there is no such value, returns the original property reference.
       *
       * @param propertyName the name of the property to retrieve
       * @param context the set of known properties
       */
      protected Object getPropertyValue( final String propertyName,
                                         final Context context )
      {
          try
          {
              return context.get( propertyName );
          }
          catch( ContextException e )
          {
              return "${" + propertyName + "}";
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultPropertyResolver.java
  
  Index: DefaultPropertyResolver.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 org.apache.myrmidon.components.workspace;
  
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.context.ContextException;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.interfaces.workspace.PropertyResolver;
  
  /**
   * Base class for PropertyResolver implementations.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a>
   * @version $Revision: 1.1 $ $Date: 2002/03/09 02:04:26 $
   */
  public class DefaultPropertyResolver
      implements PropertyResolver
  {
      private final static Resources REZ =
          ResourceManager.getPackageResources( DefaultPropertyResolver.class );
  
      /**
       * Resolve a string property. This evaluates all property
       * substitutions based on specified context.
       *
       * If the content contains a single property reference, then the property value
       * <code>Object</code> itself is returned.
       * Otherwise, a <code>String</code> is returned, comprising the supplied
       * content, with all property references replaced with the result of
       * <code>toString()</code> called on the property value.
       *
       * @param content the property to resolve
       * @param context the context in which to resolve property
       * @return the reolved property
       * @exception TaskException if an error occurs
       */
      public Object resolveProperties( final String content,
                                       final Context context )
          throws TaskException
      {
          int start = findNextProperty( content, 0 );
          if( -1 == start )
          {
              return content;
          }
  
          int end = findEnding( content, start );
  
          final int length = content.length();
  
          if( 0 == start && end == ( length - 1 ) )
          {
              return getPropertyValue( content.substring( start + 2, end ),
                                       context );
          }
  
          final StringBuffer sb = new StringBuffer( length * 2 );
          int lastPlace = 0;
  
          while( true )
          {
              final Object propertyValue =
                  getPropertyValue( content.substring( start + 2, end ),
                                    context );
  
              sb.append( content.substring( lastPlace, start ) );
              sb.append( propertyValue );
  
              lastPlace = end + 1;
  
              start = findNextProperty( content, lastPlace );
              if( -1 == start )
              {
                  break;
              }
  
              end = findEnding( content, start );
          }
  
          sb.append( content.substring( lastPlace, length ) );
  
          return sb.toString();
      }
  
      /**
       * Resolve a string property. This recursively evaluates all property
       * substitutions based on specified context.
       *
       * @param content the property to resolve
       * @param context the context in which to resolve property
       * @return the reolved property
       * @exception TaskException if an error occurs
       */
      protected Object recursiveResolveProperty( final String content,
                                                 final Context context )
          throws TaskException
      {
          int start = findNextProperty( content, 0 );
          if( -1 == start )
          {
              return content;
          }
  
          int end = findNestedEnding( content, start );
  
          final int length = content.length();
  
          if( 0 == start && end == ( length - 1 ) )
          {
              final String propertyName = content.substring( start + 2, end );
              final Object key = recursiveResolveProperty( propertyName, context );
              return getPropertyValue( key.toString(), context );
          }
  
          final StringBuffer sb = new StringBuffer( length * 2 );
  
          int lastPlace = 0;
  
          while( true )
          {
              final String propertyName = content.substring( start + 2, end );
              final Object key = recursiveResolveProperty( propertyName, context );
              final Object value = getPropertyValue( key.toString(), context );
  
              sb.append( content.substring( lastPlace, start ) );
              sb.append( value );
  
              lastPlace = end + 1;
  
              start = findNextProperty( content, lastPlace );
              if( -1 == start )
              {
                  break;
              }
  
              end = findNestedEnding( content, start );
          }
  
          sb.append( content.substring( lastPlace, length ) );
  
          return sb.toString();
      }
  
      /**
       * Finds the next occurrance of the start of a Property identifier.
       * @param content the String to search
       * @param currentPosition start location of the search
       * @return the position of the next occurrence, or <code>-1</code> if none
       *          was found.
       */
      private int findNextProperty( final String content, final int currentPosition )
      {
          //TODO: Check if it is commented out
          return content.indexOf( "${", currentPosition );
      }
  
      /**
       * Finds the next occurrence of the end of a Property identifier.
       * @param property the String to search
       * @param currentPosition start location of the search
       * @return the position of the next occurrence
       * @throws TaskException if no end was found
       */
      private int findEnding( final String property, final int currentPosition )
          throws TaskException
      {
          //TODO: Check if it is commented out
          final int index = property.indexOf( '}', currentPosition );
          if( -1 == index )
          {
              final String message = REZ.getString( "prop.mismatched-braces.error" );
              throw new TaskException( message );
          }
  
          return index;
      }
  
      /**
       * Finds the end of the property identifier at the currentPosition,
       * taking into account nested property identifiers.
       * @param property the String to search
       * @param currentPosition location of the property
       * @return the position of the propery ending.
       * @throws TaskException if the property is not properly ended.
       */
      private int findNestedEnding( final String property, final int currentPosition )
          throws TaskException
      {
          final int length = property.length();
          final int start = currentPosition + 2;
  
          int weight = 1;
          for( int i = start; ( weight > 0 ) && ( i < length ); i++ )
          {
              final char ch = property.charAt( i );
              switch( ch )
              {
                  case '}':
                      //TODO: Check if it is commented out
                      weight--;
                      if( weight == 0 )
                      {
                          return i;
                      }
                      break;
  
                  case '$':
                      {
                          //TODO: Check if it is commented out
                          final int next = i + 1;
                          if( next < length && '{' == property.charAt( next ) )
                          {
                              weight++;
                          }
                      }
                      break;
              }
          }
  
          final String message = REZ.getString( "prop.mismatched-braces.error" );
          throw new TaskException( message );
      }
  
      /**
       * Retrieve a value from the specified context using the specified key.
       *
       * @param propertyName the key of value in context
       * @param context the set of known properties
       * @return the object retrieved from context
       * @exception TaskException if the property is undefined
       */
      protected Object getPropertyValue( final String propertyName,
                                         final Context context )
          throws TaskException
      {
          try
          {
              return context.get( propertyName );
          }
          catch( ContextException e )
          {
              final String message = REZ.getString( "prop.missing-value.error", propertyName
);
              throw new TaskException( message );
          }
      }
  }
  
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/workspace/PropertyResolver.java
  
  Index: PropertyResolver.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 org.apache.myrmidon.interfaces.workspace;
  
  import org.apache.myrmidon.api.TaskException;
  import org.apache.avalon.framework.context.Context;
  
  /**
   *
   * Provides a service for the resolution of property identifiers within
   * String content.
   *
   * @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a>
   * @version $Revision: 1.1 $ $Date: 2002/03/09 02:04:26 $
   */
  public interface PropertyResolver
  {
      String ROLE = PropertyResolver.class.getName();
  
      /**
       * Resolve a string property. This evaluates all property
       * substitutions based on specified contex.
       * Rules used for property resolution are implementation dependent.
       *
       * @param value the value to resolve, which may contain property identifiers
       * @param context the set of properties to resolve against.
       * @return the resolved content
       * @exception TaskException if an error occurs
       */
      Object resolveProperties( final String value,
                                final Context context )
          throws TaskException;
  }
  
  
  

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


Mime
View raw message