Address trivial eclipse warnings
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / AbstractDataTreeCandidateNode.java
1 /*
2  * Copyright (c) 2015, 2016 Cisco Systems, Inc. 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.yangtools.yang.data.impl.schema.tree;
9
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.Collections2;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import javax.annotation.Nonnull;
16 import javax.annotation.Nullable;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
18 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
20 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
21
22 abstract class AbstractDataTreeCandidateNode implements DataTreeCandidateNode {
23     private static Optional<NormalizedNode<?, ?>> getChild(
24             final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> container,
25                     final PathArgument identifier) {
26         return container == null ? Optional.absent() : container.getChild(identifier);
27     }
28
29     static DataTreeCandidateNode deltaChild(
30             final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> oldData,
31             final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> newData, final PathArgument identifier) {
32
33         final Optional<NormalizedNode<?, ?>> maybeNewChild = getChild(newData, identifier);
34         final Optional<NormalizedNode<?, ?>> maybeOldChild = getChild(oldData, identifier);
35         if (maybeOldChild.isPresent()) {
36             final NormalizedNode<?, ?> oldChild = maybeOldChild.get();
37             if (maybeNewChild.isPresent()) {
38                 return AbstractRecursiveCandidateNode.replaceNode(oldChild, maybeNewChild.get());
39             }
40             return AbstractRecursiveCandidateNode.deleteNode(oldChild);
41         }
42
43         return maybeNewChild.isPresent() ? AbstractRecursiveCandidateNode.writeNode(maybeNewChild.get()) : null;
44     }
45
46     static Collection<DataTreeCandidateNode> deltaChildren(
47             @Nullable final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> oldData,
48             @Nullable final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> newData) {
49         Preconditions.checkArgument(newData != null || oldData != null,
50                 "No old or new data, modification type should be NONE and deltaChildren() mustn't be called.");
51         if (newData == null) {
52             return Collections2.transform(oldData.getValue(), AbstractRecursiveCandidateNode::deleteNode);
53         }
54         if (oldData == null) {
55             return Collections2.transform(newData.getValue(), AbstractRecursiveCandidateNode::writeNode);
56         }
57
58         /*
59          * This is slightly inefficient, as it requires N*F(M)+M*F(N) lookup operations, where
60          * F is dependent on the implementation of NormalizedNodeContainer.getChild().
61          *
62          * We build the return collection by iterating over new data and looking each child up
63          * in old data. Based on that we construct replaced/written nodes. We then proceed to
64          * iterate over old data and looking up each child in new data.
65          */
66         final Collection<DataTreeCandidateNode> result = new ArrayList<>();
67         for (NormalizedNode<?, ?> child : newData.getValue()) {
68             final DataTreeCandidateNode node;
69             final Optional<NormalizedNode<?, ?>> maybeOldChild = oldData.getChild(child.getIdentifier());
70
71             if (maybeOldChild.isPresent()) {
72                 // This does not find children which have not in fact been modified, as doing that
73                 // reliably would require us running a full equals() on the two nodes.
74                 node = AbstractRecursiveCandidateNode.replaceNode(maybeOldChild.get(), child);
75             } else {
76                 node = AbstractRecursiveCandidateNode.writeNode(child);
77             }
78
79             result.add(node);
80         }
81
82         // Process removals next, looking into new data to see if we processed it
83         for (NormalizedNode<?, ?> child : oldData.getValue()) {
84             if (!newData.getChild(child.getIdentifier()).isPresent()) {
85                 result.add(AbstractRecursiveCandidateNode.deleteNode(child));
86             }
87         }
88
89         return result;
90     }
91
92     private final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?,?>> data;
93
94     protected AbstractDataTreeCandidateNode(final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> data) {
95         this.data = Preconditions.checkNotNull(data);
96     }
97
98     protected final Optional<NormalizedNode<?, ?>> dataOptional() {
99         return Optional.of(data);
100     }
101
102     @Override
103     @Nonnull
104     public final PathArgument getIdentifier() {
105         return data.getIdentifier();
106     }
107
108     protected final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> getData() {
109         return data;
110     }
111
112     @Override
113     public String toString() {
114         return this.getClass().getSimpleName() + "{data = " + this.data + "}";
115     }
116 }