Browse Source

add a PropertyEnumerator delegate to better support PropertySet

master
Stefan Bodewig 4 years ago
parent
commit
0bd346c5c3
6 changed files with 133 additions and 5 deletions
  1. +14
    -0
      manual/properties.html
  2. +12
    -2
      src/main/org/apache/tools/ant/Project.java
  3. +26
    -2
      src/main/org/apache/tools/ant/PropertyHelper.java
  4. +8
    -1
      src/main/org/apache/tools/ant/property/LocalProperties.java
  5. +18
    -0
      src/main/org/apache/tools/ant/property/LocalPropertyStack.java
  6. +55
    -0
      src/tests/junit/org/apache/tools/ant/PropertyHelperTest.java

+ 14
- 0
manual/properties.html View File

@@ -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&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>


+ 12
- 2
src/main/org/apache/tools/ant/Project.java View File

@@ -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.


+ 26
- 2
src/main/org/apache/tools/ant/PropertyHelper.java View File

@@ -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().


+ 8
- 1
src/main/org/apache/tools/ant/property/LocalProperties.java View File

@@ -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();
}
}

+ 18
- 0
src/main/org/apache/tools/ant/property/LocalPropertyStack.java View File

@@ -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) {


+ 55
- 0
src/tests/junit/org/apache/tools/ant/PropertyHelperTest.java View File

@@ -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"));
}
}

Loading…
Cancel
Save