}
@Override
- public final DataTreeCandidateNode getModifiedChild(final PathArgument identifier) {
+ public final Optional<DataTreeCandidateNode> getModifiedChild(final PathArgument identifier) {
requireNonNull(identifier);
- return null;
+ return Optional.empty();
}
}
\ No newline at end of file
import com.google.common.collect.Collections2;
import java.util.Collection;
+import java.util.Optional;
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;
}
@Override
- public final DataTreeCandidateNode getModifiedChild(final PathArgument identifier) {
- return data().getChild(identifier).map(this::createChild).orElse(null);
+ public final Optional<DataTreeCandidateNode> getModifiedChild(final PathArgument identifier) {
+ return data().getChild(identifier).map(this::createChild);
}
@Override
import java.util.Collection;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
* the modification from which this candidate was created. The node itself exposes the before- and after-image
* of the tree restricted to the modified nodes.
*/
-// FIXME: 3.0.0: Use @NonNullByDefault
+// FIXME: 4.0.0: Use @NonNullByDefault
public interface DataTreeCandidateNode {
/**
* Get the node identifier.
@NonNull PathArgument getIdentifier();
/**
- * Get an unmodifiable collection of modified child nodes.
+ * Get an unmodifiable collection of modified child nodes. Note that the collection may include
+ * {@link ModificationType#UNMODIFIED} nodes, which the caller is expected to handle as if they were not present.
*
* @return Unmodifiable collection of modified child nodes.
*/
@NonNull Collection<DataTreeCandidateNode> getChildNodes();
/**
- * Returns modified child or null if child was not modified
- * / does not exists.
+ * Returns modified child or empty. Note that this method may return an {@link ModificationType#UNMODIFIED} node
+ * when there is evidence of the node or its parent being involved in modification which has turned out not to
+ * modify the node's contents.
*
* @param childIdentifier Identifier of child node
- * @return Modified child or null if child was not modified.
+ * @return Modified child or empty.
+ * @throws NullPointerException if {@code childIdentifier} is null
*/
- // FIXME: 3.0.0: document NullPointerException being thrown
- // FIXME: 3.0.0: return an Optional
- @Nullable DataTreeCandidateNode getModifiedChild(PathArgument childIdentifier);
+ @NonNull Optional<DataTreeCandidateNode> getModifiedChild(PathArgument childIdentifier);
/**
* Return the type of modification this node is undergoing.
*
* @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
+ * @return A {@link DataTreeCandidateNode} describing the change, or empty if the node is not present
*/
- public static @Nullable DataTreeCandidateNode containerDelta(
+ public static @NonNull Optional<DataTreeCandidateNode> containerDelta(
final @Nullable NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> oldData,
final @Nullable NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> newData,
final @NonNull PathArgument 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 Optional.of(maybeNewChild.isPresent() ? replaceNode(oldChild, maybeNewChild.get())
+ : deleteNode(oldChild));
}
- return maybeNewChild.isPresent() ? writeNode(maybeNewChild.get()) : null;
+ return maybeNewChild.map(DataTreeCandidateNodes::writeNode);
}
/**
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
final class EmptyDataTreeCandidateNode implements DataTreeCandidateNode {
-
private final PathArgument identifier;
EmptyDataTreeCandidateNode(final PathArgument identifier) {
}
@Override
- public DataTreeCandidateNode getModifiedChild(final PathArgument childIdentifier) {
- return null;
+ public Optional<DataTreeCandidateNode> getModifiedChild(final PathArgument childIdentifier) {
+ return Optional.empty();
}
@Override
}
@Override
- public DataTreeCandidateNode getModifiedChild(final PathArgument childIdentifier) {
+ public Optional<DataTreeCandidateNode> getModifiedChild(final PathArgument childIdentifier) {
if (data instanceof NormalizedNodeContainer) {
@SuppressWarnings({ "rawtypes", "unchecked" })
final Optional<? extends NormalizedNode<?, ?>> child =
((NormalizedNodeContainer)data).getChild(childIdentifier);
- return child.map(input -> new NormalizedNodeDataTreeCandidateNode(input)).orElse(null);
+ return child.map(NormalizedNodeDataTreeCandidateNode::new);
}
- return null;
+ return Optional.empty();
}
@Override
}
@Override
- public DataTreeCandidateNode getModifiedChild(final PathArgument identifier) {
+ public Optional<DataTreeCandidateNode> getModifiedChild(final PathArgument identifier) {
return DataTreeCandidateNodes.containerDelta(oldData, data(), identifier);
}
* 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 org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
assertTrue(childNodes instanceof List);
assertTrue(childNodes.isEmpty());
- assertNull(normalizedNodeDataTreeCandidateNode.getModifiedChild(mockedPathArgument));
+ assertEquals(Optional.empty(), normalizedNodeDataTreeCandidateNode.getModifiedChild(mockedPathArgument));
assertEquals(ModificationType.WRITE, normalizedNodeDataTreeCandidateNode.getModificationType());
assertEquals(Optional.of(mockedNormalizedNode), normalizedNodeDataTreeCandidateNode.getDataAfter());
assertEquals(3, childNodes2.size());
doReturn(Optional.empty()).when(mockedNormalizedNodeContainer).getChild(any(PathArgument.class));
- assertNull(normalizedNodeDataTreeCandidateNode2.getModifiedChild(mockedPathArgument));
+ assertEquals(Optional.empty(), normalizedNodeDataTreeCandidateNode2.getModifiedChild(mockedPathArgument));
doReturn(Optional.of(mockedChildNormNode1)).when(mockedNormalizedNodeContainer).getChild(
any(PathArgument.class));
- assertNotNull(normalizedNodeDataTreeCandidateNode2.getModifiedChild(mockedPathArgument));
+ assertTrue(normalizedNodeDataTreeCandidateNode2.getModifiedChild(mockedPathArgument).isPresent());
}
}
}
@Override
- public final DataTreeCandidateNode getModifiedChild(final PathArgument identifier) {
+ public final Optional<DataTreeCandidateNode> getModifiedChild(final PathArgument identifier) {
switch (mod.getModificationType()) {
case APPEARED:
case DISAPPEARED:
case SUBTREE_MODIFIED:
- final Optional<ModifiedNode> childMod = mod.getChild(identifier);
- if (childMod.isPresent()) {
- return childNode(childMod.get());
- }
- return null;
+ return mod.getChild(identifier).map(this::childNode);
case UNMODIFIED:
if (!canHaveChildren(oldMeta, newMeta)) {
- return null;
+ return Optional.empty();
}
- final Optional<NormalizedNode<?, ?>> maybeChild = getContainer(newMeta != null ? newMeta : oldMeta)
- .getChild(identifier);
- return maybeChild.isPresent() ? DataTreeCandidateNodes.unmodified(maybeChild.get()) : null;
+ return getContainer(newMeta != null ? newMeta : oldMeta).getChild(identifier)
+ .map(DataTreeCandidateNodes::unmodified);
case DELETE:
case WRITE:
if (!canHaveChildren(oldMeta, newMeta)) {
- return null;
+ return Optional.empty();
}
return DataTreeCandidateNodes.containerDelta(getContainer(oldMeta), getContainer(newMeta), identifier);
default:
}
@Override
- public DataTreeCandidateNode getModifiedChild(final PathArgument identifier) {
- return null;
+ public Optional<DataTreeCandidateNode> getModifiedChild(final PathArgument identifier) {
+ return Optional.empty();
}
};