Skip to content

Commit

Permalink
add a PropertyEnumerator delegate to better support PropertySet
Browse files Browse the repository at this point in the history
  • Loading branch information
bodewig committed Aug 2, 2020
1 parent 6022806 commit 0bd346c
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 5 deletions.
14 changes: 14 additions & 0 deletions manual/properties.html
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,20 @@ <h1 id="propertyHelper">PropertyHelpers</h1>
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&mdash;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>
Expand Down
14 changes: 12 additions & 2 deletions src/main/org/apache/tools/ant/Project.java
Original file line number Diff line number Diff line change
Expand Up @@ -642,13 +642,23 @@ public String getUserProperty(final String propertyName) {

/**
* 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.
Expand Down
28 changes: 26 additions & 2 deletions src/main/org/apache/tools/ant/PropertyHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,19 @@ boolean set(
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();
}

// --------------------------------------------------------
//
Expand Down Expand Up @@ -842,6 +854,18 @@ public Object getProperty(String name) {
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.
*
Expand Down Expand Up @@ -1014,7 +1038,7 @@ public void copyUserProperties(Project other) {
// 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().
Expand Down
9 changes: 8 additions & 1 deletion src/main/org/apache/tools/ant/property/LocalProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@
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
*/
public class LocalProperties
extends InheritableThreadLocal<LocalPropertyStack>
implements PropertyHelper.PropertyEvaluator,
PropertyHelper.PropertySetter {
PropertyHelper.PropertySetter, PropertyHelper.PropertyEnumerator {

/**
* Get a localproperties for the given project.
Expand Down Expand Up @@ -147,4 +149,9 @@ public boolean set(
String property, Object value, PropertyHelper propertyHelper) {
return get().set(property, value, propertyHelper);
}

@Override
public Set<String> getPropertyNames() {
return get().getPropertyNames();
}
}
18 changes: 18 additions & 0 deletions src/main/org/apache/tools/ant/property/LocalPropertyStack.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -148,6 +152,20 @@ public boolean set(String property, Object value, PropertyHelper propertyHelper)
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) {
Expand Down
55 changes: 55 additions & 0 deletions src/tests/junit/org/apache/tools/ant/PropertyHelperTest.java
Original file line number Diff line number Diff line change
@@ -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"));
}
}

0 comments on commit 0bd346c

Please sign in to comment.