+/*
+ * 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/epl-v10.html
+ */
package org.opendaylight.yangtools.yang.parser.impl.util;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getArgumentString;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getFirstContext;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.getArgumentString;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableSet;
import java.io.InputStream;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
-
+import java.util.Objects;
+import java.util.Set;
+import org.antlr.v4.runtime.ParserRuleContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Belongs_to_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Import_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Include_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtsContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Submodule_stmtContext;
-import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.YangContext;
+import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser;
+import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser.StatementContext;
+import org.opendaylight.yangtools.concepts.SemVer;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.ModuleImport;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableSet;
+import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.SupportedExtensionsMapping;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
+
+/**
+ * Helper transfer object which holds basic and dependency information for YANG
+ * model.
+ *
+ *
+ *
+ * There are two concrete implementations of this interface:
+ * <ul>
+ * <li>{@link ModuleDependencyInfo} - Dependency information for module</li>
+ * <li>{@link SubmoduleDependencyInfo} - Dependency information for submodule</li>
+ * </ul>
+ *
+ * @see ModuleDependencyInfo
+ * @see SubmoduleDependencyInfo
+ *
+ */
public abstract class YangModelDependencyInfo {
private final String name;
private final String formattedRevision;
private final Date revision;
+ private final Optional<SemVer> semVer;
private final ImmutableSet<ModuleImport> submoduleIncludes;
private final ImmutableSet<ModuleImport> moduleImports;
private final ImmutableSet<ModuleImport> dependencies;
- public YangModelDependencyInfo(String name, String formattedRevision, ImmutableSet<ModuleImport> imports,
- ImmutableSet<ModuleImport> includes) {
+ YangModelDependencyInfo(final String name, final String formattedRevision,
+ final ImmutableSet<ModuleImport> imports,
+ final ImmutableSet<ModuleImport> includes) {
+ this(name, formattedRevision, imports, includes, Optional.absent());
+ }
+
+ YangModelDependencyInfo(final String name, final String formattedRevision,
+ final ImmutableSet<ModuleImport> imports,
+ final ImmutableSet<ModuleImport> includes,
+ final Optional<SemVer> semVer) {
this.name = name;
this.formattedRevision = formattedRevision;
- this.revision = QName.parseRevision(formattedRevision);
+ this.revision = formattedRevision == null ? null : QName
+ .parseRevision(formattedRevision);
this.moduleImports = imports;
this.submoduleIncludes = includes;
- this.dependencies = ImmutableSet.<ModuleImport> builder() //
- .addAll(moduleImports) //
- .addAll(submoduleIncludes) //
- .build();
+ this.dependencies = ImmutableSet.<ModuleImport> builder()
+ .addAll(moduleImports).addAll(submoduleIncludes).build();
+ this.semVer = semVer;
}
+ /**
+ * Returns immutable collection of all module imports.
+ *
+ * This collection contains both <code>import</code> statements and
+ * <code>include</code> statements for submodules.
+ *
+ * @return Immutable collection of imports.
+ */
public ImmutableSet<ModuleImport> getDependencies() {
return dependencies;
}
+ /**
+ * Returns model name
+ *
+ * @return model name
+ */
public String getName() {
return name;
}
+ /**
+ * Returns formatted revision string
+ *
+ * @return formatted revision string
+ */
public String getFormattedRevision() {
return formattedRevision;
}
- public Date getRevision() {
+ /**
+ * Returns revision
+ *
+ * @return revision
+ */
+ Date getRevision() {
return revision;
}
+ /**
+ * Returns semantic version of module
+ *
+ * @return semantic version
+ */
+ public Optional<SemVer> getSemanticVersion() {
+ return semVer;
+ }
+
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((formattedRevision == null) ? 0 : formattedRevision.hashCode());
- result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + Objects.hashCode(formattedRevision);
+ result = prime * result + Objects.hashCode(name);
+ result = prime * result + Objects.hashCode(semVer);
return result;
}
@Override
- public boolean equals(Object obj) {
- if (this == obj)
+ public boolean equals(final Object obj) {
+ if (this == obj) {
return true;
- if (obj == null)
+ }
+ if (obj == null) {
return false;
- if (!(obj instanceof YangModelDependencyInfo))
+ }
+ if (!(obj instanceof YangModelDependencyInfo)) {
return false;
- YangModelDependencyInfo other = (YangModelDependencyInfo) obj;
+ }
+ final YangModelDependencyInfo other = (YangModelDependencyInfo) obj;
if (formattedRevision == null) {
- if (other.formattedRevision != null)
+ if (other.formattedRevision != null) {
return false;
- } else if (!formattedRevision.equals(other.formattedRevision))
+ }
+ } else if (!formattedRevision.equals(other.formattedRevision)) {
return false;
+ }
if (name == null) {
- if (other.name != null)
+ if (other.name != null) {
return false;
- } else if (!name.equals(other.name))
+ }
+ } else if (!name.equals(other.name)) {
+ return false;
+ }
+ if(!Objects.equals(semVer, other.semVer)) {
return false;
+ }
+
return true;
}
- public static YangModelDependencyInfo fromInputStream(InputStream yangStream) {
- YangContext yangContext = YangParserImpl.parseStreamWithoutErrorListeners(yangStream);
+ /**
+ * Extracts {@link YangModelDependencyInfo} from an abstract syntax tree of
+ * a YANG model.
+ *
+ * @param tree
+ * Abstract syntax tree
+ * @return {@link YangModelDependencyInfo}
+ * @throws YangSyntaxErrorException
+ * If the AST is not a valid YANG module/submodule
+ */
+ public static YangModelDependencyInfo fromAST(final String name,
+ final ParserRuleContext tree) throws YangSyntaxErrorException {
+
+ if (tree instanceof YangStatementParser.StatementContext) {
+ final YangStatementParser.StatementContext rootStatement = (YangStatementParser.StatementContext) tree;
+ return parseAST(rootStatement);
+ }
- Optional<Module_stmtContext> moduleCtx = getFirstContext(yangContext, Module_stmtContext.class);
+ final Optional<Module_stmtContext> moduleCtx = ParserListenerUtils
+ .getFirstContext(tree, Module_stmtContext.class);
if (moduleCtx.isPresent()) {
- return fromModuleContext(moduleCtx.get());
+ return parseModuleContext(moduleCtx.get());
}
- Optional<Submodule_stmtContext> submoduleCtx = getFirstContext(yangContext, Submodule_stmtContext.class);
+
+ final Optional<Submodule_stmtContext> submoduleCtx = ParserListenerUtils
+ .getFirstContext(tree, Submodule_stmtContext.class);
if (submoduleCtx.isPresent()) {
- return fromSubmoduleContext(submoduleCtx.get());
+ return parseSubmoduleContext(submoduleCtx.get());
}
- throw new IllegalArgumentException("Supplied stream is not valid yang file.");
+
+ throw new YangSyntaxErrorException(name, 0, 0, "Unknown YANG text type");
}
- private static YangModelDependencyInfo fromModuleContext(Module_stmtContext module) {
- String name = getArgumentString(module);
- // String prefix =
- // getArgumentString(module.module_header_stmts().prefix_stmt(0));
- String namespace = getArgumentString(module.module_header_stmts().namespace_stmt(0));
- String latestRevision = getLatestRevision(module.revision_stmts());
- ImmutableSet<ModuleImport> imports = getImports(module.linkage_stmts().import_stmt());
- ImmutableSet<ModuleImport> includes = getIncludes(module.linkage_stmts().include_stmt());
+ private static YangModelDependencyInfo parseAST(
+ final YangStatementParser.StatementContext rootStatement) {
+ if (rootStatement
+ .keyword()
+ .getText()
+ .equals(Rfc6020Mapping.MODULE.getStatementName().getLocalName())) {
+ return parseModuleContext(rootStatement);
+ } else if (rootStatement
+ .keyword()
+ .getText()
+ .equals(Rfc6020Mapping.SUBMODULE.getStatementName()
+ .getLocalName())) {
+ return parseSubmoduleContext(rootStatement);
+ }
+
+ throw new IllegalArgumentException(
+ "Root of parsed AST must be either module or submodule");
+ }
+
+ /**
+ * Extracts {@link YangModelDependencyInfo} from input stream containing
+ * YANG model.
+ *
+ * This parsing does not validate full YANG module, only parses header up to
+ * the revisions and imports.
+ *
+ * @param yangStream
+ * Opened Input stream containing text source of YANG model
+ * @return {@link YangModelDependencyInfo}
+ * @throws IllegalArgumentException
+ * If input stream is not valid YANG stream
+ */
+ public static YangModelDependencyInfo fromInputStream(
+ final InputStream yangStream) {
+ final StatementContext yangAST = new YangStatementSourceImpl(yangStream)
+ .getYangAST();
+ return parseAST(yangAST);
+ }
+
+ private static YangModelDependencyInfo parseModuleContext(
+ final Module_stmtContext module) {
+ final String name = getArgumentString(module);
+ final String latestRevision = getLatestRevision(module.revision_stmts());
+ final ImmutableSet<ModuleImport> imports = parseImports(module
+ .linkage_stmts().import_stmt());
+ final ImmutableSet<ModuleImport> includes = parseIncludes(module
+ .linkage_stmts().include_stmt());
+
+ return new ModuleDependencyInfo(name, latestRevision, imports, includes);
+ }
+
+ private static YangModelDependencyInfo parseModuleContext(
+ final YangStatementParser.StatementContext module) {
+ final String name = Utils.stringFromStringContext(module.argument());
+ final String latestRevision = getLatestRevision(module);
+ final Optional<SemVer> semVer = Optional.fromNullable(getSemanticVersion(module));
+ final ImmutableSet<ModuleImport> imports = parseImports(module);
+ final ImmutableSet<ModuleImport> includes = parseIncludes(module);
+
+ return new ModuleDependencyInfo(name, latestRevision, imports, includes, semVer);
+ }
- return new ModuleDependencyInfo(name, latestRevision, namespace, imports, includes);
+ private static ImmutableSet<ModuleImport> parseImports(
+ final YangStatementParser.StatementContext module) {
+ final Set<ModuleImport> result = new HashSet<>();
+ final List<StatementContext> subStatements = module.statement();
+ for (final StatementContext subStatementContext : subStatements) {
+ if (subStatementContext
+ .keyword()
+ .getText()
+ .equals(Rfc6020Mapping.IMPORT.getStatementName()
+ .getLocalName())) {
+ final String revisionDateStr = getRevisionDateString(subStatementContext);
+ final String importedModuleName = Utils
+ .stringFromStringContext(subStatementContext.argument());
+ final Date revisionDate = (revisionDateStr == null) ? null : QName
+ .parseRevision(revisionDateStr);
+ final Optional<SemVer> importSemVer = Optional.fromNullable(getSemanticVersion(subStatementContext));
+ result.add(new ModuleImportImpl(importedModuleName,
+ revisionDate, importSemVer));
+ }
+ }
+ return ImmutableSet.copyOf(result);
}
- private static ImmutableSet<ModuleImport> getImports(List<Import_stmtContext> importStatements) {
- ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
- for (Import_stmtContext importStmt : importStatements) {
- String moduleName = getArgumentString(importStmt);
- Date revision = getRevision(importStmt.revision_date_stmt());
- String prefix = getArgumentString(importStmt.prefix_stmt());
+ private static SemVer getSemanticVersion(final StatementContext statement) {
+ final List<StatementContext> subStatements = statement.statement();
+ String semVerString = null;
+ final String semVerStmtName = SupportedExtensionsMapping.SEMANTIC_VERSION.getStatementName().getLocalName();
+ for (final StatementContext subStatement : subStatements) {
+ final String subStatementName = Utils.trimPrefix(subStatement.keyword().getText());
+ if (semVerStmtName.equals(subStatementName)) {
+ semVerString = Utils.stringFromStringContext(subStatement.argument());
+ break;
+ }
+ }
+
+ if (Strings.isNullOrEmpty(semVerString)) {
+ return null;
+ }
+
+ return SemVer.valueOf(semVerString);
+ }
+
+ private static ImmutableSet<ModuleImport> parseIncludes(
+ final YangStatementParser.StatementContext module) {
+ final Set<ModuleImport> result = new HashSet<>();
+ final List<StatementContext> subStatements = module.statement();
+ for (final StatementContext subStatementContext : subStatements) {
+ if (subStatementContext
+ .keyword()
+ .getText()
+ .equals(Rfc6020Mapping.INCLUDE.getStatementName()
+ .getLocalName())) {
+ final String revisionDateStr = getRevisionDateString(subStatementContext);
+ final String IncludeModuleName = Utils
+ .stringFromStringContext(subStatementContext.argument());
+ final Date revisionDate = (revisionDateStr == null) ? null : QName
+ .parseRevision(revisionDateStr);
+ result.add(new ModuleImportImpl(IncludeModuleName, revisionDate));
+ }
+ }
+ return ImmutableSet.copyOf(result);
+ }
+
+ private static String getRevisionDateString(final StatementContext importStatement) {
+ final List<StatementContext> importSubStatements = importStatement
+ .statement();
+ String revisionDateStr = null;
+ for (final StatementContext importSubStatement : importSubStatements) {
+ if (importSubStatement
+ .keyword()
+ .getText()
+ .equals(Rfc6020Mapping.REVISION_DATE.getStatementName()
+ .getLocalName())) {
+ revisionDateStr = Utils
+ .stringFromStringContext(importSubStatement.argument());
+ }
+ }
+ return revisionDateStr;
+ }
+
+ private static ImmutableSet<ModuleImport> parseImports(
+ final List<Import_stmtContext> importStatements) {
+ final ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
+ for (final Import_stmtContext importStmt : importStatements) {
+ final String moduleName = getArgumentString(importStmt);
+ final Date revision = getRevision(importStmt.revision_date_stmt());
builder.add(new ModuleImportImpl(moduleName, revision));
}
return builder.build();
}
- private static String getLatestRevision(Revision_stmtsContext revision_stmts) {
- List<Revision_stmtContext> revisions = revision_stmts.getRuleContexts(Revision_stmtContext.class);
+ public static String getLatestRevision(
+ final YangStatementParser.StatementContext module) {
+ final List<StatementContext> subStatements = module.statement();
+ String latestRevision = null;
+ for (final StatementContext subStatementContext : subStatements) {
+ if (subStatementContext
+ .keyword()
+ .getText()
+ .equals(Rfc6020Mapping.REVISION.getStatementName()
+ .getLocalName())) {
+ final String currentRevision = Utils
+ .stringFromStringContext(subStatementContext.argument());
+ if (latestRevision == null
+ || latestRevision.compareTo(currentRevision) == -1) {
+ latestRevision = currentRevision;
+ }
+ }
+ }
+ return latestRevision;
+ }
+
+ public static String getLatestRevision(
+ final Revision_stmtsContext revisionStmts) {
+ final List<Revision_stmtContext> revisions = revisionStmts
+ .getRuleContexts(Revision_stmtContext.class);
String latestRevision = null;
- for (Revision_stmtContext revisionStmt : revisions) {
- String currentRevision = getArgumentString(revisionStmt);
- if (latestRevision == null || latestRevision.compareTo(currentRevision) == 1) {
+ for (final Revision_stmtContext revisionStmt : revisions) {
+ final String currentRevision = getArgumentString(revisionStmt);
+ if (latestRevision == null
+ || latestRevision.compareTo(currentRevision) == -1) {
latestRevision = currentRevision;
}
}
return latestRevision;
}
- private static YangModelDependencyInfo fromSubmoduleContext(Submodule_stmtContext submodule) {
- String name = getArgumentString(submodule);
- Belongs_to_stmtContext belongsToStmt = submodule.submodule_header_stmts().belongs_to_stmt(0);
- String belongsTo = getArgumentString(belongsToStmt);
+ private static YangModelDependencyInfo parseSubmoduleContext(
+ final YangStatementParser.StatementContext submodule) {
+ final String name = Utils.stringFromStringContext(submodule.argument());
+ final String belongsTo = parseBelongsTo(submodule);
+
+ final String latestRevision = getLatestRevision(submodule);
+ final ImmutableSet<ModuleImport> imports = parseImports(submodule);
+ final ImmutableSet<ModuleImport> includes = parseIncludes(submodule);
- String latestRevision = getLatestRevision(submodule.revision_stmts());
- ImmutableSet<ModuleImport> imports = getImports(submodule.linkage_stmts().import_stmt());
- ImmutableSet<ModuleImport> includes = getIncludes(submodule.linkage_stmts().include_stmt());
+ return new SubmoduleDependencyInfo(name, latestRevision, belongsTo,
+ imports, includes);
+ }
- return new SubmoduleDependencyInfo(name, latestRevision, belongsTo, imports, includes);
+ private static String parseBelongsTo(final StatementContext submodule) {
+ final List<StatementContext> subStatements = submodule.statement();
+ for (final StatementContext subStatementContext : subStatements) {
+ if (subStatementContext
+ .keyword()
+ .getText()
+ .equals(Rfc6020Mapping.BELONGS_TO.getStatementName()
+ .getLocalName())) {
+ return Utils.stringFromStringContext(subStatementContext
+ .argument());
+ }
+ }
+ return null;
}
- private static ImmutableSet<ModuleImport> getIncludes(List<Include_stmtContext> importStatements) {
- ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
- for (Include_stmtContext importStmt : importStatements) {
- String moduleName = getArgumentString(importStmt);
- Date revision = getRevision(importStmt.revision_date_stmt());
+ private static YangModelDependencyInfo parseSubmoduleContext(
+ final Submodule_stmtContext submodule) {
+ final String name = getArgumentString(submodule);
+ final Belongs_to_stmtContext belongsToStmt = submodule
+ .submodule_header_stmts().belongs_to_stmt(0);
+ final String belongsTo = getArgumentString(belongsToStmt);
+
+ final String latestRevision = getLatestRevision(submodule.revision_stmts());
+ final ImmutableSet<ModuleImport> imports = parseImports(submodule
+ .linkage_stmts().import_stmt());
+ final ImmutableSet<ModuleImport> includes = parseIncludes(submodule
+ .linkage_stmts().include_stmt());
+
+ return new SubmoduleDependencyInfo(name, latestRevision, belongsTo,
+ imports, includes);
+ }
+
+ private static ImmutableSet<ModuleImport> parseIncludes(
+ final List<Include_stmtContext> importStatements) {
+ final ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
+ for (final Include_stmtContext importStmt : importStatements) {
+ final String moduleName = getArgumentString(importStmt);
+ final Date revision = getRevision(importStmt.revision_date_stmt());
builder.add(new ModuleImportImpl(moduleName, revision));
}
return builder.build();
}
- private static Date getRevision(Revision_date_stmtContext revision_date_stmt) {
- if (revision_date_stmt == null) {
+ private static Date getRevision(
+ final Revision_date_stmtContext revisionDateStmt) {
+ if (revisionDateStmt == null) {
return null;
}
- String formatedDate = getArgumentString(revision_date_stmt);
+ final String formatedDate = getArgumentString(revisionDateStmt);
return QName.parseRevision(formatedDate);
}
- public static final class ModuleDependencyInfo extends YangModelDependencyInfo {
-
- private ModuleDependencyInfo(String name, String latestRevision, String namespace,
- ImmutableSet<ModuleImport> imports, ImmutableSet<ModuleImport> includes) {
+ /**
+ *
+ * Dependency information for YANG module.
+ *
+ */
+ public static class ModuleDependencyInfo extends
+ YangModelDependencyInfo {
+
+ private ModuleDependencyInfo(final String name,
+ final String latestRevision,
+ final ImmutableSet<ModuleImport> imports,
+ final ImmutableSet<ModuleImport> includes) {
super(name, latestRevision, imports, includes);
}
+ private ModuleDependencyInfo(final String name,
+ final String latestRevision,
+ final ImmutableSet<ModuleImport> imports,
+ final ImmutableSet<ModuleImport> includes,
+ final Optional<SemVer> semVer) {
+ super(name, latestRevision, imports, includes, semVer);
+ }
+
@Override
public String toString() {
- return "Module [name=" + getName() + ", revision=" + getRevision()
- + ", dependencies=" + getDependencies() + "]";
+ return "Module [name=" + getName() + ", revision=" + getRevision() + ", semanticVersion="
+ + getSemanticVersion().or(Module.DEFAULT_SEMANTIC_VERSION) + ", dependencies=" + getDependencies()
+ + "]";
}
-
}
- public static final class SubmoduleDependencyInfo extends YangModelDependencyInfo {
+ /**
+ *
+ * Dependency information for submodule, also provides name for parent
+ * module.
+ *
+ */
+ public static final class SubmoduleDependencyInfo extends
+ YangModelDependencyInfo {
private final String belongsTo;
+ private SubmoduleDependencyInfo(final String name,
+ final String latestRevision, final String belongsTo,
+ final ImmutableSet<ModuleImport> imports,
+ final ImmutableSet<ModuleImport> includes) {
+ super(name, latestRevision, imports, includes);
+ this.belongsTo = belongsTo;
+ }
+
+ /**
+ * Returns name of parent module.
+ *
+ */
public String getParentModule() {
return belongsTo;
}
- private SubmoduleDependencyInfo(String name, String latestRevision, String belongsTo,
- ImmutableSet<ModuleImport> imports, ImmutableSet<ModuleImport> includes) {
- super(name, latestRevision, imports, includes);
- this.belongsTo = belongsTo;
- }
-
@Override
public String toString() {
- return "Submodule [name=" + getName() + ", revision=" + getRevision()
- + ", dependencies=" + getDependencies() + "]";
+ return "Submodule [name=" + getName() + ", revision="
+ + getRevision() + ", dependencies=" + getDependencies()
+ + "]";
}
-
}
+ /**
+ * Utility implementation of {@link ModuleImport} to be used by
+ * {@link YangModelDependencyInfo}.
+ *
+ */
private static final class ModuleImportImpl implements ModuleImport {
- private Date revision;
- private String name;
+ private final Date revision;
+ private final SemVer semVer;
+ private final String name;
+
+ public ModuleImportImpl(final String moduleName, final Date revision) {
+ this(moduleName, revision, Optional.absent());
+ }
- public ModuleImportImpl(String moduleName, Date revision) {
- this.name = moduleName;
+ public ModuleImportImpl(final String moduleName, final Date revision, final Optional<SemVer> semVer) {
+ this.name = Preconditions.checkNotNull(moduleName, "Module name must not be null.");
this.revision = revision;
+ this.semVer = semVer.or(Module.DEFAULT_SEMANTIC_VERSION);
}
@Override
return this.revision;
}
+ @Override
+ public SemVer getSemanticVersion() {
+ return this.semVer;
+ }
+
@Override
public String getPrefix() {
return null;
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- result = prime * result + ((revision == null) ? 0 : revision.hashCode());
+ result = prime * result + Objects.hashCode(name);
+ result = prime * result + Objects.hashCode(revision);
+ result = prime * result + Objects.hashCode(semVer);
return result;
}
@Override
- public boolean equals(Object obj) {
- if (this == obj)
+ public boolean equals(final Object obj) {
+ if (this == obj) {
return true;
- if (obj == null)
+ }
+ if (obj == null) {
return false;
- if (getClass() != obj.getClass())
+ }
+ if (getClass() != obj.getClass()) {
return false;
- ModuleImportImpl other = (ModuleImportImpl) obj;
+ }
+ final ModuleImportImpl other = (ModuleImportImpl) obj;
if (name == null) {
- if (other.name != null)
+ if (other.name != null) {
return false;
- } else if (!name.equals(other.name))
+ }
+ } else if (!name.equals(other.name)) {
return false;
+ }
if (revision == null) {
- if (other.revision != null)
+ if (other.revision != null) {
return false;
- } else if (!revision.equals(other.revision))
+ }
+ } else if (!revision.equals(other.revision)) {
return false;
+ }
+
+ if (!Objects.equals(getSemanticVersion(), other.getSemanticVersion())) {
+ return false;
+ }
return true;
}
@Override
public String toString() {
- return "ModuleImportImpl [name=" + name + ", revision=" + QName.formattedRevision(revision) + "]";
+ return "ModuleImportImpl [name=" + name + ", revision="
+ + QName.formattedRevision(revision) + ", semanticVersion=" + getSemanticVersion() + "]";
}
-
-
}
}