2 * Copyright (c) 2013 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.util;
10 import java.math.BigDecimal;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
15 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
16 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
17 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
18 import org.opendaylight.yangtools.yang.model.util.BaseConstraints;
21 * Holder object for holding YANG type constraints.
23 public final class TypeConstraints {
24 private final String moduleName;
25 private final int line;
26 private final List<List<RangeConstraint>> ranges = new ArrayList<List<RangeConstraint>>();
27 private final List<List<LengthConstraint>> lengths = new ArrayList<List<LengthConstraint>>();
28 private final List<List<PatternConstraint>> patterns = new ArrayList<List<PatternConstraint>>();
29 private final List<Integer> fractionDigits = new ArrayList<Integer>();
31 public TypeConstraints(final String moduleName, final int line) {
32 this.moduleName = moduleName;
36 List<List<RangeConstraint>> getAllRanges() {
40 public List<RangeConstraint> getRange() {
41 if (ranges.size() < 2) {
42 return Collections.emptyList();
45 final List<RangeConstraint> resolved = ranges.get(0);
46 RangeConstraint firstRange = resolved.get(0);
47 RangeConstraint lastRange = resolved.get(resolved.size() - 1);
48 Number min = firstRange.getMin();
49 Number max = lastRange.getMax();
51 if (!(min instanceof UnknownBoundaryNumber) && !(max instanceof UnknownBoundaryNumber)) {
52 if (ranges.size() > 1) {
53 validateRange(resolved);
58 if (firstRange.equals(lastRange)) {
59 if (min instanceof UnknownBoundaryNumber) {
60 min = resolveMinRange(min);
62 if (max instanceof UnknownBoundaryNumber) {
63 max = resolveMaxRange(max);
65 firstRange = BaseConstraints.rangeConstraint(min, max, firstRange.getDescription(),
66 firstRange.getReference());
67 resolved.set(0, firstRange);
68 lastRange = BaseConstraints.rangeConstraint(min, max, lastRange.getDescription(), lastRange.getReference());
69 resolved.set(resolved.size() - 1, lastRange);
71 if (min instanceof UnknownBoundaryNumber) {
72 min = resolveMinRange(min);
73 firstRange = BaseConstraints.rangeConstraint(min, firstRange.getMax(), firstRange.getDescription(),
74 firstRange.getReference());
75 resolved.set(0, firstRange);
77 if (max instanceof UnknownBoundaryNumber) {
78 max = resolveMaxRange(max);
79 lastRange = BaseConstraints.rangeConstraint(lastRange.getMin(), max, lastRange.getDescription(),
80 lastRange.getReference());
81 resolved.set(resolved.size() - 1, lastRange);
84 if (this.ranges.size() > 1) {
85 validateRange(resolved);
90 private Number resolveMinRange(Number min) {
92 while (min instanceof UnknownBoundaryNumber) {
93 final List<RangeConstraint> act = ranges.get(i);
94 min = act.get(0).getMin();
100 private Number resolveMaxRange(Number max) {
102 while (max instanceof UnknownBoundaryNumber) {
103 final List<RangeConstraint> act = ranges.get(i);
104 max = act.get(act.size() - 1).getMax();
110 public void addRanges(final List<RangeConstraint> ranges) {
111 if (ranges != null && !(ranges.isEmpty())) {
112 this.ranges.add(ranges);
116 public List<List<LengthConstraint>> getAllLengths() {
120 public List<LengthConstraint> getLength() {
121 if (lengths.size() < 2) {
122 return Collections.emptyList();
125 final List<LengthConstraint> resolved = lengths.get(0);
126 LengthConstraint firstLength = resolved.get(0);
127 LengthConstraint lastLength = resolved.get(resolved.size() - 1);
128 Number min = firstLength.getMin();
129 Number max = lastLength.getMax();
131 if (!(min instanceof UnknownBoundaryNumber) && !(max instanceof UnknownBoundaryNumber)) {
132 if (lengths.size() > 1) {
133 validateLength(resolved);
138 if (firstLength.equals(lastLength)) {
139 if (min instanceof UnknownBoundaryNumber) {
140 min = resolveMinLength(min);
142 if (max instanceof UnknownBoundaryNumber) {
143 max = resolveMaxLength(max);
145 firstLength = BaseConstraints.lengthConstraint(min, max, firstLength.getDescription(),
146 firstLength.getReference());
147 resolved.set(0, firstLength);
148 lastLength = BaseConstraints.lengthConstraint(min, max, lastLength.getDescription(),
149 lastLength.getReference());
150 resolved.set(resolved.size() - 1, lastLength);
152 if (min instanceof UnknownBoundaryNumber) {
153 min = resolveMinLength(min);
154 firstLength = BaseConstraints.lengthConstraint(min, firstLength.getMax(), firstLength.getDescription(),
155 firstLength.getReference());
156 resolved.set(0, firstLength);
158 if (max instanceof UnknownBoundaryNumber) {
159 max = resolveMaxLength(max);
160 lastLength = BaseConstraints.lengthConstraint(lastLength.getMin(), max, lastLength.getDescription(),
161 lastLength.getReference());
162 resolved.set(resolved.size() - 1, lastLength);
166 if (lengths.size() > 1) {
167 validateLength(resolved);
172 private Number resolveMinLength(Number min) {
174 while (min instanceof UnknownBoundaryNumber) {
175 final List<LengthConstraint> act = lengths.get(i);
176 min = act.get(0).getMin();
182 private Number resolveMaxLength(Number max) {
184 while (max instanceof UnknownBoundaryNumber) {
185 final List<LengthConstraint> act = lengths.get(i);
186 max = act.get(act.size() - 1).getMax();
192 public void addLengths(final List<LengthConstraint> lengths) {
193 if (lengths != null && !(lengths.isEmpty())) {
194 this.lengths.add(lengths);
198 public List<PatternConstraint> getPatterns() {
199 if(patterns.isEmpty()) {
200 return Collections.emptyList();
202 return patterns.get(0);
205 public void addPatterns(final List<PatternConstraint> patterns) {
206 this.patterns.add(patterns);
209 public Integer getFractionDigits() {
210 if (fractionDigits.isEmpty()) {
213 return fractionDigits.get(0);
216 public void addFractionDigits(final Integer fractionDigits) {
217 this.fractionDigits.add(fractionDigits);
220 public void validateConstraints() {
225 private void validateRange() {
226 if (ranges.size() < 2) {
229 List<RangeConstraint> typeRange = getRange();
231 for (RangeConstraint range : typeRange) {
232 if (range.getMin() instanceof UnknownBoundaryNumber || range.getMax() instanceof UnknownBoundaryNumber) {
233 throw new YangParseException(moduleName, line, "Unresolved range constraints");
235 final long min = range.getMin().longValue();
236 final long max = range.getMax().longValue();
238 List<RangeConstraint> parentRanges = ranges.get(1);
239 boolean check = false;
240 for (RangeConstraint r : parentRanges) {
241 Number parentMinNumber = r.getMin();
242 if (parentMinNumber instanceof UnknownBoundaryNumber) {
243 parentMinNumber = resolveMinRange(parentMinNumber);
245 long parentMin = parentMinNumber.longValue();
247 Number parentMaxNumber = r.getMax();
248 if (parentMaxNumber instanceof UnknownBoundaryNumber) {
249 parentMaxNumber = resolveMaxRange(parentMaxNumber);
251 long parentMax = parentMaxNumber.longValue();
253 if (parentMin <= min && parentMax >= max) {
259 throw new YangParseException(moduleName, line, "Invalid range constraint: <" + min + ", " + max
260 + "> (parent: " + parentRanges + ").");
265 private void validateRange(List<RangeConstraint> typeRange) {
266 if (ranges.size() < 2) {
270 for (RangeConstraint range : typeRange) {
271 if (range.getMin() instanceof UnknownBoundaryNumber || range.getMax() instanceof UnknownBoundaryNumber) {
272 throw new YangParseException(moduleName, line, "Unresolved range constraints");
274 final BigDecimal min = new BigDecimal(range.getMin().toString());
275 final BigDecimal max = new BigDecimal(range.getMax().toString());
277 List<RangeConstraint> parentRanges = ranges.get(1);
278 boolean check = false;
279 for (RangeConstraint r : parentRanges) {
280 Number parentMinNumber = r.getMin();
281 if (parentMinNumber instanceof UnknownBoundaryNumber) {
282 parentMinNumber = resolveMinRange(parentMinNumber);
284 BigDecimal parentMin = new BigDecimal(parentMinNumber.toString());
286 Number parentMaxNumber = r.getMax();
287 if (parentMaxNumber instanceof UnknownBoundaryNumber) {
288 parentMaxNumber = resolveMaxRange(parentMaxNumber);
290 BigDecimal parentMax = new BigDecimal(parentMaxNumber.toString());
292 if(parentMin.compareTo(min) <=0 && parentMax.compareTo(max) >= 0) {
298 throw new YangParseException(moduleName, line, "Invalid range constraint: <" + min + ", " + max
299 + "> (parent: " + parentRanges + ").");
304 private void validateLength() {
305 if (lengths.size() < 2) {
308 List<LengthConstraint> typeLength = getLength();
310 for (LengthConstraint length : typeLength) {
311 if (length.getMin() instanceof UnknownBoundaryNumber || length.getMax() instanceof UnknownBoundaryNumber) {
312 throw new YangParseException(moduleName, line, "Unresolved length constraints");
314 final long min = length.getMin().longValue();
315 final long max = length.getMax().longValue();
317 List<LengthConstraint> parentLengths = lengths.get(1);
318 boolean check = false;
319 for (LengthConstraint lc : parentLengths) {
320 Number parentMinNumber = lc.getMin();
321 if (parentMinNumber instanceof UnknownBoundaryNumber) {
322 parentMinNumber = resolveMinLength(parentMinNumber);
324 long parentMin = parentMinNumber.longValue();
326 Number parentMaxNumber = lc.getMax();
327 if (parentMaxNumber instanceof UnknownBoundaryNumber) {
328 parentMaxNumber = resolveMaxLength(parentMaxNumber);
330 long parentMax = parentMaxNumber.longValue();
332 if (parentMin <= min && parentMax >= max) {
338 throw new YangParseException(moduleName, line, "Invalid length constraint: <" + min + ", " + max
339 + "> (parent: " + parentLengths + ").");
344 private void validateLength(List<LengthConstraint> typeLength) {
345 if (lengths.size() < 2) {
349 for (LengthConstraint length : typeLength) {
350 if (length.getMin() instanceof UnknownBoundaryNumber || length.getMax() instanceof UnknownBoundaryNumber) {
351 throw new YangParseException(moduleName, line, "Unresolved length constraints");
353 final long min = length.getMin().longValue();
354 final long max = length.getMax().longValue();
356 List<LengthConstraint> parentLengths = lengths.get(1);
357 boolean check = false;
358 for (LengthConstraint lc : parentLengths) {
359 Number parentMinNumber = lc.getMin();
360 if (parentMinNumber instanceof UnknownBoundaryNumber) {
361 parentMinNumber = resolveMinLength(parentMinNumber);
363 long parentMin = parentMinNumber.longValue();
365 Number parentMaxNumber = lc.getMax();
366 if (parentMaxNumber instanceof UnknownBoundaryNumber) {
367 parentMaxNumber = resolveMaxLength(parentMaxNumber);
369 long parentMax = parentMaxNumber.longValue();
371 if (parentMin <= min && parentMax >= max) {
377 throw new YangParseException(moduleName, line, "Invalid length constraint: <" + min + ", " + max
378 + "> (parent: " + parentLengths + ").");