*/
package org.opendaylight.yangtools.sal.binding.generator.impl;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
+import com.google.common.io.ByteSource;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
-import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
import org.opendaylight.yangtools.util.ClassLoaderUtils;
import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
-import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
+import org.opendaylight.yangtools.yang.parser.repo.YangTextSchemaContextResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class ModuleInfoBackedContext extends GeneratedClassLoadingStrategy //
- implements //
- ModuleInfoRegistry, SchemaContextProvider {
+public class ModuleInfoBackedContext extends GeneratedClassLoadingStrategy
+ implements ModuleInfoRegistry, SchemaContextProvider, SchemaSourceProvider<YangTextSchemaSource> {
+
+ private final YangTextSchemaContextResolver ctxResolver = YangTextSchemaContextResolver.create("binding-context");
private ModuleInfoBackedContext(final ClassLoadingStrategy loadingStrategy) {
this.backingLoadingStrategy = loadingStrategy;
String modulePackageName = BindingReflections.getModelRootPackageName(fullyQualifiedName);
WeakReference<ClassLoader> classLoaderRef = packageNameToClassLoader.get(modulePackageName);
- ClassLoader classloader = null;
+ ClassLoader classloader;
if (classLoaderRef != null && (classloader = classLoaderRef.get()) != null) {
return ClassLoaderUtils.loadClass(classloader, fullyQualifiedName);
}
}
Class<?> cls = backingLoadingStrategy.loadClass(fullyQualifiedName);
if (BindingReflections.isBindingClass(cls)) {
- boolean newModule = resolveModuleInfo(cls);
- if (newModule) {
- recreateSchemaContext();
- }
+ resolveModuleInfo(cls);
}
- return cls;
- }
-
- private synchronized Optional<SchemaContext> recreateSchemaContext() {
- try {
- ImmutableList<InputStream> streams = getAvailableStreams();
- YangParserImpl parser = new YangParserImpl();
- Set<Module> modules = parser.parseYangModelsFromStreams(streams);
- SchemaContext schemaContext = parser.resolveSchemaContext(modules);
- return Optional.of(schemaContext);
- } catch (IOException e) {
- LOG.error("Schema was not recreated.",e);
- }
- return Optional.absent();
+ return cls;
}
// TODO finish schema parsing and expose as SchemaService
// Unite with current SchemaService
// Implement remove ModuleInfo to update SchemaContext
- public synchronized Optional<SchemaContext> tryToCreateSchemaContext() {
- return recreateSchemaContext();
- }
-
- private ImmutableList<InputStream> getAvailableStreams() throws IOException {
- ImmutableSet<YangModuleInfo> moduleInfos = ImmutableSet.copyOf(sourceIdentifierToModuleInfo.values());
-
- ImmutableList.Builder<InputStream> sourceStreams = ImmutableList.<InputStream> builder();
- for (YangModuleInfo moduleInfo : moduleInfos) {
- sourceStreams.add(moduleInfo.getModuleSourceStream());
- }
- return sourceStreams.build();
+ public Optional<SchemaContext> tryToCreateSchemaContext() {
+ return ctxResolver.getSchemaContext();
}
private boolean resolveModuleInfo(final Class<?> cls) {
SourceIdentifier identifier = sourceIdentifierFrom(moduleInfo);
YangModuleInfo previous = sourceIdentifierToModuleInfo.putIfAbsent(identifier, moduleInfo);
ClassLoader moduleClassLoader = moduleInfo.getClass().getClassLoader();
- if (previous == null) {
- String modulePackageName = moduleInfo.getClass().getPackage().getName();
- packageNameToClassLoader.putIfAbsent(modulePackageName, new WeakReference<ClassLoader>(moduleClassLoader));
-
- for (YangModuleInfo importedInfo : moduleInfo.getImportedModules()) {
- resolveModuleInfo(importedInfo);
+ try {
+ if (previous == null) {
+ String modulePackageName = moduleInfo.getClass().getPackage().getName();
+ packageNameToClassLoader.putIfAbsent(modulePackageName,
+ new WeakReference<>(moduleClassLoader));
+ ctxResolver.registerSource(toYangTextSource(identifier, moduleInfo));
+ for (YangModuleInfo importedInfo : moduleInfo.getImportedModules()) {
+ resolveModuleInfo(importedInfo);
+ }
+ } else {
+ return false;
}
- } else {
- return false;
+ } catch (Exception e) {
+ LOG.error("Not including {} in YANG sources because of error.", moduleInfo, e);
}
return true;
}
+ private static YangTextSchemaSource toYangTextSource(final SourceIdentifier identifier, final YangModuleInfo moduleInfo) {
+ return new YangTextSchemaSource(identifier) {
+
+ @Override
+ public InputStream openStream() throws IOException {
+ return moduleInfo.getModuleSourceStream();
+ }
+
+ @Override
+ protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+ return toStringHelper;
+ }
+ };
+ }
+
private static SourceIdentifier sourceIdentifierFrom(final YangModuleInfo moduleInfo) {
- return SourceIdentifier.create(moduleInfo.getName(), Optional.of(moduleInfo.getRevision()));
+ return RevisionSourceIdentifier.create(moduleInfo.getName(), Optional.of(moduleInfo.getRevision()));
}
public void addModuleInfos(final Iterable<? extends YangModuleInfo> moduleInfos) {
@Override
public ObjectRegistration<YangModuleInfo> registerModuleInfo(final YangModuleInfo yangModuleInfo) {
YangModuleInfoRegistration registration = new YangModuleInfoRegistration(yangModuleInfo, this);
-
resolveModuleInfo(yangModuleInfo);
-
return registration;
}
+ @Override public CheckedFuture<? extends YangTextSchemaSource, SchemaSourceException> getSource(
+ final SourceIdentifier sourceIdentifier) {
+ final YangModuleInfo yangModuleInfo = sourceIdentifierToModuleInfo.get(sourceIdentifier);
+
+ if (yangModuleInfo == null) {
+ LOG.debug("Unknown schema source requested: {}, available sources: {}", sourceIdentifier, sourceIdentifierToModuleInfo.keySet());
+ return Futures
+ .immediateFailedCheckedFuture(new SchemaSourceException("Unknown schema source: " + sourceIdentifier));
+ }
+
+ return Futures
+ .immediateCheckedFuture(YangTextSchemaSource.delegateForByteSource(sourceIdentifier, new ByteSource() {
+ @Override public InputStream openStream() throws IOException {
+ return yangModuleInfo.getModuleSourceStream();
+ }
+ }));
+ }
+
private static class YangModuleInfoRegistration extends AbstractObjectRegistration<YangModuleInfo> {
private final ModuleInfoBackedContext context;