BUG-4202: ForeignShardModificationContext should check readiness
[mdsal.git] / dom / mdsal-dom-inmemory-datastore / src / main / java / org / opendaylight / mdsal / dom / store / inmemory / WriteableNodeOperation.java
1 /*
2  * Copyright (c) 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
9 package org.opendaylight.mdsal.dom.store.inmemory;
10
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import java.util.Map.Entry;
14 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
15 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
16 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
17 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
18
19 abstract class WriteableNodeOperation implements WriteCursorStrategy {
20     private final WriteableModificationNode node;
21     private final DOMDataTreeWriteCursor cursor;
22
23     WriteableNodeOperation(final WriteableModificationNode node, final DOMDataTreeWriteCursor cursor) {
24         this.node = Preconditions.checkNotNull(node);
25         this.cursor = Preconditions.checkNotNull(cursor);
26     }
27
28     protected final DOMDataTreeWriteCursor getCursor() {
29         return cursor;
30     }
31
32     private void delete(final PathArgument arg, final WriteableModificationNode potentialChild) {
33         cursor.delete(arg);
34         if (potentialChild != null) {
35             potentialChild.markDeleted();
36         }
37     }
38
39     @Override
40     public final void delete(final PathArgument arg) {
41         delete(arg, node.getChild(arg));
42     }
43
44     @Override
45     public final void merge(final PathArgument arg, final NormalizedNode<?, ?> data) {
46         WriteableModificationNode potentialChild = node.getChild(arg);
47         if (potentialChild == null) {
48             cursor.merge(arg, data);
49         } else {
50             potentialChild.createOperation(cursor).mergeToCurrent((NormalizedNodeContainer<?, ?, ?>) data);
51         }
52     }
53
54     @Override
55     public final void write(final PathArgument arg, final NormalizedNode<?, ?> data) {
56         WriteableModificationNode potentialChild = node.getChild(arg);
57         if (potentialChild == null) {
58             cursor.write(arg, data);
59         } else {
60             potentialChild.createOperation(cursor).writeToCurrent((NormalizedNodeContainer<?, ?, ?>) data);
61         }
62     }
63
64     @Override
65     public final WriteCursorStrategy enter(final PathArgument arg) {
66         cursor.enter(arg);
67         WriteableModificationNode child = node.getChild(arg);
68         if (child != null) {
69             return child.createOperation(cursor);
70         }
71         return new DelegatingWriteCursorStrategy() {
72             @Override
73             protected DOMDataTreeWriteCursor delegate() {
74                 return cursor;
75             }
76         };
77     }
78
79     @Override
80     public final void mergeToCurrent(final NormalizedNodeContainer<?, ?, ?> data) {
81         for (NormalizedNode<?, ?> child : data.getValue()) {
82             PathArgument childId = child.getIdentifier();
83             WriteableModificationNode shardChild = node.getChild(childId);
84             if (shardChild != null) {
85                 // FIXME: Decompose somehow
86                 throw new UnsupportedOperationException("Not implemented yet");
87             } else {
88                 cursor.merge(childId, child);
89             }
90         }
91     }
92
93     @Override
94     @SuppressWarnings("rawtypes")
95     public final void writeToCurrent(final NormalizedNodeContainer<?, ?, ?> data) {
96         for (NormalizedNode<?, ?> writtenChild : data.getValue()) {
97             write(writtenChild.getIdentifier(), writtenChild);
98         }
99         // Delete step
100         for (Entry<PathArgument, WriteableModificationNode> shardChild : node.getChildrenWithSubshards().entrySet()) {
101             PathArgument childId = shardChild.getKey();
102             @SuppressWarnings("unchecked")
103             Optional<NormalizedNode<?, ?>> writtenValue = ((NormalizedNodeContainer) data).getChild(childId);
104             if (!writtenValue.isPresent()) {
105                 delete(childId, shardChild.getValue());
106             }
107         }
108     }
109 }