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.netconf.test.tool.schemacache;
10 import com.google.common.util.concurrent.Futures;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.util.AbstractMap;
13 import java.util.HashSet;
16 import java.util.stream.Collectors;
17 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
18 import org.opendaylight.yangtools.yang.common.QName;
19 import org.opendaylight.yangtools.yang.common.Revision;
20 import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
21 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
22 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
23 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
24 import org.opendaylight.yangtools.yang.model.repo.spi.AbstractSchemaSourceCache;
25 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource.Costs;
26 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * Cache implementation that stores schemas in form of files under provided folder.
33 public final class SchemaSourceCache<T extends SchemaSourceRepresentation> extends AbstractSchemaSourceCache<T> {
35 private static final Logger LOG = LoggerFactory.getLogger(SchemaSourceCache.class);
37 private final Class<T> representation;
38 private Map<SourceIdentifier, YangModuleInfo> cachedSchemas;
40 public SchemaSourceCache(final SchemaSourceRegistry consumer,
41 final Class<T> representation,
42 final Set<YangModuleInfo> moduleList) {
43 super(consumer, representation, Costs.LOCAL_IO);
44 this.representation = representation;
45 initializeCachedSchemas(moduleList);
49 * Restore cache state using input set of modules. Cached schemas are filled with dependencies of input modules too.
51 * @param moduleList Set of modules information.
53 private void initializeCachedSchemas(final Set<YangModuleInfo> moduleList) {
54 // searching for all dependencies
55 final Set<YangModuleInfo> allModulesInfo = new HashSet<>(moduleList);
56 allModulesInfo.addAll(moduleList.stream()
57 .flatMap(yangModuleInfo -> collectYangModuleInfoDependencies(yangModuleInfo, moduleList).stream())
58 .collect(Collectors.toSet()));
60 // creation of source identifiers for all yang module info
61 cachedSchemas = allModulesInfo.stream()
62 .map(yangModuleInfo -> {
63 final QName name = yangModuleInfo.getName();
64 final SourceIdentifier revisionSourceIdentifier = new SourceIdentifier(
65 name.getLocalName(), name.getRevision().map(Revision::toString).orElse(null));
66 return new AbstractMap.SimpleEntry<>(revisionSourceIdentifier, yangModuleInfo);
68 .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
69 cachedSchemas.keySet().forEach(this::register);
73 * Collection of all direct and indirect dependencies of input YANG module info.
75 * @param yangModuleInfo Input YANG module info for which this method collects dependencies.
76 * @param collectedModulesInfo Already collected module information.
77 * @return Already collected module information union found direct and indirect dependencies.
79 private static Set<YangModuleInfo> collectYangModuleInfoDependencies(
80 final YangModuleInfo yangModuleInfo, final Set<YangModuleInfo> collectedModulesInfo) {
81 // resolution of direct dependencies that haven't already been collected
82 final Set<YangModuleInfo> allDependencies = new HashSet<>(collectedModulesInfo);
83 final Set<YangModuleInfo> directDependencies = yangModuleInfo.getImportedModules().stream()
84 .filter(importedYangModuleInfo -> !collectedModulesInfo.contains(importedYangModuleInfo))
85 .collect(Collectors.toSet());
86 allDependencies.addAll(directDependencies);
88 // resolution of indirect dependencies through recursion
89 final Set<YangModuleInfo> indirectDependencies = directDependencies.stream()
90 .flatMap(importedYangModuleInfo ->
91 collectYangModuleInfoDependencies(importedYangModuleInfo, allDependencies).stream())
92 .collect(Collectors.toSet());
93 allDependencies.addAll(indirectDependencies);
94 return allDependencies;
98 public synchronized ListenableFuture<? extends T> getSource(final SourceIdentifier sourceIdentifier) {
99 final YangModuleInfo yangModuleInfo = cachedSchemas.get(sourceIdentifier);
100 if (yangModuleInfo != null) {
101 final YangTextSchemaSource yangTextSchemaSource = YangTextSchemaSource.delegateForByteSource(
102 sourceIdentifier, yangModuleInfo.getYangTextByteSource());
103 return Futures.immediateFuture(representation.cast(yangTextSchemaSource));
106 LOG.debug("Source {} not found in cache", sourceIdentifier);
107 return Futures.immediateFailedFuture(new MissingSchemaSourceException("Source not found", sourceIdentifier));
111 protected synchronized void offer(final T source) {
112 LOG.trace("Source {} offered to cache", source.getIdentifier());