Modernize AbstractDataObjectModification
[mdsal.git] / binding / mdsal-binding-dom-adapter / src / main / java / org / opendaylight / mdsal / binding / dom / adapter / LazyAugmentationModification.java
1 /*
2  * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.mdsal.binding.dom.adapter;
9
10 import static java.util.Objects.requireNonNull;
11 import static org.opendaylight.yangtools.yang.data.tree.api.ModificationType.UNMODIFIED;
12
13 import com.google.common.base.MoreObjects.ToStringHelper;
14 import com.google.common.collect.ImmutableList;
15 import java.util.Collection;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.mdsal.binding.dom.codec.api.BindingAugmentationCodecTreeNode;
19 import org.opendaylight.yangtools.yang.binding.Augmentation;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
21 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
22 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateNode;
23
24 /**
25  * Specialization of {@link AbstractDataObjectModification} for {@link Augmentation}s. Is based on a parent
26  * {@link DataTreeCandidateNode}, but contains only a subset of its modifications.
27  */
28 final class LazyAugmentationModification<A extends Augmentation<?>>
29         extends AbstractDataObjectModification<A, BindingAugmentationCodecTreeNode<A>> {
30     private final @NonNull ImmutableList<DataTreeCandidateNode> domChildNodes;
31
32     private LazyAugmentationModification(final BindingAugmentationCodecTreeNode<A> codec,
33             final DataTreeCandidateNode parent, final ImmutableList<DataTreeCandidateNode> domChildNodes) {
34         super(parent, codec, codec.deserializePathArgument(null));
35         this.domChildNodes = requireNonNull(domChildNodes);
36     }
37
38     static <A extends Augmentation<?>> @Nullable LazyAugmentationModification<A> forModifications(
39             final BindingAugmentationCodecTreeNode<A> codec, final DataTreeCandidateNode parent,
40             final Collection<DataTreeCandidateNode> children) {
41         // Filter out any unmodified children first
42         final var domChildren = children.stream()
43             .filter(childMod -> childMod.modificationType() != UNMODIFIED)
44             .collect(ImmutableList.toImmutableList());
45         // Only return a modification if there is something left
46         return domChildren.isEmpty() ? null : new LazyAugmentationModification<>(codec, parent, domChildren);
47     }
48
49     static <A extends Augmentation<?>> @Nullable LazyAugmentationModification<A> forParent(
50             final BindingAugmentationCodecTreeNode<A> codec, final DataTreeCandidateNode parent) {
51         final var builder = ImmutableList.<DataTreeCandidateNode>builder();
52         for (var pathArg : codec.childPathArguments()) {
53             final var child = parent.modifiedChild(pathArg);
54             if (child != null) {
55                 builder.add(child);
56             }
57         }
58         final var domChildren = builder.build();
59         return domChildren.isEmpty() ? null : new LazyAugmentationModification<>(codec, parent, domChildren);
60     }
61
62     @Override
63     ImmutableList<DataTreeCandidateNode> domChildNodes() {
64         return domChildNodes;
65     }
66
67     @Override
68     org.opendaylight.yangtools.yang.data.tree.api.ModificationType domModificationType() {
69         final var before = getDataBefore();
70         final var after = getDataAfter();
71         if (before == null) {
72             return after == null ? org.opendaylight.yangtools.yang.data.tree.api.ModificationType.UNMODIFIED
73                 :  org.opendaylight.yangtools.yang.data.tree.api.ModificationType.APPEARED;
74         }
75         return after == null ? org.opendaylight.yangtools.yang.data.tree.api.ModificationType.DISAPPEARED
76             : org.opendaylight.yangtools.yang.data.tree.api.ModificationType.SUBTREE_MODIFIED;
77     }
78
79
80     @Override
81     A deserialize(final NormalizedNode normalized) {
82         return codec.filterFrom(normalized);
83     }
84
85     @Override
86     DataTreeCandidateNode firstModifiedChild(final PathArgument arg) {
87         // Not entirely efficient linear search, but otherwise we'd have to index, which is even slower
88         return domChildNodes.stream()
89             .filter(child -> arg.equals(child.name()))
90             .findFirst()
91             .orElse(null);
92     }
93
94     @Override
95     ToStringHelper addToStringAttributes(final ToStringHelper helper) {
96         return super.addToStringAttributes(helper)
97             .add("domType", domData.modificationType())
98             .add("domChildren", domChildNodes);
99     }
100 }