Bump versions by x.y.(z+1)
[mdsal.git] / binding2 / mdsal-binding2-dom-adapter / src / main / java / org / opendaylight / mdsal / binding / javav2 / dom / adapter / impl / operation / LazyDOMOperationResultFuture.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mdsal.binding.javav2.dom.adapter.impl.operation;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Preconditions;
12 import com.google.common.base.Throwables;
13 import com.google.common.util.concurrent.CheckedFuture;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.Executor;
17 import java.util.concurrent.TimeUnit;
18 import java.util.concurrent.TimeoutException;
19 import javax.annotation.Nonnull;
20 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
21 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
22 import org.opendaylight.mdsal.dom.api.DOMRpcException;
23 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
24 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
25 import org.opendaylight.yangtools.yang.binding.DataContainer;
26 import org.opendaylight.yangtools.yang.common.RpcResult;
27 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
28
29 /**
30  * DOM operation result from Binding.
31  */
32 @Beta
33 final class LazyDOMOperationResultFuture implements CheckedFuture<DOMRpcResult, DOMRpcException> {
34
35     private final ListenableFuture<RpcResult<?>> bindingFuture;
36     private final BindingNormalizedNodeCodecRegistry codec;
37     private volatile DOMRpcResult result;
38
39     private LazyDOMOperationResultFuture(final ListenableFuture<RpcResult<?>> delegate,
40             final BindingNormalizedNodeCodecRegistry codec) {
41         this.bindingFuture = Preconditions.checkNotNull(delegate, "delegate");
42         this.codec = Preconditions.checkNotNull(codec, "codec");
43     }
44
45     static CheckedFuture<DOMRpcResult, DOMRpcException> create(final BindingNormalizedNodeCodecRegistry codec,
46             final ListenableFuture<RpcResult<?>> bindingResult) {
47         return new LazyDOMOperationResultFuture(bindingResult, codec);
48     }
49
50     ListenableFuture<RpcResult<?>> getBindingFuture() {
51         return bindingFuture;
52     }
53
54     @Override
55     public boolean cancel(final boolean mayInterruptIfRunning) {
56         return bindingFuture.cancel(mayInterruptIfRunning);
57     }
58
59     @Override
60     public void addListener(@Nonnull final Runnable listener, @Nonnull final Executor executor) {
61         bindingFuture.addListener(listener, executor);
62     }
63
64     @Override
65     public DOMRpcResult get() throws InterruptedException, ExecutionException {
66         if (result != null) {
67             return result;
68         }
69         return transformIfNecessary(bindingFuture.get());
70     }
71
72     @Override
73     public DOMRpcResult get(@Nonnull final long timeout, final TimeUnit unit)
74             throws InterruptedException, ExecutionException, TimeoutException {
75         if (result != null) {
76             return result;
77         }
78         return transformIfNecessary(bindingFuture.get(timeout, unit));
79     }
80
81     @Override
82     public DOMRpcResult checkedGet() throws DOMRpcException {
83         try {
84             return get();
85         } catch (InterruptedException | ExecutionException e) {
86             // FIXME: Add exception mapping
87             throw Throwables.propagate(e);
88         }
89     }
90
91     @Override
92     public DOMRpcResult checkedGet(@Nonnull final long timeout, final TimeUnit unit)
93             throws TimeoutException, DOMRpcException {
94         try {
95             return get(timeout, unit);
96         } catch (InterruptedException | ExecutionException e) {
97             // FIXME: Add exception mapping
98             throw Throwables.propagate(e);
99         }
100     }
101
102     @Override
103     public boolean isCancelled() {
104         return bindingFuture.isCancelled();
105     }
106
107     @Override
108     public boolean isDone() {
109         return bindingFuture.isDone();
110     }
111
112     private synchronized DOMRpcResult transformIfNecessary(final RpcResult<?> input) {
113         if (result == null) {
114             result = transform(input);
115         }
116         return result;
117     }
118
119     private DOMRpcResult transform(final RpcResult<?> input) {
120         if (input.isSuccessful()) {
121             final Object inputData = input.getResult();
122             if (inputData instanceof DataContainer) {
123                 return new DefaultDOMRpcResult(codec.toNormalizedNodeOperationData((TreeNode) inputData));
124             } else {
125                 return new DefaultDOMRpcResult((NormalizedNode<?, ?>) null);
126             }
127         }
128         return new DefaultDOMRpcResult(input.getErrors());
129     }
130
131 }