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.util.ArrayList;
11 import java.util.Collections;
12 import java.util.List;
14 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
15 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
16 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
17 import org.opendaylight.yangtools.yang.model.util.BaseConstraints;
20 * Holder object for holding YANG type constraints.
22 public final class TypeConstraints {
23 private final String moduleName;
24 private final int line;
25 private final List<List<RangeConstraint>> ranges = new ArrayList<List<RangeConstraint>>();
26 private final List<List<LengthConstraint>> lengths = new ArrayList<List<LengthConstraint>>();
27 private final List<List<PatternConstraint>> patterns = new ArrayList<List<PatternConstraint>>();
28 private final List<Integer> fractionDigits = new ArrayList<Integer>();
30 public TypeConstraints(final String moduleName, final int line) {
31 this.moduleName = moduleName;
35 List<List<RangeConstraint>> getAllRanges() {
39 public List<RangeConstraint> getRange() {
40 if (ranges.size() < 2) {
41 return Collections.emptyList();
44 final List<RangeConstraint> resolved = ranges.get(0);
45 RangeConstraint firstRange = resolved.get(0);
46 RangeConstraint lastRange = resolved.get(resolved.size() - 1);
47 Number min = firstRange.getMin();
48 Number max = lastRange.getMax();
50 if (!(min instanceof UnknownBoundaryNumber) && !(max instanceof UnknownBoundaryNumber)) {
51 if (ranges.size() > 1) {
52 validateRange(resolved);
57 if (firstRange.equals(lastRange)) {
58 if (min instanceof UnknownBoundaryNumber) {
59 min = resolveMinRange(min);
61 if (max instanceof UnknownBoundaryNumber) {
62 max = resolveMaxRange(max);
64 firstRange = BaseConstraints.rangeConstraint(min, max, firstRange.getDescription(),
65 firstRange.getReference());
66 resolved.set(0, firstRange);
67 lastRange = BaseConstraints.rangeConstraint(min, max, lastRange.getDescription(), lastRange.getReference());
68 resolved.set(resolved.size() - 1, lastRange);
70 if (min instanceof UnknownBoundaryNumber) {
71 min = resolveMinRange(min);
72 firstRange = BaseConstraints.rangeConstraint(min, firstRange.getMax(), firstRange.getDescription(),
73 firstRange.getReference());
74 resolved.set(0, firstRange);
76 if (max instanceof UnknownBoundaryNumber) {
77 max = resolveMaxRange(max);
78 lastRange = BaseConstraints.rangeConstraint(lastRange.getMin(), max, lastRange.getDescription(),
79 lastRange.getReference());
80 resolved.set(resolved.size() - 1, lastRange);
83 if (this.ranges.size() > 1) {
84 validateRange(resolved);
89 private Number resolveMinRange(Number min) {
91 while (min instanceof UnknownBoundaryNumber) {
92 final List<RangeConstraint> act = ranges.get(i);
93 min = act.get(0).getMin();
99 private Number resolveMaxRange(Number max) {
101 while (max instanceof UnknownBoundaryNumber) {
102 final List<RangeConstraint> act = ranges.get(i);
103 max = act.get(act.size() - 1).getMax();
109 public void addRanges(final List<RangeConstraint> ranges) {
110 if (ranges != null && !(ranges.isEmpty())) {
111 this.ranges.add(ranges);
115 public List<List<LengthConstraint>> getAllLengths() {
119 public List<LengthConstraint> getLength() {
120 if (lengths.size() < 2) {
121 return Collections.emptyList();
124 final List<LengthConstraint> resolved = lengths.get(0);
125 LengthConstraint firstLength = resolved.get(0);
126 LengthConstraint lastLength = resolved.get(resolved.size() - 1);
127 Number min = firstLength.getMin();
128 Number max = lastLength.getMax();
130 if (!(min instanceof UnknownBoundaryNumber) && !(max instanceof UnknownBoundaryNumber)) {
131 if (lengths.size() > 1) {
132 validateLength(resolved);
137 if (firstLength.equals(lastLength)) {
138 if (min instanceof UnknownBoundaryNumber) {
139 min = resolveMinLength(min);
141 if (max instanceof UnknownBoundaryNumber) {
142 max = resolveMaxLength(max);
144 firstLength = BaseConstraints.lengthConstraint(min, max, firstLength.getDescription(),
145 firstLength.getReference());
146 resolved.set(0, firstLength);
147 lastLength = BaseConstraints.lengthConstraint(min, max, lastLength.getDescription(),
148 lastLength.getReference());
149 resolved.set(resolved.size() - 1, lastLength);
151 if (min instanceof UnknownBoundaryNumber) {
152 min = resolveMinLength(min);
153 firstLength = BaseConstraints.lengthConstraint(min, firstLength.getMax(), firstLength.getDescription(),
154 firstLength.getReference());
155 resolved.set(0, firstLength);
157 if (max instanceof UnknownBoundaryNumber) {
158 max = resolveMaxLength(max);
159 lastLength = BaseConstraints.lengthConstraint(lastLength.getMin(), max, lastLength.getDescription(),
160 lastLength.getReference());
161 resolved.set(resolved.size() - 1, lastLength);
165 if (lengths.size() > 1) {
166 validateLength(resolved);
171 private Number resolveMinLength(Number min) {
173 while (min instanceof UnknownBoundaryNumber) {
174 final List<LengthConstraint> act = lengths.get(i);
175 min = act.get(0).getMin();
181 private Number resolveMaxLength(Number max) {
183 while (max instanceof UnknownBoundaryNumber) {
184 final List<LengthConstraint> act = lengths.get(i);
185 max = act.get(act.size() - 1).getMax();
191 public void addLengths(final List<LengthConstraint> lengths) {
192 if (lengths != null && !(lengths.isEmpty())) {
193 this.lengths.add(lengths);
197 public List<PatternConstraint> getPatterns() {
198 if(patterns.isEmpty()) {
199 return Collections.emptyList();
201 return patterns.get(0);
204 public void addPatterns(final List<PatternConstraint> patterns) {
205 this.patterns.add(patterns);
208 public Integer getFractionDigits() {
209 if (fractionDigits.isEmpty()) {
212 return fractionDigits.get(0);
215 public void addFractionDigits(final Integer fractionDigits) {
216 this.fractionDigits.add(fractionDigits);
219 public void validateConstraints() {
224 private void validateRange() {
225 if (ranges.size() < 2) {
228 List<RangeConstraint> typeRange = getRange();
230 for (RangeConstraint range : typeRange) {
231 if (range.getMin() instanceof UnknownBoundaryNumber || range.getMax() instanceof UnknownBoundaryNumber) {
232 throw new YangParseException(moduleName, line, "Unresolved range constraints");
234 final long min = range.getMin().longValue();
235 final long max = range.getMax().longValue();
237 List<RangeConstraint> parentRanges = ranges.get(1);
238 boolean check = false;
239 for (RangeConstraint r : parentRanges) {
240 Number parentMinNumber = r.getMin();
241 if (parentMinNumber instanceof UnknownBoundaryNumber) {
242 parentMinNumber = resolveMinRange(parentMinNumber);
244 long parentMin = parentMinNumber.longValue();
246 Number parentMaxNumber = r.getMax();
247 if (parentMaxNumber instanceof UnknownBoundaryNumber) {
248 parentMaxNumber = resolveMaxRange(parentMaxNumber);
250 long parentMax = parentMaxNumber.longValue();
252 if (parentMin <= min && parentMax >= max) {
258 throw new YangParseException(moduleName, line, "Invalid range constraint: <" + min + ", " + max
259 + "> (parent: " + parentRanges + ").");
264 private void validateRange(List<RangeConstraint> typeRange) {
265 if (ranges.size() < 2) {
269 for (RangeConstraint range : typeRange) {
270 if (range.getMin() instanceof UnknownBoundaryNumber || range.getMax() instanceof UnknownBoundaryNumber) {
271 throw new YangParseException(moduleName, line, "Unresolved range constraints");
273 final long min = range.getMin().longValue();
274 final long max = range.getMax().longValue();
276 List<RangeConstraint> parentRanges = ranges.get(1);
277 boolean check = false;
278 for (RangeConstraint r : parentRanges) {
279 Number parentMinNumber = r.getMin();
280 if (parentMinNumber instanceof UnknownBoundaryNumber) {
281 parentMinNumber = resolveMinRange(parentMinNumber);
283 long parentMin = parentMinNumber.longValue();
285 Number parentMaxNumber = r.getMax();
286 if (parentMaxNumber instanceof UnknownBoundaryNumber) {
287 parentMaxNumber = resolveMaxRange(parentMaxNumber);
289 long parentMax = parentMaxNumber.longValue();
291 if (parentMin <= min && parentMax >= max) {
297 throw new YangParseException(moduleName, line, "Invalid range constraint: <" + min + ", " + max
298 + "> (parent: " + parentRanges + ").");
303 private void validateLength() {
304 if (lengths.size() < 2) {
307 List<LengthConstraint> typeLength = getLength();
309 for (LengthConstraint length : typeLength) {
310 if (length.getMin() instanceof UnknownBoundaryNumber || length.getMax() instanceof UnknownBoundaryNumber) {
311 throw new YangParseException(moduleName, line, "Unresolved length constraints");
313 final long min = length.getMin().longValue();
314 final long max = length.getMax().longValue();
316 List<LengthConstraint> parentLengths = lengths.get(1);
317 boolean check = false;
318 for (LengthConstraint lc : parentLengths) {
319 Number parentMinNumber = lc.getMin();
320 if (parentMinNumber instanceof UnknownBoundaryNumber) {
321 parentMinNumber = resolveMinLength(parentMinNumber);
323 long parentMin = parentMinNumber.longValue();
325 Number parentMaxNumber = lc.getMax();
326 if (parentMaxNumber instanceof UnknownBoundaryNumber) {
327 parentMaxNumber = resolveMaxLength(parentMaxNumber);
329 long parentMax = parentMaxNumber.longValue();
331 if (parentMin <= min && parentMax >= max) {
337 throw new YangParseException(moduleName, line, "Invalid length constraint: <" + min + ", " + max
338 + "> (parent: " + parentLengths + ").");
343 private void validateLength(List<LengthConstraint> typeLength) {
344 if (lengths.size() < 2) {
348 for (LengthConstraint length : typeLength) {
349 if (length.getMin() instanceof UnknownBoundaryNumber || length.getMax() instanceof UnknownBoundaryNumber) {
350 throw new YangParseException(moduleName, line, "Unresolved length constraints");
352 final long min = length.getMin().longValue();
353 final long max = length.getMax().longValue();
355 List<LengthConstraint> parentLengths = lengths.get(1);
356 boolean check = false;
357 for (LengthConstraint lc : parentLengths) {
358 Number parentMinNumber = lc.getMin();
359 if (parentMinNumber instanceof UnknownBoundaryNumber) {
360 parentMinNumber = resolveMinLength(parentMinNumber);
362 long parentMin = parentMinNumber.longValue();
364 Number parentMaxNumber = lc.getMax();
365 if (parentMaxNumber instanceof UnknownBoundaryNumber) {
366 parentMaxNumber = resolveMaxLength(parentMaxNumber);
368 long parentMax = parentMaxNumber.longValue();
370 if (parentMin <= min && parentMax >= max) {
376 throw new YangParseException(moduleName, line, "Invalid length constraint: <" + min + ", " + max
377 + "> (parent: " + parentLengths + ").");