| @@ -154,6 +154,20 @@ | |||
| this would be <code class="code">org.apache.tools.ant.property.LocalProperties</code> which | |||
| implements storage for <a href="Tasks/local.html">local properties</a>.</p> | |||
| </li> | |||
| <li><code class="code">org.apache.tools.ant.PropertyHelper$PropertyEnumerator</code> | |||
| is responsible for enumerating property names. | |||
| <p>This is the interface you'd implement if you want to provide | |||
| your own storage independent of Ant's project | |||
| instance—the interface represents part of the reading | |||
| end. An example for this would | |||
| be <code class="code">org.apache.tools.ant.property.LocalProperties</code> | |||
| which implements storage for <a href="Tasks/local.html">local | |||
| properties</a>.</p> | |||
| <p><em>This interface has been added with Ant 1.10.9.</em></p> | |||
| </li> | |||
| </ul> | |||
| <p>The default <code class="code">PropertyExpander</code> looks similar to:</p> | |||
| @@ -642,13 +642,23 @@ public class Project implements ResourceFactory { | |||
| /** | |||
| * Return a copy of the properties table. | |||
| * @return a hashtable containing all properties | |||
| * (including user properties). | |||
| * @return a hashtable containing all properties (including user | |||
| * properties) known to the project directly, does not | |||
| * contain local properties. | |||
| */ | |||
| public Hashtable<String, Object> getProperties() { | |||
| return PropertyHelper.getPropertyHelper(this).getProperties(); | |||
| } | |||
| /** | |||
| * Returns the names of all known properties. | |||
| * @since 1.10.9 | |||
| * @return the names of all known properties including local user and local properties. | |||
| */ | |||
| public Set<String> getPropertyNames() { | |||
| return PropertyHelper.getPropertyHelper(this).getPropertyNames(); | |||
| } | |||
| /** | |||
| * Return a copy of the user property hashtable. | |||
| * @return a hashtable containing just the user properties. | |||
| @@ -161,7 +161,19 @@ public class PropertyHelper implements GetProperty { | |||
| String property, Object value, PropertyHelper propertyHelper); | |||
| } | |||
| //TODO PropertyEnumerator Delegate type, would improve PropertySet | |||
| /** | |||
| * Obtains the names of all known properties. | |||
| * | |||
| * @since 1.10.9 | |||
| */ | |||
| public interface PropertyEnumerator extends Delegate { | |||
| /** | |||
| * Returns the names of all properties known to this delegate. | |||
| * | |||
| * @return the names of all properties known to this delegate. | |||
| */ | |||
| Set<String> getPropertyNames(); | |||
| } | |||
| // -------------------------------------------------------- | |||
| // | |||
| @@ -842,6 +854,18 @@ public class PropertyHelper implements GetProperty { | |||
| return properties.get(name); | |||
| } | |||
| /** | |||
| * Returns the names of all known properties. | |||
| * @since 1.10.9 | |||
| * @return the names of all known properties. | |||
| */ | |||
| public Set<String> getPropertyNames() { | |||
| final Set<String> names = new HashSet<>(properties.keySet()); | |||
| getDelegates(PropertyEnumerator.class) | |||
| .forEach(e -> names.addAll(e.getPropertyNames())); | |||
| return Collections.unmodifiableSet(names); | |||
| } | |||
| /** | |||
| * Returns the value of a user property, if it is set. | |||
| * | |||
| @@ -1014,7 +1038,7 @@ public class PropertyHelper implements GetProperty { | |||
| // Moved from ProjectHelper. You can override the static method - | |||
| // this is used for backward compatibility (for code that calls | |||
| // the parse method in ProjectHelper). | |||
| /** | |||
| * Default parsing method. It is here only to support backward compatibility | |||
| * for the static ProjectHelper.parsePropertyString(). | |||
| @@ -21,6 +21,8 @@ import org.apache.tools.ant.MagicNames; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.PropertyHelper; | |||
| import java.util.Set; | |||
| /** | |||
| * Thread local class containing local properties. | |||
| * @since Ant 1.8.0 | |||
| @@ -28,7 +30,7 @@ import org.apache.tools.ant.PropertyHelper; | |||
| public class LocalProperties | |||
| extends InheritableThreadLocal<LocalPropertyStack> | |||
| implements PropertyHelper.PropertyEvaluator, | |||
| PropertyHelper.PropertySetter { | |||
| PropertyHelper.PropertySetter, PropertyHelper.PropertyEnumerator { | |||
| /** | |||
| * Get a localproperties for the given project. | |||
| @@ -147,4 +149,9 @@ public class LocalProperties | |||
| String property, Object value, PropertyHelper propertyHelper) { | |||
| return get().set(property, value, propertyHelper); | |||
| } | |||
| @Override | |||
| public Set<String> getPropertyNames() { | |||
| return get().getPropertyNames(); | |||
| } | |||
| } | |||
| @@ -17,10 +17,14 @@ | |||
| */ | |||
| package org.apache.tools.ant.property; | |||
| import java.util.Collections; | |||
| import java.util.Deque; | |||
| import java.util.HashSet; | |||
| import java.util.LinkedList; | |||
| import java.util.Map; | |||
| import java.util.Set; | |||
| import java.util.concurrent.ConcurrentHashMap; | |||
| import java.util.stream.Collector; | |||
| import org.apache.tools.ant.PropertyHelper; | |||
| @@ -148,6 +152,20 @@ public class LocalPropertyStack { | |||
| return true; | |||
| } | |||
| /** | |||
| * Returns the names of all known local properties. | |||
| * @since 1.10.9 | |||
| * @return the names of all known local properties. | |||
| */ | |||
| public Set<String> getPropertyNames() { | |||
| final Set<String> names = stack.stream().map(Map::keySet) | |||
| .collect(Collector.of(() -> new HashSet<String>(), | |||
| (ns, ks) -> ns.addAll(ks), | |||
| (ns1, ns2) -> { ns1.addAll(ns2); return ns1; }, | |||
| Collector.Characteristics.UNORDERED, Collector.Characteristics.IDENTITY_FINISH)); | |||
| return Collections.unmodifiableSet(names); | |||
| } | |||
| private Map<String, Object> getMapForProperty(String property) { | |||
| synchronized (LOCK) { | |||
| for (Map<String, Object> map : stack) { | |||
| @@ -0,0 +1,55 @@ | |||
| /* | |||
| * 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 | |||
| * | |||
| * https://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; | |||
| import org.apache.tools.ant.property.LocalProperties; | |||
| import org.junit.Test; | |||
| import static org.junit.Assert.assertFalse; | |||
| import static org.junit.Assert.assertTrue; | |||
| public class PropertyHelperTest { | |||
| @Test | |||
| public void findsPropertyNamesSetDirectly() { | |||
| Project p = new Project(); | |||
| p.setNewProperty("foo", "bar"); | |||
| assertTrue(p.getPropertyNames().contains("foo")); | |||
| } | |||
| @Test | |||
| public void findsPropertyNamesSetForLocalProperties() { | |||
| Project p = new Project(); | |||
| p.setNewProperty("foo", "bar"); | |||
| LocalProperties localProperties = LocalProperties.get(p); | |||
| localProperties.enterScope(); | |||
| localProperties.addLocal("baz"); | |||
| p.setNewProperty("baz", "xyzzy"); | |||
| assertTrue(p.getPropertyNames().contains("foo")); | |||
| assertTrue(p.getPropertyNames().contains("baz")); | |||
| assertTrue(p.getProperties().keySet().contains("foo")); | |||
| assertFalse(p.getProperties().keySet().contains("baz")); | |||
| localProperties.exitScope(); | |||
| assertTrue(p.getPropertyNames().contains("foo")); | |||
| assertFalse(p.getPropertyNames().contains("baz")); | |||
| } | |||
| } | |||