Use ModuleInfoSnapshot instead of ModuleInfoBackedContext
[mdsal.git] / binding / mdsal-binding-runtime-spi / src / main / java / org / opendaylight / mdsal / binding / runtime / spi / BindingRuntimeHelpers.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, 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.runtime.spi;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Throwables;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.stream.Collectors;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
17 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeGenerator;
18 import org.opendaylight.mdsal.binding.runtime.api.DefaultBindingRuntimeContext;
19 import org.opendaylight.mdsal.binding.runtime.api.ModuleInfoSnapshot;
20 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
21 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
22 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
23 import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
24
25 /**
26  * Simple helpers to help with reconstruction of BindingRuntimeContext from generated binding classes. These involve
27  * reflection and YANG model assembly, hence should not be used without any caching whatsoever or any support for
28  * dynamic schema updates.
29  */
30 @Beta
31 public final class BindingRuntimeHelpers {
32     private BindingRuntimeHelpers() {
33
34     }
35
36     public static @NonNull EffectiveModelContext createEffectiveModel(final Class<?>... classes) {
37         return createEffectiveModel(Arrays.stream(classes)
38             .map(BindingRuntimeHelpers::extractYangModuleInfo)
39             .collect(Collectors.toList()));
40     }
41
42     public static @NonNull EffectiveModelContext createEffectiveModel(
43             final Iterable<? extends YangModuleInfo> moduleInfos) {
44         return createEffectiveModel(ServiceLoaderState.ParserFactory.INSTANCE, moduleInfos);
45     }
46
47     public static @NonNull EffectiveModelContext createEffectiveModel(final YangParserFactory parserFactory,
48             final Iterable<? extends YangModuleInfo> moduleInfos) {
49         return prepareContext(parserFactory, moduleInfos).getEffectiveModelContext();
50     }
51
52     public static @NonNull BindingRuntimeContext createRuntimeContext() {
53         final ModuleInfoSnapshot infos = prepareContext(ServiceLoaderState.ParserFactory.INSTANCE,
54             BindingReflections.loadModuleInfos());
55         return DefaultBindingRuntimeContext.create(ServiceLoaderState.Generator.INSTANCE.generateTypeMapping(
56             infos.getEffectiveModelContext()), infos);
57     }
58
59     public static @NonNull BindingRuntimeContext createRuntimeContext(final Class<?>... classes) {
60         return createRuntimeContext(ServiceLoaderState.ParserFactory.INSTANCE, ServiceLoaderState.Generator.INSTANCE,
61             classes);
62     }
63
64     public static @NonNull BindingRuntimeContext createRuntimeContext(final YangParserFactory parserFactory,
65             final BindingRuntimeGenerator generator, final Class<?>... classes) {
66         return createRuntimeContext(parserFactory, generator, Arrays.asList(classes));
67     }
68
69     public static @NonNull BindingRuntimeContext createRuntimeContext(final YangParserFactory parserFactory,
70             final BindingRuntimeGenerator generator, final Collection<Class<?>> classes) {
71         final ModuleInfoSnapshot infos = prepareContext(parserFactory, classes.stream()
72             .map(BindingRuntimeHelpers::extractYangModuleInfo)
73             .collect(Collectors.toList()));
74         return DefaultBindingRuntimeContext.create(
75             generator.generateTypeMapping(infos.getEffectiveModelContext()), infos);
76     }
77
78     @SuppressWarnings("checkstyle:IllegalCatch")
79     static @NonNull YangModuleInfo extractYangModuleInfo(final Class<?> clazz) {
80         try {
81             return BindingReflections.getModuleInfo(clazz);
82         } catch (Exception e) {
83             Throwables.throwIfUnchecked(e);
84             throw new IllegalStateException("Failed to extract module info from " + clazz, e);
85         }
86     }
87
88     private static @NonNull ModuleInfoSnapshot prepareContext(final YangParserFactory parserFactory,
89             final Iterable<? extends YangModuleInfo> moduleInfos) {
90         final ModuleInfoSnapshotBuilder ctx = new ModuleInfoSnapshotBuilder("helper", parserFactory);
91         ctx.registerModuleInfos(moduleInfos);
92         return ctx.build();
93     }
94 }