From: Robert Varga Date: Wed, 12 Apr 2017 13:54:23 +0000 (+0200) Subject: BUG-8123: be better at guessing identifiers X-Git-Tag: release/carbon~11 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;ds=sidebyside;h=8bfdcd0056b08db284a87b55913691c0187c34bb;p=yangtools.git BUG-8123: be better at guessing identifiers Given an URI we need to attempt to interpret it to improve our guess of the module name and revision. Change-Id: I4d74b06fb9f949c538911d215b6d90a383560f1f Signed-off-by: Robert Varga --- diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/repo/api/RevisionSourceIdentifier.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/repo/api/RevisionSourceIdentifier.java index 5ec07d04ef..0f47513fae 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/repo/api/RevisionSourceIdentifier.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/repo/api/RevisionSourceIdentifier.java @@ -7,10 +7,16 @@ */ package org.opendaylight.yangtools.yang.model.repo.api; +import static org.opendaylight.yangtools.yang.common.YangConstants.RFC6020_YANG_FILE_EXTENSION; + import com.google.common.annotations.Beta; import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import java.text.ParseException; +import java.util.AbstractMap.SimpleImmutableEntry; +import java.util.Map.Entry; import java.util.Objects; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; /** * YANG Schema revision source identifier @@ -113,6 +119,46 @@ public final class RevisionSourceIdentifier extends SourceIdentifier { return new RevisionSourceIdentifier(moduleName); } + /** + * Creates a new RevisionSourceIdentifier based on the provided file name. + * + * @param fileName file name + * @throws IllegalArgumentException when fileName does not have correct format + * @throws NullPointerException when fileName is null + * @throws ParseException if the revision part has invalid format + */ + public static RevisionSourceIdentifier fromFileName(final String fileName) throws ParseException { + final Entry split = splitFileName(fileName); + if (split.getValue() != null) { + SimpleDateFormatUtil.getRevisionFormat().parse(split.getValue()); + } + + return new RevisionSourceIdentifier(split.getKey(), Optional.fromNullable(split.getValue())); + } + + /** + * Creates a new RevisionSourceIdentifier based on the provided file name. This variant ignores any revision + * part. + * + * @param fileName file name + * @throws IllegalArgumentException when fileName does not have correct format + * @throws NullPointerException when fileName is null + */ + public static RevisionSourceIdentifier fromFileNameLenientRevision(final String fileName) { + final Entry split = splitFileName(fileName); + return new RevisionSourceIdentifier(split.getKey(), Optional.fromNullable(split.getValue())); + } + + private static Entry splitFileName(final String fileName) { + Preconditions.checkArgument(fileName.endsWith(RFC6020_YANG_FILE_EXTENSION), + "File name '%s' does not end with %s", fileName, RFC6020_YANG_FILE_EXTENSION); + + final String noExt = fileName.substring(0, fileName.length() - RFC6020_YANG_FILE_EXTENSION.length()); + final int atIndex = noExt.indexOf('@'); + return atIndex == -1 ? new SimpleImmutableEntry<>(noExt, null) + : new SimpleImmutableEntry<>(noExt.substring(0, atIndex), noExt.substring(atIndex + 1)); + } + @Override public int hashCode() { final int prime = 31; diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/YangTextSchemaContextResolver.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/YangTextSchemaContextResolver.java index 7880f38b37..0b0cdb4ff9 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/YangTextSchemaContextResolver.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/YangTextSchemaContextResolver.java @@ -20,6 +20,7 @@ import com.google.common.util.concurrent.Futures; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.text.ParseException; import java.util.Collection; import java.util.Set; import java.util.concurrent.ConcurrentLinkedDeque; @@ -163,7 +164,7 @@ public final class YangTextSchemaContextResolver implements AutoCloseable, Schem IOException, YangSyntaxErrorException { checkArgument(url != null, "Supplied URL must not be null"); - final SourceIdentifier guessedId = RevisionSourceIdentifier.create(url.getFile(), Optional.absent()); + final SourceIdentifier guessedId = guessSourceIdentifier(url.getFile()); return registerSource(new YangTextSchemaSource(guessedId) { @Override public InputStream openStream() throws IOException { @@ -177,6 +178,18 @@ public final class YangTextSchemaContextResolver implements AutoCloseable, Schem }); } + private static SourceIdentifier guessSourceIdentifier(final String fileName) { + try { + return RevisionSourceIdentifier.fromFileName(fileName); + } catch (ParseException e) { + LOG.debug("Malformed revision in '{}'", fileName, e); + return RevisionSourceIdentifier.fromFileNameLenientRevision(fileName); + } catch (IllegalArgumentException e) { + LOG.debug("Invalid file name format in '{}'", fileName, e); + return RevisionSourceIdentifier.create(fileName); + } + } + /** * Try to parse all currently available yang files and build new schema context. * @return new schema context iif there is at least 1 yang file registered and