X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fimpl%2Fschema%2Ftree%2FAbstractModifiedNodeBasedCandidateNode.java;h=e6967edae404d3043a24ac4c8e71a4683018f00a;hb=b19410d5a467d095d05057d58e9c3e0b95a92f5b;hp=4788029b8a3d1cd3367f8c65b3f35fcbc7cf06dd;hpb=16fdedd458eb5f8d9ee03c8fd84ca8015560d59b;p=yangtools.git diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractModifiedNodeBasedCandidateNode.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractModifiedNodeBasedCandidateNode.java index 4788029b8a..e6967edae4 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractModifiedNodeBasedCandidateNode.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractModifiedNodeBasedCandidateNode.java @@ -12,16 +12,24 @@ import com.google.common.base.Preconditions; import com.google.common.base.Verify; import com.google.common.collect.Collections2; import java.util.Collection; -import javax.annotation.Nonnull; +import java.util.Collections; 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; import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType; import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode; - abstract class AbstractModifiedNodeBasedCandidateNode implements DataTreeCandidateNode { + + private static final Function, DataTreeCandidateNode> TO_UNMODIFIED_NODE = new Function, DataTreeCandidateNode>() { + @Override + public DataTreeCandidateNode apply(final NormalizedNode input) { + return AbstractRecursiveCandidateNode.unmodifiedNode(input); + } + }; + private final ModifiedNode mod; private final TreeNode newMeta; private final TreeNode oldMeta; @@ -45,7 +53,7 @@ abstract class AbstractModifiedNodeBasedCandidateNode implements DataTreeCandida return oldMeta; } - private static final TreeNode childMeta(final TreeNode parent, final PathArgument id) { + private static TreeNode childMeta(final TreeNode parent, final PathArgument id) { if (parent != null) { return parent.getChild(id).orNull(); } else { @@ -53,29 +61,58 @@ abstract class AbstractModifiedNodeBasedCandidateNode implements DataTreeCandida } } - private DataTreeCandidateNode childNode(final ModifiedNode input) { - final PathArgument id = input.getIdentifier(); - return createChildNode(input, childMeta(oldMeta, id), childMeta(newMeta, id)); - } - - private static DataTreeCandidateNode createChildNode(@Nonnull final ModifiedNode input, @Nullable final TreeNode oldMeta, @Nullable final TreeNode newMeta) { - if(oldMeta == null) { - return RecursiveModificationCandidateNode.initialWriteNode(newMeta.getData()); + private static boolean canHaveChildren(@Nullable final TreeNode oldMeta, @Nullable final TreeNode newMeta) { + if (oldMeta != null) { + return oldMeta.getData() instanceof NormalizedNodeContainer; } - if(newMeta == null) { - return RecursiveModificationCandidateNode.deleteNode(oldMeta.getData()); + if (newMeta != null) { + return newMeta.getData() instanceof NormalizedNodeContainer; } - return new ChildNode(input, oldMeta, newMeta); + return false; + } + + @SuppressWarnings("unchecked") + private static NormalizedNodeContainer> getContainer(@Nullable final TreeNode meta) { + return (meta == null ? null : (NormalizedNodeContainer>)meta.getData()); + } + + private ChildNode childNode(final ModifiedNode childMod) { + final PathArgument id = childMod.getIdentifier(); + return new ChildNode(childMod, childMeta(oldMeta, id), childMeta(newMeta, id)); } @Override public Collection getChildNodes() { - return Collections2.transform(mod.getChildren(), new Function() { - @Override - public DataTreeCandidateNode apply(final ModifiedNode input) { - return childNode(input); + switch (mod.getModificationType()) { + case APPEARED: + case DISAPPEARED: + case SUBTREE_MODIFIED: + return Collections2.transform(mod.getChildren(), new Function() { + @Override + public DataTreeCandidateNode apply(final ModifiedNode input) { + return childNode(input); + } + }); + case UNMODIFIED: + // Unmodified node, but we still need to resolve potential children. canHaveChildren returns + // false if both arguments are null. + if (canHaveChildren(oldMeta, newMeta)) { + return Collections2.transform(getContainer(newMeta != null ? newMeta : oldMeta).getValue(), TO_UNMODIFIED_NODE); + } else { + return Collections.emptyList(); + } + case DELETE: + case WRITE: + // This is unusual, the user is requesting we follow into an otherwise-terminal node. + // We need to fudge things based on before/after data to correctly fake the expectations. + if (canHaveChildren(oldMeta, newMeta)) { + return AbstractDataTreeCandidateNode.deltaChildren(getContainer(oldMeta), getContainer(newMeta)); + } else { + return Collections.emptyList(); } - }); + default: + throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType()); + } } @Override @@ -83,7 +120,7 @@ abstract class AbstractModifiedNodeBasedCandidateNode implements DataTreeCandida return Verify.verifyNotNull(mod.getModificationType(), "Node %s does not have resolved modification type", mod); } - private Optional> optionalData(final TreeNode meta) { + private static Optional> optionalData(final TreeNode meta) { if (meta != null) { return Optional.>of(meta.getData()); } else { @@ -92,26 +129,51 @@ abstract class AbstractModifiedNodeBasedCandidateNode implements DataTreeCandida } @Override - public Optional> getDataAfter() { + public final Optional> getDataAfter() { return optionalData(newMeta); } @Override - public Optional> getDataBefore() { + public final Optional> getDataBefore() { return optionalData(oldMeta); } @Override - public DataTreeCandidateNode getModifiedChild(final PathArgument identifier) { - final Optional childMod = mod.getChild(identifier); - if (childMod.isPresent()) { - return childNode(childMod.get()); + public final DataTreeCandidateNode getModifiedChild(final PathArgument identifier) { + switch (mod.getModificationType()) { + case APPEARED: + case DISAPPEARED: + case SUBTREE_MODIFIED: + final Optional childMod = mod.getChild(identifier); + if (childMod.isPresent()) { + return childNode(childMod.get()); + } + return null; + case UNMODIFIED: + if (canHaveChildren(oldMeta, newMeta)) { + final Optional> maybeChild = getContainer(newMeta != null ? newMeta : oldMeta).getChild(identifier); + if (maybeChild.isPresent()) { + return TO_UNMODIFIED_NODE.apply(maybeChild.get()); + } else { + return null; + } + } else { + return null; + } + case DELETE: + case WRITE: + if (canHaveChildren(oldMeta, newMeta)) { + return AbstractDataTreeCandidateNode.deltaChild(getContainer(oldMeta), getContainer(newMeta), identifier); + } else { + return null; + } + default: + throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType()); } - return null; } - static final class ChildNode extends AbstractModifiedNodeBasedCandidateNode { - public ChildNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) { + private static final class ChildNode extends AbstractModifiedNodeBasedCandidateNode { + ChildNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) { super(mod, oldMeta, newMeta); } @@ -120,4 +182,10 @@ abstract class AbstractModifiedNodeBasedCandidateNode implements DataTreeCandida return getMod().getIdentifier(); } } -} \ No newline at end of file + + @Override + public String toString() { + return this.getClass().getSimpleName() + "{mod = " + this.mod + ", oldMeta = " + this.oldMeta + ", newMeta = " + + this.newMeta + "}"; + } +}