YANGTOOLS-706: reorganize statement definitions
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / import_ / ImportEffectiveStatementImpl.java
1 /**
2  * Copyright (c) 2015 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/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.import_;
9
10 import com.google.common.base.MoreObjects;
11 import java.util.Objects;
12 import java.util.Optional;
13 import org.opendaylight.yangtools.concepts.SemVer;
14 import org.opendaylight.yangtools.yang.common.QNameModule;
15 import org.opendaylight.yangtools.yang.common.Revision;
16 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
17 import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionEffectiveStatement;
18 import org.opendaylight.yangtools.yang.model.api.stmt.ImportEffectiveStatement;
19 import org.opendaylight.yangtools.yang.model.api.stmt.ImportStatement;
20 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixEffectiveStatement;
21 import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceEffectiveStatement;
22 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionDateEffectiveStatement;
23 import org.opendaylight.yangtools.yang.model.repo.api.SemVerSourceIdentifier;
24 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.DeclaredEffectiveStatementBase;
25 import org.opendaylight.yangtools.yang.parser.spi.meta.MissingSubstatementException;
26 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
27 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
28 import org.opendaylight.yangtools.yang.parser.spi.source.ImportPrefixToSemVerSourceIdentifier;
29 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
30
31 final class ImportEffectiveStatementImpl extends DeclaredEffectiveStatementBase<String, ImportStatement>
32         implements ImportEffectiveStatement, ModuleImport {
33
34     private final String moduleName;
35     private final Revision revision;
36     private final SemVer semVer;
37     private final String prefix;
38     private final String description;
39     private final String reference;
40
41     ImportEffectiveStatementImpl(final StmtContext<String, ImportStatement, ?> ctx) {
42         super(ctx);
43
44         moduleName = ctx.getStatementArgument();
45         final PrefixEffectiveStatement prefixStmt = firstEffective(PrefixEffectiveStatement.class);
46         if (prefixStmt != null) {
47             this.prefix = prefixStmt.argument();
48         } else {
49             throw new MissingSubstatementException("Prefix is mandatory substatement of import statement",
50                     ctx.getStatementSourceReference());
51         }
52
53         if (!ctx.isEnabledSemanticVersioning()) {
54             final RevisionDateEffectiveStatement revisionDateStmt = firstEffective(
55                 RevisionDateEffectiveStatement.class);
56             this.revision = revisionDateStmt == null ? getImportedRevision(ctx) : revisionDateStmt.argument();
57             this.semVer = null;
58         } else {
59             final SemVerSourceIdentifier importedModuleIdentifier = ctx.getFromNamespace(
60                 ImportPrefixToSemVerSourceIdentifier.class, prefix);
61             revision = importedModuleIdentifier.getRevision().orElse(null);
62             semVer = importedModuleIdentifier.getSemanticVersion().orElse(null);
63         }
64
65         final DescriptionEffectiveStatement descriptionStmt = firstEffective(DescriptionEffectiveStatement.class);
66         this.description = descriptionStmt != null ? descriptionStmt.argument() : null;
67
68         final ReferenceEffectiveStatement referenceStmt = firstEffective(ReferenceEffectiveStatement.class);
69         this.reference = referenceStmt != null ? referenceStmt.argument() : null;
70     }
71
72     private Revision getImportedRevision(final StmtContext<String, ImportStatement, ?> ctx) {
73         /*
74          * When 'revision-date' of an import is not specified in yang source, we
75          * need to find revision of imported module.
76          */
77         final QNameModule importedModule = StmtContextUtils.getModuleQNameByPrefix(ctx, this.prefix);
78         SourceException.throwIfNull(importedModule, ctx.getStatementSourceReference(),
79                 "Unable to find import of module %s with prefix %s.", this.moduleName, this.prefix);
80         return importedModule.getRevision().orElse(null);
81     }
82
83     @Override
84     public String getModuleName() {
85         return moduleName;
86     }
87
88     @Override
89     public Optional<Revision> getRevision() {
90         return Optional.ofNullable(revision);
91     }
92
93     @Override
94     public Optional<SemVer> getSemanticVersion() {
95         return Optional.ofNullable(semVer);
96     }
97
98     @Override
99     public String getPrefix() {
100         return prefix;
101     }
102
103     @Override
104     public Optional<String> getDescription() {
105         return Optional.ofNullable(description);
106     }
107
108     @Override
109     public Optional<String> getReference() {
110         return Optional.ofNullable(reference);
111     }
112
113     @Override
114     public int hashCode() {
115         return Objects.hash(moduleName, revision, prefix, semVer, description, reference);
116     }
117
118     @Override
119     public boolean equals(final Object obj) {
120         if (this == obj) {
121             return true;
122         }
123         if (obj == null) {
124             return false;
125         }
126         if (getClass() != obj.getClass()) {
127             return false;
128         }
129         final ImportEffectiveStatementImpl other = (ImportEffectiveStatementImpl) obj;
130         return Objects.equals(moduleName, other.moduleName) && Objects.equals(revision, other.revision)
131                 && Objects.equals(semVer, other.semVer) && Objects.equals(prefix, other.prefix)
132                 && Objects.equals(description, other.description) && Objects.equals(reference, other.reference);
133     }
134
135     @Override
136     public String toString() {
137         return MoreObjects.toStringHelper(this).omitNullValues().add("moduleName", getModuleName())
138                 .add("revision", revision).add("version", semVer).add("prefix", getPrefix())
139                 .add("description", description).add("reference", reference).toString();
140     }
141 }