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.SubstatementValidator.MAX;
11 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
13 import com.google.common.base.Optional;
15 import java.util.Date;
16 import java.util.NavigableMap;
17 import java.util.TreeMap;
18 import org.opendaylight.yangtools.concepts.SemVer;
19 import org.opendaylight.yangtools.yang.common.QNameModule;
20 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
21 import org.opendaylight.yangtools.yang.model.api.Module;
22 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
23 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
24 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
26 import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
27 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
28 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl;
29 import org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace;
30 import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
31 import org.opendaylight.yangtools.yang.parser.spi.PreLinkageModuleNamespace;
32 import org.opendaylight.yangtools.yang.parser.spi.SubstatementValidator;
33 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
34 import org.opendaylight.yangtools.yang.parser.spi.meta.SemanticVersionModuleNamespace;
35 import org.opendaylight.yangtools.yang.parser.spi.meta.SemanticVersionNamespace;
36 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
37 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
38 import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier;
39 import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToNamespace;
40 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleIdentifier;
41 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
42 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleIdentifierToModuleQName;
43 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
44 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToNamespace;
45 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNamespaceForBelongsTo;
46 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
47 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
48 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
49 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ModuleEffectiveStatementImpl;
51 public class ModuleStatementSupport extends
52 AbstractStatementSupport<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> {
53 private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(Rfc6020Mapping
55 .add(Rfc6020Mapping.ANYXML, 0, MAX)
56 .add(Rfc6020Mapping.AUGMENT, 0, MAX)
57 .add(Rfc6020Mapping.CHOICE, 0, MAX)
58 .add(Rfc6020Mapping.CONTACT, 0, 1)
59 .add(Rfc6020Mapping.CONTAINER, 0, MAX)
60 .add(Rfc6020Mapping.DESCRIPTION, 0, 1)
61 .add(Rfc6020Mapping.DEVIATION, 0, MAX)
62 .add(Rfc6020Mapping.EXTENSION, 0, MAX)
63 .add(Rfc6020Mapping.FEATURE, 0, MAX)
64 .add(Rfc6020Mapping.GROUPING, 0, MAX)
65 .add(Rfc6020Mapping.IDENTITY, 0, MAX)
66 .add(Rfc6020Mapping.IMPORT, 0, MAX)
67 .add(Rfc6020Mapping.INCLUDE, 0, MAX)
68 .add(Rfc6020Mapping.LEAF, 0, MAX)
69 .add(Rfc6020Mapping.LEAF_LIST, 0, MAX)
70 .add(Rfc6020Mapping.LIST, 0, MAX)
71 .add(Rfc6020Mapping.NAMESPACE, 1, 1)
72 .add(Rfc6020Mapping.NOTIFICATION, 0, MAX)
73 .add(Rfc6020Mapping.ORGANIZATION, 0, 1)
74 .add(Rfc6020Mapping.PREFIX, 1, 1)
75 .add(Rfc6020Mapping.REFERENCE, 0, 1)
76 .add(Rfc6020Mapping.REVISION, 0, MAX)
77 .add(Rfc6020Mapping.RPC, 0, MAX)
78 .add(Rfc6020Mapping.TYPEDEF, 0, MAX)
79 .add(Rfc6020Mapping.USES, 0, MAX)
80 .add(Rfc6020Mapping.YANG_VERSION, 0, 1)
81 .add(SupportedExtensionsMapping.SEMANTIC_VERSION, 0, 1)
84 public ModuleStatementSupport() {
85 super(Rfc6020Mapping.MODULE);
89 public String parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
94 public ModuleStatement createDeclared(final StmtContext<String, ModuleStatement, ?> ctx) {
95 return new ModuleStatementImpl(ctx);
99 public EffectiveStatement<String, ModuleStatement> createEffective(
100 final StmtContext<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> ctx) {
101 return new ModuleEffectiveStatementImpl(ctx);
105 public void onPreLinkageDeclared(Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
106 final String moduleName = stmt.getStatementArgument();
108 final URI moduleNs = firstAttributeOf(stmt.declaredSubstatements(),
109 NamespaceStatement.class);
110 SourceException.throwIfNull(moduleNs, stmt.getStatementSourceReference(),
111 "Namespace of the module [%s] is missing", stmt.getStatementArgument());
112 stmt.addToNs(ModuleNameToNamespace.class, moduleName, moduleNs);
114 final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class);
115 SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(),
116 "Prefix of the module [%s] is missing", stmt.getStatementArgument());
117 stmt.addToNs(ImpPrefixToNamespace.class, modulePrefix, moduleNs);
119 stmt.addContext(PreLinkageModuleNamespace.class, moduleName, stmt);
121 Optional<Date> revisionDate = Optional.fromNullable(Utils.getLatestRevision(stmt.declaredSubstatements
123 if (!revisionDate.isPresent()) {
124 revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
127 QNameModule qNameModule = QNameModule.create(moduleNs, revisionDate.orNull()).intern();
129 stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule);
133 public void onLinkageDeclared(final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
135 Optional<URI> moduleNs = Optional.fromNullable(firstAttributeOf(stmt.declaredSubstatements(),
136 NamespaceStatement.class));
137 SourceException.throwIf(!moduleNs.isPresent(), stmt.getStatementSourceReference(),
138 "Namespace of the module [%s] is missing", stmt.getStatementArgument());
140 Optional<Date> revisionDate = Optional.fromNullable(Utils.getLatestRevision(stmt.declaredSubstatements()));
141 if (!revisionDate.isPresent()) {
142 revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
145 QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orNull()).intern();
146 ModuleIdentifier moduleIdentifier = new ModuleIdentifierImpl(stmt.getStatementArgument(),
147 Optional.absent(), revisionDate);
149 stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt);
150 stmt.addContext(ModuleNamespaceForBelongsTo.class, moduleIdentifier.getName(), stmt);
151 stmt.addContext(NamespaceToModule.class, qNameModule, stmt);
153 final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class);
154 SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(),
155 "Prefix of the module [%s] is missing", stmt.getStatementArgument());
157 stmt.addToNs(PrefixToModule.class, modulePrefix, qNameModule);
158 stmt.addToNs(ModuleNameToModuleQName.class, stmt.getStatementArgument(), qNameModule);
159 stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule); // tu
160 stmt.addToNs(ModuleCtxToModuleIdentifier.class, stmt, moduleIdentifier);
161 stmt.addToNs(ModuleQNameToModuleName.class, qNameModule, stmt.getStatementArgument());
162 stmt.addToNs(ModuleIdentifierToModuleQName.class, moduleIdentifier, qNameModule);
163 stmt.addToNs(ImpPrefixToModuleIdentifier.class, modulePrefix, moduleIdentifier);
165 if (stmt.isEnabledSemanticVersioning()) {
166 addToSemVerModuleNamespace(stmt);
170 private void addToSemVerModuleNamespace(
171 final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
172 final String moduleName = stmt.getStatementArgument();
173 NavigableMap<SemVer, StmtContext<?, ?, ?>> modulesMap = stmt.getFromNamespace(
174 SemanticVersionModuleNamespace.class, moduleName);
175 if (modulesMap == null) {
176 modulesMap = new TreeMap<SemVer, StmtContext<?, ?, ?>>();
178 SemVer moduleSemVer = stmt.getFromNamespace(SemanticVersionNamespace.class, stmt);
179 if(moduleSemVer == null) {
180 moduleSemVer = Module.DEFAULT_SEMANTIC_VERSION;
182 modulesMap.put(moduleSemVer, stmt);
183 stmt.addToNs(SemanticVersionModuleNamespace.class, moduleName, modulesMap);
187 public void onFullDefinitionDeclared(final Mutable<String, ModuleStatement,
188 EffectiveStatement<String, ModuleStatement>> stmt) {
189 super.onFullDefinitionDeclared(stmt);
190 SUBSTATEMENT_VALIDATOR.validate(stmt);