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()) {
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));
}
}
@Override
- public Optional<O> getSchemaSource(SourceIdentifier sourceIdentifier) {
+ public Optional<O> getSchemaSource(final SourceIdentifier sourceIdentifier) {
return getSchemaSourceImpl(sourceIdentifier, getDelegate());
}
}
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);
}
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()) {
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
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)) {
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);
return new FilesystemSchemaCachingProvider<String>(
SchemaSourceProviders.toAdvancedSchemaSourceProvider(liveProvider),//
directory, //
- NOOP_TRANSFORMATION);
+ SchemaSourceProviders.<String>identityTransformation());
}
}
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();
}
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);
}
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() {
};
+ @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 + "]";
}
}
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) {
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));
+ }
+
+ }
+
}
--- /dev/null
+/*
+ * 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);
+}
*/
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;
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));
}
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()) {
--- /dev/null
+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
--- /dev/null
+/*
+ * 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