BUG-7052: extract SimpleSchemaContext 52/58752/4
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 12 Jun 2017 16:42:51 +0000 (18:42 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 12 Jun 2017 23:29:48 +0000 (01:29 +0200)
Some parts of EffectiveSchemaContext are not dependent on parser
proper and just fill out the blanks left by AbstractSchemaContext.

Extract these bits into SimpleSchemaContext for wider reuse.

Change-Id: I72238ec67b958e3e7918e399e9643264b11860db
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SimpleSchemaContext.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/EffectiveSchemaContext.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6961Test.java

diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SimpleSchemaContext.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SimpleSchemaContext.java
new file mode 100644 (file)
index 0000000..b813a87
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies, s.r.o. and others.  All rights reserved.
+ *
+ * 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
+ */
+package org.opendaylight.yangtools.yang.model.util;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+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.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeMap;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
+
+/**
+ * Simple subclass of {@link AbstractSchemaContext} which performs some amount of indexing to speed up common
+ * SchemaContext operations. This implementation assumes input modules are consistent and does not perform
+ * any extensive analysis to ensure the resulting object complies to SchemaContext interface.
+ */
+@Beta
+public class SimpleSchemaContext extends AbstractSchemaContext {
+    private final SetMultimap<URI, Module> namespaceToModules;
+    private final SetMultimap<String, Module> nameToModules;
+    private final Set<ModuleIdentifier> moduleIdentifiers;
+    private final Set<Module> modules;
+
+    protected SimpleSchemaContext(final Set<Module> modules) {
+        /*
+         * Instead of doing this on each invocation of getModules(), pre-compute
+         * it once and keep it around -- better than the set we got in.
+         */
+        this.modules = ImmutableSet.copyOf(ModuleDependencySort.sort(modules));
+
+        /*
+         * 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> nsMap = Multimaps.newSetMultimap(new TreeMap<>(), MODULE_SET_SUPPLIER);
+        final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(new TreeMap<>(), MODULE_SET_SUPPLIER);
+        final Set<ModuleIdentifier> modIdBuilder = new HashSet<>();
+        for (Module m : modules) {
+            nameMap.put(m.getName(), m);
+            nsMap.put(m.getNamespace(), m);
+            modIdBuilder.add(ModuleIdentifierImpl.create(m.getName(), Optional.of(m.getNamespace()),
+                Optional.of(m.getRevision())));
+            resolveSubmoduleIdentifiers(m.getSubmodules(), modIdBuilder);
+        }
+
+        namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
+        nameToModules = ImmutableSetMultimap.copyOf(nameMap);
+        moduleIdentifiers = ImmutableSet.copyOf(modIdBuilder);
+    }
+
+    /**
+     * Create a new instance from specified modules. Note that no module validation is done and hence the consistency
+     * of the resulting SchemaContext is completely in hands of the caller.
+     */
+    public static SimpleSchemaContext forModules(final Set<Module> modules) {
+        return new SimpleSchemaContext(modules);
+    }
+
+    private static void resolveSubmoduleIdentifiers(final Set<Module> submodules,
+            final Set<ModuleIdentifier> modIdBuilder) {
+        for (Module submodule : submodules) {
+            modIdBuilder.add(ModuleIdentifierImpl.create(submodule.getName(),
+                Optional.of(submodule.getNamespace()), Optional.of(submodule.getRevision())));
+        }
+    }
+
+    @Override
+    public final Set<Module> getModules() {
+        return modules;
+    }
+
+    @Override
+    public final Set<ModuleIdentifier> getAllModuleIdentifiers() {
+        return moduleIdentifiers;
+    }
+
+    @Override
+    public final String toString() {
+        return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
+    }
+
+    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+        return toStringHelper.add("modules", modules);
+    }
+
+    @Override
+    protected final Map<ModuleIdentifier, String> getIdentifiersToSources() {
+        return ImmutableMap.of();
+    }
+
+    @Override
+    protected final SetMultimap<URI, Module> getNamespaceToModules() {
+        return namespaceToModules;
+    }
+
+    @Override
+    protected final SetMultimap<String, Module> getNameToModules() {
+        return nameToModules;
+    }
+}
index 77d4d248bf1a2820650c5ba434b3cac508aee87a..1220ff775787e02a27bbad73f359a55b7b4be22f 100644 (file)
@@ -275,7 +275,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
         }
 
         sealMutableStatements();
-        return new EffectiveSchemaContext(rootStatements, rootEffectiveStatements);
+        return EffectiveSchemaContext.create(rootStatements, rootEffectiveStatements);
     }
 
     private void startPhase(final ModelProcessingPhase phase) {
index 348e12266c51f09f354a066cfba5119ec76097da..d0dc9cfc430cb3037dc445f4a0546a45eba8d8ca 100644 (file)
@@ -10,116 +10,47 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Verify;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-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.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
-import java.util.TreeMap;
 import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
-import org.opendaylight.yangtools.yang.model.util.AbstractSchemaContext;
-import org.opendaylight.yangtools.yang.model.util.ModuleDependencySort;
-import org.opendaylight.yangtools.yang.model.util.ModuleIdentifierImpl;
+import org.opendaylight.yangtools.yang.model.util.SimpleSchemaContext;
 
 @VisibleForTesting
-public final class EffectiveSchemaContext extends AbstractSchemaContext {
-
-    private final SetMultimap<URI, Module> namespaceToModules;
-    private final SetMultimap<String, Module> nameToModules;
-    private final Set<Module> modules;
-
+public final class EffectiveSchemaContext extends SimpleSchemaContext {
     private final List<DeclaredStatement<?>> rootDeclaredStatements;
     private final List<EffectiveStatement<?, ?>> rootEffectiveStatements;
-    private final Set<ModuleIdentifier> moduleIdentifiers;
 
-    EffectiveSchemaContext(final List<DeclaredStatement<?>> rootDeclaredStatements,
+    private EffectiveSchemaContext(final Set<Module> modules, final List<DeclaredStatement<?>> rootDeclaredStatements,
             final List<EffectiveStatement<?, ?>> rootEffectiveStatements) {
+        super(modules);
         this.rootDeclaredStatements = ImmutableList.copyOf(rootDeclaredStatements);
         this.rootEffectiveStatements = ImmutableList.copyOf(rootEffectiveStatements);
+    }
 
-        final Set<Module> modulesInit = new HashSet<>();
+    static EffectiveSchemaContext create(final List<DeclaredStatement<?>> rootDeclaredStatements,
+            final List<EffectiveStatement<?, ?>> rootEffectiveStatements) {
+        final Set<Module> modules = new HashSet<>();
         for (EffectiveStatement<?, ?> stmt : rootEffectiveStatements) {
             if (stmt.getDeclared() instanceof ModuleStatement) {
                 Verify.verify(stmt instanceof Module);
-                modulesInit.add((Module) stmt);
+                modules.add((Module) stmt);
             }
         }
-        this.modules = ImmutableSet.copyOf(ModuleDependencySort.sort(modulesInit));
 
-        final SetMultimap<URI, Module> nsMap = Multimaps.newSetMultimap(new TreeMap<>(), MODULE_SET_SUPPLIER);
-        final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(new TreeMap<>(), MODULE_SET_SUPPLIER);
-        final Set<ModuleIdentifier> modIdBuilder = new HashSet<>();
-        for (Module m : modulesInit) {
-            nameMap.put(m.getName(), m);
-            nsMap.put(m.getNamespace(), m);
-            modIdBuilder.add(ModuleIdentifierImpl.create(m.getName(), Optional.of(m.getNamespace()),
-                Optional.of(m.getRevision())));
-            resolveSubmoduleIdentifiers(m.getSubmodules(), modIdBuilder);
-        }
-
-        namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
-        nameToModules = ImmutableSetMultimap.copyOf(nameMap);
-        moduleIdentifiers = ImmutableSet.copyOf(modIdBuilder);
-    }
-
-    private EffectiveSchemaContext(final Set<Module> modules) {
-
-         /*
-         * Instead of doing this on each invocation of getModules(), pre-compute
-         * it once and keep it around -- better than the set we got in.
-         */
-        this.modules = ImmutableSet.copyOf(ModuleDependencySort.sort(modules));
-
-         /*
-         * 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> nsMap = Multimaps.newSetMultimap(
-                new TreeMap<>(), MODULE_SET_SUPPLIER);
-        final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(
-                new TreeMap<>(), MODULE_SET_SUPPLIER);
-
-        Set<ModuleIdentifier> modIdBuilder = new HashSet<>();
-        for (Module m : modules) {
-            nameMap.put(m.getName(), m);
-            nsMap.put(m.getNamespace(), m);
-            modIdBuilder.add(ModuleIdentifierImpl.create(m.getName(), Optional.of(m.getNamespace()),
-                Optional.of(m.getRevision())));
-            resolveSubmoduleIdentifiers(m.getSubmodules(), modIdBuilder);
-        }
-
-        namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
-        nameToModules = ImmutableSetMultimap.copyOf(nameMap);
-        moduleIdentifiers = ImmutableSet.copyOf(modIdBuilder);
-
-        rootDeclaredStatements = ImmutableList.of();
-        rootEffectiveStatements = ImmutableList.of();
+        return new EffectiveSchemaContext(modules, rootDeclaredStatements, rootEffectiveStatements);
     }
 
+    /**
+     * @deprecated Use {@link SimpleSchemaContext#forModules(Set)} instead.
+     */
+    @Deprecated
     public static SchemaContext resolveSchemaContext(final Set<Module> modules) {
-       return new EffectiveSchemaContext(modules);
-    }
-
-    private static void resolveSubmoduleIdentifiers(final Set<Module> submodules, final Set<ModuleIdentifier> modIdBuilder) {
-        for (Module submodule : submodules) {
-            modIdBuilder.add(ModuleIdentifierImpl.create(submodule.getName(),
-                Optional.of(submodule.getNamespace()), Optional.of(submodule.getRevision())));
-        }
+       return SimpleSchemaContext.forModules(modules);
     }
 
     @VisibleForTesting
@@ -131,34 +62,4 @@ public final class EffectiveSchemaContext extends AbstractSchemaContext {
     public List<EffectiveStatement<?, ?>> getRootEffectiveStatements() {
         return rootEffectiveStatements;
     }
-
-    @Override
-    protected Map<ModuleIdentifier, String> getIdentifiersToSources() {
-        return ImmutableMap.of();
-    }
-
-    @Override
-    public Set<Module> getModules() {
-        return modules;
-    }
-
-    @Override
-    protected SetMultimap<URI, Module> getNamespaceToModules() {
-        return namespaceToModules;
-    }
-
-    @Override
-    protected SetMultimap<String, Module> getNameToModules() {
-        return nameToModules;
-    }
-
-    @Override
-    public Set<ModuleIdentifier> getAllModuleIdentifiers() {
-        return moduleIdentifiers;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("EffectiveSchemaContext{modules=%s}", modules);
-    }
 }
index 9bc0923b3720b29a7be8199d8f5cfd984a09bd84..f390440db4ef37e20d363d882ebd000cd993c1fb 100644 (file)
@@ -22,7 +22,7 @@ import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.util.ModuleIdentifierImpl;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.EffectiveSchemaContext;
+import org.opendaylight.yangtools.yang.model.util.SimpleSchemaContext;
 
 public class Bug6961Test {
 
@@ -41,7 +41,7 @@ public class Bug6961Test {
         final Set<ModuleIdentifier> allModuleIdentifiers = context.getAllModuleIdentifiers();
         assertNotNull(allModuleIdentifiers);
         assertEquals(6, allModuleIdentifiers.size());
-        final SchemaContext schemaContext = EffectiveSchemaContext.resolveSchemaContext(context.getModules());
+        final SchemaContext schemaContext = SimpleSchemaContext.forModules(context.getModules());
         assertNotNull(schemaContext);
         final Set<ModuleIdentifier> allModuleIdentifiersResolved = schemaContext.getAllModuleIdentifiers();
         assertNotNull(allModuleIdentifiersResolved);