package org.opendaylight.yangtools.binding.data.codec.impl;
import com.google.common.base.Preconditions;
-
import java.io.IOException;
import java.util.AbstractMap;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Map;
import java.util.Map.Entry;
-
import org.opendaylight.yangtools.concepts.Delegator;
import org.opendaylight.yangtools.yang.binding.Augmentation;
import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
@Override
public void startMapEntryNode(final Identifier<?> key, final int childSizeHint) throws IOException, IllegalArgumentException {
duplicateSchemaEnter();
- NodeIdentifierWithPredicates identifier = ((ListNodeCodecContext) current()).serialize(key);
+ NodeIdentifierWithPredicates identifier = ((KeyedListNodeCodecContext) current()).serialize(key);
getDelegate().startMapEntryNode(identifier, childSizeHint);
};
package org.opendaylight.yangtools.binding.data.codec.impl;
import com.google.common.collect.Iterables;
-
import javax.annotation.concurrent.GuardedBy;
-
import org.opendaylight.yangtools.binding.data.codec.impl.NodeCodecContext.CodecContextFactory;
import org.opendaylight.yangtools.yang.binding.DataRoot;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
if (schema instanceof ContainerSchemaNode) {
return new ContainerNodeCodecContext((DataContainerCodecPrototype) this);
} else if (schema instanceof ListSchemaNode) {
- return new ListNodeCodecContext((DataContainerCodecPrototype) this);
+ if (Identifiable.class.isAssignableFrom(getBindingClass())) {
+ return new KeyedListNodeCodecContext((DataContainerCodecPrototype) this);
+ } else {
+ return new ListNodeCodecContext((DataContainerCodecPrototype) this);
+ }
} else if (schema instanceof ChoiceNode) {
return new ChoiceNodeCodecContext((DataContainerCodecPrototype) this);
} else if (schema instanceof AugmentationSchema) {
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.binding.data.codec.impl;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+final class KeyedListNodeCodecContext extends ListNodeCodecContext {
+ private final Codec<NodeIdentifierWithPredicates, IdentifiableItem<?, ?>> codec;
+ private final Method keyGetter;
+
+ KeyedListNodeCodecContext(final DataContainerCodecPrototype<ListSchemaNode> prototype) {
+ super(prototype);
+
+ this.codec = factory().getPathArgumentCodec(bindingClass(), schema());
+ try {
+ this.keyGetter = bindingClass().getMethod("getKey");
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException("Required method not available", e);
+ }
+ }
+
+ @Override
+ protected void addYangPathArgument(final InstanceIdentifier.PathArgument arg, final List<YangInstanceIdentifier.PathArgument> builder) {
+ /*
+ * DOM Instance Identifier for list is always represent by two
+ * entries one for map and one for children. This is also true for
+ * wildcarded instance identifiers
+ */
+ if (builder == null) {
+ return;
+ }
+
+ super.addYangPathArgument(arg, builder);
+ if (arg instanceof IdentifiableItem<?, ?>) {
+ builder.add(codec.serialize((IdentifiableItem<?, ?>) arg));
+ } else {
+ // Adding wildcarded
+ super.addYangPathArgument(arg, builder);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ Object getBindingChildValue(final Method method, final NormalizedNodeContainer dom) {
+ if (dom instanceof MapEntryNode && keyGetter.equals(method)) {
+ NodeIdentifierWithPredicates identifier = ((MapEntryNode) dom).getIdentifier();
+ return codec.deserialize(identifier).getKey();
+ } else {
+ return super.getBindingChildValue(method, dom);
+ }
+ }
+
+ @Override
+ protected InstanceIdentifier.PathArgument getBindingPathArgument(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument domArg) {
+ if (domArg instanceof NodeIdentifierWithPredicates) {
+ return codec.deserialize((NodeIdentifierWithPredicates) domArg);
+ }
+ return super.getBindingPathArgument(domArg);
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ NodeIdentifierWithPredicates serialize(final Identifier<?> key) {
+ return codec.serialize(new IdentifiableItem(bindingClass(), key));
+ }
+}
package org.opendaylight.yangtools.binding.data.codec.impl;
import com.google.common.collect.Iterables;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
-import org.opendaylight.yangtools.concepts.Codec;
import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.Identifiable;
-import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-final class ListNodeCodecContext extends DataObjectCodecContext<ListSchemaNode> {
- private final Codec<NodeIdentifierWithPredicates, IdentifiableItem<?, ?>> codec;
- private final Method keyGetter;
-
- ListNodeCodecContext(final DataContainerCodecPrototype<ListSchemaNode> prototype) {
+class ListNodeCodecContext extends DataObjectCodecContext<ListSchemaNode> {
+ protected ListNodeCodecContext(final DataContainerCodecPrototype<ListSchemaNode> prototype) {
super(prototype);
- if (Identifiable.class.isAssignableFrom(bindingClass())) {
- this.codec = factory().getPathArgumentCodec(bindingClass(),schema());
- try {
- this.keyGetter = bindingClass().getMethod("getKey");
- } catch (NoSuchMethodException e) {
- throw new IllegalStateException("Required method not available");
- }
- } else {
- this.codec = null;
- this.keyGetter = null;
- }
- }
-
- @Override
- public void addYangPathArgument(final InstanceIdentifier.PathArgument arg, final List<YangInstanceIdentifier.PathArgument> builder) {
-
- /*
- * DOM Instance Identifier for list is always represent by two
- * entries one for map and one for children. This is also true for
- * wildcarded instance identifiers
- */
- if (builder == null) {
- return;
- }
- super.addYangPathArgument(arg, builder);
- if (arg instanceof IdentifiableItem<?, ?>) {
- builder.add(codec.serialize((IdentifiableItem<?, ?>) arg));
- } else {
- // Adding wildcarded
- super.addYangPathArgument(arg, builder);
- }
- }
-
- @Override
- public InstanceIdentifier.PathArgument getBindingPathArgument(
- final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument domArg) {
- if (domArg instanceof NodeIdentifierWithPredicates) {
- return codec.deserialize((NodeIdentifierWithPredicates) domArg);
- }
- return super.getBindingPathArgument(domArg);
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public NodeIdentifierWithPredicates serialize(final Identifier<?> key) {
- return codec.serialize(new IdentifiableItem(bindingClass(), key));
}
@Override
}
return ret;
}
-
- @Override
- @SuppressWarnings("rawtypes")
- Object getBindingChildValue(final Method method, final NormalizedNodeContainer dom) {
- if (dom instanceof MapEntryNode && method.equals(keyGetter)) {
- NodeIdentifierWithPredicates identifier = ((MapEntryNode) dom).getIdentifier();
- return codec.deserialize(identifier).getKey();
- }
- return super.getBindingChildValue(method, dom);
- }
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
<!--
-Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
-This program and the accompanying materials are made available under the
-terms of the Eclipse Public License v1.0 which accompanies this distribution,
-and is available at http://www.eclipse.org/legal/epl-v10.html
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.opendaylight.odlparent</groupId>
<yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
<salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
</properties>
+
<profiles>
<profile>
<activation>
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.yangtools.yang.data.impl.schema;
+package org.opendaylight.yangtools.yang.data.api.schema;
import static com.google.common.base.Preconditions.checkNotNull;
-
+import com.google.common.annotations.Beta;
import com.google.common.base.Optional;
-
+import com.google.common.base.Strings;
import java.util.Iterator;
-
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-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 final class NormalizedNodeUtils {
- private NormalizedNodeUtils() {
- throw new UnsupportedOperationException("Utilities class should not be instantiated");
+/**
+ * A set of utility methods for interacting with {@link NormalizedNode} objects.
+ */
+@Beta
+public final class NormalizedNodes {
+ private static final int STRINGTREE_INDENT = 4;
+
+ private NormalizedNodes() {
+ throw new UnsupportedOperationException("Utility class should not be instantiated");
}
public static Optional<NormalizedNode<?, ?>> findNode(final YangInstanceIdentifier rootPath, final NormalizedNode<?, ?> rootNode, final YangInstanceIdentifier childPath) {
}
return Optional.absent();
}
+
+ /**
+ * Convert a data subtree under a node into a human-readable string format.
+ *
+ * @param node Data subtree root
+ * @return String containing a human-readable form of the subtree.
+ */
+ public static String toStringTree(final NormalizedNode<?, ?> node) {
+ final StringBuilder builder = new StringBuilder();
+ toStringTree(builder, node, 0);
+ return builder.toString();
+ }
+
+ private static void toStringTree(final StringBuilder builder, final NormalizedNode<?, ?> node, final int offset) {
+ final String prefix = Strings.repeat(" ", offset);
+
+ builder.append(prefix).append(toStringTree(node.getIdentifier()));
+ if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
+ final NormalizedNodeContainer<?, ?, ?> container = (NormalizedNodeContainer<?, ?, ?>) node;
+
+ builder.append(" {\n");
+ for (NormalizedNode<?, ?> child : container.getValue()) {
+ toStringTree(builder, child, offset + STRINGTREE_INDENT);
+ }
+
+ builder.append(prefix).append('}');
+ } else {
+ builder.append(' ').append(node.getValue());
+ }
+ builder.append('\n');
+ }
+
+ private static String toStringTree(final PathArgument identifier) {
+ if (identifier instanceof NodeIdentifierWithPredicates) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(identifier.getNodeType().getLocalName());
+ builder.append(((NodeIdentifierWithPredicates) identifier).getKeyValues().values());
+ return builder.toString();
+ } else if (identifier instanceof AugmentationIdentifier) {
+ return "augmentation";
+ } else {
+ return identifier.getNodeType().getLocalName();
+ }
+ }
}
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.yangtools.yang.data.impl.schema.tree;
+package org.opendaylight.yangtools.yang.data.api.schema.tree;
+import com.google.common.annotations.Beta;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import java.util.Map;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode;
/**
- * A set of utility methods for interacting with {@link org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode} objects.
+ * A set of utility methods for interacting with {@link StoreTreeNode} objects.
*/
-public final class TreeNodeUtils {
- private TreeNodeUtils() {
+@Beta
+public final class StoreTreeNodes {
+ private StoreTreeNodes() {
throw new UnsupportedOperationException("Utility class should not be instantiated");
}
current = current.get().getChild(pathIter.next());
nesting++;
}
- if(current.isPresent()) {
+ if (current.isPresent()) {
final YangInstanceIdentifier currentPath = YangInstanceIdentifier.create(Iterables.limit(path.getPathArguments(), nesting));
return new SimpleEntry<YangInstanceIdentifier,T>(currentPath,current.get());
}
return new SimpleEntry<YangInstanceIdentifier,T>(parentPath,parent.get());
}
- public static <T extends StoreTreeNode<T>> Optional<T> getChild(final Optional<T> parent,final PathArgument child) {
- if(parent.isPresent()) {
+ public static <T extends StoreTreeNode<T>> Optional<T> getChild(final Optional<T> parent, final PathArgument child) {
+ if (parent.isPresent()) {
return parent.get().getChild(child);
}
return Optional.absent();
}
-
}
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
- <version>${maven.surefire.version}</version>
<configuration>
<argLine>-Dlog4j.configuration=log4j-test.xml
-Xmx1500m ${jacoco.agent.ut.arg}</argLine>
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-
import javax.annotation.Nonnull;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
-
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.ModifyAction;
import org.opendaylight.yangtools.yang.data.api.Node;
import org.opendaylight.yangtools.yang.data.api.NodeModification;
import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
/**
* @author michal.rehak
*
- * @deprecated Use {@link NormalizedNodeUtils} instead.
+ * @deprecated Use {@link NormalizedNodes} instead.
*/
@Deprecated
public abstract class NodeUtils {
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableMap;
-
import java.util.Map;
-
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@Override
public String toString() {
final TreeNode r = root;
- return Objects.toStringHelper(this).add("data", StoreUtils.toStringTree(r.getData())).toString();
+ return Objects.toStringHelper(this).add("data", NormalizedNodes.toStringTree(r.getData())).toString();
}
}
\ No newline at end of file
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
final InMemoryDataTreeCandidate c = (InMemoryDataTreeCandidate)candidate;
if (LOG.isTraceEnabled()) {
- LOG.trace("Data Tree is {}", StoreUtils.toStringTree(c.getAfterRoot().getData()));
+ LOG.trace("Data Tree is {}", NormalizedNodes.toStringTree(c.getAfterRoot().getData()));
}
final TreeNode newRoot = c.getAfterRoot();
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNodes;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* the requested path which has been modified. If no such node exists,
* we use the node itself.
*/
- final Entry<YangInstanceIdentifier, ModifiedNode> entry = TreeNodeUtils.findClosestsOrFirstMatch(rootNode, path, ModifiedNode.IS_TERMINAL_PREDICATE);
+ final Entry<YangInstanceIdentifier, ModifiedNode> entry = StoreTreeNodes.findClosestsOrFirstMatch(rootNode, path, ModifiedNode.IS_TERMINAL_PREDICATE);
final YangInstanceIdentifier key = entry.getKey();
final ModifiedNode mod = entry.getValue();
final Optional<TreeNode> result = resolveSnapshot(key, mod);
if (result.isPresent()) {
NormalizedNode<?, ?> data = result.get().getData();
- return NormalizedNodeUtils.findNode(key, data, path);
+ return NormalizedNodes.findNode(key, data, path);
} else {
return Optional.absent();
}
strategyTree.upgradeIfPossible();
}
- return TreeNodeUtils.<ModificationApplyOperation>findNodeChecked(strategyTree, path);
+ return StoreTreeNodes.<ModificationApplyOperation>findNodeChecked(strategyTree, path);
}
private OperationWithModification resolveModificationFor(final YangInstanceIdentifier path) {
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
final class InMemoryDataTreeSnapshot implements DataTreeSnapshot {
private final RootModificationApplyOperation applyOper;
private final SchemaContext schemaContext;
@Override
public Optional<NormalizedNode<?, ?>> readNode(final YangInstanceIdentifier path) {
- return NormalizedNodeUtils.findNode(rootNode.getData(), path);
+ return NormalizedNodes.findNode(rootNode.getData(), path);
}
@Override
* to the data store tree.
*
* This tree is lazily created and populated via {@link #modifyChild(PathArgument)}
- * and {@link StoreMetadataNode} which represents original state {@link #getOriginal()}.
+ * and {@link TreeNode} which represents original state as tracked by {@link #getOriginal()}.
*/
@NotThreadSafe
final class ModifiedNode extends NodeModification implements StoreTreeNode<ModifiedNode> {
-
- public static final Predicate<ModifiedNode> IS_TERMINAL_PREDICATE = new Predicate<ModifiedNode>() {
+ static final Predicate<ModifiedNode> IS_TERMINAL_PREDICATE = new Predicate<ModifiedNode>() {
@Override
public boolean apply(final @Nonnull ModifiedNode input) {
Preconditions.checkNotNull(input);
}
/**
+ * Return the value which was written to this node.
*
- *
- * @return
+ * @return Currently-written value
*/
public NormalizedNode<?, ?> getWrittenValue() {
return value;
/**
*
- * Returns child modification if child was modified, creates {@link org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ModifiedNode}
+ * Returns child modification if child was modified, creates {@link ModifiedNode}
* for child otherwise.
*
* If this node's {@link ModificationType} is {@link ModificationType#UNMODIFIED}
* changes modification type to {@link ModificationType#SUBTREE_MODIFIED}
*
* @param child
- * @return {@link org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ModifiedNode} for specified child, with {@link #getOriginal()}
+ * @return {@link ModifiedNode} for specified child, with {@link #getOriginal()}
* containing child metadata if child was present in original data.
*/
- public ModifiedNode modifyChild(final PathArgument child, final boolean isOrdered) {
+ ModifiedNode modifyChild(final PathArgument child, final boolean isOrdered) {
clearSnapshot();
if (modificationType == ModificationType.UNMODIFIED) {
updateModificationType(ModificationType.SUBTREE_MODIFIED);
}
/**
- *
* Returns all recorded direct child modification
*
* @return all recorded direct child modifications
}
/**
- *
* Records a delete for associated node.
- *
*/
- public void delete() {
+ void delete() {
final ModificationType newType;
switch (modificationType) {
}
/**
- *
* Records a write for associated node.
*
* @param value
*/
- public void write(final NormalizedNode<?, ?> value) {
+ void write(final NormalizedNode<?, ?> value) {
clearSnapshot();
updateModificationType(ModificationType.WRITE);
children.clear();
this.value = value;
}
- public void merge(final NormalizedNode<?, ?> data) {
+ void merge(final NormalizedNode<?, ?> value) {
clearSnapshot();
updateModificationType(ModificationType.MERGE);
- // FIXME: Probably merge with previous value.
- this.value = data;
+
+ /*
+ * Blind overwrite of any previous data is okay, no matter whether the node
+ * is simple or complex type.
+ *
+ * If this is a simple or complex type with unkeyed children, this merge will
+ * be turned into a write operation, overwriting whatever was there before.
+ *
+ * If this is a container with keyed children, there are two possibilities:
+ * - if it existed before, this value will never be consulted and the children
+ * will get explicitly merged onto the original data.
+ * - if it did not exist before, this value will be used as a seed write and
+ * children will be merged into it.
+ * In either case we rely on OperationWithModification to manipulate the children
+ * before calling this method, so unlike a write we do not want to clear them.
+ */
+ this.value = value;
}
/**
@SuppressWarnings("rawtypes")
@Override
protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
- checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass);
+ checkArgument(nodeClass.isInstance(writtenValue), "Node %s is not of type %s", writtenValue, nodeClass);
checkArgument(writtenValue instanceof NormalizedNodeContainer);
NormalizedNodeContainer container = (NormalizedNodeContainer) writtenValue;
* As it turns out, once we materialize the written data, we can share the
* code path with the subtree change. So let's create an unsealed TreeNode
* and run the common parts on it -- which end with the node being sealed.
+ *
+ * FIXME: this code needs to be moved out from the prepare() path and into
+ * the read() and seal() paths. Merging of writes needs to be charged
+ * to the code which originated this, not to the code which is
+ * attempting to make it visible.
*/
final MutableTreeNode mutable = newValueMeta.mutable();
mutable.setSubtreeVersion(version);
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
import java.util.List;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-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.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
import org.opendaylight.yangtools.yang.data.api.schema.tree.IncorrectDataStructureException;
import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.MutableTreeNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNodeFactory;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
final Optional<TreeNode> current) throws DataValidationFailedException;
protected abstract void verifyWrittenStructure(NormalizedNode<?, ?> writtenValue);
-
- public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation {
-
- private final Optional<ModificationApplyOperation> entryStrategy;
-
- protected UnkeyedListModificationStrategy(final ListSchemaNode schema) {
- entryStrategy = Optional.<ModificationApplyOperation> of(new DataNodeContainerModificationStrategy.UnkeyedListItemModificationStrategy(schema));
- }
-
- @Override
- boolean isOrdered() {
- return true;
- }
-
- @Override
- protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
- final Version version) {
- return applyWrite(modification, Optional.of(currentMeta), version);
- }
-
- @Override
- protected TreeNode applySubtreeChange(final ModifiedNode modification,
- final TreeNode currentMeta, final Version version) {
- throw new UnsupportedOperationException("UnkeyedList does not support subtree change.");
- }
-
- @Override
- protected TreeNode applyWrite(final ModifiedNode modification,
- final Optional<TreeNode> currentMeta, final Version version) {
- final NormalizedNode<?, ?> newValue = modification.getWrittenValue();
- final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, version);
-
- if (Iterables.isEmpty(modification.getChildren())) {
- return newValueMeta;
- }
-
- /*
- * This is where things get interesting. The user has performed a write and
- * then she applied some more modifications to it. So we need to make sense
- * of that an apply the operations on top of the written value. We could have
- * done it during the write, but this operation is potentially expensive, so
- * we have left it out of the fast path.
- *
- * As it turns out, once we materialize the written data, we can share the
- * code path with the subtree change. So let's create an unsealed TreeNode
- * and run the common parts on it -- which end with the node being sealed.
- */
- final MutableTreeNode mutable = newValueMeta.mutable();
- mutable.setSubtreeVersion(version);
-
- @SuppressWarnings("rawtypes")
- final NormalizedNodeContainerBuilder dataBuilder = ImmutableUnkeyedListEntryNodeBuilder
- .create((UnkeyedListEntryNode) newValue);
-
- return mutateChildren(mutable, dataBuilder, version, modification.getChildren());
- }
-
- /**
- * Applies write/remove diff operation for each modification child in modification subtree.
- * Operation also sets the Data tree references for each Tree Node (Index Node) in meta (MutableTreeNode) structure.
- *
- * @param meta MutableTreeNode (IndexTreeNode)
- * @param data DataBuilder
- * @param nodeVersion Version of TreeNode
- * @param modifications modification operations to apply
- * @return Sealed immutable copy of TreeNode structure with all Data Node references set.
- */
- @SuppressWarnings({ "rawtypes", "unchecked" })
- private TreeNode mutateChildren(final MutableTreeNode meta, final NormalizedNodeContainerBuilder data,
- final Version nodeVersion, final Iterable<ModifiedNode> modifications) {
-
- for (ModifiedNode mod : modifications) {
- final PathArgument id = mod.getIdentifier();
- final Optional<TreeNode> cm = meta.getChild(id);
-
- Optional<TreeNode> result = resolveChildOperation(id).apply(mod, cm, nodeVersion);
- if (result.isPresent()) {
- final TreeNode tn = result.get();
- meta.addChild(tn);
- data.addChild(tn.getData());
- } else {
- meta.removeChild(id);
- data.removeChild(id);
- }
- }
-
- meta.setData(data.build());
- return meta.seal();
- }
-
- @Override
- public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
- if (child instanceof NodeIdentifier) {
- return entryStrategy;
- }
- return Optional.absent();
- }
-
- @Override
- protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
-
- }
-
- @Override
- protected void checkSubtreeModificationApplicable(final YangInstanceIdentifier path, final NodeModification modification,
- final Optional<TreeNode> current) throws IncorrectDataStructureException {
- throw new IncorrectDataStructureException(path, "Subtree modification is not allowed.");
- }
- }
}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-
-import com.google.common.base.Strings;
-
-/**
- * Data store tree manipulation utilities.
- */
-public final class StoreUtils {
- private static final int STRINGTREE_INDENT = 4;
-
- private StoreUtils() {
- throw new UnsupportedOperationException("Utility class should not be instantiated");
- }
-
- /**
- * Convert a data subtree under a node into a human-readable string format.
- *
- * @param node Data subtree root
- * @return String containing a human-readable form of the subtree.
- */
- public static String toStringTree(final NormalizedNode<?, ?> node) {
- final StringBuilder builder = new StringBuilder();
- toStringTree(builder, node, 0);
- return builder.toString();
- }
-
- private static void toStringTree(final StringBuilder builder, final NormalizedNode<?, ?> node, final int offset) {
- final String prefix = Strings.repeat(" ", offset);
-
- builder.append(prefix).append(toStringTree(node.getIdentifier()));
- if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
- final NormalizedNodeContainer<?, ?, ?> container = (NormalizedNodeContainer<?, ?, ?>) node;
-
- builder.append(" {\n");
- for (NormalizedNode<?, ?> child : container.getValue()) {
- toStringTree(builder, child, offset + STRINGTREE_INDENT);
- }
-
- builder.append(prefix).append('}');
- } else {
- builder.append(' ').append(node.getValue());
- }
- builder.append('\n');
- }
-
- private static String toStringTree(final PathArgument identifier) {
- if (identifier instanceof NodeIdentifierWithPredicates) {
- StringBuilder builder = new StringBuilder();
- builder.append(identifier.getNodeType().getLocalName());
- builder.append(((NodeIdentifierWithPredicates) identifier).getKeyValues().values());
- return builder.toString();
- } else if (identifier instanceof AugmentationIdentifier) {
- return "augmentation";
- }
- return identifier.getNodeType().getLocalName();
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.impl.schema.tree;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+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.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.IncorrectDataStructureException;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.MutableTreeNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNodeFactory;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+final class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation {
+
+ private final Optional<ModificationApplyOperation> entryStrategy;
+
+ protected UnkeyedListModificationStrategy(final ListSchemaNode schema) {
+ entryStrategy = Optional.<ModificationApplyOperation> of(new DataNodeContainerModificationStrategy.UnkeyedListItemModificationStrategy(schema));
+ }
+
+ @Override
+ boolean isOrdered() {
+ return true;
+ }
+
+ @Override
+ protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
+ final Version version) {
+ return applyWrite(modification, Optional.of(currentMeta), version);
+ }
+
+ @Override
+ protected TreeNode applySubtreeChange(final ModifiedNode modification,
+ final TreeNode currentMeta, final Version version) {
+ throw new UnsupportedOperationException("UnkeyedList does not support subtree change.");
+ }
+
+ @Override
+ protected TreeNode applyWrite(final ModifiedNode modification,
+ final Optional<TreeNode> currentMeta, final Version version) {
+ final NormalizedNode<?, ?> newValue = modification.getWrittenValue();
+ final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, version);
+
+ if (Iterables.isEmpty(modification.getChildren())) {
+ return newValueMeta;
+ }
+
+ /*
+ * This is where things get interesting. The user has performed a write and
+ * then she applied some more modifications to it. So we need to make sense
+ * of that an apply the operations on top of the written value. We could have
+ * done it during the write, but this operation is potentially expensive, so
+ * we have left it out of the fast path.
+ *
+ * As it turns out, once we materialize the written data, we can share the
+ * code path with the subtree change. So let's create an unsealed TreeNode
+ * and run the common parts on it -- which end with the node being sealed.
+ */
+ final MutableTreeNode mutable = newValueMeta.mutable();
+ mutable.setSubtreeVersion(version);
+
+ @SuppressWarnings("rawtypes")
+ final NormalizedNodeContainerBuilder dataBuilder = ImmutableUnkeyedListEntryNodeBuilder
+ .create((UnkeyedListEntryNode) newValue);
+
+ return mutateChildren(mutable, dataBuilder, version, modification.getChildren());
+ }
+
+ /**
+ * Applies write/remove diff operation for each modification child in modification subtree.
+ * Operation also sets the Data tree references for each Tree Node (Index Node) in meta (MutableTreeNode) structure.
+ *
+ * @param meta MutableTreeNode (IndexTreeNode)
+ * @param data DataBuilder
+ * @param nodeVersion Version of TreeNode
+ * @param modifications modification operations to apply
+ * @return Sealed immutable copy of TreeNode structure with all Data Node references set.
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private TreeNode mutateChildren(final MutableTreeNode meta, final NormalizedNodeContainerBuilder data,
+ final Version nodeVersion, final Iterable<ModifiedNode> modifications) {
+
+ for (ModifiedNode mod : modifications) {
+ final PathArgument id = mod.getIdentifier();
+ final Optional<TreeNode> cm = meta.getChild(id);
+
+ Optional<TreeNode> result = resolveChildOperation(id).apply(mod, cm, nodeVersion);
+ if (result.isPresent()) {
+ final TreeNode tn = result.get();
+ meta.addChild(tn);
+ data.addChild(tn.getData());
+ } else {
+ meta.removeChild(id);
+ data.removeChild(id);
+ }
+ }
+
+ meta.setData(data.build());
+ return meta.seal();
+ }
+
+ @Override
+ public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
+ if (child instanceof NodeIdentifier) {
+ return entryStrategy;
+ }
+ return Optional.absent();
+ }
+
+ @Override
+ protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
+
+ }
+
+ @Override
+ protected void checkSubtreeModificationApplicable(final YangInstanceIdentifier path, final NodeModification modification,
+ final Optional<TreeNode> current) throws IncorrectDataStructureException {
+ throw new IncorrectDataStructureException(path, "Subtree modification is not allowed.");
+ }
+}
\ No newline at end of file
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
-
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
-
import org.custommonkey.xmlunit.Diff;
import org.junit.Assert;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
/**
* @author michal.rehak
*
- * @deprecated Use {@link NormalizedNodeUtils} instead.
+ * @deprecated Use {@link NormalizedNodes} instead.
*/
@Deprecated
public abstract class NodeHelper {
import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
-
+import com.google.common.base.Optional;
import org.junit.Test;
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.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import com.google.common.base.Optional;
-
/**
*
* Schema structure of document is
NormalizedNode<?, ?> tree = createDocumentOne();
assertNotNull(tree);
- Optional<NormalizedNode<?, ?>> listFooResult = NormalizedNodeUtils.findNode(tree, LIST_A_FOO_PATH);
+ Optional<NormalizedNode<?, ?>> listFooResult = NormalizedNodes.findNode(tree, LIST_A_FOO_PATH);
assertTrue(listFooResult.isPresent());
- Optional<NormalizedNode<?, ?>> listTwoResult = NormalizedNodeUtils.findNode(tree, LIST_B_TWO_PATH);
+ Optional<NormalizedNode<?, ?>> listTwoResult = NormalizedNodes.findNode(tree, LIST_B_TWO_PATH);
assertTrue(listTwoResult.isPresent());
}
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
import static org.junit.Assert.assertEquals;
import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
-
import com.google.common.base.Optional;
-
import java.util.Map;
-
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNodes;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNodeFactory;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-public class TreeNodeUtilsTest {
- private static final Logger LOG = LoggerFactory.getLogger(TreeNodeUtilsTest.class);
+public class StoreTreeNodesTest {
+ private static final Logger LOG = LoggerFactory.getLogger(StoreTreeNodesTest.class);
private static final Short ONE_ID = 1;
private static final Short TWO_ID = 2;
InMemoryDataTreeSnapshot inMemoryDataTreeSnapshot = new InMemoryDataTreeSnapshot(schemaContext,
TreeNodeFactory.createTreeNodeRecursively(createDocumentOne(), Version.initial()), rootOper);
TreeNode rootNode = inMemoryDataTreeSnapshot.getRootNode();
- Optional<TreeNode> node = TreeNodeUtils.findNode(rootNode, OUTER_LIST_1_PATH);
+ Optional<TreeNode> node = StoreTreeNodes.findNode(rootNode, OUTER_LIST_1_PATH);
assertPresentAndType(node, TreeNode.class);
}
final YangInstanceIdentifier outerList1InvalidPath = YangInstanceIdentifier.builder(TestModel.OUTER_LIST_PATH)
.nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 3) //
.build();
- Optional<TreeNode> node = TreeNodeUtils.findNode(rootNode, outerList1InvalidPath);
+ Optional<TreeNode> node = StoreTreeNodes.findNode(rootNode, outerList1InvalidPath);
assertFalse(node.isPresent());
}
TreeNode rootNode = inMemoryDataTreeSnapshot.getRootNode();
TreeNode foundNode = null;
try {
- foundNode = TreeNodeUtils.findNodeChecked(rootNode, OUTER_LIST_1_PATH);
+ foundNode = StoreTreeNodes.findNodeChecked(rootNode, OUTER_LIST_1_PATH);
} catch (IllegalArgumentException e) {
fail("Illegal argument exception was thrown and should not have been" + e.getMessage());
}
.nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 3) //
.build();
try {
- TreeNodeUtils.findNodeChecked(rootNode, outerList1InvalidPath);
+ StoreTreeNodes.findNodeChecked(rootNode, outerList1InvalidPath);
fail("Illegal argument exception should have been thrown");
} catch (IllegalArgumentException e) {
LOG.debug("Illegal argument exception was thrown as expected: '{}' - '{}'", e.getClass(), e.getMessage());
InMemoryDataTreeSnapshot inMemoryDataTreeSnapshot = new InMemoryDataTreeSnapshot(schemaContext,
TreeNodeFactory.createTreeNodeRecursively(createDocumentOne(), Version.initial()), rootOper);
TreeNode rootNode = inMemoryDataTreeSnapshot.getRootNode();
- Optional<TreeNode> expectedNode = TreeNodeUtils.findNode(rootNode, TWO_TWO_PATH);
+ Optional<TreeNode> expectedNode = StoreTreeNodes.findNode(rootNode, TWO_TWO_PATH);
assertPresentAndType(expectedNode, TreeNode.class);
- Map.Entry<YangInstanceIdentifier, TreeNode> actualNode = TreeNodeUtils.findClosest(rootNode, TWO_TWO_PATH);
+ Map.Entry<YangInstanceIdentifier, TreeNode> actualNode = StoreTreeNodes.findClosest(rootNode, TWO_TWO_PATH);
assertEquals("Expected node and actual node are not the same", expectedNode.get(), actualNode.getValue());
}
.node(TestModel.INNER_LIST_QNAME) //
.nodeWithKey(TestModel.INNER_LIST_QNAME, TestModel.NAME_QNAME, "three") //
.build();
- Optional<TreeNode> expectedNode = TreeNodeUtils.findNode(rootNode, outerListInnerListPath);
+ Optional<TreeNode> expectedNode = StoreTreeNodes.findNode(rootNode, outerListInnerListPath);
assertPresentAndType(expectedNode, TreeNode.class);
- Map.Entry<YangInstanceIdentifier, TreeNode> actualNode = TreeNodeUtils.findClosest(rootNode, twoTwoInvalidPath);
+ Map.Entry<YangInstanceIdentifier, TreeNode> actualNode = StoreTreeNodes.findClosest(rootNode, twoTwoInvalidPath);
assertEquals("Expected node and actual node are not the same", expectedNode.get(), actualNode.getValue());
}
InMemoryDataTreeSnapshot inMemoryDataTreeSnapshot = new InMemoryDataTreeSnapshot(schemaContext,
TreeNodeFactory.createTreeNodeRecursively(createDocumentOne(), Version.initial()), rootOper);
TreeNode rootNode = inMemoryDataTreeSnapshot.getRootNode();
- Optional<TreeNode> node = TreeNodeUtils.getChild(Optional.fromNullable(rootNode),
+ Optional<TreeNode> node = StoreTreeNodes.getChild(Optional.fromNullable(rootNode),
TestModel.TEST_PATH.getLastPathArgument());
assertPresentAndType(node, TreeNode.class);
}
InMemoryDataTreeSnapshot inMemoryDataTreeSnapshot = new InMemoryDataTreeSnapshot(schemaContext,
TreeNodeFactory.createTreeNodeRecursively(createDocumentOne(), Version.initial()), rootOper);
TreeNode rootNode = inMemoryDataTreeSnapshot.getRootNode();
- Optional<TreeNode> node = TreeNodeUtils.getChild(Optional.fromNullable(rootNode),
+ Optional<TreeNode> node = StoreTreeNodes.getChild(Optional.fromNullable(rootNode),
TestModel.OUTER_LIST_PATH.getLastPathArgument());
assertFalse(node.isPresent());
}
yang_version_stmt : YANG_VERSION_KEYWORD string stmtend;
data_def_stmt : container_stmt | leaf_stmt | leaf_list_stmt | list_stmt | choice_stmt | anyxml_stmt | uses_stmt;
body_stmts : (( identifier_stmt| extension_stmt | feature_stmt | identity_stmt | typedef_stmt | grouping_stmt | data_def_stmt | augment_stmt | rpc_stmt | notification_stmt | deviation_stmt) )*;
-revision_stmts : (revision_stmt )* (stmtsep)*;
+revision_stmts : (revision_stmt | stmtsep)*;
linkage_stmts : (import_stmt stmtsep* | include_stmt stmtsep*)*;
meta_stmts : (organization_stmt stmtsep* | contact_stmt stmtsep* | description_stmt stmtsep* | reference_stmt stmtsep*)*;
submodule_header_stmts : (yang_version_stmt stmtsep* | belongs_to_stmt stmtsep*)+ ;
module_header_stmts : (yang_version_stmt stmtsep* | namespace_stmt stmtsep* | prefix_stmt stmtsep*)+ ;
-submodule_stmt : SUBMODULE_KEYWORD string LEFT_BRACE submodule_header_stmts linkage_stmts meta_stmts revision_stmts body_stmts RIGHT_BRACE;
+submodule_stmt : SUBMODULE_KEYWORD string LEFT_BRACE stmtsep* submodule_header_stmts linkage_stmts meta_stmts revision_stmts body_stmts RIGHT_BRACE;
module_stmt : MODULE_KEYWORD string LEFT_BRACE stmtsep* module_header_stmts linkage_stmts meta_stmts revision_stmts body_stmts RIGHT_BRACE;
\ No newline at end of file
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.URI;
+import java.net.URISyntaxException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.Set;
+
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
import org.opendaylight.yangtools.yang.model.util.Decimal64;
import org.opendaylight.yangtools.yang.model.util.ExtendedType;
import org.opendaylight.yangtools.yang.model.util.Int16;
import org.opendaylight.yangtools.yang.model.util.Uint32;
import org.opendaylight.yangtools.yang.model.util.UnionType;
import org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils;
+import org.opendaylight.yangtools.yang.parser.util.YangParseException;
public class YangParserTest {
public static final String FS = File.separator;
assertEquals(2, foo.getAugmentations().size());
}
+ @Test
+ public void unknownStatementInSubmoduleHeaderTest() throws IOException, URISyntaxException {
+
+ File yang = new File(getClass().getResource("/yang-grammar-test/submodule-header-extension.yang").toURI());
+
+ try {
+ YangParserImpl.getInstance().parseFile(yang, yang.getParentFile());
+ } catch (YangSyntaxErrorException | YangParseException e) {
+ e.printStackTrace();
+ fail("YangSyntaxErrorException or YangParseException should not be thrown");
+ }
+
+ }
+
+ @Test
+ public void unknownStatementBetweenRevisionsTest() throws IOException, URISyntaxException {
+
+ File yangModul = new File(getClass().getResource("/yang-grammar-test/revisions-extension.yang").toURI());
+ File yangSubmodul = new File(getClass().getResource("/yang-grammar-test/submodule-header-extension.yang")
+ .toURI());
+
+ List<File> yangs = new ArrayList<File>();
+ yangs.add(yangModul);
+ yangs.add(yangSubmodul);
+
+ try {
+ YangParserImpl.getInstance().parseFiles(yangs);
+ } catch (YangParseException e) {
+ e.printStackTrace();
+ fail("YangParseException should not be thrown");
+ }
+ }
}
--- /dev/null
+module revisions-extension {
+ namespace "my-namespace";
+ prefix pre;
+
+ include submodule-header-extension {
+ revision-date 2007-06-09;
+ }
+
+ revision "2007-06-09" {
+ description "Initial revision.";
+ }
+
+ pre:my-extension 1;
+
+ revision "2008-06-09" {
+ description "Revision 2.";
+ }
+
+ extension my-extension {
+ description "my description ...";
+ argument "number";
+ }
+
+}
--- /dev/null
+submodule submodule-header-extension {
+
+ pre:my-extension2 2;
+
+ belongs-to revisions-extension {
+ prefix pre;
+ }
+
+ revision "2007-06-09" {
+ description "Initial revision.";
+ }
+
+ extension my-extension2 {
+ description "my description ...";
+ argument "number";
+ }
+
+}