Centralize AbstractDOMRpcImplementationAdapter.serialize()
[mdsal.git] / binding / mdsal-binding-dom-adapter / src / main / java / org / opendaylight / mdsal / binding / dom / adapter / BindingDOMRpcProviderServiceAdapter.java
1 /*
2  * Copyright (c) 2015 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.mdsal.binding.dom.adapter;
9
10 import com.google.common.annotations.VisibleForTesting;
11 import com.google.common.collect.ClassToInstanceMap;
12 import com.google.common.collect.ImmutableClassToInstanceMap;
13 import com.google.common.collect.ImmutableMap;
14 import com.google.common.collect.ImmutableSet;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.HashSet;
18 import java.util.Set;
19 import org.opendaylight.mdsal.binding.api.RpcProviderService;
20 import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
21 import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
22 import org.opendaylight.mdsal.dom.api.DOMRpcProviderService;
23 import org.opendaylight.yangtools.concepts.ObjectRegistration;
24 import org.opendaylight.yangtools.concepts.Registration;
25 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
26 import org.opendaylight.yangtools.yang.binding.Rpc;
27 import org.opendaylight.yangtools.yang.binding.RpcService;
28 import org.opendaylight.yangtools.yang.common.QName;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
30
31 @VisibleForTesting
32 public class BindingDOMRpcProviderServiceAdapter extends AbstractBindingAdapter<DOMRpcProviderService>
33         implements RpcProviderService {
34     private static final ImmutableSet<YangInstanceIdentifier> GLOBAL = ImmutableSet.of(YangInstanceIdentifier.empty());
35
36     public BindingDOMRpcProviderServiceAdapter(final AdapterContext adapterContext,
37             final DOMRpcProviderService domRpcRegistry) {
38         super(adapterContext, domRpcRegistry);
39     }
40
41     @Override
42     @Deprecated
43     public <R extends RpcService, I extends R> ObjectRegistration<I> registerRpcImplementation(final Class<R> type,
44             final I implementation) {
45         return register(currentSerializer(), type, implementation, GLOBAL);
46     }
47
48     @Override
49     @Deprecated
50     public <R extends RpcService, I extends R> ObjectRegistration<I> registerRpcImplementation(final Class<R> type,
51             final I implementation, final Set<InstanceIdentifier<?>> paths) {
52         final var serializer = currentSerializer();
53         return register(serializer, type, implementation, toYangInstanceIdentifiers(serializer, paths));
54     }
55
56     @Override
57     public Registration registerRpcImplementation(final Rpc<?, ?> implementation) {
58         return register(currentSerializer(), implementation, GLOBAL);
59     }
60
61     @Override
62     public Registration registerRpcImplementation(final Rpc<?, ?> implementation,
63             final Set<InstanceIdentifier<?>> paths) {
64         final var serializer = currentSerializer();
65         return register(serializer, implementation, toYangInstanceIdentifiers(serializer, paths));
66     }
67
68     @Override
69     public Registration registerRpcImplementations(final ClassToInstanceMap<Rpc<?, ?>> implementations) {
70         return register(currentSerializer(), implementations, GLOBAL);
71     }
72
73     @Override
74     public Registration registerRpcImplementations(final ClassToInstanceMap<Rpc<?, ?>> implementations,
75             final Set<InstanceIdentifier<?>> paths) {
76         final var serializer = currentSerializer();
77         return register(serializer, implementations, toYangInstanceIdentifiers(serializer, paths));
78     }
79
80     private <T extends Rpc<?, ?>> Registration register(final CurrentAdapterSerializer serializer,
81             final T implementation, final Collection<YangInstanceIdentifier> rpcContextPaths) {
82         @SuppressWarnings("unchecked")
83         final var type = (Class<T>) implementation.implementedInterface();
84         return register(serializer, ImmutableClassToInstanceMap.of(type, implementation), rpcContextPaths);
85     }
86
87     private Registration register(final CurrentAdapterSerializer serializer,
88             final ClassToInstanceMap<Rpc<?, ?>> implementations,
89             final Collection<YangInstanceIdentifier> rpcContextPaths) {
90         final var context = serializer.getRuntimeContext();
91         final var builder = ImmutableMap.<DOMRpcIdentifier, DOMRpcImplementation>builderWithExpectedSize(
92             implementations.size());
93         for (var entry : implementations.entrySet()) {
94             final var type = entry.getKey();
95             final var def = context.getRpcDefinition(type);
96             if (def == null) {
97                 throw new IllegalArgumentException("Cannot resolve YANG definition of " + type);
98             }
99             final var rpcName  = def.statement().argument();
100             final var impl = new BindingDOMRpcImplementationAdapter(adapterContext(), rpcName, entry.getValue());
101
102             for (var id : createDomRpcIdentifiers(Set.of(rpcName), rpcContextPaths)) {
103                 builder.put(id, impl);
104             }
105         }
106
107         return getDelegate().registerRpcImplementations(builder.build());
108     }
109
110     @Deprecated
111     private <S extends RpcService, T extends S> ObjectRegistration<T> register(
112             final CurrentAdapterSerializer serializer, final Class<S> type, final T implementation,
113             final Collection<YangInstanceIdentifier> rpcContextPaths) {
114         final var methodHandles = serializer.getRpcMethods(type);
115         final var builder = ImmutableMap.<DOMRpcIdentifier, DOMRpcImplementation>builderWithExpectedSize(
116             methodHandles.size());
117         for (var entry : methodHandles.entrySet()) {
118             final var rpcName = entry.getKey();
119             final var impl = new LegacyDOMRpcImplementationAdapter(adapterContext(), rpcName,
120                 entry.getValue().bindTo(implementation));
121             for (var id : createDomRpcIdentifiers(Set.of(rpcName), rpcContextPaths)) {
122                 builder.put(id, impl);
123             }
124         }
125
126         return new BindingRpcAdapterRegistration<>(implementation,
127             getDelegate().registerRpcImplementations(builder.build()));
128     }
129
130     private static Set<DOMRpcIdentifier> createDomRpcIdentifiers(final Set<QName> rpcs,
131             final Collection<YangInstanceIdentifier> paths) {
132         final Set<DOMRpcIdentifier> ret = new HashSet<>();
133         for (final YangInstanceIdentifier path : paths) {
134             for (final QName rpc : rpcs) {
135                 ret.add(DOMRpcIdentifier.create(rpc, path));
136             }
137         }
138         return ret;
139     }
140
141     private static Collection<YangInstanceIdentifier> toYangInstanceIdentifiers(
142             final CurrentAdapterSerializer serializer, final Set<InstanceIdentifier<?>> identifiers) {
143         final var ret = new ArrayList<YangInstanceIdentifier>(identifiers.size());
144         for (final InstanceIdentifier<?> binding : identifiers) {
145             ret.add(serializer.toCachedYangInstanceIdentifier(binding));
146         }
147         return ret;
148     }
149 }