ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gle...@ca.ibm.com
Subject [PATCH] Fix for loading properties from a file or resource.
Date Wed, 05 Jul 2000 21:30:23 GMT




Hello all.

A while ago I noticed that loading properties from a file didn't work if
you had somthing like the following:

base.dir=some/really/long/directory/name/that/I/don't/want/to/type/again
src.dir=${base.dir}/src

You can't guarantee the order in which the properties are evaluated.  More
often than not, the result is

base.dir=some/really/long/directory/name/that/I/don't/want/to/type/again
src.dir=null/src

I created a fix for this a while ago in a custom task, but I decided to try
my hand at patching the existing Property.java and ProjectHelper.java
files.  The upshot of this patch is:

1. Properties loaded from a file or resource will be resolved _before_
adding them to the project properties - this enforces the rule that
properties set in a parent build or from the command line are unaffected.
2. Properties are resolved from existing project properties, and from the
set loaded from a file or resource.
3. If a property substitution cannot be accomplished, the ${blah} is left
in the value, rather than replacing it with null.
4. Keep iterating over the newly loaded properties untill there are no more
${blah} substitutions that can be made.

I like 3 because it becomes REALLY obvious when I've made a mistake with a
property.

Be warned, this is a reasonably long patch.

Index: ProjectHelper.java
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/ProjectHelper.java,v
retrieving revision 1.15
diff -u -r1.15 ProjectHelper.java
--- ProjectHelper.java        2000/07/04 18:18:02        1.15
+++ ProjectHelper.java        2000/07/05 21:08:19
@@ -503,7 +503,7 @@
                                             value );
                }
                String n=value.substring( pos+2, endName );
-                String v=(String) keys.get( n );
+                String v=(keys.containsKey(n)) ? (String) keys.get( n ) :
"${"+n+"}";
                //System.out.println("N: " + n + " " + " V:" + v);
                sb.append( v );
                prev=endName+1;
Index: taskdefs/Property.java
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Property.java,v
retrieving revision 1.6
diff -u -r1.6 Property.java
--- taskdefs/Property.java        2000/06/24 15:17:00        1.6
+++ taskdefs/Property.java        2000/07/05 21:08:22
@@ -64,6 +64,7 @@
 *
 * @author costin@dnt.ro
 * @author Sam Ruby <rubys@us.ibm.com>
+ * @author Glenn McAllister <glennm@ca.ibm.com>
 */
public class Property extends Task {

@@ -101,20 +102,7 @@
    public void init() throws BuildException {
        try {
            if ((name != null) && (value != null)) {
-                if( userProperty )
-                    if (project.getUserProperty(name) == null) {
-                        project.setUserProperty(name, value);
-                    } else {
-                        project.log("Override ignored for " + name,
-                                    project.MSG_VERBOSE);
-                    }
-                else
-                    if (project.getProperty(name) == null) {
-                        project.setProperty(name, value);
-                    } else {
-                        project.log("Override ignored for " + name,
-                                    project.MSG_VERBOSE);
-                    }
+                addProperty(name, value);
            }

             if (file != null) loadFile(file);
@@ -133,6 +121,8 @@
            if (new File(name).exists()) {
                props.load(new FileInputStream(name));
                addProperties(props);
+            } else {
+                project.log("Unable to find " + name,
project.MSG_VERBOSE);
            }
        } catch(Exception ex) {
            ex.printStackTrace();
@@ -152,29 +142,98 @@
            ex.printStackTrace();
        }
    }
-
+
    private void addProperties(Properties props) {
+        resolveAllProperties(props);
+
        Enumeration e = props.keys();
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
-            String value = (String) props.getProperty(name);
-            String v = ProjectHelper.replaceProperties(value,
project.getProperties());
-            if( userProperty )
-                if (project.getUserProperty(name) == null) {
-                    project.setUserProperty(name, v);
-                } else {
-                    project.log("Override ignored for " + name,
-                                project.MSG_VERBOSE);
+            String value = (String) props.get(name);
+            addProperty(name, value);
+        }
+    }
+
+    private void addProperty(String n, String v) {
+        if( userProperty )
+            if (project.getUserProperty(n) == null) {
+                project.setUserProperty(n, v);
+            } else {
+                project.log("Override ignored for " + n,
+                            project.MSG_VERBOSE);
+            }
+        else
+            if (project.getProperty(n) == null) {
+                project.setProperty(n, v);
+            } else {
+                project.log("Override ignored for " + n,
+                            project.MSG_VERBOSE);
+            }
+    }
+
+    private void resolveAllProperties(Hashtable props) {
+        Hashtable toResolve = new Hashtable();
+        Enumeration e = props.keys();
+        boolean more = true;
+
+        while (more) {
+            while (e.hasMoreElements()) {
+                Vector propsInValue = new Vector();
+                String name = (String) e.nextElement();
+                String value = (String) props.get(name);
+
+                if (extractProperties(value, propsInValue)) {
+                    for (int i=0; i < propsInValue.size(); i++) {
+                        String elem = (String) propsInValue.elementAt(i);
+                        if (project.getProperties().containsKey(elem) ||
props.containsKey(elem)) {
+                            toResolve.put(name, value);
+                            break;
+                        }
+                    }
                }
-            else
-                if (project.getProperty(name) == null) {
-                    project.setProperty(name, v);
-                } else {
-                    project.log("Override ignored for " + name,
-                                project.MSG_VERBOSE);
+            }
+
+            if (toResolve.size() > 0) {
+                Enumeration tre = toResolve.keys();
+                while (tre.hasMoreElements()) {
+                  String name = (String) tre.nextElement();
+                  String value = (String) toResolve.get(name);
+                  String v = ProjectHelper.replaceProperties(value,
project.getProperties());
+                  v = ProjectHelper.replaceProperties(v, props);
+                  String old = (String) props.put(name, v);
                }
+
+                toResolve.clear();
+                e = props.keys();
+            } else {
+                more = false;
+            }
+        }
+    }
+
+    private boolean extractProperties(String source, Vector properties) {
+        // This is an abreviated version of
ProjectHelper.replaceProperties method
+
+        int i=0;
+        int prev=0;
+        int pos;
+        while( (pos=source.indexOf( "$", prev )) >= 0 ) {
+            if( pos == (source.length() - 1)) {
+                prev = pos + 1;
+            }
+            else if (source.charAt( pos + 1 ) != '{' )
{{.replaceProperties
+                prev=pos+2;
+            } else {
+                int endName=source.indexOf( '}', pos );
+                String n=source.substring( pos+2, endName );
+                properties.addElement(n);
+                prev=endName+1;
+            }
        }
+
+        return (properties.size() > 0);
    }
+

     public void setUserProperty( boolean userP ) {
        userProperty=userP;


Glenn McAllister
TID - Software Developer - VisualAge for Java
IBM Toronto Lab, (416) 448-3805
"An approximate answer to the right question is better than the
right answer to the wrong question." - John W. Tukey



Mime
View raw message