2 * Copyright (c) 2018 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.dom.adapter;
10 import static java.util.Objects.requireNonNull;
11 import static org.opendaylight.mdsal.binding.dom.adapter.StaticConfiguration.ENABLE_CODEC_SHORTCUT;
12 import static org.opendaylight.yangtools.yang.common.YangConstants.operationInputQName;
14 import com.google.common.util.concurrent.Futures;
15 import com.google.common.util.concurrent.ListenableFuture;
16 import com.google.common.util.concurrent.MoreExecutors;
17 import java.lang.reflect.InvocationHandler;
18 import java.lang.reflect.Method;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
22 import org.opendaylight.mdsal.dom.api.DOMActionResult;
23 import org.opendaylight.mdsal.dom.api.DOMActionService;
24 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
25 import org.opendaylight.yangtools.yang.binding.Action;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.opendaylight.yangtools.yang.binding.RpcInput;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
29 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
32 final class ActionAdapter extends AbstractBindingAdapter<DOMActionService> implements InvocationHandler {
33 private final Class<? extends Action<?, ?, ?>> type;
34 private final NodeIdentifier inputName;
35 private final Absolute actionPath;
37 ActionAdapter(final AdapterContext codec, final DOMActionService delegate,
38 final Class<? extends Action<?, ?, ?>> type) {
39 super(codec, delegate);
40 this.type = requireNonNull(type);
41 this.actionPath = currentSerializer().getActionPath(type);
42 this.inputName = NodeIdentifier.create(operationInputQName(actionPath.lastNodeIdentifier().getModule()));
46 public @Nullable Object invoke(final @Nullable Object proxy, final @Nullable Method method,
47 final Object @Nullable [] args) throws Throwable {
48 switch (method.getName()) {
50 if (args.length == 1) {
51 return proxy == args[0];
55 if (args.length == 0) {
56 return System.identityHashCode(proxy);
60 if (args.length == 0) {
61 return type.getName() + "$Adapter{delegate=" + getDelegate() + "}";
65 if (args.length == 2) {
66 final InstanceIdentifier<?> path = (InstanceIdentifier<?>) requireNonNull(args[0]);
67 final RpcInput input = (RpcInput) requireNonNull(args[1]);
68 final CurrentAdapterSerializer serializer = currentSerializer();
69 final ListenableFuture<? extends DOMActionResult> future = getDelegate().invokeAction(actionPath,
70 new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
71 serializer.toYangInstanceIdentifier(path)),
72 serializer.toLazyNormalizedNodeActionInput(type, inputName, input));
74 // Invocation returned a future we know about -- return that future instead
75 if (ENABLE_CODEC_SHORTCUT && future instanceof BindingRpcFutureAware) {
76 return ((BindingRpcFutureAware) future).getBindingFuture();
79 return Futures.transform(future,
80 dom -> RpcResultUtil.rpcResultFromDOM(dom.getErrors(), dom.getOutput()
81 .map(output -> serializer.fromNormalizedNodeActionOutput(type, output))
83 MoreExecutors.directExecutor());
90 throw new NoSuchMethodError("Method " + method.toString() + "is unsupported.");