API Claritity: Documented org.opendaylight.yangtools.yang.model.util.repo 96/7396/8
authorTony Tkacik <ttkacik@cisco.com>
Mon, 26 May 2014 10:49:19 +0000 (12:49 +0200)
committerRobert Varga <rovarga@cisco.com>
Thu, 29 May 2014 12:40:41 +0000 (12:40 +0000)
Improved documentation of poorly-documented public APIs in
org.opendaylight.yang.model.util.repo which are actually used by
existing implementations.

Added package-info which describes abstract concepts for this package
which are not materialized in interface or class in this package.

Change-Id: I785a48df0af46d363690ed6c733425f8c1790e0d
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/AbstractCachingSchemaSourceProvider.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/AdvancedSchemaSourceProvider.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/FilesystemSchemaCachingProvider.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/SchemaService.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/SchemaSourceProvider.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/SchemaSourceProviders.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/SchemaSourceTransformation.java [new file with mode: 0644]
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/SourceIdentifier.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/TransformingSourceProvider.java [new file with mode: 0644]
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/package-info.java [new file with mode: 0644]

index bbe870bd76951ba5a6e3a1b2f64801b10960a72f..6b1d6c61232e0221c718d15a9a16a95a0b03df54 100644 (file)
@@ -8,44 +8,68 @@
 package org.opendaylight.yangtools.yang.model.util.repo;
 
 import org.opendaylight.yangtools.concepts.Delegator;
+
+import com.google.common.annotations.Beta;
 import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 
-import static com.google.common.base.Preconditions.*;
 
+/**
+ *
+ * Abstract caching schema provider with support of multiple context
+ * per backing {@link SchemaSourceProvider}.
+ *
+ * @param <I> Input Schema Source Representation
+ * @param <O> Output Schema Source Representation
+ */
 public abstract class AbstractCachingSchemaSourceProvider<I, O> implements AdvancedSchemaSourceProvider<O>,
         Delegator<AdvancedSchemaSourceProvider<I>> {
 
-    public class CompatibilitySchemaSourceProviderInstance implements SchemaSourceProvider<O> {
-
-        @Override
-        public Optional<O> getSchemaSource(String moduleName, Optional<String> revision) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-    }
-
     private final AdvancedSchemaSourceProvider<I> defaultDelegate;
 
-    protected AbstractCachingSchemaSourceProvider(AdvancedSchemaSourceProvider<I> delegate) {
+    /**
+     * Construct caching schema source provider with supplied delegate.
+     *
+     * Default delegate is is used to retrieve schema source when cache does not
+     * contain requested sources.
+     *
+     * @param delegate SchemaSourceProvided used to look up and retrieve schema source
+     * when cache does not contain requested sources.
+     */
+    protected AbstractCachingSchemaSourceProvider(final AdvancedSchemaSourceProvider<I> delegate) {
         this.defaultDelegate = delegate;
     }
 
     @Override
-    public Optional<O> getSchemaSource(String moduleName, Optional<String> revision) {
-        checkNotNull(moduleName, "Module name should not be null.");
-        checkNotNull(revision, "Revision should not be null");
+    public Optional<O> getSchemaSource(final String moduleName, final Optional<String> revision) {
+        Preconditions.checkNotNull(moduleName, "Module name should not be null.");
+        Preconditions.checkNotNull(revision, "Revision should not be null");
         return getSchemaSource(SourceIdentifier.create(moduleName, revision));
     }
-    
+
     @Override
-    public Optional<O> getSchemaSource(SourceIdentifier sourceIdentifier) {
+    public Optional<O> getSchemaSource(final SourceIdentifier sourceIdentifier) {
         return getSchemaSourceImpl(sourceIdentifier, defaultDelegate);
     }
 
-    protected final Optional<O> getSchemaSourceImpl(SourceIdentifier identifier,
-            AdvancedSchemaSourceProvider<I> delegate) {
-        checkNotNull(identifier, "Source identifier name should not be null.");
+    /**
+     * Actual implementation of schema source retrieval.
+     *
+     * <ul>
+     * <li>look up cached schema source via {@link #getCachedSchemaSource(SourceIdentifier)}
+     * <li>If source was found in cache, returns source to client code.
+     * <li>If source was not found in cache, Look up schema source in supplied <code>delegate</code>
+     * <li>Updates cache with schema from delegate by {@link #cacheSchemaSource(SourceIdentifier, Optional)}
+     * <li>Result is returned to client code.
+     * </ul>
+     *
+     * @param identifier Source identifier
+     * @param delegate Delegate to lookup if there is a miss.
+     * @return Optional of schema source, present if source was found. Absent otherwise.
+     */
+    protected final Optional<O> getSchemaSourceImpl(final SourceIdentifier identifier,
+            final AdvancedSchemaSourceProvider<I> delegate) {
+        Preconditions.checkNotNull(identifier, "Source identifier name should not be null.");
 
         Optional<O> cached = getCachedSchemaSource(identifier);
         if (cached.isPresent()) {
@@ -55,33 +79,81 @@ public abstract class AbstractCachingSchemaSourceProvider<I, O> implements Advan
         return cacheSchemaSource(identifier, live);
     }
 
-    abstract protected Optional<O> cacheSchemaSource(SourceIdentifier identifier, Optional<I> stream);
-
+    /**
+     * Caches supplied result and returns cached result which should be returned to client.
+     *
+     * <p>
+     * Implementations of cache are required to cache schema source if possible.
+     * They are not required to cache {@link Optional#absent()}.
+     *
+     * Implementations are required to transform source representation if <code>O</code> and <code>I</code>
+     * are different.
+     *
+     * This method SHOULD NOT fail and should recover from Runtime exceptions
+     * by not caching source and only transforming it.
+     *
+     * @param identifier Source Identifier for which schema SHOULD be cached
+     * @param input Optional of schema source, representing one returned from delegate.
+     * @return Optional of schema source, representing result returned from this cache.
+     */
+    abstract protected Optional<O> cacheSchemaSource(SourceIdentifier identifier, Optional<I> input);
+
+    /**
+     * Returns cached schema source of {@link Optional#absent()} if source is not present in cache.
+     *
+     * <p>
+     * Implementations of cache MUST return cached schema source, if it is present in cache,
+     * otherwise source will be requested from deleate and then cache will be updated
+     * via {@link #cacheSchemaSource(SourceIdentifier, Optional)}.
+     *
+     * @param identifier Source Identifier for which schema should be retrieved.
+     * @return Cached schema source.
+     */
     abstract protected Optional<O> getCachedSchemaSource(SourceIdentifier identifier);
 
+    @Override
     public AdvancedSchemaSourceProvider<I> getDelegate() {
         return defaultDelegate;
     }
 
-    public SchemaSourceProvider<O> createInstanceFor(SchemaSourceProvider<I> delegate) {
-        checkNotNull(delegate, "Delegate should not be null");
+    /**
+     * Creates an lightweight instance of source provider, which uses this cache for caching
+     * and supplied additional delegate for lookup of not cached sources.
+     * <p>
+     *
+     * @param delegate Backing {@link SchemaSourceProvider} which should be used for lookup
+     *   for sources not present in schema.
+     * @return new instance of {@link SchemaSourceProvider} which first lookup in cache
+     *   and then in delegate.
+     *
+     */
+    @Beta
+    public SchemaSourceProvider<O> createInstanceFor(final SchemaSourceProvider<I> delegate) {
         return new SchemaSourceProviderInstance(SchemaSourceProviders.toAdvancedSchemaSourceProvider(delegate));
-            
+
     }
 
+    /**
+     *
+     * Lightweight instance of source provider, which is associated with parent
+     * {@link AbstractCachingSchemaSourceProvider}, but uses
+     * different delegate for retrieving not cached sources.
+     *
+     */
+    @Beta
     private class SchemaSourceProviderInstance implements //
-    AdvancedSchemaSourceProvider<O>, 
+    AdvancedSchemaSourceProvider<O>,
     Delegator<AdvancedSchemaSourceProvider<I>> {
 
         private final AdvancedSchemaSourceProvider<I> delegate;
 
-        protected SchemaSourceProviderInstance(AdvancedSchemaSourceProvider<I> delegate) {
+        protected SchemaSourceProviderInstance(final AdvancedSchemaSourceProvider<I> delegate) {
             super();
-            this.delegate = delegate;
+            this.delegate = Preconditions.checkNotNull(delegate, "Delegate should not be null");;
         }
 
         @Override
-        public Optional<O> getSchemaSource(String moduleName, Optional<String> revision) {
+        public Optional<O> getSchemaSource(final String moduleName, final Optional<String> revision) {
             return getSchemaSource(SourceIdentifier.create(moduleName, revision));
         }
 
@@ -91,7 +163,7 @@ public abstract class AbstractCachingSchemaSourceProvider<I, O> implements Advan
         }
 
         @Override
-        public Optional<O> getSchemaSource(SourceIdentifier sourceIdentifier) {
+        public Optional<O> getSchemaSource(final SourceIdentifier sourceIdentifier) {
             return getSchemaSourceImpl(sourceIdentifier, getDelegate());
         }
     }
index 1c7ffa1da54889bb04077f73c52fc21bd118f7d0..0b82e089089b317403b1a0ecac5a8609f7adb91f 100644 (file)
@@ -9,7 +9,51 @@ package org.opendaylight.yangtools.yang.model.util.repo;
 
 import com.google.common.base.Optional;
 
-public interface AdvancedSchemaSourceProvider<F> extends SchemaSourceProvider<F> {
+/**
+ * Provider of representation of YANG schema sources.
+ *
+ * <p>
+ * {@link AdvancedSchemaSourceProvider} is extension of
+ * {@link SchemaSourceProvider} which did not have object concept of source
+ * identifier, and introduces {@link SourceIdentifier} (which contains schema
+ * name and revision) as identifier of sources.
+ *
+ * <p>
+ * <b>Schema Source representation</b>
+ * <p>
+ * Representation of schema source. Representation of schema source could exists
+ * in various formats (Java types), depending on stage of processing, but
+ * representation MUST BE still result of processing of only single unit of schema
+ * source (file, input stream). E.g.:
+ * <ul>
+ * <li>{@link java.lang.String} - textual representation of source code
+ * <li>{@link java.io.InputStream} - input stream containing source code
+ * <li>{@link com.google.common.io.ByteSource} - source for input streams
+ * containing source code
+ * <li>Parsed AST - abstract syntax tree, which is result of a parser, but still
+ * it is not linked against other schemas.
+ *
+ * <p>
+ * Conversion between representations should be done via implementations of
+ * {@link SchemaSourceTransformation}.
+ *
+ * @param <T>
+ *            Schema source representation type provided by this implementation
+ */
+public interface AdvancedSchemaSourceProvider<T> extends SchemaSourceProvider<T> {
 
-    Optional<F> getSchemaSource(SourceIdentifier sourceIdentifier);
+    /**
+     * Returns representation source for supplied YANG source identifier.
+     *
+     * Returned representation of schema source must be immutable, must not
+     * change during runtime if {@link SourceIdentifier} has specified both
+     * {@link SourceIdentifier#getName()} and
+     * {@link SourceIdentifier#getRevision()}
+     *
+     * @param sourceIdentifier
+     *            source identifier.
+     * @return source representation if supplied YANG module is available
+     *         {@link Optional#absent()} otherwise.
+     */
+    Optional<T> getSchemaSource(SourceIdentifier sourceIdentifier);
 }
index 153a110c473f76c9ce486c7b968b2af6e2b56799..71ab88bfc4c0049b46c44eb8242d7a5ce1e767c1 100644 (file)
@@ -32,21 +32,83 @@ import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 
-public class FilesystemSchemaCachingProvider<I> extends AbstractCachingSchemaSourceProvider<I, InputStream> {
+/**
+ * Filesystem-based schema caching source provider
+ *
+ * This schema source provider caches all YANG modules loaded from backing
+ * schema source providers (registered via
+ * {@link #createInstanceFor(SchemaSourceProvider)} to supplied folder.
+ *
+ * @param <I>
+ *            Input format in which schema source is represented.
+ *
+ */
+public final class FilesystemSchemaCachingProvider<I> extends AbstractCachingSchemaSourceProvider<I, InputStream> {
     private static final Logger LOG = LoggerFactory.getLogger(FilesystemSchemaCachingProvider.class);
 
     private final File storageDirectory;
-    private final Function<I, String> transformationFunction;
+    private final SchemaSourceTransformation<I, String> transformationFunction;
+
+    /**
+     *
+     * Construct filesystem caching schema source provider.
+     *
+     *
+     * @param delegate
+     *            Default delegate to lookup for missed entries in cache.
+     * @param directory
+     *            Directory where YANG files should be cached.
+     * @param transformationFunction
+     *            Transformation function which translates from input in format
+     *            <code>I</code> to InputStream.
+     * @throws IllegalArgumentException
+     *             If supplied directory does not exists or is not directory.
+     */
+    public FilesystemSchemaCachingProvider(final AdvancedSchemaSourceProvider<I> delegate, final File directory,
+            final SchemaSourceTransformation<I, String> transformationFunction) {
+        super(delegate);
+        Preconditions.checkNotNull(directory, "directory must not be null.");
+        Preconditions.checkArgument(directory.exists(), "directory must be directory.");
+        Preconditions.checkArgument(directory.isDirectory(), "directory must be directory.");
+        this.storageDirectory = directory;
+        this.transformationFunction = Preconditions.checkNotNull(transformationFunction,
+                "transformationFunction must not be null.");
+    }
 
+    /**
+     *
+     * Construct filesystem caching schema source provider.
+     *
+     *
+     * @param delegate
+     *            Default delegate to lookup for missed entries in cache.
+     * @param directory
+     *            Directory where YANG files should be cached.
+     * @param transformationFunction
+     *            Transformation function which translates from input in format
+     *            <code>I</code> to InputStream.
+     * @throws IllegalArgumentException
+     *             If supplied directory does not exists or is not directory.
+     * @deprecated Use
+     *             {@link #FilesystemSchemaCachingProvider(AdvancedSchemaSourceProvider, File, SchemaSourceTransformation)}
+     *             with
+     *             {@link SchemaSourceProviders#schemaSourceTransformationFrom(Function)}
+     *             instead.
+     */
+    @Deprecated
     public FilesystemSchemaCachingProvider(final AdvancedSchemaSourceProvider<I> delegate, final File directory,
             final Function<I, String> transformationFunction) {
         super(delegate);
+        Preconditions.checkNotNull(directory, "directory must not be null.");
+        Preconditions.checkArgument(directory.exists(), "directory must be directory.");
+        Preconditions.checkArgument(directory.isDirectory(), "directory must be directory.");
         this.storageDirectory = directory;
-        this.transformationFunction = transformationFunction;
+        this.transformationFunction = SchemaSourceProviders.schemaSourceTransformationFrom(transformationFunction);
     }
 
     @Override
-    protected synchronized Optional<InputStream> cacheSchemaSource(final SourceIdentifier identifier, final Optional<I> source) {
+    protected synchronized Optional<InputStream> cacheSchemaSource(final SourceIdentifier identifier,
+            final Optional<I> source) {
         File schemaFile = toFile(identifier);
         try {
             if (source.isPresent() && schemaFile.createNewFile()) {
@@ -55,25 +117,25 @@ public class FilesystemSchemaCachingProvider<I> extends AbstractCachingSchemaSou
                     writer.write(transformToString(source.get()));
                     writer.flush();
                 } catch (IOException e) {
-
+                    LOG.warn("Could not chache source for {}. Source: ",identifier,source.get(),e);
                 }
             }
         } catch (IOException e) {
-
+            LOG.warn("Could not create cache file for {}. File: ",identifier,schemaFile,e);
         }
         return transformToStream(source);
     }
 
     private Optional<InputStream> transformToStream(final Optional<I> source) {
         if (source.isPresent()) {
-            return Optional.<InputStream> of(
-                    new ByteArrayInputStream(transformToString(source.get()).getBytes(Charsets.UTF_8)));
+            return Optional.<InputStream> of(new ByteArrayInputStream(transformToString(source.get()).getBytes(
+                    Charsets.UTF_8)));
         }
         return Optional.absent();
     }
 
     private String transformToString(final I input) {
-        return transformationFunction.apply(input);
+        return transformationFunction.transform(input);
     }
 
     @Override
@@ -104,6 +166,7 @@ public class FilesystemSchemaCachingProvider<I> extends AbstractCachingSchemaSou
     private File findFileWithNewestRev(final SourceIdentifier identifier) {
         File[] files = storageDirectory.listFiles(new FilenameFilter() {
             final String regex = identifier.getName() + "(\\.yang|@\\d\\d\\d\\d-\\d\\d-\\d\\d.yang)";
+
             @Override
             public boolean accept(final File dir, final String name) {
                 if (name.matches(regex)) {
@@ -147,13 +210,6 @@ public class FilesystemSchemaCachingProvider<I> extends AbstractCachingSchemaSou
         return file;
     }
 
-    private static final Function<String, String> NOOP_TRANSFORMATION = new Function<String, String>() {
-        @Override
-        public String apply(final String input) {
-            return input;
-        }
-    };
-
     public static FilesystemSchemaCachingProvider<String> createFromStringSourceProvider(
             final SchemaSourceProvider<String> liveProvider, final File directory) {
         Preconditions.checkNotNull(liveProvider);
@@ -162,6 +218,6 @@ public class FilesystemSchemaCachingProvider<I> extends AbstractCachingSchemaSou
         return new FilesystemSchemaCachingProvider<String>(
                 SchemaSourceProviders.toAdvancedSchemaSourceProvider(liveProvider),//
                 directory, //
-                NOOP_TRANSFORMATION);
+                SchemaSourceProviders.<String>identityTransformation());
     }
 }
index b2fd12fbbe423c0e2ca9d27e091beb235c0f87c2..8804eaacd12231617461d4c9907d0787e4152f30 100644 (file)
@@ -8,9 +8,18 @@
 package org.opendaylight.yangtools.yang.model.util.repo;
 
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextHolder;
 
+
+/**
+ * Represent Schema Service.
+ *
+ *
+ * @deprecated Replaced by {@link SchemaContextHolder}, which provides
+ *    component-local view for actual {@link SchemaContext}.
+ */
+@Deprecated
 public interface SchemaService {
 
-    
     SchemaContext getSchemaContext();
 }
index 2e56634adf9b6134d7641ed52da34011e2010c23..82fea38e4a296c99aace36e74499f6c1b290a1b3 100644 (file)
@@ -9,8 +9,28 @@ package org.opendaylight.yangtools.yang.model.util.repo;
 
 import com.google.common.base.Optional;
 
+/**
+ * Provider of text stream representation of YANG Modules
+ *
+ * Provider is holder / user implemented service, which
+ * may be able to retrieve representation of YANG sources
+ * for other components.
+ *
+ * @param <F> Format in which YANG source is represented.
+ */
 public interface SchemaSourceProvider<F> {
 
+    /**
+     * Returns source for supplied YANG module identifier and revision.
+     *
+     * @param moduleName module name
+     * @param revision revision of module
+     * @return source representation if supplied YANG module is available
+     *  {@link Optional#absent()} otherwise.
+     *  @deprecated Use {@link AdvancedSchemaSourceProvider#getSchemaSource(SourceIdentifier)}
+     *     instead.
+     */
+    @Deprecated
     Optional<F> getSchemaSource(String moduleName, Optional<String> revision);
 
 }
index a0a2f512444f8610bb27924f4e16cdd7b9f337be..24a92ba872215c730733af4426fbba2156336e62 100644 (file)
@@ -13,9 +13,16 @@ import java.io.InputStream;
 import org.opendaylight.yangtools.concepts.Delegator;
 
 import com.google.common.base.Charsets;
+import com.google.common.base.Function;
 import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 
-public class SchemaSourceProviders {
+/**
+ *
+ * Utility functions for {@link SchemaSourceProvider}
+ *
+ */
+public final class SchemaSourceProviders {
 
     @SuppressWarnings("rawtypes")
     private static final SchemaSourceProvider NOOP_PROVIDER = new AdvancedSchemaSourceProvider() {
@@ -32,51 +39,98 @@ public class SchemaSourceProviders {
 
     };
 
+    @SuppressWarnings("rawtypes")
+    private static final SchemaSourceTransformation IDENTITY_TRANFORMATION = new IdentityTransformation();
+
+    private static final StringToInputStreamTransformation STRING_TO_INPUTSTREAM_TRANSFORMATION = new StringToInputStreamTransformation();
+
+    private SchemaSourceProviders() {
+        throw new UnsupportedOperationException("Utility class.");
+    }
+
+    /**
+     * Returns a noop schema source provider.
+     *
+     * Noop schema provider returns {@link Optional#absent()} for each call to
+     * query schema source.
+     *
+     * @return
+     */
     @SuppressWarnings("unchecked")
     public static <T> SchemaSourceProvider<T> noopProvider() {
         return NOOP_PROVIDER;
     }
 
+    /**
+     *
+     * Returns delegating schema source provider which returns InputStream from
+     * supplied String based schema source provider.
+     *
+     * @param delegate
+     * @return
+     */
     public static SchemaSourceProvider<InputStream> inputStreamProviderfromStringProvider(
             final AdvancedSchemaSourceProvider<String> delegate) {
-        return new StringToInputStreamSchemaSourceProvider(delegate);
+        return TransformingSourceProvider.create(delegate, STRING_TO_INPUTSTREAM_TRANSFORMATION);
     }
 
-    public static <O> AdvancedSchemaSourceProvider<O> toAdvancedSchemaSourceProvider(final SchemaSourceProvider<O> schemaSourceProvider) {
+    /**
+     * Returns identity implementation of SchemaSourceTransformation
+     *
+     * Identity implementation of SchemaSourceTransformation is useful
+     * for usecases where Input and Output of SchemaSourceTransformation
+     * are identitcal, and you want to reuse input as an output.
+     *
+     * This implementation is really simple <code>return input;</code>.
+     *
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    public static <I> SchemaSourceTransformation<I, I> identityTransformation() {
+        return IDENTITY_TRANFORMATION;
+    }
+
+    public static <I, O> SchemaSourceTransformation<I, O> schemaSourceTransformationFrom(
+            final Function<I, O> transformation) {
+        return new FunctionBasedSchemaSourceTransformation<I, O>(transformation);
+    }
+
+    /**
+     *
+     * Casts {@link SchemaSourceProvider} to
+     * {@link AdvancedSchemaSourceProvider} or wraps it with utility
+     * implementation if supplied delegate does not implement
+     * {@link AdvancedSchemaSourceProvider}.
+     *
+     * @param schemaSourceProvider
+     */
+    public static <O> AdvancedSchemaSourceProvider<O> toAdvancedSchemaSourceProvider(
+            final SchemaSourceProvider<O> schemaSourceProvider) {
         if (schemaSourceProvider instanceof AdvancedSchemaSourceProvider<?>) {
             return (AdvancedSchemaSourceProvider<O>) schemaSourceProvider;
         }
         return new SchemaSourceCompatibilityWrapper<O>(schemaSourceProvider);
     }
 
-    private final static class StringToInputStreamSchemaSourceProvider implements //
-            AdvancedSchemaSourceProvider<InputStream>, Delegator<AdvancedSchemaSourceProvider<String>> {
+    private static final class FunctionBasedSchemaSourceTransformation<I, O> implements
+            SchemaSourceTransformation<I, O> {
 
-        private final AdvancedSchemaSourceProvider<String> delegate;
 
-        public StringToInputStreamSchemaSourceProvider(final AdvancedSchemaSourceProvider<String> delegate) {
-            this.delegate = delegate;
-        }
+        private final Function<I, O> delegate;
 
-        @Override
-        public AdvancedSchemaSourceProvider<String> getDelegate() {
-            return delegate;
+        protected FunctionBasedSchemaSourceTransformation(final Function<I, O> delegate) {
+            super();
+            this.delegate = Preconditions.checkNotNull(delegate, "delegate MUST NOT be null.");
         }
 
         @Override
-        public Optional<InputStream> getSchemaSource(final SourceIdentifier sourceIdentifier) {
-            Optional<String> potentialSource = getDelegate().getSchemaSource(sourceIdentifier);
-            if (potentialSource.isPresent()) {
-                final String stringSource = potentialSource.get();
-                return Optional.<InputStream> of(
-                        new ByteArrayInputStream(stringSource.getBytes(Charsets.UTF_8)));
-            }
-            return Optional.absent();
+        public O transform(final I input) {
+            return delegate.apply(input);
         }
 
         @Override
-        public Optional<InputStream> getSchemaSource(final String moduleName, final Optional<String> revision) {
-            return getSchemaSource(SourceIdentifier.create(moduleName, revision));
+        public String toString() {
+            return "FunctionBasedSchemaSourceTransformation [delegate=" + delegate + "]";
         }
     }
 
@@ -95,6 +149,16 @@ public class SchemaSourceProviders {
             return delegate;
         }
 
+
+        /*
+         * Deprecation warnings are suppresed, since this implementation
+         * needs to invoke deprecated method in order to provide
+         * implementation of non-deprecated APIs using legacy ones.
+         *
+         * (non-Javadoc)
+         * @see org.opendaylight.yangtools.yang.model.util.repo.AdvancedSchemaSourceProvider#getSchemaSource(org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier)
+         */
+        @SuppressWarnings("deprecation")
         @Override
         public Optional<O> getSchemaSource(final SourceIdentifier sourceIdentifier) {
 
@@ -103,10 +167,37 @@ public class SchemaSourceProviders {
             return delegate.getSchemaSource(moduleName, revision);
         }
 
+        /*
+         * Deprecation warnings are suppresed, since this implementation
+         * needs to invoke deprecated method in order to provide
+         * implementation of non-deprecated APIs using legacy ones.
+         *
+         * (non-Javadoc)
+         * @see org.opendaylight.yangtools.yang.model.util.repo.AdvancedSchemaSourceProvider#getSchemaSource(org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier)
+         */
         @Override
+        @SuppressWarnings("deprecation")
         public Optional<O> getSchemaSource(final String moduleName, final Optional<String> revision) {
             return delegate.getSchemaSource(moduleName, revision);
         }
     }
 
+    @SuppressWarnings("rawtypes")
+    private static class  IdentityTransformation implements SchemaSourceTransformation {
+
+        @Override
+        public Object transform(final Object input) {
+            return input;
+        }
+    }
+
+    private static class StringToInputStreamTransformation implements SchemaSourceTransformation<String, InputStream> {
+
+        @Override
+        public InputStream transform(final String input) {
+            return new ByteArrayInputStream(input.getBytes(Charsets.UTF_8));
+        }
+
+    }
+
 }
diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/SchemaSourceTransformation.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/SchemaSourceTransformation.java
new file mode 100644 (file)
index 0000000..6836618
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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
+ */
+package org.opendaylight.yangtools.yang.model.util.repo;
+
+import com.google.common.annotations.Beta;
+
+/**
+ *
+ * Schema Source Transformation which transforms from one schema source
+ * representation to another.
+ *
+ * <p>
+ * <b>Representation of Schema Source</b>
+ * <p>
+ * Schema source may be represented by
+ * various Java Types, which depends on provider and/or consumer.
+ * <p>
+ * E.g example of possible representations:
+ * <ul>
+ * <li>{@link String}
+ * <li>{@link java.io.InputStream}
+ * <li>{@link com.google.common.io.ByteSource}
+ * </ul>
+ *
+ * FIXME: <b>Beta:</b> Consider allowing transformations, which may
+ * fail to produce Output, this will require introduction of
+ * checked exception.
+ *
+ * @param <I> Input schema source representation
+ * @param <O> Output schema source representation
+ */
+@Beta
+public interface SchemaSourceTransformation<I, O> {
+
+    /**
+     *
+     * Transforms supplied schema source in format <code>I</code> to schema
+     * source in format <code>O</code>.
+     *
+     * <ul>
+     * <li>Its execution does not cause any observable side effects.
+     * <li>If the contents of a,b are semantically same (e.g. contents of InputStream),
+     * output representations MUST BE also semantically equals.
+     * </ul>
+     *
+     * Implementations of transformation SHOULD NOT fail to
+     * transform valid non-null input to output representation.
+     *
+     *
+     * FIXME: <b>Beta:</b> Consider lowering condition for safe transformation
+     * and introduce checked exception for cases when transformation may fail.
+     *
+     * @param input Not null input which should be transformed
+     * @return Representation of input in <code>O</code> format.
+     * @throws NullPointerException if input is null.
+     *
+     */
+    @Beta
+    O transform(I input);
+}
index 5e06a57efa9b9a5d0a865c319345853c3dca2ce4..3c7812b0d81d5cbc58fe3087ba7d7a8cce9c7b4c 100644 (file)
@@ -7,19 +7,70 @@
  */
 package org.opendaylight.yangtools.yang.model.util.repo;
 
+import org.opendaylight.yangtools.concepts.Immutable;
+
 import com.google.common.base.Optional;
 
-public final class SourceIdentifier {
+/**
+ *
+ * YANG Schema source identifier
+ *
+ * Simple transfer object represents identifier of source for YANG schema (module or submodule),
+ * which consists of
+ * <ul>
+ * <li>YANG schema name ({@link #getName()}
+ * <li>Module revision (optional) ({link {@link #getRevision()})
+ * </ul>
+ *
+ * Source identifier is designated to be carry only necessary information
+ * to look-up YANG model source and to be used by {@link AdvancedSchemaSourceProvider}
+ * and similar.
+ *
+ * <b>Note:</b>On source retrieval layer it is impossible to distinguish
+ * between YANG module and/or submodule unless source is present.
+ *
+ * <p>
+ * (For further reference see: http://tools.ietf.org/html/rfc6020#section-5.2 and
+ * http://tools.ietf.org/html/rfc6022#section-3.1 ).
+ *
+ *
+ */
+public final class SourceIdentifier implements Immutable {
 
     private final String name;
     private final String revision;
 
+    /**
+     *
+     * Creates new YANG Schema source identifier.
+     *
+     * @param name Name of schema
+     * @param formattedRevision Revision of source in format YYYY-mm-dd
+     */
     public SourceIdentifier(final String name, final Optional<String> formattedRevision) {
         super();
         this.name = name;
         this.revision = formattedRevision.orNull();
     }
 
+    /**
+     * Returns model name
+     *
+     * @return model name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns revision of source or null if revision was not supplied.
+     *
+     * @return revision of source or null if revision was not supplied.
+     */
+    public String getRevision() {
+        return revision;
+    }
+
     @Override
     public int hashCode() {
         final int prime = 31;
@@ -58,18 +109,23 @@ public final class SourceIdentifier {
         return true;
     }
 
-    public String getName() {
-        return name;
-    }
-
-    public String getRevision() {
-        return revision;
-    }
-
     public static SourceIdentifier create(final String moduleName, final Optional<String> revision) {
         return new SourceIdentifier(moduleName, revision);
     }
 
+    /**
+     * Returns filename for this YANG module as specified in RFC 6020.
+     *
+     * Returns filename in format
+     * <code>name ['@' revision] '.yang'</code>
+     * <p>
+     * Where revision is  date in format YYYY-mm-dd.
+     * <p>
+     * See
+     * http://tools.ietf.org/html/rfc6020#section-5.2
+     *
+     * @return Filename for this source identifier.
+     */
     public String toYangFilename() {
         return toYangFileName(name, Optional.fromNullable(revision));
     }
@@ -79,6 +135,20 @@ public final class SourceIdentifier {
         return "SourceIdentifier [name=" + name + "@" + revision + "]";
     }
 
+    /**
+     * Returns filename for this YANG module as specified in RFC 6020.
+     *
+     * Returns filename in format
+     * <code>moduleName ['@' revision] '.yang'</code>
+     *
+     * Where Where revision-date is in format YYYY-mm-dd.
+     *
+     * <p>
+     * See
+     * http://tools.ietf.org/html/rfc6020#section-5.2
+     *
+     * @return Filename for this source identifier.
+     */
     public static final String toYangFileName(final String moduleName, final Optional<String> revision) {
         StringBuilder filename = new StringBuilder(moduleName);
         if (revision.isPresent()) {
diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/TransformingSourceProvider.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/TransformingSourceProvider.java
new file mode 100644 (file)
index 0000000..502bc9d
--- /dev/null
@@ -0,0 +1,69 @@
+package org.opendaylight.yangtools.yang.model.util.repo;
+
+import org.opendaylight.yangtools.concepts.Delegator;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/**
+ *
+ * Utility Source Provider implementation which uses delegate to retrieve
+ * sources and transformation function to convert sources to different
+ * representation.
+ *
+ *
+ * @param <I>
+ *            Representation of schema sources used by delegate
+ * @param <O>
+ *            Representation of schema sources exposed by this provider
+ */
+public final class TransformingSourceProvider<I, O> implements //
+        AdvancedSchemaSourceProvider<O>, Delegator<AdvancedSchemaSourceProvider<I>> {
+
+    private final AdvancedSchemaSourceProvider<I> delegate;
+    private final SchemaSourceTransformation<I, O> transformation;
+
+    /**
+     * Creates instance of transforming schema source provider which uses
+     * supplied delegate to retrieve sources and transformation to change
+     * sources to different representation.
+     *
+     * @param delegate
+     *            Delegate which provides sources.
+     * @param transformation
+     *            Transformation function which converts sources
+     * @return Instance of TransformingSourceProvider
+     * @throws NullPointerException
+     *             if any of arguments is null.
+     */
+    public static final <I, O> TransformingSourceProvider<I, O> create(final AdvancedSchemaSourceProvider<I> delegate,
+            final SchemaSourceTransformation<I, O> transformation) {
+        return new TransformingSourceProvider<>(delegate, transformation);
+    }
+
+    private TransformingSourceProvider(final AdvancedSchemaSourceProvider<I> delegate,
+            final SchemaSourceTransformation<I, O> transformation) {
+        this.delegate = Preconditions.checkNotNull(delegate, "delegate must not be null");
+        this.transformation = Preconditions.checkNotNull(transformation, "transformation must not be null");
+    }
+
+    @Override
+    public AdvancedSchemaSourceProvider<I> getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public Optional<O> getSchemaSource(final SourceIdentifier sourceIdentifier) {
+        Optional<I> potentialSource = getDelegate().getSchemaSource(sourceIdentifier);
+        if (potentialSource.isPresent()) {
+            I inputSource = potentialSource.get();
+            return Optional.<O> of(transformation.transform(inputSource));
+        }
+        return Optional.absent();
+    }
+
+    @Override
+    public Optional<O> getSchemaSource(final String moduleName, final Optional<String> revision) {
+        return getSchemaSource(SourceIdentifier.create(moduleName, revision));
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/package-info.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/repo/package-info.java
new file mode 100644 (file)
index 0000000..6e31ba1
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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
+ */
+/**
+ * This package introduces concepts, generic interfaces and implementations for
+ * creating and working with YANG Schema source repositories and working with them.
+ *
+ * <h2>Concepts</h2>
+ * <dl>
+ * <dt>Schema Source</dt>
+ * <dd>Source of YANG Schema, which is not processed, not resolved against other schemas
+ *    and from contents of <i>Schema Source</i> in combination with other Schema sources
+ *    it is possible to create resolved YANG Schema context.
+ * </dd>
+ * <dt>{@link org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier}</dt>
+ * <dd>Identifier of Schema Source. Identifier is not tied with source or representation.</dd>
+ * <dt>Schema Source Representation</dt>
+ * <dd>Representation of schema source. Representation of schema source could exists in various
+ * formats (Java types), depending on stage of processing, but representation MUST BE
+ * still result of processing only single unit of schema source (e.g. file, input stream). E.g.:
+ * <ul>
+ * <li>{@link java.lang.String} - textual representation of source code
+ * <li>{@link InputStream} - input stream containing source code
+ * <li>{@link com.google.common.io.ByteSource} - source for input streams containing source code
+ * <li>Parsed AST - abstract syntax tree, which is result of a parser, but still it is not linked
+ * against other schemas.
+ * </ul>
+ * </dd>
+ * <dt>{@link org.opendaylight.yangtools.yang.model.util.repo.AdvancedSchemaSourceProvider}</dt>
+ * <dd>
+ *    Service which provides query API to obtain <i>Schema Source Representation</i> associated
+ *    with {@link org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier}.
+ * </dd>
+ * <dt>{@link org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceTransformation}</dt>
+ * <dd>
+ * Function (service) which provides transformation from one <i>Schema Source Representation</i>
+ * type to another.
+ * </dd>
+ * </dl>
+ *
+ *
+ */
+package org.opendaylight.yangtools.yang.model.util.repo;
\ No newline at end of file