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.model.repo.api.MissingSchemaSourceException;
19 import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
20 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
21 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
22 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
23 import org.opendaylight.yangtools.yang.model.repo.spi.AbstractSchemaSourceCache;
24 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource.Costs;
25 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * Cache implementation that stores schemas in form of files under provided folder.
32 public final class SchemaSourceCache<T extends SchemaSourceRepresentation> extends AbstractSchemaSourceCache<T> {
34 private static final Logger LOG = LoggerFactory.getLogger(SchemaSourceCache.class);
36 private final Class<T> representation;
37 private Map<SourceIdentifier, YangModuleInfo> cachedSchemas;
39 public SchemaSourceCache(final SchemaSourceRegistry consumer,
40 final Class<T> representation,
41 final Set<YangModuleInfo> moduleList) {
42 super(consumer, representation, Costs.LOCAL_IO);
43 this.representation = representation;
44 initializeCachedSchemas(moduleList);
48 * Restore cache state using input set of modules. Cached schemas are filled with dependencies of input modules too.
50 * @param moduleList Set of modules information.
52 private void initializeCachedSchemas(final Set<YangModuleInfo> moduleList) {
53 // searching for all dependencies
54 final Set<YangModuleInfo> allModulesInfo = new HashSet<>(moduleList);
55 allModulesInfo.addAll(moduleList.stream()
56 .flatMap(yangModuleInfo -> collectYangModuleInfoDependencies(yangModuleInfo, moduleList).stream())
57 .collect(Collectors.toSet()));
59 // creation of source identifiers for all yang module info
60 cachedSchemas = allModulesInfo.stream()
61 .map(yangModuleInfo -> {
62 final RevisionSourceIdentifier revisionSourceIdentifier = RevisionSourceIdentifier.create(
63 yangModuleInfo.getName().getLocalName(),
64 yangModuleInfo.getName().getRevision());
65 return new AbstractMap.SimpleEntry<>(revisionSourceIdentifier, yangModuleInfo);
67 .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
68 cachedSchemas.keySet().forEach(this::register);
72 * Collection of all direct and indirect dependencies of input YANG module info.
74 * @param yangModuleInfo Input YANG module info for which this method collects dependencies.
75 * @param collectedModulesInfo Already collected module information.
76 * @return Already collected module information union found direct and indirect dependencies.
78 private static Set<YangModuleInfo> collectYangModuleInfoDependencies(
79 final YangModuleInfo yangModuleInfo, final Set<YangModuleInfo> collectedModulesInfo) {
80 // resolution of direct dependencies that haven't already been collected
81 final Set<YangModuleInfo> allDependencies = new HashSet<>(collectedModulesInfo);
82 final Set<YangModuleInfo> directDependencies = yangModuleInfo.getImportedModules().stream()
83 .filter(importedYangModuleInfo -> !collectedModulesInfo.contains(importedYangModuleInfo))
84 .collect(Collectors.toSet());
85 allDependencies.addAll(directDependencies);
87 // resolution of indirect dependencies through recursion
88 final Set<YangModuleInfo> indirectDependencies = directDependencies.stream()
89 .flatMap(importedYangModuleInfo ->
90 collectYangModuleInfoDependencies(importedYangModuleInfo, allDependencies).stream())
91 .collect(Collectors.toSet());
92 allDependencies.addAll(indirectDependencies);
93 return allDependencies;
97 public synchronized ListenableFuture<? extends T> getSource(final SourceIdentifier sourceIdentifier) {
98 final YangModuleInfo yangModuleInfo = cachedSchemas.get(sourceIdentifier);
99 if (yangModuleInfo != null) {
100 final YangTextSchemaSource yangTextSchemaSource = YangTextSchemaSource.delegateForByteSource(
101 sourceIdentifier, yangModuleInfo.getYangTextByteSource());
102 return Futures.immediateFuture(representation.cast(yangTextSchemaSource));
105 LOG.debug("Source {} not found in cache", sourceIdentifier);
106 return Futures.immediateFailedFuture(new MissingSchemaSourceException("Source not found", sourceIdentifier));
110 protected synchronized void offer(final T source) {
111 LOG.trace("Source {} offered to cache", source.getIdentifier());