29087156512c117d27bc64d5dbb0d2bbc33e5f28
[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         // write the entire thing into the cursor
97         write(data.getIdentifier(), data);
98         // write the children with subshard check and subshard write if we are going into subshard
99         cursor.enter(data.getIdentifier());
100         for (NormalizedNode<?, ?> writtenChild : data.getValue()) {
101             write(writtenChild.getIdentifier(), writtenChild);
102         }
103         // Delete step - remove subshard data that was written into current shard
104         for (Entry<PathArgument, WriteableModificationNode> shardChild : node.getChildrenWithSubshards().entrySet()) {
105             PathArgument childId = shardChild.getKey();
106             @SuppressWarnings("unchecked")
107             Optional<NormalizedNode<?, ?>> writtenValue = ((NormalizedNodeContainer) data).getChild(childId);
108             if (writtenValue.isPresent()) {
109                 // delete from current
110                 cursor.delete(childId);
111             }
112         }
113         cursor.exit();
114     }
115 }