API Clarity: Documentented o.o.y.yang.parser.impl.util 47/7647/3
authorTony Tkacik <ttkacik@cisco.com>
Tue, 3 Jun 2014 15:51:51 +0000 (17:51 +0200)
committerTony Tkacik <ttkacik@cisco.com>
Mon, 9 Jun 2014 08:58:36 +0000 (10:58 +0200)
Change-Id: Ic98387e4e5f191cbd920279c9a5520ffa81d3607
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/util/YangModelDependencyInfo.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/util/YangSourceContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/util/YangSourceContextResolver.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/util/YangSourceFromCapabilitiesResolver.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/util/YangSourceFromDependencyInfoResolver.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/BitImpl.java

index 6530c92510c8d6aabd43eb5640a4ae146b5c71ca..bbc49453bdd45cae6b4659fa73b49d73fa88ce03 100644 (file)
@@ -1,6 +1,5 @@
 /*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
+ * Copyright (c) 2014 Cisco Systems, Inc. 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/eplv10.html
@@ -30,6 +29,22 @@ import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSet;
 
+/**
+ * Helper transfer object which holds basic and dependency information for YANG
+ * model.
+ *
+ *
+ *
+ * There are two concrete implementations of this interface:
+ * <ul>
+ * <li>{@link ModuleDependencyInfo} - Dependency information for module</li>
+ * <li>{@link SubmoduleDependencyInfo} - Dependency information for submodule</li>
+ * </ul>
+ *
+ * @see ModuleDependencyInfo
+ * @see SubmoduleDependencyInfo
+ *
+ */
 public abstract class YangModelDependencyInfo {
 
     private final String name;
@@ -39,8 +54,8 @@ public abstract class YangModelDependencyInfo {
     private final ImmutableSet<ModuleImport> moduleImports;
     private final ImmutableSet<ModuleImport> dependencies;
 
-    public YangModelDependencyInfo(final String name, final String formattedRevision, final ImmutableSet<ModuleImport> imports,
-            final ImmutableSet<ModuleImport> includes) {
+    protected YangModelDependencyInfo(final String name, final String formattedRevision,
+            final ImmutableSet<ModuleImport> imports, final ImmutableSet<ModuleImport> includes) {
         this.name = name;
         this.formattedRevision = formattedRevision;
         this.revision = QName.parseRevision(formattedRevision);
@@ -52,18 +67,41 @@ public abstract class YangModelDependencyInfo {
                 .build();
     }
 
+    /**
+     * Returns immutable collection of all module imports.
+     *
+     * This collection contains both <code>import</code> statements
+     * and <code>include</code> statements for submodules.
+     *
+     * @return Immutable collection of imports.
+     */
     public ImmutableSet<ModuleImport> getDependencies() {
         return dependencies;
     }
 
+    /**
+     * Returns model name
+     *
+     * @return model name
+     */
     public String getName() {
         return name;
     }
 
+    /**
+     * Returns formatted revision string
+     *
+     * @return formatted revision string
+     */
     public String getFormattedRevision() {
         return formattedRevision;
     }
 
+    /**
+     * Returns revision
+     *
+     * @return revision
+     */
     public Date getRevision() {
         return revision;
     }
@@ -106,33 +144,46 @@ public abstract class YangModelDependencyInfo {
         return true;
     }
 
+    /**
+     * Extracts {@link YangModelDependencyInfo} from input stream
+     * containing YANG model.
+     *
+     * This parsing does not validate full YANG module, only
+     * parses header up to the revisions and imports.
+     *
+     * @param yangStream
+     *            Opened Input stream containing text source of YANG model
+     * @return {@link YangModelDependencyInfo}
+     * @throws IllegalArgumentException
+     *             If input stream is not valid YANG stream
+     */
     public static YangModelDependencyInfo fromInputStream(final InputStream yangStream) {
         YangContext yangContext = YangParserImpl.parseStreamWithoutErrorListeners(yangStream);
 
         Optional<Module_stmtContext> moduleCtx = getFirstContext(yangContext, Module_stmtContext.class);
         if (moduleCtx.isPresent()) {
-            return fromModuleContext(moduleCtx.get());
+            return parseModuleContext(moduleCtx.get());
         }
         Optional<Submodule_stmtContext> submoduleCtx = getFirstContext(yangContext, Submodule_stmtContext.class);
         if (submoduleCtx.isPresent()) {
-            return fromSubmoduleContext(submoduleCtx.get());
+            return parseSubmoduleContext(submoduleCtx.get());
         }
         throw new IllegalArgumentException("Supplied stream is not valid yang file.");
     }
 
-    private static YangModelDependencyInfo fromModuleContext(final Module_stmtContext module) {
+    private static YangModelDependencyInfo parseModuleContext(final Module_stmtContext module) {
         String name = getArgumentString(module);
         // String prefix =
         // getArgumentString(module.module_header_stmts().prefix_stmt(0));
         String namespace = getArgumentString(module.module_header_stmts().namespace_stmt(0));
         String latestRevision = getLatestRevision(module.revision_stmts());
-        ImmutableSet<ModuleImport> imports = getImports(module.linkage_stmts().import_stmt());
-        ImmutableSet<ModuleImport> includes = getIncludes(module.linkage_stmts().include_stmt());
+        ImmutableSet<ModuleImport> imports = parseImports(module.linkage_stmts().import_stmt());
+        ImmutableSet<ModuleImport> includes = parseIncludes(module.linkage_stmts().include_stmt());
 
         return new ModuleDependencyInfo(name, latestRevision, namespace, imports, includes);
     }
 
-    private static ImmutableSet<ModuleImport> getImports(final List<Import_stmtContext> importStatements) {
+    private static ImmutableSet<ModuleImport> parseImports(final List<Import_stmtContext> importStatements) {
         ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
         for (Import_stmtContext importStmt : importStatements) {
             String moduleName = getArgumentString(importStmt);
@@ -154,19 +205,19 @@ public abstract class YangModelDependencyInfo {
         return latestRevision;
     }
 
-    private static YangModelDependencyInfo fromSubmoduleContext(final Submodule_stmtContext submodule) {
+    private static YangModelDependencyInfo parseSubmoduleContext(final Submodule_stmtContext submodule) {
         String name = getArgumentString(submodule);
         Belongs_to_stmtContext belongsToStmt = submodule.submodule_header_stmts().belongs_to_stmt(0);
         String belongsTo = getArgumentString(belongsToStmt);
 
         String latestRevision = getLatestRevision(submodule.revision_stmts());
-        ImmutableSet<ModuleImport> imports = getImports(submodule.linkage_stmts().import_stmt());
-        ImmutableSet<ModuleImport> includes = getIncludes(submodule.linkage_stmts().include_stmt());
+        ImmutableSet<ModuleImport> imports = parseImports(submodule.linkage_stmts().import_stmt());
+        ImmutableSet<ModuleImport> includes = parseIncludes(submodule.linkage_stmts().include_stmt());
 
         return new SubmoduleDependencyInfo(name, latestRevision, belongsTo, imports, includes);
     }
 
-    private static ImmutableSet<ModuleImport> getIncludes(final List<Include_stmtContext> importStatements) {
+    private static ImmutableSet<ModuleImport> parseIncludes(final List<Include_stmtContext> importStatements) {
         ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
         for (Include_stmtContext importStmt : importStatements) {
             String moduleName = getArgumentString(importStmt);
@@ -184,6 +235,11 @@ public abstract class YangModelDependencyInfo {
         return QName.parseRevision(formatedDate);
     }
 
+    /**
+     *
+     * Dependency information for YANG module.
+     *
+     */
     public static final class ModuleDependencyInfo extends YangModelDependencyInfo {
 
         private ModuleDependencyInfo(final String name, final String latestRevision, final String namespace,
@@ -193,15 +249,25 @@ public abstract class YangModelDependencyInfo {
 
         @Override
         public String toString() {
-            return "Module [name=" + getName() + ", revision=" + getRevision()
-                    + ", dependencies=" + getDependencies() + "]";
+            return "Module [name=" + getName() + ", revision=" + getRevision() + ", dependencies=" + getDependencies()
+                    + "]";
         }
     }
 
+    /**
+     *
+     * Dependency information for submodule, also provides name
+     * for parent module.
+     *
+     */
     public static final class SubmoduleDependencyInfo extends YangModelDependencyInfo {
 
         private final String belongsTo;
 
+        /**
+         * Returns name of parent module.
+         *
+         */
         public String getParentModule() {
             return belongsTo;
         }
@@ -214,11 +280,16 @@ public abstract class YangModelDependencyInfo {
 
         @Override
         public String toString() {
-            return "Submodule [name=" + getName() + ", revision=" + getRevision()
-                    + ", dependencies=" + getDependencies() + "]";
+            return "Submodule [name=" + getName() + ", revision=" + getRevision() + ", dependencies="
+                    + getDependencies() + "]";
         }
     }
 
+    /**
+     * Utility implementation of {@link ModuleImport} to be used by
+     * {@link YangModelDependencyInfo}.
+     *
+     */
     private static final class ModuleImportImpl implements ModuleImport {
 
         private final Date revision;
index fe0e81e43e22debf9286b50402c4d6dc24ee0674..1975d165a9305bd26801a2d0004936009f45f262 100644 (file)
@@ -1,6 +1,5 @@
 /*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
+ * Copyright (c) 2014 Cisco Systems, Inc. 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/eplv10.html
@@ -14,6 +13,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.opendaylight.yangtools.concepts.Delegator;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
@@ -29,7 +29,33 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.ImmutableSet;
 
-public class YangSourceContext implements AdvancedSchemaSourceProvider<InputStream>, AutoCloseable {
+/**
+ *
+ * Context of YANG model sources
+ *
+ * YANG sources context represent information learned about set of model sources
+ * which could be derived from dependency information only.
+ *
+ * Contains following information:
+ * <ul>
+ * <li>{@link #getValidSources()} - set of {@link SourceIdentifier} which have
+ * their dependencies present and are safe to be used by full blown parser.
+ * <li>{@link #getMissingSources()} - set of {@link SourceIdentifier} which have
+ * been referenced by other YANG sources, but source code for them is missing.
+ * <li>{@link #getMissingDependencies()} - map of {@link SourceIdentifier} and
+ * their imports for which source codes was not available.
+ *
+ * {@link YangSourceContext} may be associated with {@link SchemaSourceProvider}
+ * (see {@link #getDelegate()}, which was used for retrieval of sources during
+ * context computation.
+ *
+ * {@link YangSourceContext} may be used as schema source provider to retrieve
+ * this sources.
+ *
+ *
+ */
+public class YangSourceContext implements AdvancedSchemaSourceProvider<InputStream>, AutoCloseable,
+        Delegator<AdvancedSchemaSourceProvider<InputStream>> {
 
     private final ImmutableSet<SourceIdentifier> validSources;
 
@@ -37,24 +63,62 @@ public class YangSourceContext implements AdvancedSchemaSourceProvider<InputStre
     private final ImmutableMultimap<SourceIdentifier, ModuleImport> missingDependencies;
     private AdvancedSchemaSourceProvider<InputStream> sourceProvider;
 
+    /**
+     * Construct YANG Source Context
+     * 
+     * @param validSourcesSet Set of identifiers of valid sources
+     * @param missingSourcesSet Set of identifiers of missing sources
+     * @param missingDependenciesMap Map of identifiers of resolved sources and their missing imports.
+     * @param sourceProvider Source provider which was used for context resolution or 
+     *          null if provider was not used.
+     */
     YangSourceContext(final ImmutableSet<SourceIdentifier> validSourcesSet,
             final ImmutableSet<SourceIdentifier> missingSourcesSet,
             final ImmutableMultimap<SourceIdentifier, ModuleImport> missingDependenciesMap,
-            final AdvancedSchemaSourceProvider<InputStream> sourceProvicer) {
-        validSources = validSourcesSet;
-        missingSources = missingSourcesSet;
-        missingDependencies = missingDependenciesMap;
-        sourceProvider = sourceProvicer;
+            final AdvancedSchemaSourceProvider<InputStream> sourceProvider) {
+        validSources = Preconditions.checkNotNull(validSourcesSet, "Valid source set must not be null");
+        missingSources = Preconditions.checkNotNull(missingSourcesSet, "Missing sources set must not be null");
+        missingDependencies = Preconditions.checkNotNull(missingDependenciesMap, "Missing dependencies map must not be null");
+        this.sourceProvider = sourceProvider;
     }
 
+    /**
+     * Returns set of valid source identifiers.
+     *
+     * Source identifier is considered valid if it's source
+     * was present during resolution and sources
+     * for all known dependencies was present at the time of creation
+     * of {@link YangSourceContext}.
+     *
+     * @return Set of valid source identifiers.
+     */
     public ImmutableSet<SourceIdentifier> getValidSources() {
         return validSources;
     }
 
+    /**
+     * Returns set of source identifiers, whom sources was not resolved.
+     *
+     * Source is considered missing if the source was not present
+     * during resolution of {@link YangSourceContext}.
+     *
+     * @return Set of missing sources.
+     */
     public ImmutableSet<SourceIdentifier> getMissingSources() {
         return missingSources;
     }
 
+    /**
+     * Returns a multimap of Source Identifier and imports which had missing
+     * sources.
+     *
+     * Maps a source identifier to its imports, which was not resolved
+     * during resolution of this context, so it is unable to fully
+     * processed source identifier.
+     *
+     *
+     * @return Multi-map of source identifier to it's unresolved dependencies.
+     */
     public ImmutableMultimap<SourceIdentifier, ModuleImport> getMissingDependencies() {
         return missingDependencies;
     }
@@ -77,6 +141,11 @@ public class YangSourceContext implements AdvancedSchemaSourceProvider<InputStre
         return sourceProvider;
     }
 
+    @Override
+    public AdvancedSchemaSourceProvider<InputStream> getDelegate() {
+        return sourceProvider;
+    }
+
     @Override
     public void close() {
         if (sourceProvider != null) {
@@ -84,33 +153,119 @@ public class YangSourceContext implements AdvancedSchemaSourceProvider<InputStre
         }
     }
 
+    /**
+     * Creates YANG Source context from supplied capabilities and schema source
+     * provider.
+     *
+     * @param capabilities
+     *            Set of QName representing module capabilities,
+     *            {@link QName#getLocalName()} represents
+     *            source name and {@link QName#getRevision()} represents
+     *            revision of source.
+     *
+     * @param schemaSourceProvider
+     *            - {@link SchemaSourceProvider} which should be used to resolve
+     *            sources.
+     * @return YANG source context which describes resolution of capabilities
+     *         and their dependencies
+     *         against supplied schema source provider.
+     */
     public static final YangSourceContext createFrom(final Iterable<QName> capabilities,
             final SchemaSourceProvider<InputStream> schemaSourceProvider) {
         YangSourceContextResolver resolver = new YangSourceFromCapabilitiesResolver(capabilities, schemaSourceProvider);
         return resolver.resolveContext();
     }
 
-    public static final YangSourceContext createFrom(final Map<SourceIdentifier, YangModelDependencyInfo> moduleDependencies) {
+    public static final YangSourceContext createFrom(
+            final Map<SourceIdentifier, YangModelDependencyInfo> moduleDependencies) {
         YangSourceContextResolver resolver = new YangSourceFromDependencyInfoResolver(moduleDependencies);
         return resolver.resolveContext();
     }
 
+    /**
+     * Tries to create schema context using {@link YangParserImpl} and valid
+     * sources
+     * retrieved from YANG Source context and schema source provider which
+     * was used to create YANG Source Context
+     *
+     * @param context
+     * @return Schema Context created from valid sources in YANG Source Context
+     * @deprecated Use {@link #toSchemaContext(AdvancedSchemaSourceProvider)}
+     *  with {@link #getDelegate()}
+     */
+    @Deprecated
     public static final SchemaContext toSchemaContext(final YangSourceContext context) {
-        List<InputStream> inputStreams = getValidInputStreams(context);
+        return context.toSchemaContext(context.getDelegate());
+    }
+
+    /**
+     * Tries to create schema context using {@link YangParserImpl} and valid
+     * sources
+     * retrieved from YANG Source context and schema source provider which
+     * was used to create YANG Source Context
+     *
+     * @param provider
+     *            Schema Source Provider to be used to retrieve sources
+     * @return Schema Context created from valid sources in YANG Source Context
+     */
+    public final SchemaContext toSchemaContext(AdvancedSchemaSourceProvider<InputStream> provider) {
+        List<InputStream> inputStreams = this.getValidInputStreams(provider);
         YangParserImpl parser = new YangParserImpl();
+        @SuppressWarnings("deprecation")
         Set<Module> models = parser.parseYangModelsFromStreams(inputStreams);
         return parser.resolveSchemaContext(models);
     }
 
+    /**
+     * Returns a list of valid input streams from YANG Source Context
+     * using schema source provider which was used to create YANG Source Context
+     *
+     * @param context
+     *            YANG Source context
+     * @return List of input streams for valid sources.
+     * @deprecated Use
+     *             {@link #getValidInputStreams(AdvancedSchemaSourceProvider)}
+     *             combined with {@link #getDelegate()} instead.
+     */
+    @Deprecated
     public static List<InputStream> getValidInputStreams(final YangSourceContext context) {
-        return getValidInputStreams(context, context.sourceProvider);
+        return context.getValidInputStreams(context.getDelegate());
     }
 
+    /**
+     * Returns a list of valid input streams from YANG Source Context
+     * using supplied schema source provider.
+     *
+     * @param context
+     *            YANG Source context from which list of valid sources is used
+     * @param provider
+     *            Schema Source Provider which is used to retrieve sources
+     * @return List of input streams.
+     * @deprecated Use
+     *             {@link #getValidInputStreams(AdvancedSchemaSourceProvider)}
+     *             instead.
+     */
+    @Deprecated
     public static List<InputStream> getValidInputStreams(final YangSourceContext context,
             final AdvancedSchemaSourceProvider<InputStream> provider) {
+        return context.getValidInputStreams(provider);
+    }
+
+    /**
+     * Returns a list of valid input streams from YANG Source Context
+     * using supplied schema source provider.
+     *
+     * @param context
+     *            YANG Source context from which list of valid sources is used
+     * @param provider
+     *            Schema Source Provider which is used to retrieve sources
+     * @return List of input streams.
+     */
+    public List<InputStream> getValidInputStreams(final AdvancedSchemaSourceProvider<InputStream> provider) {
+        Preconditions.checkNotNull(provider, "provider must not be null.");
         final HashSet<SourceIdentifier> sourcesToLoad = new HashSet<>();
-        sourcesToLoad.addAll(context.getValidSources());
-        for (SourceIdentifier source : context.getValidSources()) {
+        sourcesToLoad.addAll(this.getValidSources());
+        for (SourceIdentifier source : this.getValidSources()) {
             if (source.getRevision() != null) {
                 SourceIdentifier sourceWithoutRevision = SourceIdentifier.create(source.getName(),
                         Optional.<String> absent());
index 50f4a3e8cddf93ea63069b18cf0ed24150c8572e..ae63663699f9f4784dcc0aaeb26a2149070dff52 100644 (file)
@@ -1,6 +1,5 @@
 /*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
+ * Copyright (c) 2014 Cisco Systems, Inc. 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/eplv10.html
@@ -13,6 +12,7 @@ import java.util.HashMap;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
 import org.opendaylight.yangtools.yang.model.util.repo.AdvancedSchemaSourceProvider;
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
 import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -21,20 +21,78 @@ import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.ImmutableSet;
 
+/**
+ *
+ * Resolution task for YANG Source Context
+ *
+ * {@link YangSourceContextResolver} and its subclasses are responsible for
+ * resolving {@link YangSourceContext} based on provided
+ * {@link SchemaSourceProvider} and set of modules to process.
+ *
+ *
+ * <h3>Implementation notes</h3>
+ *
+ * In order to customize resolution of {@link YangSourceContext} implementators
+ * of this class are required to implement following methods:
+ * <ul>
+ * <li>{@link #getDependencyInfo(SourceIdentifier)} - Retrieval of dependency
+ * information</li>
+ * <li>{@link #resolveContext()} - Main resolution algorithm
+ * <li>
+ * </ul>
+ *
+ * This abstract class provides utility methods for implementators which may be
+ * used in {@link #resolveContext()} to create {@link YangSourceContext}:
+ * <ul>
+ * <li>{@link #resolveSource(SourceIdentifier)} and
+ * {@link #resolveSource(String, Optional)} - Tries to resolve state for
+ * supplied model identifier and updates internal state. If state was not
+ * already resolved for identifier it invokes
+ * {@link #getDependencyInfo(SourceIdentifier)} for particular identifier. This
+ * method is recursivelly invoked for all dependencies.</li>
+ * <li>{@link #createSourceContext()} - Creates {@link YangSourceContext} based
+ * on previous invocations of {@link #resolveSource(SourceIdentifier)} methods.</li>
+ * </ul>
+ *
+ */
 public abstract class YangSourceContextResolver {
 
-    enum ResolutionState {
-        MISSING_SOURCE,
-        MISSING_DEPENDENCY,
-        OTHER_ERROR,
+    /**
+     * 
+     * State of source code resolution
+     * 
+     */
+    public enum ResolutionState {
+        /**
+         * 
+         * Source was missing during source resolution
+         * 
+         */
+        MISSING_SOURCE, 
+        /**
+         * 
+         * One or multiple of dependencies of source are missing 
+         * 
+         */
+        MISSING_DEPENDENCY, 
+        /**
+         * Other error ocurred during resolution
+         * 
+         */
+        OTHER_ERROR, 
+        /**
+         * Source, its dependencies and its transient dependencies
+         * are resolved.
+         * 
+         */
         EVERYTHING_OK,
     }
 
     private static final Logger LOG = LoggerFactory.getLogger(YangSourceContextResolver.class);
     private final HashMap<SourceIdentifier, YangSourceContextResolver.ResolutionState> alreadyProcessed = new HashMap<>();
     private final ImmutableSet.Builder<SourceIdentifier> missingSources = ImmutableSet.builder();
-    private final ImmutableMultimap.Builder<SourceIdentifier, ModuleImport> missingDependencies =
-            ImmutableMultimap.builder();
+    private final ImmutableMultimap.Builder<SourceIdentifier, ModuleImport> missingDependencies = ImmutableMultimap
+            .builder();
     private final ImmutableSet.Builder<SourceIdentifier> validSources = ImmutableSet.builder();
     private final AdvancedSchemaSourceProvider<InputStream> sourceProvider;
 
@@ -43,22 +101,127 @@ public abstract class YangSourceContextResolver {
     }
 
     public YangSourceContextResolver(final AdvancedSchemaSourceProvider<InputStream> sourceProvicer) {
-        super();
         this.sourceProvider = sourceProvicer;
     }
 
+    /**
+     * Resolves {@link YangSourceContext}
+     *
+     * Implementators of this method should invoke
+     * {@link #resolveSource(SourceIdentifier)} for sources which should be
+     * present in {@link YangSourceContext} and {@link #createSourceContext()}
+     * to create resulting {@link YangSourceContext} which will contain state
+     * derived by callbacks to {@link #getDependencyInfo(SourceIdentifier)}.
+     *
+     * @return Resolved {@link YangSourceContext}.
+     */
     public abstract YangSourceContext resolveContext();
-    public abstract Optional<YangModelDependencyInfo> getDependencyInfo(SourceIdentifier identifier);
 
+    /**
+     * Returns dependency information for provided identifier
+     *
+     * Implementations are required to:
+     * <ul>
+     * <li>return {@link Optional#absent()} If source code for source is not
+     * present</li>
+     * <li>return same dependency information for multiple invocations of this
+     * method for same source identifier.</li>
+     * <li>return latest available revision if {@link SourceIdentifier} does not
+     * specify revision. If no revision is available {@link Optional#absent()}
+     * MUST be returned.</li>
+     * </ul>
+     *
+     *
+     * Internal state of this object (and resulting {@link YangSourceContext}
+     * will be updated as following:
+     * <ul>
+     * <li>If {@link Optional#absent()} is returned:
+     * <ul>
+     * <li>source will be marked as {@link ResolutionState#MISSING_SOURCE} and
+     * source identifier will be contained in -
+     * {@link YangSourceContext#getMissingSources()}</li>
+     * <li>All sources which imported or included this source will be present in
+     * {@link YangSourceContext#getMissingDependencies()}</li>
+     * </ul>
+     *
+     *
+     *
+     * @param identifier
+     *            Source identifier
+     * @return Dependency Information for {@link SourceIdentifier},
+     *         {@link Optional#absent()} if no source is present.
+     */
+    abstract Optional<YangModelDependencyInfo> getDependencyInfo(SourceIdentifier identifier);
+
+    /**
+     * Return Source provider against which YANG source context was computed
+     *
+     * @return Source provider against which YANG source context was computed or null, if source provider
+     *   is not associated with computation.
+     */
     public AdvancedSchemaSourceProvider<InputStream> getSourceProvider() {
         return sourceProvider;
     }
 
-    public YangSourceContextResolver.ResolutionState resolveSource(final String name, final Optional<String> formattedRevision) {
+    /**
+     *
+     * Resolves resolution state for provided name and formated revision
+     *
+     * This method is shorthand for {@link #resolveSource(SourceIdentifier)}
+     * with argument <code>new SourceIdentifier(name, formattedRevision)</code>
+     *
+     * @see #resolveSource(SourceIdentifier)
+     * @param name
+     *            Name of YANG model
+     * @param formattedRevision
+     *            revision of YANG model
+     * @return Resolution context of YANG Source
+     */
+    public final YangSourceContextResolver.ResolutionState resolveSource(final String name,
+            final Optional<String> formattedRevision) {
         return resolveSource(new SourceIdentifier(name, formattedRevision));
     }
 
-    public YangSourceContextResolver.ResolutionState resolveSource(final SourceIdentifier identifier) {
+    /**
+     * Resolves state of source and updates internal state accordingly.
+     *
+     * <p>
+     * Resolves state of source and updates internal state based on resolution.
+     * This method tries to get module dependency info via user implementation
+     * of {@link #getDependencyInfo(SourceIdentifier)} and then is recursively
+     * called for each announced dependency in
+     * {@link YangModelDependencyInfo#getDependencies()}.
+     *
+     * <p>
+     * Resolution state of resolveSource is internally cached and is used in
+     * subsequent resolution of dependent modules and in creation of
+     * YANGSourceContext via {@link #createSourceContext()}.
+     *
+     * <p>
+     * Possible resolution state for sources are:
+     * <ul>
+     * <li>{@link ResolutionState#EVERYTHING_OK} - If sources for module and its
+     * dependencies are available</li>
+     * <li>{@link ResolutionState#MISSING_DEPENDENCY} - If dependency of source
+     * is missing (call to {@link #getDependencyInfo(SourceIdentifier)} for
+     * imported / included model returned returned {@link Optional#absent()}.</li>
+     * <li>{@link ResolutionState#MISSING_SOURCE} - If source is missing. (call
+     * of {@link #getDependencyInfo(SourceIdentifier)} returned
+     * {@link Optional#absent()}.</li>
+     * <li>{@link ResolutionState#OTHER_ERROR} - If other runtime error
+     * prevented resolution of informations.</li>
+     * </ul>
+     *
+     * Note: Multiple invocations of this method returns cached result, since
+     * {@link #getDependencyInfo(SourceIdentifier)} contract requires
+     * implementors to return same information during life of this object.
+     *
+     *
+     * @param identifier
+     *            Source Identifier
+     * @return Returns resolution state for source.
+     */
+    public final YangSourceContextResolver.ResolutionState resolveSource(final SourceIdentifier identifier) {
 
         if (alreadyProcessed.containsKey(identifier)) {
             return alreadyProcessed.get(identifier);
@@ -91,14 +254,15 @@ public abstract class YangSourceContextResolver {
 
     private boolean checkValidSource(final SourceIdentifier identifier, final YangModelDependencyInfo info) {
         if (!identifier.getName().equals(info.getName())) {
-            LOG.warn("Incorrect model returned. Identifier name was: {}, source contained: {}",
-                    identifier.getName(), info.getName());
+            LOG.warn("Incorrect model returned. Identifier name was: {}, source contained: {}", identifier.getName(),
+                    info.getName());
             throw new IllegalStateException("Incorrect source was returned");
         }
         return true;
     }
 
-    private void updateResolutionState(final SourceIdentifier identifier, final YangSourceContextResolver.ResolutionState potentialState) {
+    private void updateResolutionState(final SourceIdentifier identifier,
+            final YangSourceContextResolver.ResolutionState potentialState) {
         alreadyProcessed.put(identifier, potentialState);
         switch (potentialState) {
         case MISSING_SOURCE:
@@ -114,8 +278,7 @@ public abstract class YangSourceContextResolver {
 
     private YangSourceContextResolver.ResolutionState resolveDependency(final ModuleImport dependency) {
         String name = dependency.getModuleName();
-        Optional<String> formattedRevision = Optional
-                .fromNullable(QName.formattedRevision(dependency.getRevision()));
+        Optional<String> formattedRevision = Optional.fromNullable(QName.formattedRevision(dependency.getRevision()));
         return resolveSource(new SourceIdentifier(name, formattedRevision));
     }
 
index 92d3fbd11414142217d8030520de3d96b5e345b7..b9941d4e032a04bb4deab05ee28c74bdeb06caac 100644 (file)
@@ -16,10 +16,28 @@ import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier;
 
 import com.google.common.base.Optional;
 
+/**
+ *
+ * Source code resolver which resolves Yang Source Context against
+ * {@link SchemaSourceProvider} and set of QName which represent capabilities.
+ *
+ * This source code resolver is useful for components which deals with
+ * capability exchange similar to YANG/Netconf specification
+ * and there is {@link SchemaSourceProvider} able to retrieve YANG models.
+ *
+ */
 public final class YangSourceFromCapabilitiesResolver extends YangSourceContextResolver {
 
     private final Iterable<QName> capabilities;
 
+    /**
+     * Construct new {@link YangSourceFromCapabilitiesResolver}.
+     *
+     * @param capabilities Set of QName representing module capabilities, {@link QName#getLocalName()} represents
+     * source name and {@link QName#getRevision()} represents revision of source.
+     *
+     * @param schemaSourceProvider - {@link SchemaSourceProvider} which should be used to resolve sources.
+     */
     public YangSourceFromCapabilitiesResolver(final Iterable<QName> capabilities,
             final SchemaSourceProvider<InputStream> schemaSourceProvider) {
         super(SchemaSourceProviders.toAdvancedSchemaSourceProvider(schemaSourceProvider));
@@ -40,16 +58,11 @@ public final class YangSourceFromCapabilitiesResolver extends YangSourceContextR
 
     @Override
     public Optional<YangModelDependencyInfo> getDependencyInfo(final SourceIdentifier identifier) {
-        Optional<InputStream> source = getSchemaSource(identifier);
+        Optional<InputStream> source = getSourceProvider().getSchemaSource(identifier);
         if (source.isPresent()) {
             return Optional.of(YangModelDependencyInfo.fromInputStream(source.get()));
         }
         return Optional.absent();
     }
 
-    private Optional<InputStream> getSchemaSource(final SourceIdentifier identifier) {
-        return getSourceProvider().getSchemaSource(identifier.getName(),
-                Optional.fromNullable(identifier.getRevision()));
-    }
-
 }
index 9893c6cfd1a9c8f7a22b7db9fe11adf83f07006e..bfe8bf908bb32a4420aca0d0cb48d3cf00c90795 100644 (file)
@@ -10,11 +10,20 @@ package org.opendaylight.yangtools.yang.parser.impl.util;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
 import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMap;
 
+/**
+ * Resolver for YANG Schema Source which is based on DependencyInfo
+ *
+ * This resolver does not use {@link SchemaSourceProvider} but supplied map
+ * of source identifiers and {@link YangModelDependencyInfo} to construct
+ * {@link YangSourceContext}.
+ *
+ */
 public final class YangSourceFromDependencyInfoResolver extends YangSourceContextResolver {
 
     private final Map<SourceIdentifier, YangModelDependencyInfo> dependencyInfo;
index 65e3b1db3984b13736cf92400c8d577e620796f2..635e57e0679a836ab9d11c0770e6a83603ad8f19 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.parser.util;
 import java.util.Collections;
 import java.util.List;
 
+import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.Status;
@@ -17,7 +18,7 @@ import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
 
-final class BitImpl implements BitsTypeDefinition.Bit {
+final class BitImpl implements BitsTypeDefinition.Bit, Immutable {
     private final Long position;
     private final QName qname;
     private final SchemaPath schemaPath;