Introduce formatting methods for SourceException
[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.SubstatementValidator.MAX;
11 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
12 import com.google.common.base.Optional;
13 import java.net.URI;
14 import java.util.Date;
15 import org.opendaylight.yangtools.yang.common.QNameModule;
16 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
17 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
18 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
19 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
20 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
21 import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
22 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
23 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl;
24 import org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace;
25 import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
26 import org.opendaylight.yangtools.yang.parser.spi.SubstatementValidator;
27 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
29 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
30 import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier;
31 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
32 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleIdentifierToModuleQName;
33 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
34 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNamespaceForBelongsTo;
35 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
36 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
37 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
38 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ModuleEffectiveStatementImpl;
39
40 public class ModuleStatementSupport extends
41         AbstractStatementSupport<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> {
42     private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(Rfc6020Mapping
43             .MODULE)
44             .add(Rfc6020Mapping.ANYXML, 0, MAX)
45             .add(Rfc6020Mapping.AUGMENT, 0, MAX)
46             .add(Rfc6020Mapping.CHOICE, 0, MAX)
47             .add(Rfc6020Mapping.CONTACT, 0, 1)
48             .add(Rfc6020Mapping.CONTAINER, 0, MAX)
49             .add(Rfc6020Mapping.DESCRIPTION, 0, 1)
50             .add(Rfc6020Mapping.DEVIATION, 0, MAX)
51             .add(Rfc6020Mapping.EXTENSION, 0, MAX)
52             .add(Rfc6020Mapping.FEATURE, 0, MAX)
53             .add(Rfc6020Mapping.GROUPING, 0, MAX)
54             .add(Rfc6020Mapping.IDENTITY, 0, MAX)
55             .add(Rfc6020Mapping.IMPORT, 0, MAX)
56             .add(Rfc6020Mapping.INCLUDE, 0, MAX)
57             .add(Rfc6020Mapping.LEAF, 0, MAX)
58             .add(Rfc6020Mapping.LEAF_LIST, 0, MAX)
59             .add(Rfc6020Mapping.LIST, 0, MAX)
60             .add(Rfc6020Mapping.NAMESPACE, 1, 1)
61             .add(Rfc6020Mapping.NOTIFICATION, 0, MAX)
62             .add(Rfc6020Mapping.ORGANIZATION, 0, 1)
63             .add(Rfc6020Mapping.PREFIX, 1, 1)
64             .add(Rfc6020Mapping.REFERENCE, 0, 1)
65             .add(Rfc6020Mapping.REVISION, 0, MAX)
66             .add(Rfc6020Mapping.RPC, 0, MAX)
67             .add(Rfc6020Mapping.TYPEDEF, 0, MAX)
68             .add(Rfc6020Mapping.USES, 0, MAX)
69             .add(Rfc6020Mapping.YANG_VERSION, 0, 1)
70             .build();
71
72     public ModuleStatementSupport() {
73         super(Rfc6020Mapping.MODULE);
74     }
75
76     @Override
77     public String parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
78         return value;
79     }
80
81     @Override
82     public ModuleStatement createDeclared(final StmtContext<String, ModuleStatement, ?> ctx) {
83         return new ModuleStatementImpl(ctx);
84     }
85
86     @Override
87     public EffectiveStatement<String, ModuleStatement> createEffective(
88             final StmtContext<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> ctx) {
89         return new ModuleEffectiveStatementImpl(ctx);
90     }
91
92     @Override
93     public void onLinkageDeclared(final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt) {
94
95         Optional<URI> moduleNs = Optional.fromNullable(firstAttributeOf(stmt.declaredSubstatements(),
96                 NamespaceStatement.class));
97         SourceException.throwIf(!moduleNs.isPresent(), stmt.getStatementSourceReference(),
98             "Namespace of the module [%s] is missing", stmt.getStatementArgument());
99
100         Optional<Date> revisionDate = Optional.fromNullable(Utils.getLatestRevision(stmt.declaredSubstatements()));
101         if (!revisionDate.isPresent()) {
102             revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
103         }
104
105         QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orNull()).intern();
106         ModuleIdentifier moduleIdentifier = new ModuleIdentifierImpl(stmt.getStatementArgument(),
107                 Optional.<URI> absent(), revisionDate);
108
109         stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt);
110         stmt.addContext(ModuleNamespaceForBelongsTo.class, moduleIdentifier.getName(), stmt);
111         stmt.addContext(NamespaceToModule.class, qNameModule, stmt);
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
117         stmt.addToNs(PrefixToModule.class, modulePrefix, qNameModule);
118         stmt.addToNs(ModuleNameToModuleQName.class, stmt.getStatementArgument(), qNameModule);
119         stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule);
120         stmt.addToNs(ModuleQNameToModuleName.class, qNameModule, stmt.getStatementArgument());
121         stmt.addToNs(ModuleIdentifierToModuleQName.class, moduleIdentifier, qNameModule);
122         stmt.addToNs(ImpPrefixToModuleIdentifier.class, modulePrefix, moduleIdentifier);
123     }
124
125     @Override
126     public void onFullDefinitionDeclared(final Mutable<String, ModuleStatement,
127             EffectiveStatement<String, ModuleStatement>> stmt) throws SourceException {
128         super.onFullDefinitionDeclared(stmt);
129         SUBSTATEMENT_VALIDATOR.validate(stmt);
130     }
131 }