* 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 java.util.Optional;
-import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
abstract class AbstractAvailableLeafCandidateNode extends AbstractLeafCandidateNode {
- protected AbstractAvailableLeafCandidateNode(final NormalizedNode<?, ?> dataAfter) {
+ AbstractAvailableLeafCandidateNode(final NormalizedNode<?, ?> dataAfter) {
super(dataAfter);
}
- @Nonnull
@Override
public final Optional<NormalizedNode<?, ?>> getDataAfter() {
return dataOptional();
--- /dev/null
+/*
+ * Copyright (c) 2015, 2016 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.api.schema.tree;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+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;
+
+abstract class AbstractDataTreeCandidateNode implements DataTreeCandidateNode {
+ private final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?,?>> data;
+
+ AbstractDataTreeCandidateNode(final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> data) {
+ this.data = requireNonNull(data);
+ }
+
+ @Override
+ public final PathArgument getIdentifier() {
+ return data.getIdentifier();
+ }
+
+ final @NonNull Optional<NormalizedNode<?, ?>> dataOptional() {
+ return Optional.of(data);
+ }
+
+ final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> data() {
+ return data;
+ }
+
+ @Override
+ public String toString() {
+ return this.getClass().getSimpleName() + "{data = " + this.data + "}";
+ }
+}
* 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 static java.util.Objects.requireNonNull;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
-import javax.annotation.Nonnull;
+import org.eclipse.jdt.annotation.NonNull;
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.tree.DataTreeCandidateNode;
abstract class AbstractLeafCandidateNode implements DataTreeCandidateNode {
private final NormalizedNode<?, ?> data;
- protected AbstractLeafCandidateNode(final NormalizedNode<?, ?> data) {
+ AbstractLeafCandidateNode(final NormalizedNode<?, ?> data) {
this.data = requireNonNull(data);
}
- protected final Optional<NormalizedNode<?, ?>> dataOptional() {
+ final @NonNull Optional<NormalizedNode<?, ?>> dataOptional() {
return Optional.of(data);
}
- @Nonnull
@Override
public final Collection<DataTreeCandidateNode> getChildNodes() {
return Collections.emptyList();
}
@Override
- @Nonnull
public final PathArgument getIdentifier() {
return data.getIdentifier();
}
@Override
public final DataTreeCandidateNode getModifiedChild(final PathArgument identifier) {
+ requireNonNull(identifier);
return null;
}
}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 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.api.schema.tree;
+
+import com.google.common.collect.Collections2;
+import java.util.Collection;
+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;
+
+abstract class AbstractRecursiveCandidateNode extends AbstractDataTreeCandidateNode {
+ AbstractRecursiveCandidateNode(final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> data) {
+ super(data);
+ }
+
+ @Override
+ public final DataTreeCandidateNode getModifiedChild(final PathArgument identifier) {
+ return data().getChild(identifier).map(this::createChild).orElse(null);
+ }
+
+ @Override
+ public final Collection<DataTreeCandidateNode> getChildNodes() {
+ return Collections2.transform(data().getValue(), this::createChild);
+ }
+
+ abstract DataTreeCandidateNode createContainer(
+ NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> childData);
+
+ abstract DataTreeCandidateNode createLeaf(NormalizedNode<?,?> childData);
+
+ @SuppressWarnings("unchecked")
+ private DataTreeCandidateNode createChild(final NormalizedNode<?, ?> childData) {
+ if (childData instanceof NormalizedNodeContainer) {
+ return createContainer((NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) childData);
+ }
+ return createLeaf(childData);
+ }
+}
* 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 javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
abstract class AbstractWriteCandidate extends AbstractAvailableLeafCandidateNode {
- protected AbstractWriteCandidate(final NormalizedNode<?, ?> dataAfter) {
+ AbstractWriteCandidate(final NormalizedNode<?, ?> dataAfter) {
super(dataAfter);
}
@Override
- @Nonnull
public final ModificationType getModificationType() {
return ModificationType.WRITE;
}
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
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.NormalizedNodeContainer;
@Beta
public final class DataTreeCandidateNodes {
/**
* Return an empty {@link DataTreeCandidateNode} identified by specified {@link PathArgument}.
+ *
* @param identifier Node identifier
* @return An empty DataTreeCandidateNode
*/
- public static DataTreeCandidateNode empty(final PathArgument identifier) {
+ public static @NonNull DataTreeCandidateNode empty(final PathArgument identifier) {
return new EmptyDataTreeCandidateNode(identifier);
}
- public static DataTreeCandidateNode fromNormalizedNode(final NormalizedNode<?, ?> node) {
+ @Deprecated
+ public static @NonNull DataTreeCandidateNode fromNormalizedNode(final NormalizedNode<?, ?> node) {
+ return written(node);
+ }
+
+ /**
+ * Return an unmodified {@link DataTreeCandidateNode} identified by specified {@link NormalizedNode}.
+ *
+ * @param node Unchanged normalized node
+ * @return An empty DataTreeCandidateNode
+ */
+ public static @NonNull DataTreeCandidateNode unmodified(final NormalizedNode<?, ?> node) {
+ if (node instanceof NormalizedNodeContainer) {
+ return new RecursiveUnmodifiedCandidateNode(
+ (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) node);
+ }
+ return new UnmodifiedLeafCandidateNode(node);
+ }
+
+ /**
+ * Return a {@link DataTreeCandidateNode} pretending specified node was written without the data exsting beforehand.
+ *
+ * @param node Unchanged normalized node
+ * @return An empty DataTreeCandidateNode
+ * @throws NullPointerException if {@code node} is null
+ */
+ public static @NonNull DataTreeCandidateNode written(final NormalizedNode<?, ?> node) {
return new NormalizedNodeDataTreeCandidateNode(node);
}
+ /**
+ * Return a collection of {@link DataTreeCandidateNode}s summarizing the changes between the contents of two
+ * {@link NormalizedNodeContainer}s.
+ *
+ * @param oldData Old data container, may be null
+ * @param newData New data container, may be null
+ * @return Collection of changes
+ */
+ public static @NonNull Collection<DataTreeCandidateNode> containerDelta(
+ final @Nullable NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> oldData,
+ final @Nullable NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> newData) {
+ if (newData == null) {
+ return oldData == null ? ImmutableList.of()
+ : Collections2.transform(oldData.getValue(), DataTreeCandidateNodes::deleteNode);
+ }
+ if (oldData == null) {
+ return Collections2.transform(newData.getValue(), DataTreeCandidateNodes::writeNode);
+ }
+
+ /*
+ * This is slightly inefficient, as it requires N*F(M)+M*F(N) lookup operations, where
+ * F is dependent on the implementation of NormalizedNodeContainer.getChild().
+ *
+ * We build the return collection by iterating over new data and looking each child up
+ * in old data. Based on that we construct replaced/written nodes. We then proceed to
+ * iterate over old data and looking up each child in new data.
+ */
+ final Collection<DataTreeCandidateNode> result = new ArrayList<>();
+ for (NormalizedNode<?, ?> child : newData.getValue()) {
+ final DataTreeCandidateNode node;
+ final Optional<NormalizedNode<?, ?>> maybeOldChild = oldData.getChild(child.getIdentifier());
+
+ if (maybeOldChild.isPresent()) {
+ // This does not find children which have not in fact been modified, as doing that
+ // reliably would require us running a full equals() on the two nodes.
+ node = replaceNode(maybeOldChild.get(), child);
+ } else {
+ node = writeNode(child);
+ }
+
+ result.add(node);
+ }
+
+ // Process removals next, looking into new data to see if we processed it
+ for (NormalizedNode<?, ?> child : oldData.getValue()) {
+ if (!newData.getChild(child.getIdentifier()).isPresent()) {
+ result.add(deleteNode(child));
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Return a collection of {@link DataTreeCandidateNode}s summarizing the change in a child, identified by a
+ * {@link PathArgument}, between two {@link NormalizedNodeContainer}s.
+ *
+ * @param oldData Old data container, may be null
+ * @param newData New data container, may be null
+ * @return A {@link DataTreeCandidateNode} describing the change, or null if the node is not present
+ */
+ public static @Nullable DataTreeCandidateNode containerDelta(
+ final @Nullable NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> oldData,
+ final @Nullable NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> newData,
+ final @NonNull PathArgument child) {
+ final Optional<NormalizedNode<?, ?>> maybeNewChild = getChild(newData, child);
+ final Optional<NormalizedNode<?, ?>> maybeOldChild = getChild(oldData, child);
+ if (maybeOldChild.isPresent()) {
+ final NormalizedNode<?, ?> oldChild = maybeOldChild.get();
+ if (maybeNewChild.isPresent()) {
+ return replaceNode(oldChild, maybeNewChild.get());
+ }
+ return deleteNode(oldChild);
+ }
+
+ return maybeNewChild.isPresent() ? writeNode(maybeNewChild.get()) : null;
+ }
+
/**
* Applies the {@code node} to the {@code cursor}, note that if the top node of (@code node} is RootNode
* you need to use {@link #applyRootedNodeToCursor(DataTreeModificationCursor, YangInstanceIdentifier,
}
}
+ private static Optional<NormalizedNode<?, ?>> getChild(
+ final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> container,
+ final PathArgument identifier) {
+ return container == null ? Optional.empty() : container.getChild(identifier);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static @NonNull DataTreeCandidateNode deleteNode(final NormalizedNode<?, ?> data) {
+ if (data instanceof NormalizedNodeContainer) {
+ return new RecursiveDeleteCandidateNode(
+ (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) data);
+ }
+ return new DeleteLeafCandidateNode(data);
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private static @NonNull DataTreeCandidateNode replaceNode(final NormalizedNode<?, ?> oldData,
+ final NormalizedNode<?, ?> newData) {
+ if (oldData instanceof NormalizedNodeContainer) {
+ return new RecursiveReplaceCandidateNode(
+ (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) oldData,
+ (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) newData);
+ }
+ return new ReplaceLeafCandidateNode(oldData, newData);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static @NonNull DataTreeCandidateNode writeNode(final NormalizedNode<?, ?> data) {
+ if (data instanceof NormalizedNodeContainer) {
+ return new RecursiveWriteCandidateNode(
+ (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) data);
+ }
+ return new WriteLeafCandidateNode(data);
+ }
+
private abstract static class AbstractNodeIterator {
private final Iterator<DataTreeCandidateNode> iterator;
return getParent();
}
- protected abstract @Nullable AbstractNodeIterator getParent();
+ abstract @Nullable AbstractNodeIterator getParent();
- protected abstract void exitNode(DataTreeModificationCursor cursor);
+ abstract void exitNode(DataTreeModificationCursor cursor);
}
private static final class RootNonExitingIterator extends AbstractNodeIterator {
- protected RootNonExitingIterator(@Nonnull final Iterator<DataTreeCandidateNode> iterator) {
+ RootNonExitingIterator(final Iterator<DataTreeCandidateNode> iterator) {
super(iterator);
}
private final AbstractNodeIterator parent;
- ExitingNodeIterator(@Nullable final AbstractNodeIterator parent,
- @Nonnull final Iterator<DataTreeCandidateNode> iterator) {
+ ExitingNodeIterator(final AbstractNodeIterator parent, final Iterator<DataTreeCandidateNode> iterator) {
super(iterator);
this.parent = parent;
}
@Override
- protected AbstractNodeIterator getParent() {
+ AbstractNodeIterator getParent() {
return parent;
}
@Override
- protected void exitNode(final DataTreeModificationCursor cursor) {
+ void exitNode(final DataTreeModificationCursor cursor) {
cursor.exit();
}
}
import com.google.common.annotations.Beta;
import java.util.Iterator;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.slf4j.Logger;
throw new UnsupportedOperationException();
}
- public static DataTreeCandidate newDataTreeCandidate(final YangInstanceIdentifier rootPath,
+ public static @NonNull DataTreeCandidate newDataTreeCandidate(final YangInstanceIdentifier rootPath,
final DataTreeCandidateNode rootNode) {
return new DefaultDataTreeCandidate(rootPath, rootNode);
}
- public static DataTreeCandidate fromNormalizedNode(final YangInstanceIdentifier rootPath,
+ public static @NonNull DataTreeCandidate fromNormalizedNode(final YangInstanceIdentifier rootPath,
final NormalizedNode<?, ?> node) {
return new DefaultDataTreeCandidate(rootPath, new NormalizedNodeDataTreeCandidateNode(node));
}
private final YangInstanceIdentifier path;
private final NodeIterator parent;
- NodeIterator(@Nullable final NodeIterator parent, @Nonnull final YangInstanceIdentifier path,
- @Nonnull final Iterator<DataTreeCandidateNode> iterator) {
+ NodeIterator(final @Nullable NodeIterator parent, final YangInstanceIdentifier path,
+ final Iterator<DataTreeCandidateNode> iterator) {
this.iterator = requireNonNull(iterator);
this.path = requireNonNull(path);
this.parent = parent;
* 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 java.util.Optional;
-import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
final class DeleteLeafCandidateNode extends AbstractLeafCandidateNode {
DeleteLeafCandidateNode(final NormalizedNode<?, ?> data) {
}
@Override
- @Nonnull
public ModificationType getModificationType() {
return ModificationType.DELETE;
}
@Override
- @Nonnull
public Optional<NormalizedNode<?, ?>> getDataAfter() {
return Optional.empty();
}
@Override
- @Nonnull
public Optional<NormalizedNode<?, ?>> getDataBefore() {
return dataOptional();
}
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.Optional;
-import javax.annotation.Nonnull;
+import org.eclipse.jdt.annotation.NonNull;
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;
*
* @param data Backing {@link NormalizedNode} data.
*/
- NormalizedNodeDataTreeCandidateNode(@Nonnull final NormalizedNode<?, ?> data) {
+ NormalizedNodeDataTreeCandidateNode(final @NonNull NormalizedNode<?, ?> data) {
this.data = requireNonNull(data);
}
- @Nonnull
@Override
public PathArgument getIdentifier() {
return data.getIdentifier();
}
- @Nonnull
@Override
public Collection<DataTreeCandidateNode> getChildNodes() {
if (data instanceof NormalizedNodeContainer) {
return null;
}
- @Nonnull
@Override
public ModificationType getModificationType() {
return ModificationType.WRITE;
}
- @Nonnull
@Override
public Optional<NormalizedNode<?, ?>> getDataAfter() {
return Optional.of(data);
}
- @Nonnull
@Override
public Optional<NormalizedNode<?, ?>> getDataBefore() {
return Optional.empty();
* 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 java.util.Optional;
-import javax.annotation.Nonnull;
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 org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
final class RecursiveDeleteCandidateNode extends AbstractRecursiveCandidateNode {
RecursiveDeleteCandidateNode(final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> data) {
}
@Override
- @Nonnull
public ModificationType getModificationType() {
return ModificationType.DELETE;
}
@Override
- DataTreeCandidateNode createContainer(
- final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> childData) {
- return new RecursiveDeleteCandidateNode(childData);
- }
-
- @Override
- @Nonnull
public Optional<NormalizedNode<?, ?>> getDataAfter() {
return Optional.empty();
}
- @Nonnull
@Override
public Optional<NormalizedNode<?, ?>> getDataBefore() {
return dataOptional();
}
+ @Override
+ DataTreeCandidateNode createContainer(
+ final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> childData) {
+ return new RecursiveDeleteCandidateNode(childData);
+ }
+
@Override
DataTreeCandidateNode createLeaf(final NormalizedNode<?, ?> childData) {
return new DeleteLeafCandidateNode(childData);
* 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 static java.util.Objects.requireNonNull;
import java.util.Collection;
import java.util.Optional;
-import javax.annotation.Nonnull;
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 org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
final class RecursiveReplaceCandidateNode extends AbstractDataTreeCandidateNode {
private final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> oldData;
}
@Override
- @Nonnull
public ModificationType getModificationType() {
return ModificationType.WRITE;
}
- @Nonnull
@Override
public Optional<NormalizedNode<?, ?>> getDataAfter() {
- return super.dataOptional();
+ return dataOptional();
}
- @Nonnull
@Override
public Optional<NormalizedNode<?, ?>> getDataBefore() {
return Optional.of(oldData);
@Override
public DataTreeCandidateNode getModifiedChild(final PathArgument identifier) {
- return deltaChild(oldData, getData(), identifier);
+ return DataTreeCandidateNodes.containerDelta(oldData, data(), identifier);
}
@Override
- @Nonnull
public Collection<DataTreeCandidateNode> getChildNodes() {
- return deltaChildren(oldData, getData());
+ return DataTreeCandidateNodes.containerDelta(oldData, data());
}
}
* 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 java.util.Optional;
-import javax.annotation.Nonnull;
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 org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
final class RecursiveUnmodifiedCandidateNode extends AbstractRecursiveCandidateNode {
- protected RecursiveUnmodifiedCandidateNode(
- final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> data) {
+ RecursiveUnmodifiedCandidateNode(final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> data) {
super(data);
}
@Override
- @Nonnull
public ModificationType getModificationType() {
return ModificationType.UNMODIFIED;
}
- @Nonnull
@Override
public Optional<NormalizedNode<?, ?>> getDataAfter() {
return dataOptional();
}
- @Nonnull
@Override
public Optional<NormalizedNode<?, ?>> getDataBefore() {
return dataOptional();
* 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 java.util.Optional;
-import javax.annotation.Nonnull;
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 org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
final class RecursiveWriteCandidateNode extends AbstractRecursiveCandidateNode {
-
RecursiveWriteCandidateNode(final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> data) {
super(data);
}
@Override
- @Nonnull
public ModificationType getModificationType() {
return ModificationType.WRITE;
}
@Override
- DataTreeCandidateNode createContainer(
- final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> childData) {
- return new RecursiveWriteCandidateNode(childData);
+ public Optional<NormalizedNode<?, ?>> getDataAfter() {
+ return dataOptional();
}
@Override
- DataTreeCandidateNode createLeaf(final NormalizedNode<?, ?> childData) {
- return new WriteLeafCandidateNode(childData);
+ public Optional<NormalizedNode<?, ?>> getDataBefore() {
+ return Optional.empty();
}
- @Nonnull
@Override
- public Optional<NormalizedNode<?, ?>> getDataAfter() {
- return dataOptional();
+ DataTreeCandidateNode createContainer(
+ final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> childData) {
+ return new RecursiveWriteCandidateNode(childData);
}
@Override
- @Nonnull
- public Optional<NormalizedNode<?, ?>> getDataBefore() {
- return Optional.empty();
+ DataTreeCandidateNode createLeaf(final NormalizedNode<?, ?> childData) {
+ return new WriteLeafCandidateNode(childData);
}
}
* 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 static java.util.Objects.requireNonNull;
import java.util.Optional;
-import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
final class ReplaceLeafCandidateNode extends AbstractWriteCandidate {
this.oldData = requireNonNull(oldData);
}
- @Nonnull
@Override
public Optional<NormalizedNode<?, ?>> getDataBefore() {
return Optional.of(oldData);
* 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 java.util.Optional;
-import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
final class UnmodifiedLeafCandidateNode extends AbstractAvailableLeafCandidateNode {
UnmodifiedLeafCandidateNode(final NormalizedNode<?, ?> data) {
}
@Override
- @Nonnull
public ModificationType getModificationType() {
return ModificationType.UNMODIFIED;
}
- @Nonnull
@Override
public Optional<NormalizedNode<?, ?>> getDataBefore() {
return dataOptional();
* 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 java.util.Optional;
-import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
final class WriteLeafCandidateNode extends AbstractWriteCandidate {
}
@Override
- @Nonnull
public Optional<NormalizedNode<?, ?>> getDataBefore() {
return Optional.empty();
}
+++ /dev/null
-/*
- * Copyright (c) 2015, 2016 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 com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.Collections2;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Optional;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-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 org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-
-abstract class AbstractDataTreeCandidateNode implements DataTreeCandidateNode {
- private static Optional<NormalizedNode<?, ?>> getChild(
- final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> container,
- final PathArgument identifier) {
- return container == null ? Optional.empty() : container.getChild(identifier);
- }
-
- static DataTreeCandidateNode deltaChild(
- final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> oldData,
- final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> newData,
- final PathArgument identifier) {
-
- final Optional<NormalizedNode<?, ?>> maybeNewChild = getChild(newData, identifier);
- final Optional<NormalizedNode<?, ?>> maybeOldChild = getChild(oldData, identifier);
- if (maybeOldChild.isPresent()) {
- final NormalizedNode<?, ?> oldChild = maybeOldChild.get();
- if (maybeNewChild.isPresent()) {
- return AbstractRecursiveCandidateNode.replaceNode(oldChild, maybeNewChild.get());
- }
- return AbstractRecursiveCandidateNode.deleteNode(oldChild);
- }
-
- return maybeNewChild.isPresent() ? AbstractRecursiveCandidateNode.writeNode(maybeNewChild.get()) : null;
- }
-
- static Collection<DataTreeCandidateNode> deltaChildren(
- @Nullable final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> oldData,
- @Nullable final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> newData) {
- checkArgument(newData != null || oldData != null,
- "No old or new data, modification type should be NONE and deltaChildren() mustn't be called.");
- if (newData == null) {
- return Collections2.transform(oldData.getValue(), AbstractRecursiveCandidateNode::deleteNode);
- }
- if (oldData == null) {
- return Collections2.transform(newData.getValue(), AbstractRecursiveCandidateNode::writeNode);
- }
-
- /*
- * This is slightly inefficient, as it requires N*F(M)+M*F(N) lookup operations, where
- * F is dependent on the implementation of NormalizedNodeContainer.getChild().
- *
- * We build the return collection by iterating over new data and looking each child up
- * in old data. Based on that we construct replaced/written nodes. We then proceed to
- * iterate over old data and looking up each child in new data.
- */
- final Collection<DataTreeCandidateNode> result = new ArrayList<>();
- for (NormalizedNode<?, ?> child : newData.getValue()) {
- final DataTreeCandidateNode node;
- final Optional<NormalizedNode<?, ?>> maybeOldChild = oldData.getChild(child.getIdentifier());
-
- if (maybeOldChild.isPresent()) {
- // This does not find children which have not in fact been modified, as doing that
- // reliably would require us running a full equals() on the two nodes.
- node = AbstractRecursiveCandidateNode.replaceNode(maybeOldChild.get(), child);
- } else {
- node = AbstractRecursiveCandidateNode.writeNode(child);
- }
-
- result.add(node);
- }
-
- // Process removals next, looking into new data to see if we processed it
- for (NormalizedNode<?, ?> child : oldData.getValue()) {
- if (!newData.getChild(child.getIdentifier()).isPresent()) {
- result.add(AbstractRecursiveCandidateNode.deleteNode(child));
- }
- }
-
- return result;
- }
-
- private final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?,?>> data;
-
- protected AbstractDataTreeCandidateNode(final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> data) {
- this.data = requireNonNull(data);
- }
-
- protected final Optional<NormalizedNode<?, ?>> dataOptional() {
- return Optional.of(data);
- }
-
- @Override
- @Nonnull
- public final PathArgument getIdentifier() {
- return data.getIdentifier();
- }
-
- protected final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> getData() {
- return data;
- }
-
- @Override
- public String toString() {
- return this.getClass().getSimpleName() + "{data = " + this.data + "}";
- }
-}
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.Optional;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import org.eclipse.jdt.annotation.Nullable;
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 org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNodes;
import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
return parent == null ? null : parent.getChild(id).orElse(null);
}
- private static boolean canHaveChildren(@Nullable final TreeNode oldMeta, @Nullable final TreeNode newMeta) {
+ private static boolean canHaveChildren(final @Nullable TreeNode oldMeta, final @Nullable TreeNode newMeta) {
if (oldMeta != null) {
return oldMeta.getData() instanceof NormalizedNodeContainer;
}
@SuppressWarnings("unchecked")
private static NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> getContainer(
- @Nullable final TreeNode meta) {
+ final @Nullable TreeNode meta) {
return meta == null ? null : (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>)meta.getData();
}
}
@Override
- @Nonnull
public Collection<DataTreeCandidateNode> getChildNodes() {
switch (mod.getModificationType()) {
case APPEARED:
}
return Collections2.transform(getContainer(newMeta != null ? newMeta : oldMeta).getValue(),
- AbstractRecursiveCandidateNode::unmodifiedNode);
+ DataTreeCandidateNodes::unmodified);
case DELETE:
case WRITE:
// This is unusual, the user is requesting we follow into an otherwise-terminal node.
if (!canHaveChildren(oldMeta, newMeta)) {
return ImmutableList.of();
}
- return AbstractDataTreeCandidateNode.deltaChildren(getContainer(oldMeta), getContainer(newMeta));
+ return DataTreeCandidateNodes.containerDelta(getContainer(oldMeta), getContainer(newMeta));
default:
throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
}
}
@Override
- @Nonnull
public ModificationType getModificationType() {
return verifyNotNull(mod.getModificationType(), "Node %s does not have resolved modification type", mod);
}
}
@Override
- @Nonnull
public final Optional<NormalizedNode<?, ?>> getDataAfter() {
return optionalData(newMeta);
}
@Override
- @Nonnull
public final Optional<NormalizedNode<?, ?>> getDataBefore() {
return optionalData(oldMeta);
}
}
final Optional<NormalizedNode<?, ?>> maybeChild = getContainer(newMeta != null ? newMeta : oldMeta)
.getChild(identifier);
- return maybeChild.isPresent() ? AbstractRecursiveCandidateNode.unmodifiedNode(maybeChild.get()) : null;
+ return maybeChild.isPresent() ? DataTreeCandidateNodes.unmodified(maybeChild.get()) : null;
case DELETE:
case WRITE:
if (!canHaveChildren(oldMeta, newMeta)) {
return null;
}
- return AbstractDataTreeCandidateNode.deltaChild(getContainer(oldMeta), getContainer(newMeta),
- identifier);
+ return DataTreeCandidateNodes.containerDelta(getContainer(oldMeta), getContainer(newMeta), identifier);
default:
throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
}
}
@Override
- @Nonnull
public PathArgument getIdentifier() {
return getMod().getIdentifier();
}
+++ /dev/null
-/*
- * Copyright (c) 2015 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.collect.Collections2;
-import java.util.Collection;
-import java.util.Optional;
-import javax.annotation.Nonnull;
-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 org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-
-abstract class AbstractRecursiveCandidateNode extends AbstractDataTreeCandidateNode {
-
- protected AbstractRecursiveCandidateNode(
- final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> data) {
- super(data);
- }
-
- @SuppressWarnings("unchecked")
- static DataTreeCandidateNode deleteNode(final NormalizedNode<?, ?> data) {
- if (data instanceof NormalizedNodeContainer) {
- return new RecursiveDeleteCandidateNode(
- (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) data);
- }
- return new DeleteLeafCandidateNode(data);
- }
-
- @SuppressWarnings("unchecked")
- static DataTreeCandidateNode replaceNode(final NormalizedNode<?, ?> oldData, final NormalizedNode<?, ?> newData) {
- if (isContainer(oldData)) {
- return new RecursiveReplaceCandidateNode(
- (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) oldData,
- (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) newData);
- }
- return new ReplaceLeafCandidateNode(oldData, newData);
- }
-
- @SuppressWarnings("unchecked")
- static DataTreeCandidateNode unmodifiedNode(final NormalizedNode<?, ?> data) {
- if (data instanceof NormalizedNodeContainer) {
- return new RecursiveUnmodifiedCandidateNode(
- (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) data);
- }
- return new UnmodifiedLeafCandidateNode(data);
- }
-
- @SuppressWarnings("unchecked")
- static DataTreeCandidateNode writeNode(final NormalizedNode<?, ?> data) {
- if (data instanceof NormalizedNodeContainer) {
- return new RecursiveWriteCandidateNode(
- (NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) data);
- }
- return new WriteLeafCandidateNode(data);
- }
-
- protected static boolean isContainer(final NormalizedNode<?, ?> data) {
- return data instanceof NormalizedNodeContainer;
- }
-
- @Override
- public final DataTreeCandidateNode getModifiedChild(final PathArgument identifier) {
- final Optional<NormalizedNode<?, ?>> potential = getData().getChild(identifier);
- if (potential.isPresent()) {
- return createChild(potential.get());
- }
- return null;
- }
-
- @Nonnull
- @Override
- public final Collection<DataTreeCandidateNode> getChildNodes() {
- return Collections2.transform(getData().getValue(), this::createChild);
- }
-
- @SuppressWarnings("unchecked")
- private DataTreeCandidateNode createChild(final NormalizedNode<?, ?> childData) {
- if (isContainer(childData)) {
- return createContainer((NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>>) childData);
- }
- return createLeaf(childData);
- }
-
- abstract DataTreeCandidateNode createContainer(
- NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> childData);
-
- abstract DataTreeCandidateNode createLeaf(NormalizedNode<?,?> childData);
-}
\ No newline at end of file