package org.opendaylight.yangtools.yang.data.jaxen;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Verify.verify;
import static com.google.common.base.Verify.verifyNotNull;
import static java.util.Objects.requireNonNull;
-import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterators;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.jaxen.Context;
import org.jaxen.ContextSupport;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
* traversing upwards the NormalizedNode tree.
*/
@NonNullByDefault
-final class NormalizedNodeContext extends Context implements Function<NormalizedNode<?, ?>, NormalizedNodeContext> {
+final class NormalizedNodeContext extends Context {
private static final long serialVersionUID = 1L;
private final @Nullable NormalizedNodeContext parent;
private final DataSchemaContextNode<?> schema;
return schema;
}
- @Override
- public NormalizedNodeContext apply(final NormalizedNode<?, ?> input) {
+ NormalizedNodeContext createChild(final NormalizedNode<?, ?> input) {
DataSchemaContextNode<?> childSchema = schema.getChild(input.getIdentifier());
if (childSchema == null) {
/* This feels very much like a hack: but solves lookup of child nodes with predicates.
checkArgument(childSchema != null, "Failed to find schema for child %s", input);
return new NormalizedNodeContext(getContextSupport(), childSchema, input, this);
}
+
+ Optional<NormalizedNodeContext> findChild(final PathArgument arg) {
+ return node instanceof DataContainerNode ? ((DataContainerNode<?>)node).getChild(arg).map(this::createChild)
+ : Optional.empty();
+ }
+
+ Optional<NormalizedNodeContext> findDescendant(final YangInstanceIdentifier path) {
+ if (path.isEmpty()) {
+ return Optional.of(this);
+ }
+
+ NormalizedNodeContext ctxWalk = this;
+ NormalizedNode<?, ?> dataWalk = node;
+ for (PathArgument arg : path.getPathArguments()) {
+ checkArgument(dataWalk instanceof DataContainerNode, "Path %s refers beyond node %s", path, dataWalk);
+
+ final Optional<DataContainerChild<? extends @Nullable PathArgument, ?>> optChild =
+ ((DataContainerNode)dataWalk).getChild(arg);
+ if (!optChild.isPresent()) {
+ return Optional.empty();
+ }
+
+ dataWalk = optChild.get();
+ ctxWalk = createChild(dataWalk);
+ }
+
+ return Optional.of(ctxWalk.createChild(dataWalk));
+ }
+
+ Iterator<NormalizedNodeContext> iterateChildren(final DataContainerNode<?> data) {
+ return Iterators.transform(((DataContainerNode<?>) node).getValue().iterator(), this::createChild);
+ }
+
+ @Nullable Iterator<NormalizedNodeContext> iterateChildrenNamed(final DataContainerNode<?> data, final QName qname) {
+ final NodeIdentifier arg = new NodeIdentifier(qname);
+ final Optional<DataContainerChild<? extends @Nullable PathArgument, ?>> maybeChild = data.getChild(arg);
+ if (!maybeChild.isPresent()) {
+ return null;
+ }
+
+ final NormalizedNode<?, ?> child = maybeChild.get();
+ final Collection<? extends NormalizedNode<?, ?>> collection;
+
+ // The child may be a structural node
+ if (child instanceof MapNode) {
+ collection = ((MapNode)child).getValue();
+ } else if (child instanceof LeafSetNode) {
+ collection = ((LeafSetNode<?>)child).getValue();
+ } else {
+ return Iterators.singletonIterator(createChild(child));
+ }
+
+ return Iterators.transform(collection.iterator(), this::createChild);
+ }
+
+ static NormalizedNodeContext cast(@Nullable Context context) {
+ verify(context instanceof NormalizedNodeContext);
+ return (@NonNull NormalizedNodeContext) context;
+ }
}
import com.google.common.collect.UnmodifiableIterator;
import com.google.common.io.BaseEncoding;
import java.util.AbstractMap.SimpleImmutableEntry;
-import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
-import java.util.Optional;
import java.util.Set;
import org.jaxen.DefaultNavigator;
import org.jaxen.NamedAccessNavigator;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
/**
public Iterator<NormalizedNodeContext> getChildAxisIterator(final Object contextNode) {
final NormalizedNodeContext ctx = cast(contextNode);
final NormalizedNode<?, ?> node = ctx.getNode();
- if (node instanceof DataContainerNode) {
- return Iterators.transform(((DataContainerNode<?>) node).getValue().iterator(), ctx);
- }
-
- return null;
+ return node instanceof DataContainerNode ? ctx.iterateChildren((DataContainerNode<?>) node) : null;
}
@Override
final String namespacePrefix, final String namespaceURI) {
final NormalizedNodeContext ctx = cast(contextNode);
final NormalizedNode<?, ?> node = ctx.getNode();
- if (!(node instanceof DataContainerNode)) {
- return null;
- }
-
- final QName qname = resolveQName(node, namespacePrefix, localName);
- @SuppressWarnings({ "unchecked", "rawtypes" })
- final Optional<NormalizedNode<?, ?>> maybeChild = ((DataContainerNode)node).getChild(new NodeIdentifier(qname));
- if (!maybeChild.isPresent()) {
- return null;
- }
-
- final NormalizedNode<?, ?> child = maybeChild.get();
- final Collection<? extends NormalizedNode<?, ?>> collection;
-
- // The child may be a structural node
- if (child instanceof MapNode) {
- collection = ((MapNode)child).getValue();
- } else if (child instanceof LeafSetNode) {
- collection = ((LeafSetNode<?>)child).getValue();
- } else {
- return Iterators.singletonIterator(ctx.apply(child));
- }
-
- return Iterators.transform(collection.iterator(), ctx);
+ return node instanceof DataContainerNode
+ ? ctx.iterateChildrenNamed((DataContainerNode<?>)node, resolveQName(node, namespacePrefix, localName))
+ : null;
}
@Override