import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
+
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.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import java.util.TreeSet;
+
import javax.annotation.concurrent.Immutable;
+
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
@Immutable
final class SchemaContextImpl implements SchemaContext {
- private static final Supplier<HashSet<Module>> URI_SET_SUPPLIER = new Supplier<HashSet<Module>>() {
+ private static final Comparator<Module> REVISION_COMPARATOR = new Comparator<Module>() {
+ @Override
+ public int compare(final Module o1, final Module o2) {
+ if (o2.getRevision() == null) {
+ return -1;
+ }
+
+ return o2.getRevision().compareTo(o1.getRevision());
+ }
+ };
+
+ private static final Supplier<TreeSet<Module>> MODULE_SET_SUPPLIER = new Supplier<TreeSet<Module>>() {
@Override
- public HashSet<Module> get() {
- return new HashSet<>();
+ public TreeSet<Module> get() {
+ return new TreeSet<>(REVISION_COMPARATOR);
}
};
- private final ImmutableMap<ModuleIdentifier, String> identifiersToSources;
- private final ImmutableSetMultimap<URI, Module> namespaceToModules;
- private final ImmutableSet<Module> modules;
+ private final Map<ModuleIdentifier, String> identifiersToSources;
+ private final SetMultimap<URI, Module> namespaceToModules;
+ private final SetMultimap<String, Module> nameToModules;
+ private final Set<Module> modules;
SchemaContextImpl(final Set<Module> modules, final Map<ModuleIdentifier, String> identifiersToSources) {
this.identifiersToSources = ImmutableMap.copyOf(identifiersToSources);
this.modules = ImmutableSet.copyOf(ModuleDependencySort.sort(modules.toArray(new Module[modules.size()])));
/*
- * The most common lookup is from Namespace->Module. Invest some quality time in
- * building that up.
+ * The most common lookup is from Namespace->Module.
+ *
+ * RESTCONF performs lookups based on module name only, where it wants
+ * to receive the latest revision
+ *
+ * Invest some quality time in building up lookup tables for both.
*/
- final SetMultimap<URI, Module> multimap = Multimaps.newSetMultimap(
- new TreeMap<URI, Collection<Module>>(), URI_SET_SUPPLIER);
+ 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);
for (Module m : modules) {
- multimap.put(m.getNamespace(), m);
+ nameMap.put(m.getName(), m);
+ nsMap.put(m.getNamespace(), m);
}
- namespaceToModules = ImmutableSetMultimap.copyOf(multimap);
+ namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
+ nameToModules = ImmutableSetMultimap.copyOf(nameMap);
}
@Override
@Override
public Module findModuleByName(final String name, final Date revision) {
- if (name != null) {
- for (final Module module : modules) {
- if (revision == null) {
- if (module.getName().equals(name)) {
- return module;
- }
- } else if (module.getName().equals(name) && module.getRevision().equals(revision)) {
- return module;
- }
+ for (final Module module : nameToModules.get(name)) {
+ if (revision == null || revision.equals(module.getRevision())) {
+ return module;
}
}
+
return null;
}
if (namespace == null) {
return null;
}
- final Set<Module> modules = findModuleByNamespace(namespace);
- if (modules.isEmpty()) {
- return null;
- }
-
- if (revision == null) {
- // FIXME: The ordering of modules in Multimap could just guarantee this...
- TreeMap<Date, Module> map = new TreeMap<>();
- for (Module module : modules) {
- map.put(module.getRevision(), module);
- }
- if (map.isEmpty()) {
- return null;
- }
- return map.lastEntry().getValue();
- } else {
- for (Module module : modules) {
- if (module.getRevision().equals(revision)) {
- return(module);
- }
+ for (Module module : findModuleByNamespace(namespace)) {
+ if (revision == null || revision.equals(module.getRevision())) {
+ return module;
}
}
return null;
@Override
public DataSchemaNode getDataChildByName(final QName name) {
- DataSchemaNode result = null;
for (Module module : modules) {
- result = module.getDataChildByName(name);
+ final DataSchemaNode result = module.getDataChildByName(name);
if (result != null) {
- break;
+ return result;
}
}
- return result;
+ return null;
}
@Override
public DataSchemaNode getDataChildByName(final String name) {
- DataSchemaNode result = null;
for (Module module : modules) {
- result = module.getDataChildByName(name);
+ final DataSchemaNode result = module.getDataChildByName(name);
if (result != null) {
- break;
+ return result;
}
}
- return result;
+ return null;
}
@Override