2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/eplv10.html
8 package org.opendaylight.yangtools.yang.parser.impl.util;
10 import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getArgumentString;
11 import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getFirstContext;
13 import java.io.InputStream;
14 import java.util.Date;
15 import java.util.List;
17 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Belongs_to_stmtContext;
18 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Import_stmtContext;
19 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Include_stmtContext;
20 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_stmtContext;
21 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_date_stmtContext;
22 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtContext;
23 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtsContext;
24 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Submodule_stmtContext;
25 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.YangContext;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
28 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
30 import com.google.common.base.Optional;
31 import com.google.common.collect.ImmutableSet;
33 public abstract class YangModelDependencyInfo {
35 private final String name;
36 private final String formattedRevision;
37 private final Date revision;
38 private final ImmutableSet<ModuleImport> submoduleIncludes;
39 private final ImmutableSet<ModuleImport> moduleImports;
40 private final ImmutableSet<ModuleImport> dependencies;
42 public YangModelDependencyInfo(final String name, final String formattedRevision, final ImmutableSet<ModuleImport> imports,
43 final ImmutableSet<ModuleImport> includes) {
45 this.formattedRevision = formattedRevision;
46 this.revision = QName.parseRevision(formattedRevision);
47 this.moduleImports = imports;
48 this.submoduleIncludes = includes;
49 this.dependencies = ImmutableSet.<ModuleImport> builder() //
50 .addAll(moduleImports) //
51 .addAll(submoduleIncludes) //
55 public ImmutableSet<ModuleImport> getDependencies() {
59 public String getName() {
63 public String getFormattedRevision() {
64 return formattedRevision;
67 public Date getRevision() {
72 public int hashCode() {
75 result = prime * result + ((formattedRevision == null) ? 0 : formattedRevision.hashCode());
76 result = prime * result + ((name == null) ? 0 : name.hashCode());
81 public boolean equals(final Object obj) {
88 if (!(obj instanceof YangModelDependencyInfo)) {
91 YangModelDependencyInfo other = (YangModelDependencyInfo) obj;
92 if (formattedRevision == null) {
93 if (other.formattedRevision != null) {
96 } else if (!formattedRevision.equals(other.formattedRevision)) {
100 if (other.name != null) {
103 } else if (!name.equals(other.name)) {
109 public static YangModelDependencyInfo fromInputStream(final InputStream yangStream) {
110 YangContext yangContext = YangParserImpl.parseStreamWithoutErrorListeners(yangStream);
112 Optional<Module_stmtContext> moduleCtx = getFirstContext(yangContext, Module_stmtContext.class);
113 if (moduleCtx.isPresent()) {
114 return fromModuleContext(moduleCtx.get());
116 Optional<Submodule_stmtContext> submoduleCtx = getFirstContext(yangContext, Submodule_stmtContext.class);
117 if (submoduleCtx.isPresent()) {
118 return fromSubmoduleContext(submoduleCtx.get());
120 throw new IllegalArgumentException("Supplied stream is not valid yang file.");
123 private static YangModelDependencyInfo fromModuleContext(final Module_stmtContext module) {
124 String name = getArgumentString(module);
126 // getArgumentString(module.module_header_stmts().prefix_stmt(0));
127 String namespace = getArgumentString(module.module_header_stmts().namespace_stmt(0));
128 String latestRevision = getLatestRevision(module.revision_stmts());
129 ImmutableSet<ModuleImport> imports = getImports(module.linkage_stmts().import_stmt());
130 ImmutableSet<ModuleImport> includes = getIncludes(module.linkage_stmts().include_stmt());
132 return new ModuleDependencyInfo(name, latestRevision, namespace, imports, includes);
135 private static ImmutableSet<ModuleImport> getImports(final List<Import_stmtContext> importStatements) {
136 ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
137 for (Import_stmtContext importStmt : importStatements) {
138 String moduleName = getArgumentString(importStmt);
139 Date revision = getRevision(importStmt.revision_date_stmt());
140 builder.add(new ModuleImportImpl(moduleName, revision));
142 return builder.build();
145 private static String getLatestRevision(final Revision_stmtsContext revision_stmts) {
146 List<Revision_stmtContext> revisions = revision_stmts.getRuleContexts(Revision_stmtContext.class);
147 String latestRevision = null;
148 for (Revision_stmtContext revisionStmt : revisions) {
149 String currentRevision = getArgumentString(revisionStmt);
150 if (latestRevision == null || latestRevision.compareTo(currentRevision) == -1) {
151 latestRevision = currentRevision;
154 return latestRevision;
157 private static YangModelDependencyInfo fromSubmoduleContext(final Submodule_stmtContext submodule) {
158 String name = getArgumentString(submodule);
159 Belongs_to_stmtContext belongsToStmt = submodule.submodule_header_stmts().belongs_to_stmt(0);
160 String belongsTo = getArgumentString(belongsToStmt);
162 String latestRevision = getLatestRevision(submodule.revision_stmts());
163 ImmutableSet<ModuleImport> imports = getImports(submodule.linkage_stmts().import_stmt());
164 ImmutableSet<ModuleImport> includes = getIncludes(submodule.linkage_stmts().include_stmt());
166 return new SubmoduleDependencyInfo(name, latestRevision, belongsTo, imports, includes);
169 private static ImmutableSet<ModuleImport> getIncludes(final List<Include_stmtContext> importStatements) {
170 ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
171 for (Include_stmtContext importStmt : importStatements) {
172 String moduleName = getArgumentString(importStmt);
173 Date revision = getRevision(importStmt.revision_date_stmt());
174 builder.add(new ModuleImportImpl(moduleName, revision));
176 return builder.build();
179 private static Date getRevision(final Revision_date_stmtContext revision_date_stmt) {
180 if (revision_date_stmt == null) {
183 String formatedDate = getArgumentString(revision_date_stmt);
184 return QName.parseRevision(formatedDate);
187 public static final class ModuleDependencyInfo extends YangModelDependencyInfo {
189 private ModuleDependencyInfo(final String name, final String latestRevision, final String namespace,
190 final ImmutableSet<ModuleImport> imports, final ImmutableSet<ModuleImport> includes) {
191 super(name, latestRevision, imports, includes);
195 public String toString() {
196 return "Module [name=" + getName() + ", revision=" + getRevision()
197 + ", dependencies=" + getDependencies() + "]";
201 public static final class SubmoduleDependencyInfo extends YangModelDependencyInfo {
203 private final String belongsTo;
205 public String getParentModule() {
209 private SubmoduleDependencyInfo(final String name, final String latestRevision, final String belongsTo,
210 final ImmutableSet<ModuleImport> imports, final ImmutableSet<ModuleImport> includes) {
211 super(name, latestRevision, imports, includes);
212 this.belongsTo = belongsTo;
216 public String toString() {
217 return "Submodule [name=" + getName() + ", revision=" + getRevision()
218 + ", dependencies=" + getDependencies() + "]";
222 private static final class ModuleImportImpl implements ModuleImport {
224 private final Date revision;
225 private final String name;
227 public ModuleImportImpl(final String moduleName, final Date revision) {
228 this.name = moduleName;
229 this.revision = revision;
233 public String getModuleName() {
238 public Date getRevision() {
239 return this.revision;
243 public String getPrefix() {
248 public int hashCode() {
249 final int prime = 31;
251 result = prime * result + ((name == null) ? 0 : name.hashCode());
252 result = prime * result + ((revision == null) ? 0 : revision.hashCode());
257 public boolean equals(final Object obj) {
264 if (getClass() != obj.getClass()) {
267 ModuleImportImpl other = (ModuleImportImpl) obj;
269 if (other.name != null) {
272 } else if (!name.equals(other.name)) {
275 if (revision == null) {
276 if (other.revision != null) {
279 } else if (!revision.equals(other.revision)) {
286 public String toString() {
287 return "ModuleImportImpl [name=" + name + ", revision=" + QName.formattedRevision(revision) + "]";