2 * Copyright (c) 2015 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/epl-v10.html
8 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
10 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
13 import java.util.Date;
14 import java.util.NavigableMap;
15 import java.util.Optional;
16 import java.util.TreeMap;
17 import org.opendaylight.yangtools.concepts.SemVer;
18 import org.opendaylight.yangtools.yang.common.QNameModule;
19 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
20 import org.opendaylight.yangtools.yang.model.api.Module;
21 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
22 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
23 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
24 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
26 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
27 import org.opendaylight.yangtools.yang.model.util.ModuleIdentifierImpl;
28 import org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace;
29 import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
30 import org.opendaylight.yangtools.yang.parser.spi.PreLinkageModuleNamespace;
31 import org.opendaylight.yangtools.yang.parser.spi.SubstatementValidator;
32 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
33 import org.opendaylight.yangtools.yang.parser.spi.meta.SemanticVersionModuleNamespace;
34 import org.opendaylight.yangtools.yang.parser.spi.meta.SemanticVersionNamespace;
35 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
36 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
37 import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier;
38 import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToNamespace;
39 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleIdentifier;
40 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
41 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleIdentifierToModuleQName;
42 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
43 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToNamespace;
44 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNamespaceForBelongsTo;
45 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
46 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
47 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
48 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ModuleEffectiveStatementImpl;
50 public class ModuleStatementSupport extends
51 AbstractStatementSupport<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> {
52 private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(YangStmtMapping
54 .addAny(YangStmtMapping.ANYXML)
55 .addAny(YangStmtMapping.AUGMENT)
56 .addAny(YangStmtMapping.CHOICE)
57 .addOptional(YangStmtMapping.CONTACT)
58 .addAny(YangStmtMapping.CONTAINER)
59 .addOptional(YangStmtMapping.DESCRIPTION)
60 .addAny(YangStmtMapping.DEVIATION)
61 .addAny(YangStmtMapping.EXTENSION)
62 .addAny(YangStmtMapping.FEATURE)
63 .addAny(YangStmtMapping.GROUPING)
64 .addAny(YangStmtMapping.IDENTITY)
65 .addAny(YangStmtMapping.IMPORT)
66 .addAny(YangStmtMapping.INCLUDE)
67 .addAny(YangStmtMapping.LEAF)
68 .addAny(YangStmtMapping.LEAF_LIST)
69 .addAny(YangStmtMapping.LIST)
70 .addMandatory(YangStmtMapping.NAMESPACE)
71 .addAny(YangStmtMapping.NOTIFICATION)
72 .addOptional(YangStmtMapping.ORGANIZATION)
73 .addMandatory(YangStmtMapping.PREFIX)
74 .addOptional(YangStmtMapping.REFERENCE)
75 .addAny(YangStmtMapping.REVISION)
76 .addAny(YangStmtMapping.RPC)
77 .addAny(YangStmtMapping.TYPEDEF)
78 .addAny(YangStmtMapping.USES)
79 .addOptional(YangStmtMapping.YANG_VERSION)
80 .addOptional(SupportedExtensionsMapping.SEMANTIC_VERSION)
83 public ModuleStatementSupport() {
84 super(YangStmtMapping.MODULE);
88 public String parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
93 public ModuleStatement createDeclared(final StmtContext<String, ModuleStatement, ?> ctx) {
94 return new ModuleStatementImpl(ctx);
98 public EffectiveStatement<String, ModuleStatement> createEffective(
99 final StmtContext<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> ctx) {
100 return new ModuleEffectiveStatementImpl(ctx);
104 public void onPreLinkageDeclared(final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
105 final String moduleName = stmt.getStatementArgument();
107 final URI moduleNs = firstAttributeOf(stmt.declaredSubstatements(), NamespaceStatement.class);
108 SourceException.throwIfNull(moduleNs, stmt.getStatementSourceReference(),
109 "Namespace of the module [%s] is missing", stmt.getStatementArgument());
110 stmt.addToNs(ModuleNameToNamespace.class, moduleName, moduleNs);
112 final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class);
113 SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(),
114 "Prefix of the module [%s] is missing", stmt.getStatementArgument());
115 stmt.addToNs(ImpPrefixToNamespace.class, modulePrefix, moduleNs);
117 stmt.addContext(PreLinkageModuleNamespace.class, moduleName, stmt);
119 Optional<Date> revisionDate = Optional.ofNullable(Utils.getLatestRevision(stmt.declaredSubstatements()));
120 if (!revisionDate.isPresent()) {
121 revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
124 final QNameModule qNameModule = QNameModule.create(moduleNs, revisionDate.orElse(null)).intern();
126 stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule);
130 public void onLinkageDeclared(final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
132 final Optional<URI> moduleNs = Optional.ofNullable(firstAttributeOf(stmt.declaredSubstatements(),
133 NamespaceStatement.class));
134 SourceException.throwIf(!moduleNs.isPresent(), stmt.getStatementSourceReference(),
135 "Namespace of the module [%s] is missing", stmt.getStatementArgument());
137 Optional<Date> revisionDate = Optional.ofNullable(Utils.getLatestRevision(stmt.declaredSubstatements()));
138 if (!revisionDate.isPresent()) {
139 revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
142 final QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orElse(null)).intern();
143 final ModuleIdentifier moduleIdentifier = ModuleIdentifierImpl.create(stmt.getStatementArgument(),
144 Optional.empty(), revisionDate);
146 stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt);
147 stmt.addContext(ModuleNamespaceForBelongsTo.class, moduleIdentifier.getName(), stmt);
148 stmt.addContext(NamespaceToModule.class, qNameModule, stmt);
150 final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class);
151 SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(),
152 "Prefix of the module [%s] is missing", stmt.getStatementArgument());
154 stmt.addToNs(PrefixToModule.class, modulePrefix, qNameModule);
155 stmt.addToNs(ModuleNameToModuleQName.class, stmt.getStatementArgument(), qNameModule);
156 stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule); // tu
157 stmt.addToNs(ModuleCtxToModuleIdentifier.class, stmt, moduleIdentifier);
158 stmt.addToNs(ModuleQNameToModuleName.class, qNameModule, stmt.getStatementArgument());
159 stmt.addToNs(ModuleIdentifierToModuleQName.class, moduleIdentifier, qNameModule);
160 stmt.addToNs(ImpPrefixToModuleIdentifier.class, modulePrefix, moduleIdentifier);
162 if (stmt.isEnabledSemanticVersioning()) {
163 addToSemVerModuleNamespace(stmt);
167 private static void addToSemVerModuleNamespace(
168 final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
169 final String moduleName = stmt.getStatementArgument();
170 NavigableMap<SemVer, StmtContext<?, ?, ?>> modulesMap = stmt.getFromNamespace(
171 SemanticVersionModuleNamespace.class, moduleName);
172 if (modulesMap == null) {
173 modulesMap = new TreeMap<>();
175 SemVer moduleSemVer = stmt.getFromNamespace(SemanticVersionNamespace.class, stmt);
176 if(moduleSemVer == null) {
177 moduleSemVer = Module.DEFAULT_SEMANTIC_VERSION;
179 modulesMap.put(moduleSemVer, stmt);
180 stmt.addToNs(SemanticVersionModuleNamespace.class, moduleName, modulesMap);
184 protected SubstatementValidator getSubstatementValidator() {
185 return SUBSTATEMENT_VALIDATOR;