DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=23600>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=23600

augmenting the "${}" property replacement algorithm

           Summary: augmenting the "${}" property replacement algorithm
           Product: Ant
           Version: unspecified
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: Enhancement
          Priority: Other
         Component: Core
        AssignedTo: [EMAIL PROTECTED]
        ReportedBy: [EMAIL PROTECTED]


The patch concerns how Ant does "${}" property replacement.
Currently, embedded "${}" are not evaluated, which is to say
${com.acme.{jboss.service.name}.naming.host}
can not be evaluated.
There are many case in my Ant scripts where the use of
parameterized properties would be a great simplification.

Say one has two string, "foo" and "bar", and that there are a number
of property names that are same except for an embedded "foo" or "bar", e.g.,

com.acme.foo.port
com.acme.bar.port
com.acme.foo.host
com.acme.bar.host

If one had a target such as:
    
    <target name="example"> 
        <!-- do something with host and port -->
        <echo>
        port=${com.acme.${name}.port}
        host=${com.acme.${name}.host}
        </echo>
    </target>
        
then one could call the target:

    <antcall target="example">
        <param name="name" value="foo"/>
    </antcall>
    <antcall target="example">
        <param name="name" value="bar"/>
    </antcall>

Included is a standalone file, PropertyReplacer.java, which allows one
to test the new "${}" property replacement algorithm.

I am submitting the new "${}" property replacement algorithm to the
JBoss group also since it would be very useful in many of xml initialization
scripts we use.

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
file: PropertyReplacer.java
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

import java.util.Properties;

public class PropertyReplacer {
    // States used in property parsing
    private static final int NORMAL = 0;
    private static final int SEEN_DOLLAR = 1;
    //private static final int SEEN_BRACKET = 2;
    private static final int IN_BRACKET = 3;


    public static String replace(String string, Properties props) {
        if (string == null) {
            return null;
        }
        int start = string.indexOf('$');
        if (start == -1) {
            return string;
        }
        final char[] chars = string.toCharArray();
        StringBuffer buf = new StringBuffer(chars.length + 50);

        if (start > 0) {
            buf.append(chars, 0, start);
        }
//System.out.println("initial=" + buf.toString());

        int state = SEEN_DOLLAR;
        int i = start+1;
        while (i < chars.length) {
            char c = chars[i];
//System.out.println("c=" + c);

            if (state == NORMAL) {
                if (c == '$') {
                    state = SEEN_DOLLAR;
                } else {
                    buf.append(c);
                }
            } else if (state == SEEN_DOLLAR) {
                if (c == '{') {
                    i++;
                    i = getPropName(chars, i, buf, props);
                } else if (c == '$') {
                    // this is how Ant escapes a '$'
                    buf.append('$');
                } else {
                    buf.append('$');
                    buf.append(c);
                } 
                state = NORMAL;
            }
        
            i++;
        }

        return buf.toString();
    }       
    private static int getPropName(char[] chars, int i, StringBuffer buf,
                                    Properties props) {

        StringBuffer propNameBuf = new StringBuffer(50);
        int state = IN_BRACKET;
        int prop_name_start = i;
        while (i < chars.length) {
            char c = chars[i];
            if (state == IN_BRACKET) {
                if (c == '}') {
                    String name = propNameBuf.toString();
//System.out.println("prop name=" + name);
                    String value = props.getProperty(name);
                    if (value != null) {
                        buf.append(value);
                    } else {
                        // What to do if there is no property
                        // with the name? This is the Ant
                        // behavior (which is imho allows for easier
                        // error recovery than the jboss behavior).
                        buf.append('$');
                        buf.append('{');
                        buf.append(name);
                        buf.append('}');
                    }
                    prop_name_start = -1;
                    break;

                } else if (c == '$') {
                    state = SEEN_DOLLAR;
                } else {
                    propNameBuf.append(c);
                }
            } else if (state == SEEN_DOLLAR) {
                if (c == '{') {
                    i++;            
                    i = getPropName(chars, i, propNameBuf, props);
                } else if (c == '$') { 
                    // this is how Ant escapes a '$'
                    buf.append('$');
                } else {
                    propNameBuf.append('$');
                    propNameBuf.append(c);
                }
                state = IN_BRACKET;
            }
            i++;    
        }           
        if ((i == chars.length) && (prop_name_start != -1)) {
            // did not see '}' so append all of it
            buf.append('$');
            buf.append('{');
            buf.append(chars, prop_name_start, i - prop_name_start);
        }               
        return i;       
    }                   
    private static void runtest(String inStr, String expected,
                            Properties props) {
        String outStr = replace(inStr, props);

        if (inStr == null) {
            if (outStr != null) {
                System.err.println("Error: for null inStr");
                System.err.println("  but got non null \"" + outStr + "\"");
            }
        } else if (outStr == null) {
            System.err.println("Error: for inStr \"" + inStr + "\"");
            System.err.println("  but got null outStr");
        } else {
            if (! outStr.equals(expected)) {
                System.err.println("Error: for inStr \"" + inStr + "\"");
                System.err.println("  expected \"" + expected + "\"");
                System.err.println("  but got \"" + outStr + "\"");
            }
        }
    }
    
    public static void main(String[] args) {
        Properties props = System.getProperties();
        if (args.length > 0) {
            // do arguments
            for (int i =  0; i < args.length; i++) {
                String arg = args[i];
                String inStr = arg;
                String outStr = replace(inStr, props);
                System.out.println("("+inStr +"," +outStr+ ")");
            }
        } else {
            // do tests
            runtest("XXX", "XXX", props);
            runtest("XXX$YY", "XXX$YY", props);
            runtest("XXX$$YY", "XXX$YY", props);
            runtest("XXX${aa$bb}", "XXX${aa$bb}", props);
            props.setProperty("foo", "bar");
            runtest("XXX.${foo}.YYY", "XXX.bar.YYY", props);
            runtest("XXX.$${foo}.YYY", "XXX.${foo}.YYY", props);
            runtest("XXX.${foo", "XXX.${foo", props);
            runtest("XXX.${foo}", "XXX.bar", props);
            props.setProperty("bigbar", "hoedeedoe");
            runtest("XXX.${big${foo}}.YYY", "XXX.hoedeedoe.YYY", props);
            props.setProperty("bigbarfly", "swatit");
            runtest("XXX.${big${foo}fly}.YYY", "XXX.swatit.YYY", props);
            runtest("XXX.${big${foo}x}.YYY", "XXX.${bigbarx}.YYY", props);
            props.setProperty("bar", "barvalue");
            runtest("XXX.${${foo}}.YYY", "XXX.barvalue.YYY", props);
            runtest("XXX.${noprop}.YYY.${}.ZZZ", 
                            "XXX.${noprop}.YYY.${}.ZZZ", props);
            runtest("XXX.${foo}.YYY.${aa${foo}bb}.ZZZ", 
                            "XXX.bar.YYY.${aabarbb}.ZZZ", props);
        }
    }
}

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

Reply via email to