You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@curator.apache.org by ra...@apache.org on 2017/04/26 21:53:25 UTC
[2/2] curator git commit: added a resolving version that takes
suppliers for parameters
added a resolving version that takes suppliers for parameters
Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/52b334c3
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/52b334c3
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/52b334c3
Branch: refs/heads/CURATOR-397
Commit: 52b334c30d82227ad7da3559976fa932fbbc5763
Parents: 22fdb29
Author: randgalt <ra...@apache.org>
Authored: Wed Apr 26 16:53:17 2017 -0500
Committer: randgalt <ra...@apache.org>
Committed: Wed Apr 26 16:53:17 2017 -0500
----------------------------------------------------------------------
.../apache/curator/x/async/modeled/ZPath.java | 50 ++++++++++--
.../x/async/modeled/details/ZPathImpl.java | 86 ++++++++++++++------
.../curator/x/async/modeled/TestZPath.java | 13 +++
3 files changed, 115 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/curator/blob/52b334c3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ZPath.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ZPath.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ZPath.java
index ff84d26..f68679d 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ZPath.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/ZPath.java
@@ -19,6 +19,9 @@
package org.apache.curator.x.async.modeled;
import org.apache.curator.x.async.modeled.details.ZPathImpl;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Supplier;
import java.util.regex.Pattern;
/**
@@ -58,12 +61,19 @@ public interface ZPath
*/
static ZPath from(String... names)
{
- ZPath path = root();
- for ( String n : names )
- {
- path = path.at(n);
- }
- return path;
+ return ZPathImpl.from(names);
+ }
+
+ /**
+ * Convert individual path names into a ZPath
+ *
+ * @param names path names
+ * @return ZPath
+ * @throws IllegalArgumentException if any of the names is invalid
+ */
+ static ZPath from(List<String> names)
+ {
+ return ZPathImpl.from(names);
}
/**
@@ -85,7 +95,33 @@ public interface ZPath
* parameter nodes in the path
* @return new resolved ZPath
*/
- ZPath resolved(Object... parameters);
+ default ZPath resolved(Object... parameters)
+ {
+ return resolved(Arrays.asList(parameters));
+ }
+
+ /**
+ * When creating paths, any node in the path can be set to {@link #parameterNodeName()}.
+ * At runtime, the ZPath can be "resolved" by replacing these nodes with values.
+ *
+ * @param parameters list of replacements. Must have be the same length as the number of
+ * parameter nodes in the path
+ * @return new resolved ZPath
+ */
+ ZPath resolved(List<Object> parameters);
+
+ /**
+ * An "auto" resolving version of this ZPath. i.e. if any of the path names is
+ * the {@link #parameterNodeName()} the ZPath must be resolved. This method
+ * creates a new ZPath that auto resolves by using the given parameter suppliers
+ * whenever needed.
+ *
+ * @param parameterSuppliers parameter suppliers
+ * @return new auto resolving ZNode
+ * @see #resolved(Object...)
+ * @see #parameterNodeName()
+ */
+ ZPath resolving(List<Supplier<Object>> parameterSuppliers);
/**
* Return a ZPath that represents a child ZNode of this ZPath. e.g.
http://git-wip-us.apache.org/repos/asf/curator/blob/52b334c3/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZPathImpl.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZPathImpl.java b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZPathImpl.java
index be03963..e728537 100644
--- a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZPathImpl.java
+++ b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ZPathImpl.java
@@ -21,24 +21,28 @@ package org.apache.curator.x.async.modeled.details;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
import org.apache.curator.utils.ZKPaths;
import org.apache.curator.x.async.modeled.ZPath;
import org.apache.zookeeper.common.PathUtils;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
+import java.util.function.Supplier;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
public class ZPathImpl implements ZPath
{
- public static final ZPath root = new ZPathImpl(Collections.singletonList(ZKPaths.PATH_SEPARATOR), null);
+ public static final ZPath root = new ZPathImpl(Collections.singletonList(ZKPaths.PATH_SEPARATOR), null, null);
public static final String parameter = "\u0000"; // PathUtils.validatePath() rejects this so it's useful for this purpose
private final List<String> nodes;
private final boolean isResolved;
+ private final List<Supplier<Object>> parameterSuppliers;
public static ZPath parse(String fullPath)
{
@@ -47,20 +51,36 @@ public class ZPathImpl implements ZPath
.addAll(Splitter.on(ZKPaths.PATH_SEPARATOR).omitEmptyStrings().splitToList(fullPath))
.build();
nodes.forEach(ZPathImpl::validate);
- return new ZPathImpl(nodes, null);
+ return new ZPathImpl(nodes, null, null);
+ }
+
+ public static ZPath from(String[] names)
+ {
+ return from(Arrays.asList(names));
+ }
+
+ public static ZPath from(List<String> names)
+ {
+ names = Objects.requireNonNull(names, "names cannot be null");
+ names.forEach(ZPathImpl::validate);
+ List<String> nodes = ImmutableList.<String>builder()
+ .add(ZKPaths.PATH_SEPARATOR)
+ .addAll(names)
+ .build();
+ return new ZPathImpl(nodes, null, null);
}
@Override
public ZPath at(String child)
{
- return new ZPathImpl(nodes, child);
+ return new ZPathImpl(nodes, child, parameterSuppliers);
}
@Override
public ZPath parent()
{
checkRootAccess();
- return new ZPathImpl(nodes.subList(0, nodes.size() - 1), null);
+ return new ZPathImpl(nodes.subList(0, nodes.size() - 1), null, parameterSuppliers);
}
@Override
@@ -93,7 +113,6 @@ public class ZPathImpl implements ZPath
@Override
public String nodeName()
{
- checkResolved();
return nodes.get(nodes.size() - 1);
}
@@ -127,31 +146,35 @@ public class ZPathImpl implements ZPath
}
@Override
- public ZPath resolved(Object... parameters)
+ public ZPath resolved(List<Object> parameters)
{
- List<String> nodeNames = Lists.newArrayList();
- int parameterIndex = 0;
- for ( int i = 0; i < nodes.size(); ++i )
- {
- String name = nodes.get(i);
- if ( name.equals(parameter) )
- {
- if ( parameterIndex >= parameters.length )
+ Iterator<Object> iterator = parameters.iterator();
+ List<String> nodeNames = nodes.stream()
+ .map(name -> {
+ if ( name.equals(parameter) )
{
- throw new IllegalStateException(String.format("Parameter missing at index [%d] for [%s]", parameterIndex, nodes.toString()));
+ if ( !iterator.hasNext() )
+ {
+ throw new IllegalStateException(String.format("Parameter missing for [%s]", nodes.toString()));
+ }
+ return iterator.next().toString();
}
- nodeNames.add(parameters[parameterIndex++].toString());
- }
- else
- {
- nodeNames.add(name);
- }
- }
- return new ZPathImpl(nodeNames, null);
+ return name;
+ })
+ .collect(Collectors.toList());
+ return new ZPathImpl(nodeNames, null, parameterSuppliers);
}
- private ZPathImpl(List<String> nodes, String child)
+ @Override
+ public ZPath resolving(List<Supplier<Object>> parameterSuppliers)
{
+ parameterSuppliers = Objects.requireNonNull(parameterSuppliers, "parameterSuppliers cannot be null");
+ return new ZPathImpl(nodes, null, parameterSuppliers);
+ }
+
+ private ZPathImpl(List<String> nodes, String child, List<Supplier<Object>> parameterSuppliers)
+ {
+ this.parameterSuppliers = parameterSuppliers;
ImmutableList.Builder<String> builder = ImmutableList.<String>builder().addAll(nodes);
if ( child != null )
{
@@ -159,7 +182,7 @@ public class ZPathImpl implements ZPath
builder.add(child);
}
this.nodes = builder.build();
- isResolved = !this.nodes.contains(parameter);
+ isResolved = (parameterSuppliers != null) || !this.nodes.contains(parameter);
}
private void checkRootAccess()
@@ -180,6 +203,7 @@ public class ZPathImpl implements ZPath
boolean addSeparator = false;
StringBuilder str = new StringBuilder();
int size = parent ? (nodes.size() - 1) : nodes.size();
+ int parameterIndex = 0;
for ( int i = 0; i < size; ++i )
{
if ( i > 1 )
@@ -187,7 +211,15 @@ public class ZPathImpl implements ZPath
str.append(ZKPaths.PATH_SEPARATOR);
}
String value = nodes.get(i);
- str.append(value.equals(parameter) ? ".*" : value);
+ if ( value.equals(parameter) )
+ {
+ if ( (parameterSuppliers == null) || (parameterSuppliers.size() <= parameterIndex) )
+ {
+ throw new IllegalStateException(String.format("Parameter supplier missing at index [%d] for [%s]", parameterIndex, nodes.toString()));
+ }
+ value = parameterSuppliers.get(parameterIndex++).get().toString();
+ }
+ str.append(value);
}
return str.toString();
}
http://git-wip-us.apache.org/repos/asf/curator/blob/52b334c3/curator-x-async/src/test/java/org/apache/curator/x/async/modeled/TestZPath.java
----------------------------------------------------------------------
diff --git a/curator-x-async/src/test/java/org/apache/curator/x/async/modeled/TestZPath.java b/curator-x-async/src/test/java/org/apache/curator/x/async/modeled/TestZPath.java
index 2ca38ca..8397ef5 100644
--- a/curator-x-async/src/test/java/org/apache/curator/x/async/modeled/TestZPath.java
+++ b/curator-x-async/src/test/java/org/apache/curator/x/async/modeled/TestZPath.java
@@ -22,6 +22,8 @@ import org.apache.curator.utils.ZKPaths;
import org.apache.curator.x.async.modeled.details.ZPathImpl;
import org.testng.Assert;
import org.testng.annotations.Test;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
public class TestZPath
{
@@ -68,4 +70,15 @@ public class TestZPath
ZPath path = ZPath.from("one", ZPath.parameterNodeName(), "two", ZPath.parameterNodeName());
Assert.assertEquals(path.resolved("a", "b"), ZPath.from("one", "a", "two", "b"));
}
+
+ @Test
+ public void testResolving()
+ {
+ ZPath path = ZPath.from("one", ZPath.parameterNodeName(), "two", ZPath.parameterNodeName());
+ AtomicInteger count = new AtomicInteger(0);
+ ZPath resolving = path.resolving(Arrays.asList(() -> "x" + count.get(), () -> "y" + count.get()));
+ Assert.assertEquals(resolving.fullPath(), "/one/x0/two/y0");
+ count.incrementAndGet();
+ Assert.assertEquals(resolving.fullPath(), "/one/x1/two/y1");
+ }
}