1 package org.opendaylight.yangtools.yang.parser.impl.util;
3 import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getArgumentString;
4 import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getFirstContext;
6 import java.io.InputStream;
10 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Belongs_to_stmtContext;
11 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Import_stmtContext;
12 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Include_stmtContext;
13 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_stmtContext;
14 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_date_stmtContext;
15 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtContext;
16 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtsContext;
17 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Submodule_stmtContext;
18 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.YangContext;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
21 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
23 import com.google.common.base.Optional;
24 import com.google.common.collect.ImmutableSet;
26 public abstract class YangModelDependencyInfo {
28 private final String name;
29 private final String formattedRevision;
30 private final Date revision;
31 private final ImmutableSet<ModuleImport> submoduleIncludes;
32 private final ImmutableSet<ModuleImport> moduleImports;
33 private final ImmutableSet<ModuleImport> dependencies;
35 public YangModelDependencyInfo(String name, String formattedRevision, ImmutableSet<ModuleImport> imports,
36 ImmutableSet<ModuleImport> includes) {
38 this.formattedRevision = formattedRevision;
39 this.revision = QName.parseRevision(formattedRevision);
40 this.moduleImports = imports;
41 this.submoduleIncludes = includes;
42 this.dependencies = ImmutableSet.<ModuleImport> builder() //
43 .addAll(moduleImports) //
44 .addAll(submoduleIncludes) //
48 public ImmutableSet<ModuleImport> getDependencies() {
52 public String getName() {
56 public String getFormattedRevision() {
57 return formattedRevision;
60 public Date getRevision() {
65 public int hashCode() {
68 result = prime * result + ((formattedRevision == null) ? 0 : formattedRevision.hashCode());
69 result = prime * result + ((name == null) ? 0 : name.hashCode());
74 public boolean equals(Object obj) {
79 if (!(obj instanceof YangModelDependencyInfo))
81 YangModelDependencyInfo other = (YangModelDependencyInfo) obj;
82 if (formattedRevision == null) {
83 if (other.formattedRevision != null)
85 } else if (!formattedRevision.equals(other.formattedRevision))
88 if (other.name != null)
90 } else if (!name.equals(other.name))
95 public static YangModelDependencyInfo fromInputStream(InputStream yangStream) {
96 YangContext yangContext = YangParserImpl.parseStreamWithoutErrorListeners(yangStream);
98 Optional<Module_stmtContext> moduleCtx = getFirstContext(yangContext, Module_stmtContext.class);
99 if (moduleCtx.isPresent()) {
100 return fromModuleContext(moduleCtx.get());
102 Optional<Submodule_stmtContext> submoduleCtx = getFirstContext(yangContext, Submodule_stmtContext.class);
103 if (submoduleCtx.isPresent()) {
104 return fromSubmoduleContext(submoduleCtx.get());
106 throw new IllegalArgumentException("Supplied stream is not valid yang file.");
109 private static YangModelDependencyInfo fromModuleContext(Module_stmtContext module) {
110 String name = getArgumentString(module);
112 // getArgumentString(module.module_header_stmts().prefix_stmt(0));
113 String namespace = getArgumentString(module.module_header_stmts().namespace_stmt(0));
114 String latestRevision = getLatestRevision(module.revision_stmts());
115 ImmutableSet<ModuleImport> imports = getImports(module.linkage_stmts().import_stmt());
116 ImmutableSet<ModuleImport> includes = getIncludes(module.linkage_stmts().include_stmt());
118 return new ModuleDependencyInfo(name, latestRevision, namespace, imports, includes);
121 private static ImmutableSet<ModuleImport> getImports(List<Import_stmtContext> importStatements) {
122 ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
123 for (Import_stmtContext importStmt : importStatements) {
124 String moduleName = getArgumentString(importStmt);
125 Date revision = getRevision(importStmt.revision_date_stmt());
126 String prefix = getArgumentString(importStmt.prefix_stmt());
127 builder.add(new ModuleImportImpl(moduleName, revision));
129 return builder.build();
132 private static String getLatestRevision(Revision_stmtsContext revision_stmts) {
133 List<Revision_stmtContext> revisions = revision_stmts.getRuleContexts(Revision_stmtContext.class);
134 String latestRevision = null;
135 for (Revision_stmtContext revisionStmt : revisions) {
136 String currentRevision = getArgumentString(revisionStmt);
137 if (latestRevision == null || latestRevision.compareTo(currentRevision) == 1) {
138 latestRevision = currentRevision;
141 return latestRevision;
144 private static YangModelDependencyInfo fromSubmoduleContext(Submodule_stmtContext submodule) {
145 String name = getArgumentString(submodule);
146 Belongs_to_stmtContext belongsToStmt = submodule.submodule_header_stmts().belongs_to_stmt(0);
147 String belongsTo = getArgumentString(belongsToStmt);
149 String latestRevision = getLatestRevision(submodule.revision_stmts());
150 ImmutableSet<ModuleImport> imports = getImports(submodule.linkage_stmts().import_stmt());
151 ImmutableSet<ModuleImport> includes = getIncludes(submodule.linkage_stmts().include_stmt());
153 return new SubmoduleDependencyInfo(name, latestRevision, belongsTo, imports, includes);
156 private static ImmutableSet<ModuleImport> getIncludes(List<Include_stmtContext> importStatements) {
157 ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
158 for (Include_stmtContext importStmt : importStatements) {
159 String moduleName = getArgumentString(importStmt);
160 Date revision = getRevision(importStmt.revision_date_stmt());
161 builder.add(new ModuleImportImpl(moduleName, revision));
163 return builder.build();
166 private static Date getRevision(Revision_date_stmtContext revision_date_stmt) {
167 if (revision_date_stmt == null) {
170 String formatedDate = getArgumentString(revision_date_stmt);
171 return QName.parseRevision(formatedDate);
174 public static final class ModuleDependencyInfo extends YangModelDependencyInfo {
176 private ModuleDependencyInfo(String name, String latestRevision, String namespace,
177 ImmutableSet<ModuleImport> imports, ImmutableSet<ModuleImport> includes) {
178 super(name, latestRevision, imports, includes);
182 public String toString() {
183 return "Module [name=" + getName() + ", revision=" + getRevision()
184 + ", dependencies=" + getDependencies() + "]";
189 public static final class SubmoduleDependencyInfo extends YangModelDependencyInfo {
191 private final String belongsTo;
193 public String getParentModule() {
197 private SubmoduleDependencyInfo(String name, String latestRevision, String belongsTo,
198 ImmutableSet<ModuleImport> imports, ImmutableSet<ModuleImport> includes) {
199 super(name, latestRevision, imports, includes);
200 this.belongsTo = belongsTo;
204 public String toString() {
205 return "Submodule [name=" + getName() + ", revision=" + getRevision()
206 + ", dependencies=" + getDependencies() + "]";
211 private static final class ModuleImportImpl implements ModuleImport {
213 private Date revision;
216 public ModuleImportImpl(String moduleName, Date revision) {
217 this.name = moduleName;
218 this.revision = revision;
222 public String getModuleName() {
227 public Date getRevision() {
228 return this.revision;
232 public String getPrefix() {
237 public int hashCode() {
238 final int prime = 31;
240 result = prime * result + ((name == null) ? 0 : name.hashCode());
241 result = prime * result + ((revision == null) ? 0 : revision.hashCode());
246 public boolean equals(Object obj) {
251 if (getClass() != obj.getClass())
253 ModuleImportImpl other = (ModuleImportImpl) obj;
255 if (other.name != null)
257 } else if (!name.equals(other.name))
259 if (revision == null) {
260 if (other.revision != null)
262 } else if (!revision.equals(other.revision))
268 public String toString() {
269 return "ModuleImportImpl [name=" + name + ", revision=" + QName.formattedRevision(revision) + "]";