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 [EMAIL PROTECTED]
�* @author Sam Ruby <[EMAIL PROTECTED]>
+ * @author Glenn McAllister <[EMAIL PROTECTED]>
�*/
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


Reply via email to