bdd54bc8134f8b3bf15185f4704bdd0ef4cce62b
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / util / YangModelDependencyInfo.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.parser.impl.util;
9
10 import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getArgumentString;
11 import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getFirstContext;
12
13 import java.io.InputStream;
14 import java.util.Date;
15 import java.util.List;
16
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;
29
30 import com.google.common.base.Optional;
31 import com.google.common.collect.ImmutableSet;
32
33 public abstract class YangModelDependencyInfo {
34
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;
41
42     public YangModelDependencyInfo(String name, String formattedRevision, ImmutableSet<ModuleImport> imports,
43             ImmutableSet<ModuleImport> includes) {
44         this.name = name;
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) //
52                 .build();
53     }
54
55     public ImmutableSet<ModuleImport> getDependencies() {
56         return dependencies;
57     }
58
59     public String getName() {
60         return name;
61     }
62
63     public String getFormattedRevision() {
64         return formattedRevision;
65     }
66
67     public Date getRevision() {
68         return revision;
69     }
70
71     @Override
72     public int hashCode() {
73         final int prime = 31;
74         int result = 1;
75         result = prime * result + ((formattedRevision == null) ? 0 : formattedRevision.hashCode());
76         result = prime * result + ((name == null) ? 0 : name.hashCode());
77         return result;
78     }
79
80     @Override
81     public boolean equals(Object obj) {
82         if (this == obj)
83             return true;
84         if (obj == null)
85             return false;
86         if (!(obj instanceof YangModelDependencyInfo))
87             return false;
88         YangModelDependencyInfo other = (YangModelDependencyInfo) obj;
89         if (formattedRevision == null) {
90             if (other.formattedRevision != null)
91                 return false;
92         } else if (!formattedRevision.equals(other.formattedRevision))
93             return false;
94         if (name == null) {
95             if (other.name != null)
96                 return false;
97         } else if (!name.equals(other.name))
98             return false;
99         return true;
100     }
101
102     public static YangModelDependencyInfo fromInputStream(InputStream yangStream) {
103         YangContext yangContext = YangParserImpl.parseStreamWithoutErrorListeners(yangStream);
104
105         Optional<Module_stmtContext> moduleCtx = getFirstContext(yangContext, Module_stmtContext.class);
106         if (moduleCtx.isPresent()) {
107             return fromModuleContext(moduleCtx.get());
108         }
109         Optional<Submodule_stmtContext> submoduleCtx = getFirstContext(yangContext, Submodule_stmtContext.class);
110         if (submoduleCtx.isPresent()) {
111             return fromSubmoduleContext(submoduleCtx.get());
112         }
113         throw new IllegalArgumentException("Supplied stream is not valid yang file.");
114     }
115
116     private static YangModelDependencyInfo fromModuleContext(Module_stmtContext module) {
117         String name = getArgumentString(module);
118         // String prefix =
119         // getArgumentString(module.module_header_stmts().prefix_stmt(0));
120         String namespace = getArgumentString(module.module_header_stmts().namespace_stmt(0));
121         String latestRevision = getLatestRevision(module.revision_stmts());
122         ImmutableSet<ModuleImport> imports = getImports(module.linkage_stmts().import_stmt());
123         ImmutableSet<ModuleImport> includes = getIncludes(module.linkage_stmts().include_stmt());
124
125         return new ModuleDependencyInfo(name, latestRevision, namespace, imports, includes);
126     }
127
128     private static ImmutableSet<ModuleImport> getImports(List<Import_stmtContext> importStatements) {
129         ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
130         for (Import_stmtContext importStmt : importStatements) {
131             String moduleName = getArgumentString(importStmt);
132             Date revision = getRevision(importStmt.revision_date_stmt());
133             builder.add(new ModuleImportImpl(moduleName, revision));
134         }
135         return builder.build();
136     }
137
138     private static String getLatestRevision(Revision_stmtsContext revision_stmts) {
139         List<Revision_stmtContext> revisions = revision_stmts.getRuleContexts(Revision_stmtContext.class);
140         String latestRevision = null;
141         for (Revision_stmtContext revisionStmt : revisions) {
142             String currentRevision = getArgumentString(revisionStmt);
143             if (latestRevision == null || latestRevision.compareTo(currentRevision) == -1) {
144                 latestRevision = currentRevision;
145             }
146         }
147         return latestRevision;
148     }
149
150     private static YangModelDependencyInfo fromSubmoduleContext(Submodule_stmtContext submodule) {
151         String name = getArgumentString(submodule);
152         Belongs_to_stmtContext belongsToStmt = submodule.submodule_header_stmts().belongs_to_stmt(0);
153         String belongsTo = getArgumentString(belongsToStmt);
154
155         String latestRevision = getLatestRevision(submodule.revision_stmts());
156         ImmutableSet<ModuleImport> imports = getImports(submodule.linkage_stmts().import_stmt());
157         ImmutableSet<ModuleImport> includes = getIncludes(submodule.linkage_stmts().include_stmt());
158
159         return new SubmoduleDependencyInfo(name, latestRevision, belongsTo, imports, includes);
160     }
161
162     private static ImmutableSet<ModuleImport> getIncludes(List<Include_stmtContext> importStatements) {
163         ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
164         for (Include_stmtContext importStmt : importStatements) {
165             String moduleName = getArgumentString(importStmt);
166             Date revision = getRevision(importStmt.revision_date_stmt());
167             builder.add(new ModuleImportImpl(moduleName, revision));
168         }
169         return builder.build();
170     }
171
172     private static Date getRevision(Revision_date_stmtContext revision_date_stmt) {
173         if (revision_date_stmt == null) {
174             return null;
175         }
176         String formatedDate = getArgumentString(revision_date_stmt);
177         return QName.parseRevision(formatedDate);
178     }
179
180     public static final class ModuleDependencyInfo extends YangModelDependencyInfo {
181
182         private ModuleDependencyInfo(String name, String latestRevision, String namespace,
183                 ImmutableSet<ModuleImport> imports, ImmutableSet<ModuleImport> includes) {
184             super(name, latestRevision, imports, includes);
185         }
186
187         @Override
188         public String toString() {
189             return "Module [name=" + getName() + ", revision=" + getRevision()
190                     + ", dependencies=" + getDependencies() + "]";
191         }
192
193     }
194
195     public static final class SubmoduleDependencyInfo extends YangModelDependencyInfo {
196
197         private final String belongsTo;
198
199         public String getParentModule() {
200             return belongsTo;
201         }
202
203         private SubmoduleDependencyInfo(String name, String latestRevision, String belongsTo,
204                 ImmutableSet<ModuleImport> imports, ImmutableSet<ModuleImport> includes) {
205             super(name, latestRevision, imports, includes);
206             this.belongsTo = belongsTo;
207         }
208
209         @Override
210         public String toString() {
211             return "Submodule [name=" + getName() + ", revision=" + getRevision()
212                     + ", dependencies=" + getDependencies() + "]";
213         }
214
215     }
216
217     private static final class ModuleImportImpl implements ModuleImport {
218
219         private Date revision;
220         private String name;
221
222         public ModuleImportImpl(String moduleName, Date revision) {
223             this.name = moduleName;
224             this.revision = revision;
225         }
226
227         @Override
228         public String getModuleName() {
229             return this.name;
230         }
231
232         @Override
233         public Date getRevision() {
234             return this.revision;
235         }
236
237         @Override
238         public String getPrefix() {
239             return null;
240         }
241
242         @Override
243         public int hashCode() {
244             final int prime = 31;
245             int result = 1;
246             result = prime * result + ((name == null) ? 0 : name.hashCode());
247             result = prime * result + ((revision == null) ? 0 : revision.hashCode());
248             return result;
249         }
250
251         @Override
252         public boolean equals(Object obj) {
253             if (this == obj)
254                 return true;
255             if (obj == null)
256                 return false;
257             if (getClass() != obj.getClass())
258                 return false;
259             ModuleImportImpl other = (ModuleImportImpl) obj;
260             if (name == null) {
261                 if (other.name != null)
262                     return false;
263             } else if (!name.equals(other.name))
264                 return false;
265             if (revision == null) {
266                 if (other.revision != null)
267                     return false;
268             } else if (!revision.equals(other.revision))
269                 return false;
270             return true;
271         }
272
273         @Override
274         public String toString() {
275             return "ModuleImportImpl [name=" + name + ", revision=" + QName.formattedRevision(revision) + "]";
276         }
277
278
279     }
280 }