Merge "BUG-2876: switch to using the computed ModificationType"
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / InMemoryDataTreeCandidate.java
1 /*
2  * Copyright (c) 2014 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.Function;
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.collect.Collections2;
14 import java.util.Collection;
15 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
16 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
17 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
18 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
20 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
21
22 final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate {
23     private static abstract class AbstractNode implements DataTreeCandidateNode {
24         private final ModifiedNode mod;
25         private final TreeNode newMeta;
26         private final TreeNode oldMeta;
27
28         protected AbstractNode(final ModifiedNode mod,
29                 final TreeNode oldMeta, final TreeNode newMeta) {
30             this.newMeta = newMeta;
31             this.oldMeta = oldMeta;
32             this.mod = Preconditions.checkNotNull(mod);
33         }
34
35         protected final ModifiedNode getMod() {
36             return mod;
37         }
38
39         protected final TreeNode getNewMeta() {
40             return newMeta;
41         }
42
43         protected final TreeNode getOldMeta() {
44             return oldMeta;
45         }
46
47         private static final TreeNode childMeta(final TreeNode parent, final PathArgument id) {
48             if (parent != null) {
49                 return parent.getChild(id).orNull();
50             } else {
51                 return null;
52             }
53         }
54
55         private DataTreeCandidateNode childNode(final ModifiedNode input) {
56             final PathArgument id = input.getIdentifier();
57             return new ChildNode(input, childMeta(oldMeta, id), childMeta(newMeta, id));
58         }
59
60         @Override
61         public Collection<DataTreeCandidateNode> getChildNodes() {
62             return Collections2.transform(mod.getChildren(), new Function<ModifiedNode, DataTreeCandidateNode>() {
63                 @Override
64                 public DataTreeCandidateNode apply(final ModifiedNode input) {
65                     return childNode(input);
66                 }
67             });
68         }
69
70         @Override
71         public ModificationType getModificationType() {
72             return mod.modificationType();
73         }
74
75         private Optional<NormalizedNode<?, ?>> optionalData(final TreeNode meta) {
76             if (meta != null) {
77                 return Optional.<NormalizedNode<?,?>>of(meta.getData());
78             } else {
79                 return Optional.absent();
80             }
81         }
82
83         @Override
84         public Optional<NormalizedNode<?, ?>> getDataAfter() {
85             return optionalData(newMeta);
86         }
87
88         @Override
89         public Optional<NormalizedNode<?, ?>> getDataBefore() {
90             return optionalData(oldMeta);
91         }
92
93         @Override
94         public DataTreeCandidateNode getModifiedChild(final PathArgument identifier) {
95             final Optional<ModifiedNode> childMod = mod.getChild(identifier);
96             if (childMod.isPresent()) {
97                 return childNode(mod);
98             }
99             return null;
100         }
101     }
102
103     private static final class ChildNode extends AbstractNode {
104         public ChildNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) {
105             super(mod, oldMeta, newMeta);
106         }
107
108         @Override
109         public PathArgument getIdentifier() {
110             return getMod().getIdentifier();
111         }
112     }
113
114     private static final class RootNode extends AbstractNode {
115         public RootNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) {
116             super(mod, oldMeta, newMeta);
117         }
118
119         @Override
120         public PathArgument getIdentifier() {
121             throw new IllegalStateException("Attempted to get identifier of the root node");
122         }
123     }
124
125     private final RootNode root;
126
127     InMemoryDataTreeCandidate(final YangInstanceIdentifier rootPath, final ModifiedNode modificationRoot,
128             final TreeNode beforeRoot, final TreeNode afterRoot) {
129         super(rootPath);
130         this.root = new RootNode(modificationRoot, beforeRoot, afterRoot);
131     }
132
133     TreeNode getAfterRoot() {
134         return root.getNewMeta();
135     }
136
137     TreeNode getBeforeRoot() {
138         return root.getOldMeta();
139     }
140
141     @Override
142     public DataTreeCandidateNode getRootNode() {
143         return root;
144     }
145 }