Reuse cardinality constants
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / ModuleStatementSupport.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
9
10 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
11
12 import com.google.common.base.Optional;
13 import java.net.URI;
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;
49
50 public class ModuleStatementSupport extends
51         AbstractStatementSupport<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> {
52     private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(Rfc6020Mapping
53             .MODULE)
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)
81             .build();
82
83     public ModuleStatementSupport() {
84         super(Rfc6020Mapping.MODULE);
85     }
86
87     @Override
88     public String parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
89         return value;
90     }
91
92     @Override
93     public ModuleStatement createDeclared(final StmtContext<String, ModuleStatement, ?> ctx) {
94         return new ModuleStatementImpl(ctx);
95     }
96
97     @Override
98     public EffectiveStatement<String, ModuleStatement> createEffective(
99             final StmtContext<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> ctx) {
100         return new ModuleEffectiveStatementImpl(ctx);
101     }
102
103     @Override
104     public void onPreLinkageDeclared(final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
105         final String moduleName = stmt.getStatementArgument();
106
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);
112
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);
117
118         stmt.addContext(PreLinkageModuleNamespace.class, moduleName, stmt);
119
120         Optional<Date> revisionDate = Optional.fromNullable(Utils.getLatestRevision(stmt.declaredSubstatements
121                 ()));
122         if (!revisionDate.isPresent()) {
123             revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
124         }
125
126         QNameModule qNameModule = QNameModule.create(moduleNs, revisionDate.orNull()).intern();
127
128         stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule);
129     };
130
131     @Override
132     public void onLinkageDeclared(final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
133
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());
138
139         Optional<Date> revisionDate = Optional.fromNullable(Utils.getLatestRevision(stmt.declaredSubstatements()));
140         if (!revisionDate.isPresent()) {
141             revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
142         }
143
144         QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orNull()).intern();
145         ModuleIdentifier moduleIdentifier = new ModuleIdentifierImpl(stmt.getStatementArgument(),
146                 Optional.absent(), revisionDate);
147
148         stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt);
149         stmt.addContext(ModuleNamespaceForBelongsTo.class, moduleIdentifier.getName(), stmt);
150         stmt.addContext(NamespaceToModule.class, qNameModule, stmt);
151
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());
155
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);
163
164         if (stmt.isEnabledSemanticVersioning()) {
165             addToSemVerModuleNamespace(stmt);
166         }
167     }
168
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<>();
176         }
177         SemVer moduleSemVer = stmt.getFromNamespace(SemanticVersionNamespace.class, stmt);
178         if(moduleSemVer == null) {
179             moduleSemVer = Module.DEFAULT_SEMANTIC_VERSION;
180         }
181         modulesMap.put(moduleSemVer, stmt);
182         stmt.addToNs(SemanticVersionModuleNamespace.class, moduleName, modulesMap);
183     }
184
185     @Override
186     public void onFullDefinitionDeclared(final Mutable<String, ModuleStatement,
187             EffectiveStatement<String, ModuleStatement>> stmt) {
188         super.onFullDefinitionDeclared(stmt);
189         SUBSTATEMENT_VALIDATOR.validate(stmt);
190     }
191 }