2 * Copyright (c) 2014 Cisco Systems, Inc. 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.runtime.api;
10 import static com.google.common.base.Preconditions.checkArgument;
12 import com.google.common.annotations.Beta;
13 import com.google.common.cache.CacheBuilder;
14 import com.google.common.cache.CacheLoader;
15 import com.google.common.cache.LoadingCache;
16 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
17 import org.opendaylight.yangtools.yang.binding.Action;
18 import org.opendaylight.yangtools.yang.binding.Augmentation;
19 import org.opendaylight.yangtools.yang.binding.Notification;
20 import org.opendaylight.yangtools.yang.binding.RpcInput;
21 import org.opendaylight.yangtools.yang.binding.RpcOutput;
22 import org.opendaylight.yangtools.yang.common.QName;
23 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
26 * Runtime Context for Java YANG Binding classes. It provides information derived from the backing effective model,
27 * which is not captured in generated classes (and hence cannot be obtained from {@code BindingReflections}.
30 public abstract class AbstractBindingRuntimeContext implements BindingRuntimeContext {
31 private final LoadingCache<QName, Class<?>> identityClasses = CacheBuilder.newBuilder().weakValues().build(
32 new CacheLoader<QName, Class<?>>() {
34 public Class<?> load(final QName key) {
35 final var type = getTypes().findIdentity(key).orElseThrow(
36 () -> new IllegalArgumentException("Supplied QName " + key + " is not a valid identity"));
38 return loadClass(type.getIdentifier());
39 } catch (final ClassNotFoundException e) {
40 throw new IllegalArgumentException("Required class " + type + " was not found.", e);
46 public final <T extends Augmentation<?>> AugmentRuntimeType getAugmentationDefinition(final Class<T> augClass) {
47 return getTypes().findSchema(JavaTypeName.create(augClass))
48 .filter(AugmentRuntimeType.class::isInstance)
49 .map(AugmentRuntimeType.class::cast)
54 public final CompositeRuntimeType getSchemaDefinition(final Class<?> cls) {
55 checkArgument(!Augmentation.class.isAssignableFrom(cls), "Supplied class must not be an augmentation (%s is)",
57 checkArgument(!Action.class.isAssignableFrom(cls), "Supplied class must not be an action (%s is)", cls);
58 checkArgument(!Notification.class.isAssignableFrom(cls), "Supplied class must not be a notification (%s is)",
60 return (CompositeRuntimeType) getTypes().findSchema(JavaTypeName.create(cls)).orElse(null);
64 public final ActionRuntimeType getActionDefinition(final Class<? extends Action<?, ?, ?>> cls) {
65 return (ActionRuntimeType) getTypes().findSchema(JavaTypeName.create(cls)).orElse(null);
69 public final RuntimeType getTypeWithSchema(final Class<?> type) {
70 return getTypes().findSchema(JavaTypeName.create(type))
71 .orElseThrow(() -> new IllegalArgumentException("Failed to find schema for " + type));
75 public final Class<?> getClassForSchema(final Absolute schema) {
76 final var child = getTypes().schemaTreeChild(schema);
77 checkArgument(child != null, "Failed to find binding type for %s", schema);
78 return loadClass(child);
82 public final Class<?> getIdentityClass(final QName input) {
83 return identityClasses.getUnchecked(input);
87 public final Class<? extends RpcInput> getRpcInput(final QName rpcName) {
88 return loadClass(getTypes().findRpcInput(rpcName)
89 .orElseThrow(() -> new IllegalArgumentException("Failed to find RpcInput for " + rpcName)))
90 .asSubclass(RpcInput.class);
94 public final Class<? extends RpcOutput> getRpcOutput(final QName rpcName) {
95 return loadClass(getTypes().findRpcOutput(rpcName)
96 .orElseThrow(() -> new IllegalArgumentException("Failed to find RpcOutput for " + rpcName)))
97 .asSubclass(RpcOutput.class);
100 private Class<?> loadClass(final RuntimeType type) {
102 return loadClass(type.javaType());
103 } catch (final ClassNotFoundException e) {
104 throw new IllegalStateException(e);