package org.opendaylight.yangtools.yang.model.api.source;
import static java.util.Objects.requireNonNull;
+import static org.opendaylight.yangtools.yang.common.YangConstants.RFC6020_YANG_FILE_EXTENSION;
+import static org.opendaylight.yangtools.yang.common.YangConstants.RFC6020_YIN_FILE_EXTENSION;
import java.time.format.DateTimeParseException;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.concepts.Identifier;
import org.opendaylight.yangtools.yang.common.Revision;
import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
-import org.opendaylight.yangtools.yang.common.YangConstants;
+import org.opendaylight.yangtools.yang.common.YangNames;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Base class of YANG Schema source identifiers. Source identifiers are designated to be carry only necessary
@java.io.Serial
private static final long serialVersionUID = 3L;
+ private static final Logger LOG = LoggerFactory.getLogger(SourceIdentifier.class);
+
/**
* Creates new YANG Schema source identifier for sources with or without a revision.
*
* @param name Name of schema
* @param revision Revision of schema
- * @throws NullPointerException if {@code name} is null
+ * @throws NullPointerException if {@code name} is {@code null}
*/
public SourceIdentifier {
requireNonNull(name);
* Creates new YANG Schema source identifier for sources without a revision.
*
* @param name Name of schema
- * @throws NullPointerException if {@code name} is null
+ * @throws NullPointerException if {@code name} is {@code null}
*/
public SourceIdentifier(final @NonNull Unqualified name) {
this(name, null);
* Creates new YANG Schema source identifier for sources without a revision.
*
* @param name Name of schema
- * @throws NullPointerException if {@code name} is null
+ * @throws NullPointerException if {@code name} is {@code null}
* @throws IllegalArgumentException if {@code name} is not a valid YANG identifier
*/
public SourceIdentifier(final @NonNull String name) {
*
* @param name Name of schema
* @param revision Optional schema revision
- * @throws NullPointerException if {@code name} is null
+ * @throws NullPointerException if {@code name} is {@code null}
* @throws IllegalArgumentException if {@code name} is not a valid YANG identifier
*/
public SourceIdentifier(final @NonNull String name, final @Nullable Revision revision) {
this(Unqualified.of(name), revision);
}
+ public static @NonNull SourceIdentifier ofYinFileName(final String fileName) {
+ if (fileName.endsWith(RFC6020_YIN_FILE_EXTENSION)) {
+ return ofFileName(fileName.substring(0, fileName.length() - RFC6020_YIN_FILE_EXTENSION.length()));
+ }
+ throw new IllegalArgumentException("Filename " + fileName + " does not end with '.yin'");
+ }
+
+ public static @NonNull SourceIdentifier ofYangFileName(final String fileName) {
+ if (fileName.endsWith(RFC6020_YANG_FILE_EXTENSION)) {
+ return ofFileName(fileName.substring(0, fileName.length() - RFC6020_YANG_FILE_EXTENSION.length()));
+ }
+ throw new IllegalArgumentException("Filename '" + fileName + "' does not end with '.yang'");
+ }
+
+ private static @NonNull SourceIdentifier ofFileName(final String fileName) {
+ final var parsed = YangNames.parseFilename(fileName);
+ return new SourceIdentifier(parsed.getKey(), parsed.getValue());
+ }
+
/**
* Creates new YANG Schema source identifier for sources with or without a revision.
*
* @param name Name of schema
* @param revision Optional schema revision
- * @throws NullPointerException if {@code name} is null
+ * @throws NullPointerException if {@code name} is {@code null}
* @throws IllegalArgumentException if {@code name} is not a valid YANG identifier
* @throws DateTimeParseException if {@code revision} format does not conform specification.
*/
}
/**
- * Returns filename for this YANG module as specified in RFC 6020.
- *
- * <p>
- * Returns filename in format <code>name ['@' revision] '.yang'</code>, where revision is date in format YYYY-mm-dd.
+ * Returns filename for this YANG module as specified in
+ * <a href="https://www.rfc-editor.org/rfc/rfc6020#section-5.2">RFC 6020</a>.
*
* <p>
- * @see <a href="http://www.rfc-editor.org/rfc/rfc6020#section-5.2">RFC6020</a>
+ * Returns filename formatted as {@code moduleName ['@' revision] '.yang'}, where revision-date is in format
+ * {@code YYYY-mm-dd}.
*
* @return Filename for this source identifier.
*/
return toYangFileName(name.getLocalName(), revision);
}
+ /**
+ * Returns filename for this YANG module as specified in
+ * <a href="https://www.rfc-editor.org/rfc/rfc6020#section-5.2">RFC 6020</a>.
+ *
+ * <p>
+ * Returns filename formatted as {@code moduleName ['@' revision] '.yin'}, where revision-date is in format
+ * {@code YYYY-mm-dd}.
+ *
+ * @return Filename for this source identifier.
+ */
+ public @NonNull String toYinFilename() {
+ return toYinFileName(name.getLocalName(), revision);
+ }
+
@Override
public String toString() {
final var sb = new StringBuilder("SourceIdentifier [").append(name.getLocalName());
}
/**
- * Returns filename for this YANG module as specified in RFC 6020.
+ * Returns filename for this YANG module as specified in
+ * <a href="https://www.rfc-editor.org/rfc/rfc6020#section-5.2">RFC 6020</a>.
*
* <p>
- * Returns filename in format <code>moduleName ['@' revision] '.yang'</code>,
- * where Where revision-date is in format YYYY-mm-dd.
+ * Returns filename formatted as {@code moduleName ['@' revision] '.yang'}, where revision-date is in format
+ * {@code YYYY-mm-dd}.
+ *
+ * @param moduleName module name
+ * @param revision optional revision
+ * @return Filename for this source identifier.
+ */
+ public static @NonNull String toYangFileName(final @NonNull String moduleName, final @Nullable Revision revision) {
+ return toFileName(moduleName, revision, RFC6020_YANG_FILE_EXTENSION);
+ }
+
+ /**
+ * Returns filename for this YANG module as specified in
+ * <a href="https://www.rfc-editor.org/rfc/rfc6020#section-5.2">RFC 6020</a>.
*
* <p>
- * See http://www.rfc-editor.org/rfc/rfc6020#section-5.2
+ * Returns filename formatted as {@code moduleName ['@' revision] '.yin'}, where Where revision-date is in format
+ * {@code YYYY-mm-dd}.
*
* @param moduleName module name
* @param revision optional revision
* @return Filename for this source identifier.
*/
- public static @NonNull String toYangFileName(final @NonNull String moduleName, final @Nullable Revision revision) {
+ public static @NonNull String toYinFileName(final @NonNull String moduleName, final @Nullable Revision revision) {
+ return toFileName(moduleName, revision, RFC6020_YIN_FILE_EXTENSION);
+ }
+
+ private static @NonNull String toFileName(final @NonNull String moduleName, final @Nullable Revision revision,
+ final @NonNull String extension) {
final var sb = new StringBuilder(moduleName);
if (revision != null) {
sb.append('@').append(revision);
}
- return sb.append(YangConstants.RFC6020_YANG_FILE_EXTENSION).toString();
+ return sb.append(extension).toString();
}
}
*/
package org.opendaylight.yangtools.yang.model.spi.source;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
-import static org.opendaylight.yangtools.yang.common.YangConstants.RFC6020_YANG_FILE_EXTENSION;
-import static org.opendaylight.yangtools.yang.common.YangNames.parseFilename;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
this.sourceId = requireNonNull(sourceId);
}
- public static @NonNull SourceIdentifier identifierFromFilename(final String name) {
- checkArgument(name.endsWith(RFC6020_YANG_FILE_EXTENSION), "Filename '%s' does not end with '%s'", name,
- RFC6020_YANG_FILE_EXTENSION);
-
- final String baseName = name.substring(0, name.length() - RFC6020_YANG_FILE_EXTENSION.length());
- final var parsed = parseFilename(baseName);
- return new SourceIdentifier(parsed.getKey(), parsed.getValue());
- }
-
/**
* Create a new YangTextSchemaSource with a specific source identifier and backed
* by ByteSource, which provides the actual InputStreams.
*/
public static @NonNull YangTextSource delegateForCharSource(final String fileName,
final CharSource delegate) {
- return new DelegatedYangTextSource(identifierFromFilename(fileName), delegate);
+ return new DelegatedYangTextSource(SourceIdentifier.ofYangFileName(fileName), delegate);
}
/**
* @throws NullPointerException if file is {@code null}
*/
public static @NonNull YangTextSource forPath(final Path path) {
- return forPath(path, identifierFromFilename(path.toFile().getName()));
+ // FIXME: do not use .toFile() here
+ return forPath(path, SourceIdentifier.ofYangFileName(path.toFile().getName()));
}
/**
*/
public static @NonNull YangTextSource forPath(final Path path, final SourceIdentifier identifier,
final Charset charset) {
- checkArgument(Files.isRegularFile(path), "Supplied path %s is not a regular file", path);
- return new YangTextFileSource(identifier, path, charset);
+ if (Files.isRegularFile(path)) {
+ return new YangTextFileSource(identifier, path, charset);
+ }
+ throw new IllegalArgumentException("Supplied path " + path + " is not a regular file");
}
/**
*/
public static @NonNull YangTextSource forResource(final Class<?> clazz, final String resourceName,
final Charset charset) {
- final String fileName = resourceName.substring(resourceName.lastIndexOf('/') + 1);
- final SourceIdentifier identifier = identifierFromFilename(fileName);
- final URL url = Resources.getResource(clazz, resourceName);
+ final var fileName = resourceName.substring(resourceName.lastIndexOf('/') + 1);
+ final var identifier = SourceIdentifier.ofYangFileName(fileName);
+ final var url = Resources.getResource(clazz, resourceName);
return new ResourceYangTextSource(identifier, url, charset);
}
*/
package org.opendaylight.yangtools.yang.model.spi.source;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
import com.google.common.base.MoreObjects;
import java.nio.file.Files;
import java.nio.file.Path;
import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.common.YangConstants;
-import org.opendaylight.yangtools.yang.common.YangNames;
import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier;
import org.opendaylight.yangtools.yang.model.api.source.YinSourceRepresentation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* YIN text schema source representation. Exposes an RFC6020 or RFC7950 XML representation as an {@link InputStream}.
*/
public abstract class YinTextSource extends ByteSource implements YinSourceRepresentation {
- private static final Logger LOG = LoggerFactory.getLogger(YinTextSource.class);
- private static final String XML_EXTENSION = ".xml";
-
private final @NonNull SourceIdentifier sourceId;
protected YinTextSource(final SourceIdentifier sourceId) {
this.sourceId = requireNonNull(sourceId);
}
- public static @NonNull SourceIdentifier identifierFromFilename(final String name) {
- final String baseName;
- if (name.endsWith(YangConstants.RFC6020_YIN_FILE_EXTENSION)) {
- baseName = name.substring(0, name.length() - YangConstants.RFC6020_YIN_FILE_EXTENSION.length());
- } else if (name.endsWith(XML_EXTENSION)) {
- // FIXME: BUG-7061: remove this once we do not need it
- LOG.warn("XML file {} being loaded as YIN", name);
- baseName = name.substring(0, name.length() - XML_EXTENSION.length());
- } else {
- throw new IllegalArgumentException("Filename " + name + " does not have a .yin or .xml extension");
- }
-
- final var parsed = YangNames.parseFilename(baseName);
- return new SourceIdentifier(parsed.getKey(), parsed.getValue());
- }
-
@Override
public final SourceIdentifier sourceId() {
return sourceId;
}
public static @NonNull YinTextSource forPath(final Path path) {
- checkArgument(Files.isRegularFile(path), "Supplied path %s is not a regular file", path);
- return new YinTextFileSource(identifierFromFilename(path.toFile().getName()), path);
+ if (Files.isRegularFile(path)) {
+ // FIXME: do not use toFile() here
+ return new YinTextFileSource(SourceIdentifier.ofYinFileName(path.toFile().getName()), path);
+ }
+ throw new IllegalArgumentException("Supplied path " + path + " is not a regular file");
}
public static @NonNull YinTextSource forResource(final Class<?> clazz, final String resourceName) {
final String fileName = resourceName.substring(resourceName.lastIndexOf('/') + 1);
- return new ResourceYinTextSource(identifierFromFilename(fileName),
+ return new ResourceYinTextSource(SourceIdentifier.ofYinFileName(fileName),
Resources.getResource(clazz, resourceName));
}
}
private static SourceIdentifier guessSourceIdentifier(final @NonNull String fileName) {
try {
- return YangTextSource.identifierFromFilename(fileName);
+ return SourceIdentifier.ofYangFileName(fileName);
} catch (IllegalArgumentException e) {
LOG.warn("Invalid file name format in '{}'", fileName, e);
return new SourceIdentifier(fileName);
}
public static EffectiveModelContext parseYinSources(final String yinSourcesDirectoryPath,
- final YangParserConfiguration config) throws URISyntaxException, SAXException, IOException,
- ReactorException {
- final URL resourceDir = StmtTestUtils.class.getResource(yinSourcesDirectoryPath);
- final File[] files = new File(resourceDir.toURI()).listFiles(YIN_FILE_FILTER);
- final StatementStreamSource[] sources = new StatementStreamSource[files.length];
+ final YangParserConfiguration config)
+ throws URISyntaxException, SAXException, IOException, ReactorException {
+ final var resourceDir = StmtTestUtils.class.getResource(yinSourcesDirectoryPath);
+ final var files = new File(resourceDir.toURI()).listFiles(YIN_FILE_FILTER);
+ final var sources = new StatementStreamSource[files.length];
for (int i = 0; i < files.length; i++) {
- final SourceIdentifier identifier = YinTextSource.identifierFromFilename(files[i].getName());
-
+ final var file = files[i];
sources[i] = YinStatementStreamSource.create(YinTextToDomTransformer.transformSource(
- YinTextSource.delegateForByteSource(identifier, Files.asByteSource(files[i]))));
+ YinTextSource.delegateForByteSource(SourceIdentifier.ofYinFileName(file.getName()),
+ Files.asByteSource(file))));
}
return parseYinSources(config, sources);