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.OPENCONFIG_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);
127 stmt.setRootIdentifier(ModuleIdentifierImpl.create(stmt.getStatementArgument(),
128 Optional.empty(), revisionDate));
132 public void onLinkageDeclared(final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
134 final Optional<URI> moduleNs = Optional.ofNullable(firstAttributeOf(stmt.declaredSubstatements(),
135 NamespaceStatement.class));
136 SourceException.throwIf(!moduleNs.isPresent(), stmt.getStatementSourceReference(),
137 "Namespace of the module [%s] is missing", stmt.getStatementArgument());
139 Optional<Date> revisionDate = Optional.ofNullable(Utils.getLatestRevision(stmt.declaredSubstatements()));
140 if (!revisionDate.isPresent()) {
141 revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
144 final QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orElse(null)).intern();
146 final StmtContext<?, ModuleStatement, EffectiveStatement<String, ModuleStatement>> possibleDuplicateModule =
147 stmt.getFromNamespace(NamespaceToModule.class, qNameModule);
148 if (possibleDuplicateModule != null && possibleDuplicateModule != stmt) {
149 throw new SourceException(stmt.getStatementSourceReference(), "Module namespace collision: %s. At %s",
150 qNameModule.getNamespace(), possibleDuplicateModule.getStatementSourceReference());
153 final ModuleIdentifier moduleIdentifier = ModuleIdentifierImpl.create(stmt.getStatementArgument(),
154 Optional.empty(), revisionDate);
156 stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt);
157 stmt.addContext(ModuleNamespaceForBelongsTo.class, moduleIdentifier.getName(), stmt);
158 stmt.addContext(NamespaceToModule.class, qNameModule, stmt);
160 final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class);
161 SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(),
162 "Prefix of the module [%s] is missing", stmt.getStatementArgument());
164 stmt.addToNs(PrefixToModule.class, modulePrefix, qNameModule);
165 stmt.addToNs(ModuleNameToModuleQName.class, stmt.getStatementArgument(), qNameModule);
166 stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule); // tu
167 stmt.addToNs(ModuleCtxToModuleIdentifier.class, stmt, moduleIdentifier);
168 stmt.addToNs(ModuleQNameToModuleName.class, qNameModule, stmt.getStatementArgument());
169 stmt.addToNs(ModuleIdentifierToModuleQName.class, moduleIdentifier, qNameModule);
170 stmt.addToNs(ImpPrefixToModuleIdentifier.class, modulePrefix, moduleIdentifier);
172 if (stmt.isEnabledSemanticVersioning()) {
173 addToSemVerModuleNamespace(stmt);
177 private static void addToSemVerModuleNamespace(
178 final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
179 final String moduleName = stmt.getStatementArgument();
180 NavigableMap<SemVer, StmtContext<?, ?, ?>> modulesMap = stmt.getFromNamespace(
181 SemanticVersionModuleNamespace.class, moduleName);
182 if (modulesMap == null) {
183 modulesMap = new TreeMap<>();
185 SemVer moduleSemVer = stmt.getFromNamespace(SemanticVersionNamespace.class, stmt);
186 if(moduleSemVer == null) {
187 moduleSemVer = Module.DEFAULT_SEMANTIC_VERSION;
189 modulesMap.put(moduleSemVer, stmt);
190 stmt.addToNs(SemanticVersionModuleNamespace.class, moduleName, modulesMap);
194 protected SubstatementValidator getSubstatementValidator() {
195 return SUBSTATEMENT_VALIDATOR;