X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-model-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fmodel%2Futil%2FFilteringSchemaContextProxy.java;h=ec3c9e958ab295e94caf8e86561462c5e47b7f8a;hb=c5835418bdffd06d4e929285affa68506ad8acdb;hp=47c6e1ab97586f9fdace51ffe751ab3970794ca1;hpb=b6b5995551a47b72c8e35a70fe16b1bd524ad187;p=yangtools.git diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/FilteringSchemaContextProxy.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/FilteringSchemaContextProxy.java index 47c6e1ab97..ec3c9e958a 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/FilteringSchemaContextProxy.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/FilteringSchemaContextProxy.java @@ -5,45 +5,51 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.yangtools.yang.model.util; +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; + import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; import com.google.common.collect.ImmutableSetMultimap; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.google.common.collect.SetMultimap; import com.google.common.collect.TreeMultimap; import java.net.URI; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Date; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.TreeMap; import java.util.function.Function; -import javax.annotation.concurrent.Immutable; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; import org.opendaylight.yangtools.yang.model.api.ModuleImport; +import org.opendaylight.yangtools.yang.model.api.ModuleLike; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.Submodule; -@Immutable public final class FilteringSchemaContextProxy extends AbstractSchemaContext { + private final ImmutableMap moduleMap; //collection to be filled with filtered modules - private final Set filteredModules; + private final ImmutableSet filteredModules; //collections to be filled in with filtered data - private final SetMultimap namespaceToModules; - private final SetMultimap nameToModules; + private final ImmutableSetMultimap namespaceToModules; + private final ImmutableSetMultimap nameToModules; /** * Filters SchemaContext for yang modules. @@ -55,27 +61,22 @@ public final class FilteringSchemaContextProxy extends AbstractSchemaContext { */ public FilteringSchemaContextProxy(final SchemaContext delegate, final Collection rootModules, final Set additionalModuleIds) { - Preconditions.checkNotNull(rootModules, "Base modules cannot be null."); - Preconditions.checkNotNull(additionalModuleIds, "Additional modules cannot be null."); + requireNonNull(rootModules, "Base modules cannot be null."); + requireNonNull(additionalModuleIds, "Additional modules cannot be null."); final Builder filteredModulesBuilder = new Builder<>(); - final SetMultimap nsMap = Multimaps.newSetMultimap(new TreeMap<>(), - AbstractSchemaContext::createModuleSet); - final SetMultimap nameMap = Multimaps.newSetMultimap(new TreeMap<>(), - AbstractSchemaContext::createModuleSet); - ImmutableMap.Builder identifiersToSourcesBuilder = ImmutableMap.builder(); - - //preparing map to get all modules with one name but difference in revision - final TreeMultimap nameToModulesAll = getStringModuleTreeMultimap(); + // preparing map to get all modules with one name but difference in revision + final TreeMultimap nameToModulesAll = TreeMultimap.create(String::compareTo, + REVISION_COMPARATOR); nameToModulesAll.putAll(getStringModuleMap(delegate)); - //in case there is a particular dependancy to view filteredModules/yang models - //dependancy is checked for module name and imports + // in case there is a particular dependency to view filteredModules/YANG models dependency is checked + // for module name and imports processForRootModules(delegate, rootModules, filteredModulesBuilder); - //adding additional modules + // adding additional modules processForAdditionalModules(delegate, additionalModuleIds, filteredModulesBuilder); filteredModulesBuilder.addAll(getImportedModules( @@ -83,22 +84,26 @@ public final class FilteringSchemaContextProxy extends AbstractSchemaContext { filteredModulesBuilder.build(), nameToModulesAll)); /** - * Instead of doing this on each invocation of getModules(), pre-compute - * it once and keep it around -- better than the set we got in. + * Instead of doing this on each invocation of getModules(), pre-compute it once and keep it around. */ - this.filteredModules = filteredModulesBuilder.build(); + final List sortedModules = new ArrayList<>(filteredModulesBuilder.build()); + sortedModules.sort(NAME_REVISION_COMPARATOR); + this.filteredModules = ImmutableSet.copyOf(sortedModules); - for (final Module module :filteredModules) { + final SetMultimap nsMap = Multimaps.newSetMultimap(new TreeMap<>(), + AbstractSchemaContext::createModuleSet); + final SetMultimap nameMap = Multimaps.newSetMultimap(new TreeMap<>(), + AbstractSchemaContext::createModuleSet); + final ImmutableMap.Builder moduleMapBuilder = ImmutableMap.builder(); + for (final Module module : filteredModules) { nameMap.put(module.getName(), module); nsMap.put(module.getNamespace(), module); + moduleMapBuilder.put(module.getQNameModule(), module); } namespaceToModules = ImmutableSetMultimap.copyOf(nsMap); nameToModules = ImmutableSetMultimap.copyOf(nameMap); - } - - private static TreeMultimap getStringModuleTreeMultimap() { - return TreeMultimap.create(String::compareTo, REVISION_COMPARATOR); + moduleMap = moduleMapBuilder.build(); } private static void processForAdditionalModules(final SchemaContext delegate, @@ -113,29 +118,29 @@ public final class FilteringSchemaContextProxy extends AbstractSchemaContext { module -> checkModuleDependency(module, rootModules))); } - private static Multimap getStringModuleMap(final SchemaContext delegate) { + private static Multimap getStringModuleMap(final SchemaContext delegate) { return Multimaps.index(delegate.getModules(), Module::getName); } //dealing with imported module other than root and directly importing root - private static Collection getImportedModules(final Map allModules, - final Set baseModules, final TreeMultimap nameToModulesAll) { + private static Collection getImportedModules(final Map allModules, + final Collection baseModules, final TreeMultimap nameToModulesAll) { - List relatedModules = Lists.newLinkedList(); + List relatedModules = new LinkedList<>(); for (Module module : baseModules) { for (ModuleImport moduleImport : module.getImports()) { + Optional revisionDate = moduleImport.getRevision(); + if (revisionDate.isEmpty()) { + revisionDate = nameToModulesAll.get(moduleImport.getModuleName()).first().getRevision(); + } - Date revisionDate = moduleImport.getRevision() == null - ? nameToModulesAll.get(moduleImport.getModuleName()).first().getRevision() - : moduleImport.getRevision(); - - ModuleId key = new ModuleId(moduleImport.getModuleName(),revisionDate); + ModuleId key = new ModuleId(moduleImport.getModuleName(), revisionDate); Module importedModule = allModules.get(key); Preconditions.checkArgument(importedModule != null, "Invalid schema, cannot find imported module: %s from module: %s, %s, modules:%s", key, - module.getQNameModule(), module.getName()); + module.getQNameModule(), module.getName(), allModules); relatedModules.add(importedModule); //calling imports recursive @@ -152,6 +157,11 @@ public final class FilteringSchemaContextProxy extends AbstractSchemaContext { return filteredModules; } + @Override + protected Map getModuleMap() { + return moduleMap; + } + @Override protected SetMultimap getNamespaceToModules() { return namespaceToModules; @@ -167,29 +177,22 @@ public final class FilteringSchemaContextProxy extends AbstractSchemaContext { } //check for any dependency regarding given string - private boolean checkModuleDependency(final Module module, final Collection rootModules) { - + private boolean checkModuleDependency(final ModuleLike module, final Collection rootModules) { for (ModuleId rootModule : rootModules) { - if (rootModule.equals(new ModuleId(module.getName(), module.getRevision()))) { return true; } //handling/checking imports regarding root modules for (ModuleImport moduleImport : module.getImports()) { - if (moduleImport.getModuleName().equals(rootModule.getName())) { - - if (moduleImport.getRevision() != null && !moduleImport.getRevision().equals(rootModule.getRev())) { - return false; - } - - return true; + return moduleImport.getRevision().isEmpty() + || moduleImport.getRevision().equals(rootModule.getRev()); } } //submodules handling - for (Module moduleSub : module.getSubmodules()) { + for (Submodule moduleSub : module.getSubmodules()) { return checkModuleDependency(moduleSub, rootModules); } } @@ -204,21 +207,21 @@ public final class FilteringSchemaContextProxy extends AbstractSchemaContext { public static final class ModuleId { private final String name; - private final Date rev; + private final Revision rev; - public ModuleId(final String name, final Date rev) { - Preconditions.checkArgument(!Strings.isNullOrEmpty(name), - "No module dependency name given. Nothing to do."); + public ModuleId(final String name, final Optional rev) { + checkArgument(!Strings.isNullOrEmpty(name), "No module dependency name given. Nothing to do."); this.name = name; - this.rev = Preconditions.checkNotNull(rev, "No revision date given. Nothing to do."); + checkArgument(rev.isPresent(), "No revision date given. Nothing to do."); + this.rev = rev.get(); } public String getName() { return name; } - public Date getRev() { - return rev; + public Optional getRev() { + return Optional.ofNullable(rev); } public static final Function MODULE_TO_MODULE_ID = input -> new ModuleId(input.getName(),