BUG-4688: eliminate SimpleDateFormatUtil.DEFAULT_DATE_REV
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / ModuleStatementSupport.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.stmt.rfc6020;
9
10 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
11
12 import java.net.URI;
13 import java.util.Date;
14 import java.util.Optional;
15 import org.opendaylight.yangtools.concepts.SemVer;
16 import org.opendaylight.yangtools.yang.common.QNameModule;
17 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
18 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
19 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
20 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
21 import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
22 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
23 import org.opendaylight.yangtools.yang.model.repo.api.SemVerSourceIdentifier;
24 import org.opendaylight.yangtools.yang.model.util.ModuleIdentifierImpl;
25 import org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace;
26 import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
27 import org.opendaylight.yangtools.yang.parser.spi.PreLinkageModuleNamespace;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
29 import org.opendaylight.yangtools.yang.parser.spi.meta.SemanticVersionModuleNamespace;
30 import org.opendaylight.yangtools.yang.parser.spi.meta.SemanticVersionNamespace;
31 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
32 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
33 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
34 import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
35 import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToNamespace;
36 import org.opendaylight.yangtools.yang.parser.spi.source.ImportPrefixToModuleCtx;
37 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleIdentifier;
38 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
39 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
40 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToNamespace;
41 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNamespaceForBelongsTo;
42 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
43 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
44 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
45 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ModuleEffectiveStatementImpl;
46
47 public class ModuleStatementSupport extends
48         AbstractStatementSupport<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> {
49     private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(YangStmtMapping
50             .MODULE)
51             .addAny(YangStmtMapping.ANYXML)
52             .addAny(YangStmtMapping.AUGMENT)
53             .addAny(YangStmtMapping.CHOICE)
54             .addOptional(YangStmtMapping.CONTACT)
55             .addAny(YangStmtMapping.CONTAINER)
56             .addOptional(YangStmtMapping.DESCRIPTION)
57             .addAny(YangStmtMapping.DEVIATION)
58             .addAny(YangStmtMapping.EXTENSION)
59             .addAny(YangStmtMapping.FEATURE)
60             .addAny(YangStmtMapping.GROUPING)
61             .addAny(YangStmtMapping.IDENTITY)
62             .addAny(YangStmtMapping.IMPORT)
63             .addAny(YangStmtMapping.INCLUDE)
64             .addAny(YangStmtMapping.LEAF)
65             .addAny(YangStmtMapping.LEAF_LIST)
66             .addAny(YangStmtMapping.LIST)
67             .addMandatory(YangStmtMapping.NAMESPACE)
68             .addAny(YangStmtMapping.NOTIFICATION)
69             .addOptional(YangStmtMapping.ORGANIZATION)
70             .addMandatory(YangStmtMapping.PREFIX)
71             .addOptional(YangStmtMapping.REFERENCE)
72             .addAny(YangStmtMapping.REVISION)
73             .addAny(YangStmtMapping.RPC)
74             .addAny(YangStmtMapping.TYPEDEF)
75             .addAny(YangStmtMapping.USES)
76             .addOptional(YangStmtMapping.YANG_VERSION)
77             .addOptional(SupportedExtensionsMapping.OPENCONFIG_VERSION)
78             .build();
79
80     public ModuleStatementSupport() {
81         super(YangStmtMapping.MODULE);
82     }
83
84     @Override
85     public String parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
86         return value;
87     }
88
89     @Override
90     public ModuleStatement createDeclared(final StmtContext<String, ModuleStatement, ?> ctx) {
91         return new ModuleStatementImpl(ctx);
92     }
93
94     @Override
95     public EffectiveStatement<String, ModuleStatement> createEffective(
96             final StmtContext<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> ctx) {
97         return new ModuleEffectiveStatementImpl(ctx);
98     }
99
100     @Override
101     public void onPreLinkageDeclared(final Mutable<String, ModuleStatement,
102             EffectiveStatement<String, ModuleStatement>> stmt) {
103         final String moduleName = stmt.getStatementArgument();
104
105         final URI moduleNs = firstAttributeOf(stmt.declaredSubstatements(), NamespaceStatement.class);
106         SourceException.throwIfNull(moduleNs, stmt.getStatementSourceReference(),
107             "Namespace of the module [%s] is missing", stmt.getStatementArgument());
108         stmt.addToNs(ModuleNameToNamespace.class, moduleName, moduleNs);
109
110         final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class);
111         SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(),
112             "Prefix of the module [%s] is missing", stmt.getStatementArgument());
113         stmt.addToNs(ImpPrefixToNamespace.class, modulePrefix, moduleNs);
114
115         stmt.addContext(PreLinkageModuleNamespace.class, moduleName, stmt);
116
117         final Optional<Date> revisionDate = Optional.ofNullable(StmtContextUtils.getLatestRevision(
118             stmt.declaredSubstatements()));
119         final QNameModule qNameModule = QNameModule.create(moduleNs, revisionDate.orElse(null)).intern();
120
121         stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule);
122         stmt.setRootIdentifier(ModuleIdentifierImpl.create(stmt.getStatementArgument(), revisionDate));
123     }
124
125     @Override
126     public void onLinkageDeclared(final Mutable<String, ModuleStatement,
127             EffectiveStatement<String, ModuleStatement>> stmt) {
128
129         final Optional<URI> moduleNs = Optional.ofNullable(firstAttributeOf(stmt.declaredSubstatements(),
130                 NamespaceStatement.class));
131         SourceException.throwIf(!moduleNs.isPresent(), stmt.getStatementSourceReference(),
132             "Namespace of the module [%s] is missing", stmt.getStatementArgument());
133
134         final Optional<Date> revisionDate = Optional.ofNullable(StmtContextUtils.getLatestRevision(
135             stmt.declaredSubstatements()));
136         final QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orElse(null)).intern();
137         final StmtContext<?, ModuleStatement, EffectiveStatement<String, ModuleStatement>> possibleDuplicateModule =
138                 stmt.getFromNamespace(NamespaceToModule.class, qNameModule);
139         if (possibleDuplicateModule != null && possibleDuplicateModule != stmt) {
140             throw new SourceException(stmt.getStatementSourceReference(), "Module namespace collision: %s. At %s",
141                     qNameModule.getNamespace(), possibleDuplicateModule.getStatementSourceReference());
142         }
143
144         final ModuleIdentifier moduleIdentifier = ModuleIdentifierImpl.create(stmt.getStatementArgument(),
145                 revisionDate);
146
147         stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt);
148         stmt.addContext(ModuleNamespaceForBelongsTo.class, moduleIdentifier.getName(), stmt);
149         stmt.addContext(NamespaceToModule.class, qNameModule, stmt);
150
151         final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class);
152         SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(),
153             "Prefix of the module [%s] is missing", stmt.getStatementArgument());
154
155         stmt.addToNs(PrefixToModule.class, modulePrefix, qNameModule);
156         stmt.addToNs(ModuleNameToModuleQName.class, stmt.getStatementArgument(), qNameModule);
157         stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule); // tu
158         stmt.addToNs(ModuleCtxToModuleIdentifier.class, stmt, moduleIdentifier);
159         stmt.addToNs(ModuleQNameToModuleName.class, qNameModule, stmt.getStatementArgument());
160         stmt.addToNs(ImportPrefixToModuleCtx.class, modulePrefix, stmt);
161
162         if (stmt.isEnabledSemanticVersioning()) {
163             addToSemVerModuleNamespace(stmt, moduleIdentifier);
164         }
165     }
166
167     private static void addToSemVerModuleNamespace(
168             final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt,
169             final ModuleIdentifier moduleIdentifier) {
170         final String moduleName = stmt.getStatementArgument();
171         final SemVer moduleSemVer = stmt.getFromNamespace(SemanticVersionNamespace.class, stmt);
172         final SemVerSourceIdentifier id = SemVerSourceIdentifier.create(moduleName, moduleSemVer);
173         stmt.addToNs(SemanticVersionModuleNamespace.class, id, stmt);
174     }
175
176     @Override
177     protected SubstatementValidator getSubstatementValidator() {
178         return SUBSTATEMENT_VALIDATOR;
179     }
180 }