Bug 484 - Anyxml in sal-rest-connector
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / md / sal / dom / broker / impl / AbstractDOMForwardedTransactionFactory.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.controller.md.sal.dom.broker.impl;
9
10 import java.util.Map;
11 import java.util.Map.Entry;
12
13 import javax.annotation.concurrent.GuardedBy;
14
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
17 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
18 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
19 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
20 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
21 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionFactory;
22 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
23
24 import com.google.common.base.Preconditions;
25 import com.google.common.collect.ImmutableMap;
26
27 /**
28  *
29  * Abstract composite transaction factory.
30  *
31  * Provides an convenience common implementation for composite DOM Transactions,
32  * where subtransaction is identified by {@link LogicalDatastoreType} type and
33  * implementation of subtransaction is provided by
34  * {@link DOMStoreTransactionFactory}.
35  *
36  * <b>Note:</b>This class does not have thread-safe implementation of  {@link #close()},
37  *   implementation may allow accessing and allocating new transactions during closing
38  *   this instance.
39  *
40  * @param <T>
41  *            Type of {@link DOMStoreTransactionFactory} factory.
42  */
43 public abstract class AbstractDOMForwardedTransactionFactory<T extends DOMStoreTransactionFactory> implements DOMDataCommitImplementation, AutoCloseable {
44
45     private final ImmutableMap<LogicalDatastoreType, T> storeTxFactories;
46
47     private boolean closed;
48
49     protected AbstractDOMForwardedTransactionFactory(final Map<LogicalDatastoreType, ? extends T> txFactories) {
50         this.storeTxFactories = ImmutableMap.copyOf(txFactories);
51     }
52
53     /**
54      * Implementations must return unique identifier for each and every call of
55      * this method;
56      *
57      * @return new Unique transaction identifier.
58      */
59     protected abstract Object newTransactionIdentifier();
60
61     /**
62      * Creates a new composite read-only transaction
63      *
64      * Creates a new composite read-only transaction backed by one transaction
65      * per factory in {@link #getTxFactories()}.
66      *
67      * Subtransaction for reading is selected by supplied
68      * {@link LogicalDatastoreType} as parameter for
69      * {@link DOMDataReadTransaction#read(LogicalDatastoreType,org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)}
70      * .
71      *
72      * Id of returned transaction is retrieved via
73      * {@link #newTransactionIdentifier()}.
74      *
75      * @return New composite read-only transaction.
76      */
77     public DOMDataReadTransaction newReadOnlyTransaction() {
78         checkNotClosed();
79         ImmutableMap.Builder<LogicalDatastoreType, DOMStoreReadTransaction> builder = ImmutableMap.builder();
80         for (Entry<LogicalDatastoreType, T> store : storeTxFactories.entrySet()) {
81             builder.put(store.getKey(), store.getValue().newReadOnlyTransaction());
82         }
83         return new DOMForwardedReadOnlyTransaction(newTransactionIdentifier(), builder.build());
84     }
85
86
87
88     /**
89      * Creates a new composite write-only transaction
90      *
91      * <p>
92      * Creates a new composite write-only transaction backed by one write-only
93      * transaction per factory in {@link #getTxFactories()}.
94      *
95      * <p>
96      * Implementation of composite Write-only transaction is following:
97      *
98      * <ul>
99      * <li>
100      * {@link DOMDataWriteTransaction#put(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
101      * - backing subtransaction is selected by {@link LogicalDatastoreType},
102      * {@link DOMStoreWriteTransaction#write(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
103      * is invoked on selected subtransaction.
104      * <li>
105      * {@link DOMDataWriteTransaction#merge(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
106      * - backing subtransaction is selected by {@link LogicalDatastoreType},
107      * {@link DOMStoreWriteTransaction#merge(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
108      * is invoked on selected subtransaction.
109      * <li>
110      * {@link DOMDataWriteTransaction#delete(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)
111      * - backing subtransaction is selected by {@link LogicalDatastoreType},
112      * {@link DOMStoreWriteTransaction#delete(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)} is invoked on
113      * selected subtransaction.
114      * <li> {@link DOMDataWriteTransaction#commit()} - results in invoking
115      * {@link DOMStoreWriteTransaction#ready()}, gathering all resulting cohorts
116      * and then invoking finalized implementation callback
117      * {@link #commit(DOMDataWriteTransaction, Iterable)} with transaction which
118      * was commited and gathered results.
119      * </ul>
120      *
121      * Id of returned transaction is generated via
122      * {@link #newTransactionIdentifier()}.
123      *
124      * @return New composite write-only transaction associated with this
125      *         factory.
126      */
127     public DOMDataWriteTransaction newWriteOnlyTransaction() {
128         checkNotClosed();
129         ImmutableMap.Builder<LogicalDatastoreType, DOMStoreWriteTransaction> builder = ImmutableMap.builder();
130         for (Entry<LogicalDatastoreType, T> store : storeTxFactories.entrySet()) {
131             builder.put(store.getKey(), store.getValue().newWriteOnlyTransaction());
132         }
133         return new DOMForwardedWriteTransaction<DOMStoreWriteTransaction>(newTransactionIdentifier(), builder.build(),
134                 this);
135     }
136
137     /**
138      * Creates a new composite write-only transaction
139      *
140      * <p>
141      * Creates a new composite write-only transaction backed by one write-only
142      * transaction per factory in {@link #getTxFactories()}.
143      * <p>
144      * Implementation of composite Write-only transaction is following:
145      *
146      * <ul>
147      * <li>
148      * {@link DOMDataWriteTransaction#read(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)}
149      * - backing subtransaction is selected by {@link LogicalDatastoreType},
150      * {@link DOMStoreWriteTransaction#read(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)} is invoked on
151      * selected subtransaction.
152      * <li>
153      * {@link DOMDataWriteTransaction#put(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
154      * - backing subtransaction is selected by {@link LogicalDatastoreType},
155      * {@link DOMStoreWriteTransaction#write(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
156      * is invoked on selected subtransaction.
157      * <li>
158      * {@link DOMDataWriteTransaction#merge(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
159      * - backing subtransaction is selected by {@link LogicalDatastoreType},
160      * {@link DOMStoreWriteTransaction#merge(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
161      * is invoked on selected subtransaction.
162      * <li>
163      * {@link DOMDataWriteTransaction#delete(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)
164      * - backing subtransaction is selected by {@link LogicalDatastoreType},
165      * {@link DOMStoreWriteTransaction#delete(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)} is invoked on
166      * selected subtransaction.
167      * <li> {@link DOMDataWriteTransaction#commit()} - results in invoking
168      * {@link DOMStoreWriteTransaction#ready()}, gathering all resulting cohorts
169      * and then invoking finalized implementation callback
170      * {@link #commit(DOMDataWriteTransaction, Iterable)} with transaction which
171      * was commited and gathered results.
172      * <li>
173      * </ul>
174      *
175      * Id of returned transaction is generated via
176      * {@link #newTransactionIdentifier()}.
177      *
178      * @return New composite read-write transaction associated with this
179      *         factory.
180      *
181      */
182     public DOMDataReadWriteTransaction newReadWriteTransaction() {
183         checkNotClosed();
184         ImmutableMap.Builder<LogicalDatastoreType, DOMStoreReadWriteTransaction> builder = ImmutableMap.builder();
185         for (Entry<LogicalDatastoreType, T> store : storeTxFactories.entrySet()) {
186             builder.put(store.getKey(), store.getValue().newReadWriteTransaction());
187         }
188         return new DOMForwardedReadWriteTransaction(newTransactionIdentifier(), builder.build(), this);
189     }
190
191     /**
192      * Convenience accessor of backing factories intended to be used only by
193      * finalization of this class.
194      *
195      * <b>Note:</b>
196      * Finalization of this class may want to access other functionality of
197      * supplied Transaction factories.
198      *
199      * @return Map of backing transaction factories.
200      */
201     protected final Map<LogicalDatastoreType, T> getTxFactories() {
202         return storeTxFactories;
203     }
204
205     /**
206      *
207      * Checks if instance is not closed.
208      *
209      * @throws IllegalStateException If instance of this class was closed.
210      *
211      */
212     @GuardedBy("this")
213     protected synchronized void checkNotClosed() {
214         Preconditions.checkState(!closed,"Transaction factory was closed. No further operations allowed.");
215     }
216
217     @Override
218     @GuardedBy("this")
219     public synchronized void close() {
220         closed = true;
221     }
222
223 }