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.binding.runtime.spi;
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.annotations.Beta;
14 import com.google.common.cache.CacheBuilder;
15 import com.google.common.cache.CacheLoader;
16 import com.google.common.cache.LoadingCache;
17 import com.google.common.collect.ImmutableSet;
18 import com.google.common.util.concurrent.ListenableFuture;
19 import java.util.Optional;
21 import org.checkerframework.checker.lock.qual.Holding;
22 import org.eclipse.jdt.annotation.NonNull;
23 import org.opendaylight.binding.runtime.api.BindingRuntimeContext;
24 import org.opendaylight.binding.runtime.api.BindingRuntimeGenerator;
25 import org.opendaylight.binding.runtime.api.ClassLoadingStrategy;
26 import org.opendaylight.binding.runtime.api.DefaultBindingRuntimeContext;
27 import org.opendaylight.yangtools.util.ClassLoaderUtils;
28 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
29 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
30 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextProvider;
31 import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
32 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
33 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
34 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
35 import org.opendaylight.yangtools.yang.parser.repo.YangTextSchemaContextResolver;
38 public class ModuleInfoBackedContext extends AbstractModuleInfoTracker implements ClassLoadingStrategy,
39 EffectiveModelContextProvider, SchemaSourceProvider<YangTextSchemaSource> {
40 private static final class WithFallback extends ModuleInfoBackedContext {
41 private final @NonNull ClassLoadingStrategy fallback;
43 WithFallback(final YangTextSchemaContextResolver resolver, final ClassLoadingStrategy fallback) {
45 this.fallback = requireNonNull(fallback);
49 Class<?> loadUnknownClass(final String fullyQualifiedName) throws ClassNotFoundException {
50 // We have not found a matching registration, consult the backing strategy
51 final Class<?> cls = fallback.loadClass(fullyQualifiedName);
52 registerImplicitBindingClass(cls);
57 private static final LoadingCache<ClassLoadingStrategy,
58 LoadingCache<ImmutableSet<YangModuleInfo>, ModuleInfoBackedContext>> CONTEXT_CACHES = CacheBuilder.newBuilder()
59 .weakKeys().build(new CacheLoader<ClassLoadingStrategy,
60 LoadingCache<ImmutableSet<YangModuleInfo>, ModuleInfoBackedContext>>() {
62 public LoadingCache<ImmutableSet<YangModuleInfo>, ModuleInfoBackedContext> load(
63 final ClassLoadingStrategy strategy) {
64 return CacheBuilder.newBuilder().weakValues().build(
65 new CacheLoader<Set<YangModuleInfo>, ModuleInfoBackedContext>() {
67 public ModuleInfoBackedContext load(final Set<YangModuleInfo> key) {
68 final ModuleInfoBackedContext context = ModuleInfoBackedContext.create(strategy);
69 context.registerModuleInfos(key);
76 ModuleInfoBackedContext(final YangTextSchemaContextResolver resolver) {
81 public static ModuleInfoBackedContext cacheContext(final ClassLoadingStrategy loadingStrategy,
82 final ImmutableSet<YangModuleInfo> infos) {
83 return CONTEXT_CACHES.getUnchecked(loadingStrategy).getUnchecked(infos);
86 public static ModuleInfoBackedContext create() {
87 return create("unnamed");
90 public static ModuleInfoBackedContext create(final String id) {
91 return new ModuleInfoBackedContext(YangTextSchemaContextResolver.create(id));
94 public static ModuleInfoBackedContext create(final ClassLoadingStrategy loadingStrategy) {
95 return create("unnamed", loadingStrategy);
98 public static ModuleInfoBackedContext create(final String id, final ClassLoadingStrategy loadingStrategy) {
99 return new WithFallback(YangTextSchemaContextResolver.create(id), loadingStrategy);
102 public static ModuleInfoBackedContext create(final String id, final YangParserFactory factory) {
103 return new ModuleInfoBackedContext(YangTextSchemaContextResolver.create(id, factory));
106 public static ModuleInfoBackedContext create(final String id, final YangParserFactory factory,
107 final ClassLoadingStrategy loadingStrategy) {
108 return new WithFallback(YangTextSchemaContextResolver.create(id, factory), loadingStrategy);
112 public final EffectiveModelContext getEffectiveModelContext() {
113 final Optional<? extends EffectiveModelContext> contextOptional = tryToCreateModelContext();
114 checkState(contextOptional.isPresent(), "Unable to recreate SchemaContext, error while parsing");
115 return contextOptional.get();
119 public final synchronized Class<?> loadClass(final String fullyQualifiedName) throws ClassNotFoundException {
120 final ClassLoader loader = findClassLoader(fullyQualifiedName);
121 return loader != null ? ClassLoaderUtils.loadClass(loader, fullyQualifiedName)
122 : loadUnknownClass(fullyQualifiedName);
126 public final ListenableFuture<? extends YangTextSchemaSource> getSource(final SourceIdentifier sourceIdentifier) {
127 return getResolverSource(sourceIdentifier);
131 public final @NonNull BindingRuntimeContext createRuntimeContext(final BindingRuntimeGenerator generator) {
132 return DefaultBindingRuntimeContext.create(
133 generator.generateTypeMapping(tryToCreateModelContext().orElseThrow()), this);
136 // TODO finish schema parsing and expose as SchemaService
137 // Unite with current SchemaService
139 public final Optional<? extends EffectiveModelContext> tryToCreateModelContext() {
140 return getResolverEffectiveModel();
144 Class<?> loadUnknownClass(final String fullyQualifiedName) throws ClassNotFoundException {
145 throw new ClassNotFoundException(fullyQualifiedName);