XPath evalution should identify result type 14/65714/1
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 20 Nov 2017 12:00:00 +0000 (13:00 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 20 Nov 2017 12:09:31 +0000 (13:09 +0100)
When we select a set of NormalizedNodes, we need to also report
their path, so they can be correctly correlated to schema. Fix
XPathNodesetResult to include this information.

Change-Id: I704cf5512caecb7e90c6130ef6a7809ff92d0fc2
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/xpath/XPathNodesetResult.java
yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/JaxenXPath.java
yang/yang-data-jaxen/src/main/java/org/opendaylight/yangtools/yang/data/jaxen/NormalizedNodeContext.java
yang/yang-data-jaxen/src/test/java/org/opendaylight/yangtools/yang/data/jaxen/JaxenTest.java

index 09d674229504050e05b06e351edbf4f65474520e..8be30d60b17085c11ec85317bece5d2b2e42ef4e 100644 (file)
@@ -9,12 +9,16 @@ package org.opendaylight.yangtools.yang.data.api.schema.xpath;
 
 import com.google.common.annotations.Beta;
 import java.util.Collection;
+import java.util.Map.Entry;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 /**
- * An {@link XPathResult} containing a set of nodes.
+ * An {@link XPathResult} containing a set of nodes. Resulting nodes are identified by their
+ * {@link YangInstanceIdentifier}.
  */
 @Beta
-public interface XPathNodesetResult extends XPathResult<Collection<NormalizedNode<?, ?>>> {
+public interface XPathNodesetResult
+    extends XPathResult<Collection<Entry<YangInstanceIdentifier, NormalizedNode<?, ?>>>> {
 
 }
index 00adb143b0f536307d73d3aa64de4943451616c7..f4a7a15d24467c74463067edd3a300451f8a2f4d 100644 (file)
@@ -11,7 +11,9 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.base.Converter;
+import com.google.common.base.Verify;
 import com.google.common.collect.Lists;
+import java.util.AbstractMap.SimpleImmutableEntry;
 import java.util.List;
 import java.util.Optional;
 import javax.annotation.Nonnull;
@@ -84,19 +86,23 @@ final class JaxenXPath implements XPathExpression {
         }
 
         if (result instanceof String) {
-            return Optional.of((XPathStringResult) () -> (String)result);
+            return Optional.of((XPathStringResult) () -> (String) result);
         } else if (result instanceof Number) {
             return Optional.of((XPathNumberResult) () -> (Number) result);
         } else if (result instanceof Boolean) {
             return Optional.of((XPathBooleanResult) () -> (Boolean) result);
-        } else if (result != null) {
-            return Optional.of((XPathNodesetResult) () -> {
-                // XXX: Will this really work, or do we need to perform deep transformation?
-                return Lists.transform((List<NormalizedNodeContext>) result, NormalizedNodeContext::getNode);
-            });
-        } else {
+        } else if (result == null) {
             return Optional.empty();
         }
+
+        Verify.verify(result instanceof List, "Unhandled result %s", result);
+        @SuppressWarnings("unchecked")
+        final List<NormalizedNodeContext> resultList = (List<NormalizedNodeContext>) result;
+        return Optional.of((XPathNodesetResult) () -> {
+            // XXX: Will this really work, or do we need to perform deep transformation?
+            return Lists.transform(resultList,
+                context -> new SimpleImmutableEntry<>(context.getPath(), context.getNode()));
+        });
     }
 
     @Nonnull
index bcf45a59eac17d4e1777b144ac801ca0bd78df49..362d6f7e27ec877bca8de3701b442d438b9969e1 100644 (file)
@@ -15,6 +15,7 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import org.jaxen.Context;
 import org.jaxen.ContextSupport;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 /**
@@ -35,12 +36,16 @@ final class NormalizedNodeContext extends Context implements Function<Normalized
         setNodeSet(ImmutableList.of(this));
     }
 
+    @Nonnull NormalizedNode<?, ?> getNode() {
+        return node;
+    }
+
     @Nullable NormalizedNodeContext getParent() {
         return parent;
     }
 
-    @Nonnull NormalizedNode<?, ?> getNode() {
-        return node;
+    @Nonnull YangInstanceIdentifier getPath() {
+        return (parent == null ? YangInstanceIdentifier.EMPTY : parent.getPath()).node(node.getIdentifier());
     }
 
     @Override
index 3122ba5614363b66849e1fe45f444f082f90bbea..e0144cda42013e5b2499ab495657822df2c505e3 100644 (file)
@@ -26,6 +26,7 @@ import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Optional;
 import javax.xml.xpath.XPathExpressionException;
 import org.jaxen.Context;
@@ -92,9 +93,12 @@ public class JaxenTest {
         assertNotNull(resultExpressionEvaluate);
         assertTrue(resultExpressionEvaluate.isPresent());
         XPathResult<?> xpathResult = resultExpressionEvaluate.get();
-        Object value = ((XPathNodesetResult) xpathResult).getValue().iterator().next().getValue();
-        assertNotNull(value);
-        assertEquals("three", value);
+        assertTrue(xpathResult instanceof XPathNodesetResult);
+        XPathNodesetResult nodeset = (XPathNodesetResult) xpathResult;
+
+        Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = nodeset.getValue().iterator().next();
+        assertNotNull(entry);
+        assertEquals("three", entry.getValue().getValue());
 
         convertNctx = new ConverterNamespaceContext(createPrefixes());
         navigator = new NormalizedNodeNavigator(convertNctx, (JaxenDocument) xpathDocument);
@@ -136,8 +140,12 @@ public class JaxenTest {
                 .evaluate(xpathDocument, createYangInstanceIdentifier(true));
         assertTrue(resultExpressionEvaluate.isPresent());
         XPathResult<?> xpathResult = resultExpressionEvaluate.get();
-        Object value = ((XPathNodesetResult) xpathResult).getValue().iterator().next().getValue();
-        assertEquals("two", value);
+        assertTrue(xpathResult instanceof XPathNodesetResult);
+        XPathNodesetResult nodeset = (XPathNodesetResult) xpathResult;
+
+        Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = nodeset.getValue().iterator().next();
+        assertNotNull(entry);
+        assertEquals("two", entry.getValue().getValue());
     }
 
     @Test(expected = VerifyException.class)