Browse Source

Resolve properties loaded from files before sending them to the project

helper for resolution. This removes extraneous reporting of undefined
properties due to the "reording" of properties stored in the properties
object.

Unify property extraction between ProjectHelper and property task.

PR:	2687


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269377 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 24 years ago
parent
commit
4f3e4e1690
2 changed files with 122 additions and 132 deletions
  1. +63
    -35
      src/main/org/apache/tools/ant/ProjectHelper.java
  2. +59
    -97
      src/main/org/apache/tools/ant/taskdefs/Property.java

+ 63
- 35
src/main/org/apache/tools/ant/ProjectHelper.java View File

@@ -689,52 +689,80 @@ public class ProjectHelper {
}


/** Replace ${NAME} with the property value
/**
* Replace ${} style constructions in the given value with the string value of
* the corresponding data types.
*
* @param value the string to be scanned for property references.
*/
public static String replaceProperties(Project project, String value, Hashtable keys )
throws BuildException
{
// XXX use Map instead of proj, it's too heavy

// XXX need to replace this code with something better.
StringBuffer sb=new StringBuffer();
int i=0;
int prev=0;
// assert value!=nil
throws BuildException {
if (value == null) {
return null;
}

Vector fragments = new Vector();
Vector propertyRefs = new Vector();
parsePropertyString(value, fragments, propertyRefs);

StringBuffer sb = new StringBuffer();
Enumeration i = fragments.elements();
Enumeration j = propertyRefs.elements();
while (i.hasMoreElements()) {
String fragment = (String)i.nextElement();
if (fragment == null) {
String propertyName = (String)j.nextElement();
if (!keys.containsKey(propertyName)) {
project.log("Property ${" + propertyName + "} has not been set", Project.MSG_VERBOSE);
}
fragment = (keys.containsKey(propertyName)) ? (String) keys.get(propertyName)
: "${" + propertyName + "}";
}
sb.append(fragment);
}
return sb.toString();
}

/**
* This method will parse a string containing ${value} style
* property values into two lists. The first list is a collection
* of text fragments, while the other is a set of string property names
* null entries in the first list indicate a property reference from the
* second list.
*/
public static void parsePropertyString(String value, Vector fragments, Vector propertyRefs)
throws BuildException {
int prev = 0;
int pos;
while( (pos=value.indexOf( "$", prev )) >= 0 ) {
if(pos>0) {
sb.append( value.substring( prev, pos ) );
while ((pos = value.indexOf("$", prev)) >= 0) {
if (pos > 0) {
fragments.addElement(value.substring(prev, pos));
}

if( pos == (value.length() - 1)) {
sb.append('$');
fragments.addElement("$");
prev = pos + 1;
}
else if (value.charAt( pos + 1 ) != '{' ) {
sb.append( value.charAt( pos + 1 ) );
prev=pos+2; // XXX
else if (value.charAt(pos + 1) != '{' ) {
fragments.addElement(value.substring(pos + 1, pos + 2));
prev = pos + 2;
} else {
int endName=value.indexOf( '}', pos );
if( endName < 0 ) {
throw new BuildException("Syntax error in prop: " +
value );
}
String n=value.substring( pos+2, endName );
if (!keys.containsKey(n)) {
project.log("Property ${" + n + "} has not been set", Project.MSG_VERBOSE);
int endName = value.indexOf('}', pos);
if (endName < 0) {
throw new BuildException("Syntax error in property: "
+ value );
}
String v = (keys.containsKey(n)) ? (String) keys.get(n) : "${"+n+"}";
//System.out.println("N: " + n + " " + " V:" + v);
sb.append( v );
prev=endName+1;
String propertyName = value.substring(pos + 2, endName);
fragments.addElement(null);
propertyRefs.addElement(propertyName);
prev = endName + 1;
}
}
if( prev < value.length() ) sb.append( value.substring( prev ) );
// System.out.println("After replace: " + sb.toString());
// System.out.println("Before replace: " + value);
return sb.toString();
if (prev < value.length()) {
fragments.addElement(value.substring(prev));
}
}

private static SAXParserFactory getParserFactory() {


+ 59
- 97
src/main/org/apache/tools/ant/taskdefs/Property.java View File

@@ -160,26 +160,21 @@ public class Property extends Task {
}

public void execute() throws BuildException {
try {
if ((name != null) && (value != null)) {
addProperty(name, value);
}

if (file != null) loadFile(file);

if (resource != null) loadResource(resource);

if (env != null) loadEnvironment(env);

if ((name != null) && (ref != null)) {
Object obj = ref.getReferencedObject(getProject());
if (obj != null) {
addProperty(name, obj.toString());
}
if ((name != null) && (value != null)) {
addProperty(name, value);
}
if (file != null) loadFile(file);
if (resource != null) loadResource(resource);
if (env != null) loadEnvironment(env);
if ((name != null) && (ref != null)) {
Object obj = ref.getReferencedObject(getProject());
if (obj != null) {
addProperty(name, obj.toString());
}

} catch (Exception e) {
throw new BuildException(e, location);
}
}

@@ -201,8 +196,8 @@ public class Property extends Task {
log("Unable to find property file: " + file.getAbsolutePath(),
Project.MSG_VERBOSE);
}
} catch(Exception ex) {
throw new BuildException(ex.getMessage(), ex, location);
} catch(IOException ex) {
throw new BuildException(ex, location);
}
}

@@ -231,8 +226,8 @@ public class Property extends Task {
} else {
log("Unable to find resource " + name, Project.MSG_WARN);
}
} catch (Exception ex) {
ex.printStackTrace();
} catch (IOException ex) {
throw new BuildException(ex, location);
}
}

@@ -240,22 +235,18 @@ public class Property extends Task {
Properties props = new Properties();
if (!prefix.endsWith(".")) prefix += ".";
log("Loading Environment " + prefix, Project.MSG_VERBOSE);
try {
Vector osEnv = Execute.getProcEnvironment();
for (Enumeration e = osEnv.elements(); e.hasMoreElements(); ) {
String entry = (String)e.nextElement();
int pos = entry.indexOf('=');
if (pos == -1) {
log("Ignoring: " + entry, Project.MSG_WARN);
} else {
props.put(prefix + entry.substring(0, pos),
entry.substring(pos + 1));
}
Vector osEnv = Execute.getProcEnvironment();
for (Enumeration e = osEnv.elements(); e.hasMoreElements(); ) {
String entry = (String)e.nextElement();
int pos = entry.indexOf('=');
if (pos == -1) {
log("Ignoring: " + entry, Project.MSG_WARN);
} else {
props.put(prefix + entry.substring(0, pos),
entry.substring(pos + 1));
}
addProperties(props);
} catch (Exception ex) {
throw new BuildException(ex, location);
}
addProperties(props);
}

protected void addProperties(Properties props) {
@@ -285,72 +276,43 @@ public class Property extends Task {
}
}

private void resolveAllProperties(Hashtable props) {
Hashtable unresolvableProperties = new Hashtable();
for (Enumeration e = props.keys(); e.hasMoreElements(); ) {
String name = (String) e.nextElement();
String value = (String) props.get(name);
private void resolveAllProperties(Properties props) throws BuildException {
for (Enumeration e = props.keys(); e.hasMoreElements();) {
String name = (String)e.nextElement();
String value = props.getProperty(name);

boolean resolved = false;
while (!resolved) {
Vector propsInValue = new Vector();
// assume it will be resolved
while (!resolved) {
Vector fragments = new Vector();
Vector propertyRefs = new Vector();
ProjectHelper.parsePropertyString(value, fragments, propertyRefs);
resolved = true;
boolean unresolvable = false;
if (extractProperties(value, propsInValue)) {
for (int i=0; i < propsInValue.size(); i++) {
String elem = (String) propsInValue.elementAt(i);
if (elem.equals(name) || unresolvableProperties.containsKey(elem)) {
// we won't try further resolving elements with circular
// property dependencies or dependencies on unresolvable elements
unresolvable = true;
break;
}
if (project.getProperties().containsKey(elem) ||
props.containsKey(elem)) {
resolved = false;
if (propertyRefs.size() != 0) {
StringBuffer sb = new StringBuffer();
Enumeration i = fragments.elements();
Enumeration j = propertyRefs.elements();
while (i.hasMoreElements()) {
String fragment = (String)i.nextElement();
if (fragment == null) {
String propertyName = (String)j.nextElement();
if (propertyName.equals(name)) {
throw new BuildException("Property " + name + " was circularly defined.");
}
if (props.containsKey(propertyName)) {
fragment = props.getProperty(propertyName);
resolved = false;
}
else {
fragment = "${" + propertyName + "}";
}
}
sb.append(fragment);
}
}
if (unresolvable) {
unresolvableProperties.put(name, value);
resolved = true;
}
if (!resolved) {
value = ProjectHelper.replaceProperties(project, value,
project.getProperties());
value = ProjectHelper.replaceProperties(project, value, props);
value = sb.toString();
props.put(name, value);
}
}
}
}

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 ) != '{' ) {
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);
}
}
}

Loading…
Cancel
Save