2 * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.operation;
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Preconditions;
12 import com.google.common.util.concurrent.AbstractFuture;
13 import com.google.common.util.concurrent.FluentFuture;
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.api.DefaultDOMRpcException;
25 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
26 import org.opendaylight.yangtools.util.concurrent.ExceptionMapper;
27 import org.opendaylight.yangtools.yang.binding.DataContainer;
28 import org.opendaylight.yangtools.yang.common.RpcResult;
29 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
32 * DOM operation result from Binding.
35 final class LazyDOMOperationResultFuture extends AbstractFuture<DOMRpcResult> {
36 private static final ExceptionMapper<DOMRpcException> DOM_RPC_EX_MAPPER =
37 new ExceptionMapper<DOMRpcException>("rpc", DOMRpcException.class) {
39 protected DOMRpcException newWithCause(String message, Throwable cause) {
40 return cause instanceof DOMRpcException ? (DOMRpcException)cause
41 : new DefaultDOMRpcException("RPC failed", cause);
45 private final ListenableFuture<RpcResult<?>> bindingFuture;
46 private final BindingNormalizedNodeCodecRegistry codec;
47 private volatile DOMRpcResult result;
49 private LazyDOMOperationResultFuture(final ListenableFuture<RpcResult<?>> delegate,
50 final BindingNormalizedNodeCodecRegistry codec) {
51 this.bindingFuture = Preconditions.checkNotNull(delegate, "delegate");
52 this.codec = Preconditions.checkNotNull(codec, "codec");
55 static FluentFuture<DOMRpcResult> create(final BindingNormalizedNodeCodecRegistry codec,
56 final ListenableFuture<RpcResult<?>> bindingResult) {
57 return new LazyDOMOperationResultFuture(bindingResult, codec);
60 ListenableFuture<RpcResult<?>> getBindingFuture() {
65 public boolean cancel(final boolean mayInterruptIfRunning) {
66 return bindingFuture.cancel(mayInterruptIfRunning);
70 public void addListener(@Nonnull final Runnable listener, @Nonnull final Executor executor) {
71 bindingFuture.addListener(listener, executor);
75 public DOMRpcResult get() throws InterruptedException, ExecutionException {
81 return transformIfNecessary(bindingFuture.get());
82 } catch (ExecutionException e) {
83 throw new ExecutionException(e.getMessage(), DOM_RPC_EX_MAPPER.apply(e));
88 public DOMRpcResult get(@Nonnull final long timeout, final TimeUnit unit)
89 throws InterruptedException, ExecutionException, TimeoutException {
95 return transformIfNecessary(bindingFuture.get(timeout, unit));
96 } catch (ExecutionException e) {
97 throw new ExecutionException(e.getMessage(), DOM_RPC_EX_MAPPER.apply(e));
102 public boolean isCancelled() {
103 return bindingFuture.isCancelled();
107 public boolean isDone() {
108 return bindingFuture.isDone();
111 private synchronized DOMRpcResult transformIfNecessary(final RpcResult<?> input) {
112 if (result == null) {
113 result = transform(input);
118 private DOMRpcResult transform(final RpcResult<?> input) {
119 if (input.isSuccessful()) {
120 final Object inputData = input.getResult();
121 if (inputData instanceof DataContainer) {
122 return new DefaultDOMRpcResult(codec.toNormalizedNodeOperationData((TreeNode) inputData));
124 return new DefaultDOMRpcResult((NormalizedNode<?, ?>) null);
127 return new DefaultDOMRpcResult(input.getErrors());