Merge "Fixed for bug 1197"
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / md / sal / binding / impl / BindingTranslatedTransactionChain.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.binding.impl;
9
10 import java.util.Map;
11 import java.util.WeakHashMap;
12
13 import javax.annotation.concurrent.GuardedBy;
14
15 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
16 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
17 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
21 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
22 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
23 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
24 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
25 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
26 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
27 import org.opendaylight.yangtools.concepts.Delegator;
28
29 import com.google.common.base.Preconditions;
30
31 class BindingTranslatedTransactionChain implements BindingTransactionChain, Delegator<DOMTransactionChain> {
32
33     private final DOMTransactionChain delegate;
34
35     @GuardedBy("this")
36     private final Map<AsyncTransaction<?, ?>, AsyncTransaction<?, ?>> delegateTxToBindingTx = new WeakHashMap<>();
37     private final BindingToNormalizedNodeCodec codec;
38
39     public BindingTranslatedTransactionChain(final DOMDataBroker chainFactory,
40             final BindingToNormalizedNodeCodec codec, final TransactionChainListener listener) {
41         Preconditions.checkNotNull(chainFactory, "DOM Transaction chain factory must not be null");
42         this.delegate = chainFactory.createTransactionChain(new ListenerInvoker(listener));
43         this.codec = codec;
44     }
45
46     @Override
47     public DOMTransactionChain getDelegate() {
48         return delegate;
49     }
50
51     @Override
52     public ReadOnlyTransaction newReadOnlyTransaction() {
53         DOMDataReadOnlyTransaction delegateTx = delegate.newReadOnlyTransaction();
54         ReadOnlyTransaction bindingTx = new BindingDataReadTransactionImpl(delegateTx, codec);
55         putDelegateToBinding(delegateTx, bindingTx);
56         return bindingTx;
57     }
58
59     @Override
60     public ReadWriteTransaction newReadWriteTransaction() {
61         DOMDataReadWriteTransaction delegateTx = delegate.newReadWriteTransaction();
62         ReadWriteTransaction bindingTx = new BindingDataReadWriteTransactionImpl(delegateTx, codec);
63         putDelegateToBinding(delegateTx, bindingTx);
64         return bindingTx;
65     }
66
67     @Override
68     public WriteTransaction newWriteOnlyTransaction() {
69         DOMDataWriteTransaction delegateTx = delegate.newWriteOnlyTransaction();
70         WriteTransaction bindingTx = new BindingDataWriteTransactionImpl<>(delegateTx, codec);
71         putDelegateToBinding(delegateTx, bindingTx);
72         return bindingTx;
73     }
74
75     @Override
76     public void close() {
77         delegate.close();
78     }
79
80     private synchronized void putDelegateToBinding(final AsyncTransaction<?, ?> domTx,
81             final AsyncTransaction<?, ?> bindingTx) {
82         final Object previous = delegateTxToBindingTx.put(domTx, bindingTx);
83         Preconditions.checkState(previous == null, "DOM Transaction %s has already associated binding transation %s",domTx,previous);
84     }
85
86     private synchronized AsyncTransaction<?, ?> getBindingTransaction(final AsyncTransaction<?, ?> transaction) {
87         return delegateTxToBindingTx.get(transaction);
88     }
89
90     private final class ListenerInvoker implements TransactionChainListener {
91
92         private final TransactionChainListener listener;
93
94         public ListenerInvoker(final TransactionChainListener listener) {
95             this.listener = Preconditions.checkNotNull(listener, "Listener must not be null.");
96         }
97
98         @Override
99         public void onTransactionChainFailed(final TransactionChain<?, ?> chain,
100                 final AsyncTransaction<?, ?> transaction, final Throwable cause) {
101             Preconditions.checkState(delegate.equals(chain),
102                     "Illegal state - listener for %s was invoked for incorrect chain %s.", delegate, chain);
103             AsyncTransaction<?, ?> bindingTx = getBindingTransaction(transaction);
104             listener.onTransactionChainFailed(chain, bindingTx, cause);
105         }
106
107         @Override
108         public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
109             Preconditions.checkState(delegate.equals(chain),
110                     "Illegal state - listener for %s was invoked for incorrect chain %s.", delegate, chain);
111             listener.onTransactionChainSuccessful(BindingTranslatedTransactionChain.this);
112         }
113     }
114
115 }