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;
12 import com.google.common.base.Optional;
14 import java.util.Date;
15 import java.util.NavigableMap;
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.parser.builder.impl.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.fromNullable(Utils.getLatestRevision(stmt.declaredSubstatements
122 if (!revisionDate.isPresent()) {
123 revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
126 QNameModule qNameModule = QNameModule.create(moduleNs, revisionDate.orNull()).intern();
128 stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule);
132 public void onLinkageDeclared(final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
134 Optional<URI> moduleNs = Optional.fromNullable(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.fromNullable(Utils.getLatestRevision(stmt.declaredSubstatements()));
140 if (!revisionDate.isPresent()) {
141 revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
144 QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orNull()).intern();
145 ModuleIdentifier moduleIdentifier = new ModuleIdentifierImpl(stmt.getStatementArgument(),
146 Optional.absent(), revisionDate);
148 stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt);
149 stmt.addContext(ModuleNamespaceForBelongsTo.class, moduleIdentifier.getName(), stmt);
150 stmt.addContext(NamespaceToModule.class, qNameModule, stmt);
152 final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class);
153 SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(),
154 "Prefix of the module [%s] is missing", stmt.getStatementArgument());
156 stmt.addToNs(PrefixToModule.class, modulePrefix, qNameModule);
157 stmt.addToNs(ModuleNameToModuleQName.class, stmt.getStatementArgument(), qNameModule);
158 stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule); // tu
159 stmt.addToNs(ModuleCtxToModuleIdentifier.class, stmt, moduleIdentifier);
160 stmt.addToNs(ModuleQNameToModuleName.class, qNameModule, stmt.getStatementArgument());
161 stmt.addToNs(ModuleIdentifierToModuleQName.class, moduleIdentifier, qNameModule);
162 stmt.addToNs(ImpPrefixToModuleIdentifier.class, modulePrefix, moduleIdentifier);
164 if (stmt.isEnabledSemanticVersioning()) {
165 addToSemVerModuleNamespace(stmt);
169 private void addToSemVerModuleNamespace(
170 final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
171 final String moduleName = stmt.getStatementArgument();
172 NavigableMap<SemVer, StmtContext<?, ?, ?>> modulesMap = stmt.getFromNamespace(
173 SemanticVersionModuleNamespace.class, moduleName);
174 if (modulesMap == null) {
175 modulesMap = new TreeMap<>();
177 SemVer moduleSemVer = stmt.getFromNamespace(SemanticVersionNamespace.class, stmt);
178 if(moduleSemVer == null) {
179 moduleSemVer = Module.DEFAULT_SEMANTIC_VERSION;
181 modulesMap.put(moduleSemVer, stmt);
182 stmt.addToNs(SemanticVersionModuleNamespace.class, moduleName, modulesMap);
186 public void onFullDefinitionDeclared(final Mutable<String, ModuleStatement,
187 EffectiveStatement<String, ModuleStatement>> stmt) {
188 super.onFullDefinitionDeclared(stmt);
189 SUBSTATEMENT_VALIDATOR.validate(stmt);