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.effective;
10 import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
12 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
13 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.Decimal64SpecificationEffectiveStatementImpl;
14 import java.util.ArrayList;
15 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.LengthEffectiveStatementImpl;
16 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.PatternEffectiveStatementImpl;
17 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.RangeEffectiveStatementImpl;
18 import com.google.common.base.Optional;
19 import com.google.common.collect.ImmutableList;
20 import java.util.Collections;
21 import java.util.List;
22 import org.opendaylight.yangtools.yang.common.QName;
23 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
24 import org.opendaylight.yangtools.yang.model.api.Status;
25 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
26 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
27 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
28 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
29 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
30 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
31 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
32 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
33 import org.opendaylight.yangtools.yang.model.util.ExtendedType.Builder;
34 import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace;
35 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
36 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils;
37 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
38 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.type.TypeDefinitionEffectiveBuilder;
40 public class TypeDefEffectiveStatementImpl extends
41 EffectiveStatementBase<QName, TypedefStatement> implements
42 TypeDefinition<TypeDefinition<?>>, TypeDefinitionEffectiveBuilder {
44 private final QName qName;
45 private final SchemaPath path;
47 private final TypeDefinition<?> baseType;
49 private String defaultValue;
52 private String description;
53 private String reference;
55 private Status status;
57 private final List<RangeConstraint> ranges;
58 private final List<LengthConstraint> lengths;
59 private final List<PatternConstraint> patterns;
60 private final Integer fractionDigits;
62 private ExtendedType extendedType = null;
64 public TypeDefEffectiveStatementImpl(
65 StmtContext<QName, TypedefStatement, ?> ctx) {
68 qName = ctx.getStatementArgument();
69 path = Utils.getSchemaPath(ctx);
70 baseType = parseBaseTypeFromCtx(ctx);
72 EffectiveStatementBase<?, ?> typeEffectiveStmt = firstSubstatementOfType(
73 TypeDefinition.class, EffectiveStatementBase.class);
75 ranges = initRanges(typeEffectiveStmt);
76 lengths = initLengths(typeEffectiveStmt);
77 patterns = initPatterns(typeEffectiveStmt);
79 //due to compatibility problems with original yang parser
80 //:FIXME try to find out better solution
81 if (typeEffectiveStmt.argument().equals(TypeUtils.DECIMAL64)
82 && ranges.isEmpty()) {
83 fractionDigits = null;
85 fractionDigits = initFractionDigits(typeEffectiveStmt);
88 for (final EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
89 if (effectiveStatement instanceof DefaultEffectiveStatementImpl) {
90 defaultValue = ((DefaultEffectiveStatementImpl) effectiveStatement)
93 if (effectiveStatement instanceof UnitsEffectiveStatementImpl) {
94 units = ((UnitsEffectiveStatementImpl) effectiveStatement)
97 if (effectiveStatement instanceof DescriptionEffectiveStatementImpl) {
98 description = ((DescriptionEffectiveStatementImpl) effectiveStatement)
101 if (effectiveStatement instanceof ReferenceEffectiveStatementImpl) {
102 reference = ((ReferenceEffectiveStatementImpl) effectiveStatement)
105 if (effectiveStatement instanceof StatusEffectiveStatementImpl) {
106 status = ((StatusEffectiveStatementImpl) effectiveStatement)
112 private TypeDefinition<?> parseBaseTypeFromCtx(
113 final StmtContext<QName, TypedefStatement, ?> ctx) {
115 TypeDefinition<?> baseType;
117 QName baseTypeQName = Utils.qNameFromArgument(ctx, StmtContextUtils
118 .firstAttributeOf(ctx.declaredSubstatements(),
119 TypeStatement.class));
121 if (TypeUtils.isYangBuiltInTypeString(baseTypeQName.getLocalName())) {
122 baseType = TypeUtils.getYangPrimitiveTypeFromString(baseTypeQName
124 if (baseType == null) {
125 baseType = firstSubstatementOfType(TypeDefinition.class);
127 //due to compatibility problems with original yang parser
128 //:FIXME try to find out better solution
129 if(baseType instanceof Decimal64SpecificationEffectiveStatementImpl) {
130 Decimal64SpecificationEffectiveStatementImpl decimal64 = (Decimal64SpecificationEffectiveStatementImpl) baseType;
131 if(decimal64.isExtended()) {
132 baseType = decimal64.getBaseType();
137 StmtContext<?, TypedefStatement, EffectiveStatement<QName, TypedefStatement>> baseTypeCtx = ctx
138 .getParentContext().getFromNamespace(TypeNamespace.class,
140 baseType = (TypeDefEffectiveStatementImpl) baseTypeCtx
147 protected Integer initFractionDigits(
148 EffectiveStatementBase<?, ?> typeEffectiveStmt) {
149 final FractionDigitsEffectiveStatementImpl fractionDigitsEffStmt = typeEffectiveStmt
150 .firstEffective(FractionDigitsEffectiveStatementImpl.class);
151 return fractionDigitsEffStmt != null ? fractionDigitsEffStmt.argument()
155 protected List<RangeConstraint> initRanges(
156 EffectiveStatementBase<?, ?> typeEffectiveStmt) {
157 final RangeEffectiveStatementImpl rangeConstraints = typeEffectiveStmt
158 .firstEffective(RangeEffectiveStatementImpl.class);
159 return rangeConstraints != null ? rangeConstraints.argument()
160 : Collections.<RangeConstraint> emptyList();
163 protected List<LengthConstraint> initLengths(
164 EffectiveStatementBase<?, ?> typeEffectiveStmt) {
165 final LengthEffectiveStatementImpl lengthConstraints = typeEffectiveStmt
166 .firstEffective(LengthEffectiveStatementImpl.class);
167 return lengthConstraints != null ? lengthConstraints.argument()
168 : Collections.<LengthConstraint> emptyList();
171 protected List<PatternConstraint> initPatterns(
172 EffectiveStatementBase<?, ?> typeEffectiveStmt) {
173 final List<PatternConstraint> patternConstraints = new ArrayList<>();
175 for (final EffectiveStatement<?, ?> effectiveStatement : typeEffectiveStmt
176 .effectiveSubstatements()) {
177 if (effectiveStatement instanceof PatternEffectiveStatementImpl) {
178 final PatternConstraint pattern = ((PatternEffectiveStatementImpl) effectiveStatement)
181 if (pattern != null) {
182 patternConstraints.add(pattern);
187 return !patternConstraints.isEmpty() ? ImmutableList
188 .copyOf(patternConstraints) : Collections
189 .<PatternConstraint> emptyList();
193 public TypeDefinition<?> getBaseType() {
198 public String getUnits() {
203 public Object getDefaultValue() {
208 public QName getQName() {
213 public SchemaPath getPath() {
218 public List<UnknownSchemaNode> getUnknownSchemaNodes() {
219 return Collections.emptyList();
223 public String getDescription() {
228 public String getReference() {
233 public Status getStatus() {
237 public List<RangeConstraint> getRangeConstraints() {
241 public List<LengthConstraint> getLengthConstraints() {
245 public List<PatternConstraint> getPatternConstraints() {
249 public Integer getFractionDigits() {
250 return fractionDigits;
254 public ExtendedType buildType() {
256 if (extendedType != null) {
260 Builder extendedTypeBuilder;
261 if (baseType instanceof TypeDefinitionEffectiveBuilder) {
262 TypeDefinitionEffectiveBuilder typeDefBaseType = (TypeDefinitionEffectiveBuilder) baseType;
263 extendedTypeBuilder = ExtendedType.builder(qName,
264 typeDefBaseType.buildType(),
265 Optional.fromNullable(description),
266 Optional.fromNullable(reference), path);
268 extendedTypeBuilder = ExtendedType.builder(qName, baseType,
269 Optional.fromNullable(description),
270 Optional.fromNullable(reference), path);
273 extendedTypeBuilder.defaultValue(defaultValue);
274 extendedTypeBuilder.units(units);
276 extendedTypeBuilder.fractionDigits(fractionDigits);
277 extendedTypeBuilder.ranges(ranges);
278 extendedTypeBuilder.lengths(lengths);
279 extendedTypeBuilder.patterns(patterns);
281 extendedType = extendedTypeBuilder.build();