*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html.html
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.yangtools.yang.model.util;
-import com.google.common.base.Function;
+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.Predicate;
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.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.Comparator;
-import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
+import java.util.function.Function;
+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.SchemaContext;
-@Immutable
public final class FilteringSchemaContextProxy extends AbstractSchemaContext {
+ private final ImmutableMap<QNameModule, Module> moduleMap;
//collection to be filled with filtered modules
- private final Set<Module> filteredModules;
+ private final ImmutableSet<Module> filteredModules;
//collections to be filled in with filtered data
- private final Map<ModuleIdentifier, String> identifiersToSources;
- private final SetMultimap<URI, Module> namespaceToModules;
- private final SetMultimap<String, Module> nameToModules;
+ private final ImmutableSetMultimap<URI, Module> namespaceToModules;
+ private final ImmutableSetMultimap<String, Module> nameToModules;
/**
- * Filters SchemaContext for yang modules
+ * Filters SchemaContext for yang modules.
*
* @param delegate original SchemaContext
- * @param rootModules modules (yang schemas) to be available and all their dependencies (modules importing rootModule and whole chain of their imports)
+ * @param rootModules modules (yang schemas) to be available and all their dependencies (modules importing
+ * rootModule and whole chain of their imports)
* @param additionalModuleIds (additional) modules (yang schemas) to be available and whole chain of their imports
- *
*/
- public FilteringSchemaContextProxy(final SchemaContext delegate, final Collection<ModuleId> rootModules, final Set<ModuleId> additionalModuleIds) {
-
- Preconditions.checkArgument(rootModules!=null,"Base modules cannot be null.");
- Preconditions.checkArgument(additionalModuleIds!=null,"Additional modules cannot be null.");
+ public FilteringSchemaContextProxy(final SchemaContext delegate, final Collection<ModuleId> rootModules,
+ final Set<ModuleId> additionalModuleIds) {
+ requireNonNull(rootModules, "Base modules cannot be null.");
+ requireNonNull(additionalModuleIds, "Additional modules cannot be null.");
final Builder<Module> filteredModulesBuilder = new Builder<>();
- final SetMultimap<URI, Module> nsMap = Multimaps.newSetMultimap(new TreeMap<URI, Collection<Module>>(), MODULE_SET_SUPPLIER);
- final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(new TreeMap<String, Collection<Module>>(), MODULE_SET_SUPPLIER);
-
- ImmutableMap.Builder<ModuleIdentifier, String> identifiersToSourcesBuilder = ImmutableMap.builder();
-
- //preparing map to get all modules with one name but difference in revision
- final TreeMultimap<String, Module> nameToModulesAll = getStringModuleTreeMultimap();
+ // preparing map to get all modules with one name but difference in revision
+ final TreeMultimap<String, Module> 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(
- Maps.uniqueIndex(delegate.getModules(), ModuleId.MODULE_TO_MODULE_ID), filteredModulesBuilder.build(), nameToModulesAll));
+ Maps.uniqueIndex(delegate.getModules(), ModuleId.MODULE_TO_MODULE_ID::apply),
+ 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();
-
- for (final Module module :filteredModules) {
+ final List<Module> sortedModules = new ArrayList<>(filteredModulesBuilder.build());
+ sortedModules.sort(NAME_REVISION_COMPARATOR);
+ this.filteredModules = ImmutableSet.copyOf(sortedModules);
+
+ final SetMultimap<URI, Module> nsMap = Multimaps.newSetMultimap(new TreeMap<>(),
+ AbstractSchemaContext::createModuleSet);
+ final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(new TreeMap<>(),
+ AbstractSchemaContext::createModuleSet);
+ final ImmutableMap.Builder<QNameModule, Module> moduleMapBuilder = ImmutableMap.builder();
+ for (final Module module : filteredModules) {
nameMap.put(module.getName(), module);
nsMap.put(module.getNamespace(), module);
- identifiersToSourcesBuilder.put(module, module.getSource());
+ moduleMapBuilder.put(module.getQNameModule(), module);
}
namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
nameToModules = ImmutableSetMultimap.copyOf(nameMap);
- identifiersToSources = identifiersToSourcesBuilder.build();
- }
-
- private static TreeMultimap<String, Module> getStringModuleTreeMultimap() {
- return TreeMultimap.create(new Comparator<String>() {
- @Override
- public int compare(String o1, String o2) {
- return o1.compareTo(o2);
- }
- }, REVISION_COMPARATOR);
+ moduleMap = moduleMapBuilder.build();
}
- private void processForAdditionalModules(SchemaContext delegate, final Set<ModuleId> additionalModuleIds, Builder<Module> filteredModulesBuilder) {
- filteredModulesBuilder.addAll(Collections2.filter(delegate.getModules(), new Predicate<Module>() {
- @Override
- public boolean apply(@Nullable Module module) {
- return selectAdditionalModules(module, additionalModuleIds);
- }
- }));
+ private static void processForAdditionalModules(final SchemaContext delegate,
+ final Set<ModuleId> additionalModuleIds, final Builder<Module> filteredModulesBuilder) {
+ filteredModulesBuilder.addAll(Collections2.filter(delegate.getModules(),
+ module -> selectAdditionalModules(module, additionalModuleIds)));
}
- private void processForRootModules(SchemaContext delegate, final Collection<ModuleId> rootModules, Builder<Module> filteredModulesBuilder) {
- filteredModulesBuilder.addAll(Collections2.filter(delegate.getModules(), new Predicate<Module>() {
- @Override
- public boolean apply(@Nullable Module module) {
- return checkModuleDependency(module, rootModules);
- }
- }));
+ private void processForRootModules(final SchemaContext delegate, final Collection<ModuleId> rootModules,
+ final Builder<Module> filteredModulesBuilder) {
+ filteredModulesBuilder.addAll(Collections2.filter(delegate.getModules(),
+ module -> checkModuleDependency(module, rootModules)));
}
- private Multimap<String, Module> getStringModuleMap(SchemaContext delegate) {
- return Multimaps.index(delegate.getModules(), new Function<Module, String>() {
- @Override
- public String apply(Module input) {
- return input.getName();
- }
- });
+ private static Multimap<String, Module> 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<Module> getImportedModules(Map<ModuleId, Module> allModules, Set<Module> baseModules, TreeMultimap<String, Module> nameToModulesAll) {
+ private static Collection<Module> getImportedModules(final Map<ModuleId, Module> allModules,
+ final Set<Module> baseModules, final TreeMultimap<String, Module> nameToModulesAll) {
List<Module> relatedModules = Lists.newLinkedList();
for (Module module : baseModules) {
for (ModuleImport moduleImport : module.getImports()) {
+ Optional<Revision> revisionDate = moduleImport.getRevision();
+ if (!revisionDate.isPresent()) {
+ 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() );
+ Preconditions.checkArgument(importedModule != null,
+ "Invalid schema, cannot find imported module: %s from module: %s, %s, modules:%s", key,
+ module.getQNameModule(), module.getName(), allModules);
relatedModules.add(importedModule);
//calling imports recursive
- relatedModules.addAll(getImportedModules(allModules, Collections.singleton(importedModule), nameToModulesAll));
-
+ relatedModules.addAll(getImportedModules(allModules, Collections.singleton(importedModule),
+ nameToModulesAll));
}
}
}
@Override
- protected Map<ModuleIdentifier, String> getIdentifiersToSources() {
- return identifiersToSources;
- }
-
public Set<Module> getModules() {
return filteredModules;
}
+ @Override
+ protected Map<QNameModule, Module> getModuleMap() {
+ return moduleMap;
+ }
+
@Override
protected SetMultimap<URI, Module> getNamespaceToModules() {
return namespaceToModules;
return nameToModules;
}
- private boolean selectAdditionalModules(Module module, Set<ModuleId> additionalModules){
-
- if(additionalModules.contains(new ModuleId(module.getName(), module.getRevision()))){
-
- return true;
- }
-
- return false;
+ private static boolean selectAdditionalModules(final Module module, final Set<ModuleId> additionalModules) {
+ return additionalModules.contains(new ModuleId(module.getName(), module.getRevision()));
}
//check for any dependency regarding given string
- private boolean checkModuleDependency(Module module, Collection<ModuleId> rootModules) {
-
+ private boolean checkModuleDependency(final Module module, final Collection<ModuleId> rootModules) {
for (ModuleId rootModule : rootModules) {
-
- if(rootModule.equals(new ModuleId(module.getName(), module.getRevision()))) {
+ 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;
+ if (moduleImport.getModuleName().equals(rootModule.getName())) {
+ return !moduleImport.getRevision().isPresent()
+ || moduleImport.getRevision().equals(rootModule.getRev());
}
}
public static final class ModuleId {
private final String name;
- private final Date rev;
+ private final Revision rev;
- public ModuleId(String name, Date rev) {
- Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "No module dependency name given. Nothing to do.");
+ public ModuleId(final String name, final Optional<Revision> 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<Revision> getRev() {
+ return Optional.ofNullable(rev);
}
- public static final Function<Module, ModuleId> MODULE_TO_MODULE_ID = new Function<Module, ModuleId>() {
- @Override
- public ModuleId apply(Module input) {
- return new ModuleId(input.getName(), input.getRevision());
- }
- };
+ public static final Function<Module, ModuleId> MODULE_TO_MODULE_ID = input -> new ModuleId(input.getName(),
+ input.getRevision());
@Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- ModuleId moduleId = (ModuleId) o;
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof ModuleId)) {
+ return false;
+ }
- if (name != null ? !name.equals(moduleId.name) : moduleId.name != null) return false;
- if (rev != null ? !rev.equals(moduleId.rev) : moduleId.rev != null) return false;
+ ModuleId moduleId = (ModuleId) obj;
+ if (name != null ? !name.equals(moduleId.name) : moduleId.name != null) {
+ return false;
+ }
+ if (rev != null ? !rev.equals(moduleId.rev) : moduleId.rev != null) {
+ return false;
+ }
return true;
}
@Override
public String toString() {
-
return String.format("ModuleId{name='%s', rev=%s}",name,rev);
}
}