* extact expand property from PropertyExpander * extact resolve property map from Property task * remove use of ThreadLocal from Property task * remove need of cloning of PropertyHelper when resolving properties in a map. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@578769 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -27,8 +27,13 @@ import java.util.List; | |||||
| import java.util.Set; | import java.util.Set; | ||||
| import java.util.Vector; | import java.util.Vector; | ||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.Collection; | |||||
| import org.apache.tools.ant.property.NullReturn; | import org.apache.tools.ant.property.NullReturn; | ||||
| import org.apache.tools.ant.property.GetProperty; | |||||
| import org.apache.tools.ant.property.ParseNextProperty; | |||||
| import org.apache.tools.ant.property.PropertyExpander; | |||||
| import org.apache.tools.ant.property.ParseProperties; | |||||
| /* ISSUES: | /* ISSUES: | ||||
| - ns param. It could be used to provide "namespaces" for properties, which | - ns param. It could be used to provide "namespaces" for properties, which | ||||
| @@ -60,7 +65,7 @@ import org.apache.tools.ant.property.NullReturn; | |||||
| * | * | ||||
| * @since Ant 1.6 | * @since Ant 1.6 | ||||
| */ | */ | ||||
| public class PropertyHelper implements Cloneable { | |||||
| public class PropertyHelper implements GetProperty { | |||||
| // -------------------------------------------------------- | // -------------------------------------------------------- | ||||
| // | // | ||||
| @@ -89,22 +94,6 @@ public class PropertyHelper implements Cloneable { | |||||
| Object evaluate(String property, PropertyHelper propertyHelper); | Object evaluate(String property, PropertyHelper propertyHelper); | ||||
| } | } | ||||
| /** | |||||
| * Describes an entity capable of expanding properties embedded in a string. | |||||
| * @since Ant 1.8 | |||||
| */ | |||||
| public interface PropertyExpander extends Delegate { | |||||
| /** | |||||
| * Parse the next property name. | |||||
| * @param s the String to parse. | |||||
| * @param pos the ParsePosition in use. | |||||
| * @param propertyHelper the invoking PropertyHelper. | |||||
| * @return parsed String if any, else <code>null</code>. | |||||
| */ | |||||
| String parsePropertyName( | |||||
| String s, ParsePosition pos, PropertyHelper propertyHelper); | |||||
| } | |||||
| /** | /** | ||||
| * Describes an entity capable of setting a property to a value. | * Describes an entity capable of setting a property to a value. | ||||
| * @since Ant 1.8 | * @since Ant 1.8 | ||||
| @@ -151,7 +140,7 @@ public class PropertyHelper implements Cloneable { | |||||
| private static final PropertyExpander DEFAULT_EXPANDER = new PropertyExpander() { | private static final PropertyExpander DEFAULT_EXPANDER = new PropertyExpander() { | ||||
| public String parsePropertyName( | public String parsePropertyName( | ||||
| String s, ParsePosition pos, PropertyHelper propertyHelper) { | |||||
| String s, ParsePosition pos, ParseNextProperty notUsed) { | |||||
| int index = pos.getIndex(); | int index = pos.getIndex(); | ||||
| if (s.indexOf("${", index) == index) { | if (s.indexOf("${", index) == index) { | ||||
| int end = s.indexOf('}', index); | int end = s.indexOf('}', index); | ||||
| @@ -176,7 +165,8 @@ public class PropertyHelper implements Cloneable { | |||||
| */ | */ | ||||
| // CheckStyle:LineLengthCheck ON | // CheckStyle:LineLengthCheck ON | ||||
| public String parsePropertyName( | public String parsePropertyName( | ||||
| String s, ParsePosition pos, PropertyHelper propertyHelper) { | |||||
| String s, ParsePosition pos, ParseNextProperty notUsed) { | |||||
| //System.out.println("parseproperty " + s); | |||||
| int index = pos.getIndex(); | int index = pos.getIndex(); | ||||
| if (s.indexOf("$$", index) == index) { | if (s.indexOf("$$", index) == index) { | ||||
| pos.setIndex(++index); | pos.setIndex(++index); | ||||
| @@ -331,6 +321,15 @@ public class PropertyHelper implements Cloneable { | |||||
| return helper; | return helper; | ||||
| } | } | ||||
| /** | |||||
| * Get the expanders. | |||||
| * @return the exapanders. | |||||
| */ | |||||
| public Collection getExpanders() { | |||||
| return getDelegates(PropertyExpander.class); | |||||
| } | |||||
| // -------------------- Methods to override -------------------- | // -------------------- Methods to override -------------------- | ||||
| /** | /** | ||||
| @@ -483,31 +482,8 @@ public class PropertyHelper implements Cloneable { | |||||
| * <code>null</code> if the original string is <code>null</code>. | * <code>null</code> if the original string is <code>null</code>. | ||||
| */ | */ | ||||
| public Object parseProperties(String value) throws BuildException { | public Object parseProperties(String value) throws BuildException { | ||||
| if (value == null || "".equals(value)) { | |||||
| return value; | |||||
| } | |||||
| ParsePosition pos = new ParsePosition(0); | |||||
| Object o = parseNextProperty(value, pos); | |||||
| if (o != null && pos.getIndex() == value.length()) { | |||||
| return o; | |||||
| } | |||||
| StringBuffer sb = new StringBuffer(value.length() * 2); | |||||
| if (o == null) { | |||||
| sb.append(value.charAt(pos.getIndex())); | |||||
| pos.setIndex(pos.getIndex() + 1); | |||||
| } else { | |||||
| sb.append(o); | |||||
| } | |||||
| while (pos.getIndex() < value.length()) { | |||||
| o = parseNextProperty(value, pos); | |||||
| if (o == null) { | |||||
| sb.append(value.charAt(pos.getIndex())); | |||||
| pos.setIndex(pos.getIndex() + 1); | |||||
| } else { | |||||
| sb.append(o); | |||||
| } | |||||
| } | |||||
| return sb.toString(); | |||||
| return new ParseProperties(getProject(), getExpanders(), this) | |||||
| .parseProperties(value); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -516,50 +492,8 @@ public class PropertyHelper implements Cloneable { | |||||
| * @return <code>true</code> if <code>value</code> contains property notation. | * @return <code>true</code> if <code>value</code> contains property notation. | ||||
| */ | */ | ||||
| public boolean containsProperties(String value) { | public boolean containsProperties(String value) { | ||||
| if (value == null) { | |||||
| return false; | |||||
| } | |||||
| for (ParsePosition pos = new ParsePosition(0); pos.getIndex() < value.length();) { | |||||
| if (parsePropertyName(value, pos) != null) { | |||||
| return true; | |||||
| } | |||||
| pos.setIndex(pos.getIndex() + 1); | |||||
| } | |||||
| return false; | |||||
| } | |||||
| /** | |||||
| * Return any property that can be parsed from the specified position in the specified String. | |||||
| * @param value String to parse | |||||
| * @param pos ParsePosition | |||||
| * @return Object or null if no property is at the current location. | |||||
| */ | |||||
| public Object parseNextProperty(String value, ParsePosition pos) { | |||||
| int start = pos.getIndex(); | |||||
| String propertyName = parsePropertyName(value, pos); | |||||
| if (propertyName != null) { | |||||
| Object result = getProperty(propertyName); | |||||
| if (result != null) { | |||||
| return result; | |||||
| } | |||||
| getProject().log("Property \"" + propertyName | |||||
| + "\" has not been set", Project.MSG_VERBOSE); | |||||
| return value.substring(start, pos.getIndex()); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| private String parsePropertyName(String value, ParsePosition pos) { | |||||
| for (Iterator iter = getDelegates(PropertyExpander.class).iterator(); | |||||
| iter.hasNext();) { | |||||
| String propertyName = ((PropertyExpander) iter.next()) | |||||
| .parsePropertyName(value, pos, this); | |||||
| if (propertyName == null) { | |||||
| continue; | |||||
| } | |||||
| return propertyName; | |||||
| } | |||||
| return null; | |||||
| return new ParseProperties(getProject(), getExpanders(), this) | |||||
| .containsProperties(value); | |||||
| } | } | ||||
| // -------------------- Default implementation -------------------- | // -------------------- Default implementation -------------------- | ||||
| @@ -1062,22 +996,4 @@ public class PropertyHelper implements Cloneable { | |||||
| return result; | return result; | ||||
| } | } | ||||
| /** | |||||
| * Make a clone of this PropertyHelper. | |||||
| * @return the cloned PropertyHelper. | |||||
| * @since Ant 1.8 | |||||
| */ | |||||
| public synchronized Object clone() { | |||||
| PropertyHelper result; | |||||
| try { | |||||
| result = (PropertyHelper) super.clone(); | |||||
| result.delegates = (Hashtable) delegates.clone(); | |||||
| result.properties = (Hashtable) properties.clone(); | |||||
| result.userProperties = (Hashtable) userProperties.clone(); | |||||
| result.inheritedProperties = (Hashtable) inheritedProperties.clone(); | |||||
| } catch (CloneNotSupportedException e) { | |||||
| throw new BuildException(e); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,28 @@ | |||||
| /* | |||||
| * Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| * contributor license agreements. See the NOTICE file distributed with | |||||
| * this work for additional information regarding copyright ownership. | |||||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| * (the "License"); you may not use this file except in compliance with | |||||
| * the License. You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| * | |||||
| */ | |||||
| package org.apache.tools.ant.property; | |||||
| /** Interface to a class (normally PropertyHelper) to get a property */ | |||||
| public interface GetProperty { | |||||
| /** | |||||
| * Returns the value of a property if it is set. | |||||
| * @param name name of the property. | |||||
| * @return the property value, or null for no match or for name being null. | |||||
| */ | |||||
| Object getProperty(String name); | |||||
| } | |||||
| @@ -0,0 +1,40 @@ | |||||
| /* | |||||
| * Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| * contributor license agreements. See the NOTICE file distributed with | |||||
| * this work for additional information regarding copyright ownership. | |||||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| * (the "License"); you may not use this file except in compliance with | |||||
| * the License. You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| * | |||||
| */ | |||||
| package org.apache.tools.ant.property; | |||||
| import java.text.ParsePosition; | |||||
| import org.apache.tools.ant.Project; | |||||
| /** Interface to parse a property */ | |||||
| public interface ParseNextProperty { | |||||
| /** | |||||
| * Get the current project. | |||||
| * @return the current ant project. | |||||
| */ | |||||
| Project getProject(); | |||||
| /** | |||||
| * Return any property that can be parsed from the specified position | |||||
| * in the specified String. | |||||
| * @param value String to parse | |||||
| * @param pos ParsePosition | |||||
| * @return Object or null if no property is at the current location. | |||||
| */ | |||||
| Object parseNextProperty(String value, ParsePosition pos); | |||||
| } | |||||
| @@ -0,0 +1,153 @@ | |||||
| /* | |||||
| * Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| * contributor license agreements. See the NOTICE file distributed with | |||||
| * this work for additional information regarding copyright ownership. | |||||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| * (the "License"); you may not use this file except in compliance with | |||||
| * the License. You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| * | |||||
| */ | |||||
| package org.apache.tools.ant.property; | |||||
| import java.text.ParsePosition; | |||||
| import java.util.Collection; | |||||
| import java.util.Iterator; | |||||
| import org.apache.tools.ant.Project; | |||||
| /** | |||||
| * Parse properties using a collection of expanders. | |||||
| */ | |||||
| public class ParseProperties implements ParseNextProperty { | |||||
| private final Project project; | |||||
| private final GetProperty getProperty; | |||||
| private final Collection expanders; | |||||
| /** | |||||
| * Constructor with a getProperty. | |||||
| * @param project the current ant project. | |||||
| * @param expanders a sequence of exapanders | |||||
| * @param getProperty property resolver. | |||||
| */ | |||||
| public ParseProperties( | |||||
| Project project, Collection expanders, GetProperty getProperty) { | |||||
| this.project = project; | |||||
| this.expanders = expanders; | |||||
| this.getProperty = getProperty; | |||||
| } | |||||
| /** | |||||
| * Get the project. | |||||
| * @return the current ant project. | |||||
| */ | |||||
| public Project getProject() { | |||||
| return project; | |||||
| } | |||||
| /** | |||||
| * Decode properties from a String representation. If the entire | |||||
| * contents of the String resolve to a single property, that value | |||||
| * is returned. Otherwise a String is returned. | |||||
| * | |||||
| * @param value The string to be scanned for property references. | |||||
| * May be <code>null</code>, in which case this | |||||
| * method returns immediately with no effect. | |||||
| * | |||||
| * @return the original string with the properties replaced, or | |||||
| * <code>null</code> if the original string is <code>null</code>. | |||||
| */ | |||||
| public Object parseProperties(String value) { | |||||
| if (value == null || "".equals(value) || value.indexOf('$') == -1) { | |||||
| return value; | |||||
| } | |||||
| ParsePosition pos = new ParsePosition(0); | |||||
| Object o = parseNextProperty(value, pos); | |||||
| if (o != null && pos.getIndex() == value.length()) { | |||||
| return o; | |||||
| } | |||||
| StringBuffer sb = new StringBuffer(value.length() * 2); | |||||
| if (o == null) { | |||||
| sb.append(value.charAt(pos.getIndex())); | |||||
| pos.setIndex(pos.getIndex() + 1); | |||||
| } else { | |||||
| sb.append(o); | |||||
| } | |||||
| while (pos.getIndex() < value.length()) { | |||||
| o = parseNextProperty(value, pos); | |||||
| if (o == null) { | |||||
| sb.append(value.charAt(pos.getIndex())); | |||||
| pos.setIndex(pos.getIndex() + 1); | |||||
| } else { | |||||
| sb.append(o); | |||||
| } | |||||
| } | |||||
| return sb.toString(); | |||||
| } | |||||
| /** | |||||
| * Learn whether a String contains replaceable properties. | |||||
| * @param value the String to check. | |||||
| * @return <code>true</code> if <code>value</code> contains property notation. | |||||
| */ | |||||
| public boolean containsProperties(String value) { | |||||
| if (value == null) { | |||||
| return false; | |||||
| } | |||||
| for (ParsePosition pos = new ParsePosition(0); pos.getIndex() < value.length();) { | |||||
| if (parsePropertyName(value, pos) != null) { | |||||
| return true; | |||||
| } | |||||
| pos.setIndex(pos.getIndex() + 1); | |||||
| } | |||||
| return false; | |||||
| } | |||||
| /** | |||||
| * Return any property that can be parsed from the specified position | |||||
| * in the specified String. | |||||
| * @param value String to parse | |||||
| * @param pos ParsePosition | |||||
| * @return Object or null if no property is at the current location. | |||||
| */ | |||||
| public Object parseNextProperty(String value, ParsePosition pos) { | |||||
| int start = pos.getIndex(); | |||||
| String propertyName = parsePropertyName(value, pos); | |||||
| if (propertyName != null) { | |||||
| Object result = getProperty(propertyName); | |||||
| if (result != null) { | |||||
| return result; | |||||
| } | |||||
| if (project != null) { | |||||
| project.log( | |||||
| "Property \"" + propertyName | |||||
| + "\" has not been set", Project.MSG_VERBOSE); | |||||
| } | |||||
| return value.substring(start, pos.getIndex()); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| private String parsePropertyName(String value, ParsePosition pos) { | |||||
| for (Iterator iter = expanders.iterator(); iter.hasNext();) { | |||||
| String propertyName = ((PropertyExpander) iter.next()) | |||||
| .parsePropertyName(value, pos, this); | |||||
| if (propertyName == null) { | |||||
| continue; | |||||
| } | |||||
| return propertyName; | |||||
| } | |||||
| return null; | |||||
| } | |||||
| private Object getProperty(String propertyName) { | |||||
| return getProperty.getProperty(propertyName); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,36 @@ | |||||
| /* | |||||
| * Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| * contributor license agreements. See the NOTICE file distributed with | |||||
| * this work for additional information regarding copyright ownership. | |||||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| * (the "License"); you may not use this file except in compliance with | |||||
| * the License. You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| * | |||||
| */ | |||||
| package org.apache.tools.ant.property; | |||||
| import org.apache.tools.ant.PropertyHelper; | |||||
| import java.text.ParsePosition; | |||||
| /** Interface to a class (normally PropertyHelper) to get a property */ | |||||
| public interface PropertyExpander extends PropertyHelper.Delegate { | |||||
| /** | |||||
| * Parse the next property name. | |||||
| * @param s the String to parse. | |||||
| * @param pos the ParsePosition in use. | |||||
| * @param parseNextProperty parse next property | |||||
| * @return parsed String if any, else <code>null</code>. | |||||
| */ | |||||
| String parsePropertyName( | |||||
| String s, ParsePosition pos, ParseNextProperty parseNextProperty); | |||||
| } | |||||
| @@ -0,0 +1,87 @@ | |||||
| /* | |||||
| * Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| * contributor license agreements. See the NOTICE file distributed with | |||||
| * this work for additional information regarding copyright ownership. | |||||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| * (the "License"); you may not use this file except in compliance with | |||||
| * the License. You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| * | |||||
| */ | |||||
| package org.apache.tools.ant.property; | |||||
| import java.util.Iterator; | |||||
| import java.util.Map; | |||||
| import java.util.Set; | |||||
| import java.util.HashSet; | |||||
| import java.util.Collection; | |||||
| import org.apache.tools.ant.Project; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| /** | |||||
| * Class to resolve properties in a map. | |||||
| */ | |||||
| public class ResolvePropertyMap implements GetProperty { | |||||
| private final Set seen = new HashSet(); | |||||
| private final ParseProperties parseProperties; | |||||
| private final GetProperty master; | |||||
| private Map map; | |||||
| /** | |||||
| * Constructor with a master getproperty and a collection of expanders. | |||||
| * @param project the current ant project. | |||||
| * @param master the master property holder (usually PropertyHelper) | |||||
| * @param expanders a collection of expanders (usually from PropertyHelper). | |||||
| */ | |||||
| public ResolvePropertyMap( | |||||
| Project project, GetProperty master, Collection expanders) { | |||||
| this.master = master; | |||||
| this.parseProperties = new ParseProperties(project, expanders, this); | |||||
| } | |||||
| /** | |||||
| * Returns the value of a property if it is set. | |||||
| * @param name name of the property. | |||||
| * @return the property value, or null for no match or for name being null. | |||||
| */ | |||||
| public Object getProperty(String name) { | |||||
| if (seen.contains(name)) { | |||||
| throw new BuildException( | |||||
| "Property " + name + " was circularly " + "defined."); | |||||
| } | |||||
| // Note: the master overrides (even if the name is subsequently | |||||
| // prefixed) | |||||
| Object masterProperty = master.getProperty(name); | |||||
| if (masterProperty != null) { | |||||
| return masterProperty; | |||||
| } | |||||
| try { | |||||
| seen.add(name); | |||||
| return parseProperties.parseProperties((String) map.get(name)); | |||||
| } finally { | |||||
| seen.remove(name); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * The action method - resolves all the properties in a map. | |||||
| * @param map the map to resolve properties in. | |||||
| */ | |||||
| public void resolveAllProperties(Map map) { | |||||
| this.map = map; // The map gets used in the getProperty callback | |||||
| for (Iterator i = map.keySet().iterator(); i.hasNext();) { | |||||
| String key = (String) i.next(); | |||||
| Object result = getProperty(key); | |||||
| String value = result == null ? "" : result.toString(); | |||||
| map.put(key, value); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -28,7 +28,6 @@ import java.util.HashMap; | |||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| import java.util.Properties; | import java.util.Properties; | ||||
| import java.util.Stack; | |||||
| import java.util.Vector; | import java.util.Vector; | ||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| @@ -38,6 +37,7 @@ import org.apache.tools.ant.Task; | |||||
| import org.apache.tools.ant.types.Path; | import org.apache.tools.ant.types.Path; | ||||
| import org.apache.tools.ant.types.Reference; | import org.apache.tools.ant.types.Reference; | ||||
| import org.apache.tools.ant.util.FileUtils; | import org.apache.tools.ant.util.FileUtils; | ||||
| import org.apache.tools.ant.property.ResolvePropertyMap; | |||||
| /** | /** | ||||
| * Sets a property by name, or set of properties (from file or | * Sets a property by name, or set of properties (from file or | ||||
| @@ -73,62 +73,6 @@ import org.apache.tools.ant.util.FileUtils; | |||||
| * @ant.task category="property" | * @ant.task category="property" | ||||
| */ | */ | ||||
| public class Property extends Task { | public class Property extends Task { | ||||
| private static class PropertyResolver implements PropertyHelper.PropertyEvaluator { | |||||
| private ThreadLocal getStack = new ThreadLocal() { | |||||
| protected Object initialValue() { | |||||
| return new Stack(); | |||||
| } | |||||
| }; | |||||
| private ThreadLocal replaceStack = new ThreadLocal() { | |||||
| protected Object initialValue() { | |||||
| return new Stack(); | |||||
| } | |||||
| }; | |||||
| private Map map; | |||||
| /** | |||||
| * Construct a new Property.PropertyResolver instance. | |||||
| */ | |||||
| public PropertyResolver(Map map) { | |||||
| this.map = map; | |||||
| } | |||||
| // CheckStyle:LineLengthCheck OFF see to long | |||||
| /* (non-Javadoc) | |||||
| * @see org.apache.tools.ant.PropertyHelper.PropertyEvaluator#evaluate(java.lang.String, org.apache.tools.ant.PropertyHelper) | |||||
| */ | |||||
| // CheckStyle:LineLengthCheck ON | |||||
| public Object evaluate(String property, PropertyHelper propertyHelper) { | |||||
| //our feeble properties don't matter if the PropertyHelper | |||||
| // can resolve the property without us: | |||||
| Stack stk = (Stack) getStack.get(); | |||||
| if (stk.contains(property)) { | |||||
| return null; | |||||
| } | |||||
| stk.push(property); | |||||
| try { | |||||
| if (propertyHelper.getProperty(property) != null) { | |||||
| return null; | |||||
| } | |||||
| } finally { | |||||
| stk.pop(); | |||||
| } | |||||
| Object value = map.get(property); | |||||
| if (!(value instanceof String)) { | |||||
| return null; | |||||
| } | |||||
| stk = (Stack) replaceStack.get(); | |||||
| if (stk.contains(property)) { | |||||
| throw new BuildException("Property " + property + " was circularly defined."); | |||||
| } | |||||
| stk.push(property); | |||||
| try { | |||||
| return propertyHelper.replaceProperties((String) value); | |||||
| } finally { | |||||
| stk.pop(); | |||||
| } | |||||
| } | |||||
| } | |||||
| // CheckStyle:VisibilityModifier OFF - bc | // CheckStyle:VisibilityModifier OFF - bc | ||||
| protected String name; | protected String name; | ||||
| @@ -696,16 +640,12 @@ public class Property extends Task { | |||||
| * @param props properties object to resolve | * @param props properties object to resolve | ||||
| */ | */ | ||||
| private void resolveAllProperties(Map props) throws BuildException { | private void resolveAllProperties(Map props) throws BuildException { | ||||
| PropertyHelper propertyHelper = (PropertyHelper) PropertyHelper.getPropertyHelper( | |||||
| getProject()).clone(); | |||||
| propertyHelper.add(new PropertyResolver(props)); | |||||
| for (Iterator it = props.keySet().iterator(); it.hasNext();) { | |||||
| Object k = it.next(); | |||||
| if (k instanceof String) { | |||||
| Object value = propertyHelper.getProperty((String) k); | |||||
| props.put(k, value); | |||||
| } | |||||
| } | |||||
| PropertyHelper propertyHelper | |||||
| = (PropertyHelper) PropertyHelper.getPropertyHelper(getProject()); | |||||
| new ResolvePropertyMap( | |||||
| getProject(), | |||||
| propertyHelper, | |||||
| propertyHelper.getExpanders()).resolveAllProperties(props); | |||||
| } | } | ||||
| } | } | ||||