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.Rfc6020Mapping;
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(Rfc6020Mapping
54 .addAny(Rfc6020Mapping.ANYXML)
55 .addAny(Rfc6020Mapping.AUGMENT)
56 .addAny(Rfc6020Mapping.CHOICE)
57 .addOptional(Rfc6020Mapping.CONTACT)
58 .addAny(Rfc6020Mapping.CONTAINER)
59 .addOptional(Rfc6020Mapping.DESCRIPTION)
60 .addAny(Rfc6020Mapping.DEVIATION)
61 .addAny(Rfc6020Mapping.EXTENSION)
62 .addAny(Rfc6020Mapping.FEATURE)
63 .addAny(Rfc6020Mapping.GROUPING)
64 .addAny(Rfc6020Mapping.IDENTITY)
65 .addAny(Rfc6020Mapping.IMPORT)
66 .addAny(Rfc6020Mapping.INCLUDE)
67 .addAny(Rfc6020Mapping.LEAF)
68 .addAny(Rfc6020Mapping.LEAF_LIST)
69 .addAny(Rfc6020Mapping.LIST)
70 .addMandatory(Rfc6020Mapping.NAMESPACE)
71 .addAny(Rfc6020Mapping.NOTIFICATION)
72 .addOptional(Rfc6020Mapping.ORGANIZATION)
73 .addMandatory(Rfc6020Mapping.PREFIX)
74 .addOptional(Rfc6020Mapping.REFERENCE)
75 .addAny(Rfc6020Mapping.REVISION)
76 .addAny(Rfc6020Mapping.RPC)
77 .addAny(Rfc6020Mapping.TYPEDEF)
78 .addAny(Rfc6020Mapping.USES)
79 .addOptional(Rfc6020Mapping.YANG_VERSION)
80 .addOptional(SupportedExtensionsMapping.SEMANTIC_VERSION)
83 public ModuleStatementSupport() {
84 super(Rfc6020Mapping.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(),
108 NamespaceStatement.class);
109 SourceException.throwIfNull(moduleNs, stmt.getStatementSourceReference(),
110 "Namespace of the module [%s] is missing", stmt.getStatementArgument());
111 stmt.addToNs(ModuleNameToNamespace.class, moduleName, moduleNs);
113 final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class);
114 SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(),
115 "Prefix of the module [%s] is missing", stmt.getStatementArgument());
116 stmt.addToNs(ImpPrefixToNamespace.class, modulePrefix, moduleNs);
118 stmt.addContext(PreLinkageModuleNamespace.class, moduleName, stmt);
120 Optional<Date> revisionDate = Optional.ofNullable(Utils.getLatestRevision(stmt.declaredSubstatements()));
121 if (!revisionDate.isPresent()) {
122 revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
125 final QNameModule qNameModule = QNameModule.create(moduleNs, revisionDate.orElse(null)).intern();
127 stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule);
131 public void onLinkageDeclared(final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
133 final Optional<URI> moduleNs = Optional.ofNullable(firstAttributeOf(stmt.declaredSubstatements(),
134 NamespaceStatement.class));
135 SourceException.throwIf(!moduleNs.isPresent(), stmt.getStatementSourceReference(),
136 "Namespace of the module [%s] is missing", stmt.getStatementArgument());
138 Optional<Date> revisionDate = Optional.ofNullable(Utils.getLatestRevision(stmt.declaredSubstatements()));
139 if (!revisionDate.isPresent()) {
140 revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
143 final QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orElse(null)).intern();
144 final ModuleIdentifier moduleIdentifier = ModuleIdentifierImpl.create(stmt.getStatementArgument(),
145 Optional.empty(), revisionDate);
147 stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt);
148 stmt.addContext(ModuleNamespaceForBelongsTo.class, moduleIdentifier.getName(), stmt);
149 stmt.addContext(NamespaceToModule.class, qNameModule, stmt);
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());
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(ModuleIdentifierToModuleQName.class, moduleIdentifier, qNameModule);
161 stmt.addToNs(ImpPrefixToModuleIdentifier.class, modulePrefix, moduleIdentifier);
163 if (stmt.isEnabledSemanticVersioning()) {
164 addToSemVerModuleNamespace(stmt);
168 private static void addToSemVerModuleNamespace(
169 final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
170 final String moduleName = stmt.getStatementArgument();
171 NavigableMap<SemVer, StmtContext<?, ?, ?>> modulesMap = stmt.getFromNamespace(
172 SemanticVersionModuleNamespace.class, moduleName);
173 if (modulesMap == null) {
174 modulesMap = new TreeMap<>();
176 SemVer moduleSemVer = stmt.getFromNamespace(SemanticVersionNamespace.class, stmt);
177 if(moduleSemVer == null) {
178 moduleSemVer = Module.DEFAULT_SEMANTIC_VERSION;
180 modulesMap.put(moduleSemVer, stmt);
181 stmt.addToNs(SemanticVersionModuleNamespace.class, moduleName, modulesMap);
185 public void onFullDefinitionDeclared(final Mutable<String, ModuleStatement,
186 EffectiveStatement<String, ModuleStatement>> stmt) {
187 super.onFullDefinitionDeclared(stmt);
188 getSubstatementValidator().validate(stmt);
191 protected SubstatementValidator getSubstatementValidator() {
192 return SUBSTATEMENT_VALIDATOR;