From 4f3e4e1690289144b15872597586ed34ae92efb5 Mon Sep 17 00:00:00 2001 From: Conor MacNeill Date: Mon, 23 Jul 2001 16:31:56 +0000 Subject: [PATCH] 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 --- .../org/apache/tools/ant/ProjectHelper.java | 98 +++++++---- .../apache/tools/ant/taskdefs/Property.java | 156 +++++++----------- 2 files changed, 122 insertions(+), 132 deletions(-) diff --git a/src/main/org/apache/tools/ant/ProjectHelper.java b/src/main/org/apache/tools/ant/ProjectHelper.java index c88df83e3..50acab8db 100644 --- a/src/main/org/apache/tools/ant/ProjectHelper.java +++ b/src/main/org/apache/tools/ant/ProjectHelper.java @@ -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() { diff --git a/src/main/org/apache/tools/ant/taskdefs/Property.java b/src/main/org/apache/tools/ant/taskdefs/Property.java index b54dc74e4..44be8a000 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Property.java +++ b/src/main/org/apache/tools/ant/taskdefs/Property.java @@ -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); - } - + } }