X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-dom-adapter%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fdom%2Fadapter%2FLazyDataObjectModification.java;fp=binding%2Fmdsal-binding-dom-adapter%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fdom%2Fadapter%2FLazyDataObjectModification.java;h=dc47be3aff1a33c90f57c39d73fc0051e5c17758;hb=076dcd04523bd003935796c3795ea4f81dfa8898;hp=b4e14b6d772e1d729194fbde694d486bd9e6b246;hpb=dcd3e44d3c582bd12287e56798e12478fcdbc96d;p=mdsal.git diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazyDataObjectModification.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazyDataObjectModification.java index b4e14b6d77..dc47be3aff 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazyDataObjectModification.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazyDataObjectModification.java @@ -45,7 +45,9 @@ final class LazyDataObjectModification implements DataObje private final BindingCodecTreeNode codec; private final DataTreeCandidateNode domData; private final PathArgument identifier; - private Collection> childNodesCache; + + private volatile Collection> childNodesCache; + private volatile ModificationType modificationType; private LazyDataObjectModification(final BindingCodecTreeNode codec, final DataTreeCandidateNode domData) { this.codec = Preconditions.checkNotNull(codec); @@ -137,29 +139,68 @@ final class LazyDataObjectModification implements DataObje } @Override - public DataObjectModification.ModificationType getModificationType() { + public ModificationType getModificationType() { + ModificationType localType = modificationType; + if (localType != null) { + return localType; + } + switch (domData.getModificationType()) { case APPEARED: case WRITE: - return DataObjectModification.ModificationType.WRITE; - case SUBTREE_MODIFIED: - return DataObjectModification.ModificationType.SUBTREE_MODIFIED; + localType = ModificationType.WRITE; + break; case DISAPPEARED: case DELETE: - return DataObjectModification.ModificationType.DELETE; - + localType = ModificationType.DELETE; + break; + case SUBTREE_MODIFIED: + localType = resolveSubtreeModificationType(); + break; default: // TODO: Should we lie about modification type instead of exception? throw new IllegalStateException("Unsupported DOM Modification type " + domData.getModificationType()); } + + modificationType = localType; + return localType; + } + + private ModificationType resolveSubtreeModificationType() { + switch (codec.getChildAddressabilitySummary()) { + case ADDRESSABLE: + // All children are addressable, it is safe to report SUBTREE_MODIFIED + return ModificationType.SUBTREE_MODIFIED; + case UNADDRESSABLE: + // All children are non-addressable, report WRITE + return ModificationType.WRITE; + case MIXED: + // This case is not completely trivial, as we may have NOT_ADDRESSABLE nodes underneath us. If that + // is the case, we need to turn this modification into a WRITE operation, so that the user is able + // to observe those nodes being introduced. This is not efficient, but unfortunately unavoidable, + // as we cannot accurately represent such changes. + for (DataTreeCandidateNode child : domData.getChildNodes()) { + if (BindingStructuralType.recursiveFrom(child) == BindingStructuralType.NOT_ADDRESSABLE) { + // We have a non-addressable child, turn this modification into a write + return ModificationType.WRITE; + } + } + + // No unaddressable children found, proceed in addressed mode + return ModificationType.SUBTREE_MODIFIED; + default: + throw new IllegalStateException("Unsupported child addressability summary " + + codec.getChildAddressabilitySummary()); + } } @Override public Collection> getModifiedChildren() { - if (childNodesCache == null) { - childNodesCache = from(codec, domData.getChildNodes()); + Collection> local = childNodesCache; + if (local == null) { + childNodesCache = local = from(codec, domData.getChildNodes()); } - return childNodesCache; + return local; } @SuppressWarnings("unchecked")