* 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); | |||||
} | } | ||||
} | } |