bf14d7399697d2040d7f7c9ce32fbd849a37322f
[mdsal.git] / dom / mdsal-dom-spi / src / main / java / org / opendaylight / mdsal / dom / spi / shard / ForeignShardModificationContext.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.spi.shard;
10
11 import static com.google.common.base.Preconditions.checkState;
12 import static java.util.Objects.requireNonNull;
13
14 import com.google.common.annotations.Beta;
15 import com.google.common.util.concurrent.ListenableFuture;
16 import javax.annotation.concurrent.NotThreadSafe;
17 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
18 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteCursor;
19 import org.opendaylight.yangtools.concepts.Identifiable;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 @Beta
24 @NotThreadSafe
25 public final class ForeignShardModificationContext implements Identifiable<DOMDataTreeIdentifier> {
26     private static final Logger LOG = LoggerFactory.getLogger(ForeignShardModificationContext.class);
27
28     private final DOMDataTreeIdentifier identifier;
29     private final DOMDataTreeShardProducer producer;
30
31     private DOMDataTreeShardWriteTransaction tx;
32     private DOMDataTreeWriteCursor cursor;
33
34     private volatile boolean ready = false;
35
36     public ForeignShardModificationContext(final DOMDataTreeIdentifier identifier,
37                                            final DOMDataTreeShardProducer producer) {
38         this.identifier = requireNonNull(identifier);
39         this.producer = requireNonNull(producer);
40     }
41
42     public DOMDataTreeWriteCursor getCursor() {
43         checkState(!ready, "Context %s has been readied", this);
44
45         if (cursor == null) {
46             if (tx == null) {
47                 tx = producer.createTransaction();
48             }
49             cursor = tx.createCursor(getIdentifier());
50         }
51         return cursor;
52     }
53
54     public boolean isModified() {
55         return tx != null;
56     }
57
58     public void ready() {
59         if (ready) {
60             // Idempotent, but emit a debug
61             LOG.debug("Duplicate ready() of context {}", this);
62             return;
63         }
64
65         ready = true;
66         if (cursor != null) {
67             cursor.close();
68             cursor = null;
69         }
70         if (tx != null) {
71             tx.ready();
72             // TODO: it would be nice if we could clear this reference
73             // tx = null;
74         }
75     }
76
77     @Override
78     public DOMDataTreeIdentifier getIdentifier() {
79         return identifier;
80     }
81
82     public ListenableFuture<Boolean> validate() {
83         return tx.validate();
84     }
85
86     public ListenableFuture<Void> prepare() {
87         return tx.prepare();
88     }
89
90     public ListenableFuture<Void> submit() {
91         checkState(ready, "Modification context %s has to be ready before submit", this);
92         final ListenableFuture<Void> commit = tx.commit();
93         ready = false;
94         tx = null;
95         return commit;
96     }
97
98     public void closeForeignTransaction() {
99         if (cursor != null) {
100             cursor.close();
101             cursor = null;
102         }
103
104         if (tx != null) {
105             tx.close();
106             tx = null;
107         }
108     }
109 }