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.mdsal.binding.java.api.generator;
10 import com.google.common.collect.Range;
11 import java.lang.reflect.Array;
12 import java.util.Locale;
14 import java.util.function.Function;
15 import org.opendaylight.yangtools.yang.binding.CodeHelpers;
16 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
19 * Abstract base for generators which require instantiation of boundary values to check. These are implemented
20 * by generating an array constant within the class, which contains {@link Range} instances, which hold pre-instantiated
23 * @param <T> type of the class
25 abstract class AbstractBigRangeGenerator<T extends Number & Comparable<T>> extends AbstractRangeGenerator<T> {
26 protected AbstractBigRangeGenerator(final Class<T> typeClass) {
30 private static String range(final Function<Class<?>, String> classImporter) {
31 return classImporter.apply(Range.class);
34 private String itemType(final Function<Class<?>, String> classImporter) {
35 return range(classImporter) + '<' + getTypeName() + '>';
38 private String arrayType(final Function<Class<?>, String> classImporter) {
39 return itemType(classImporter) + "[]";
43 protected final String generateRangeCheckerImplementation(final String checkerName,
44 final RangeConstraint<?> constraint, final Function<Class<?>, String> classImporter) {
45 final Set<? extends Range<? extends Number>> constraints = constraint.getAllowedRanges().asRanges();
46 final String fieldName = checkerName.toUpperCase(Locale.ENGLISH) + "_RANGES";
47 final StringBuilder sb = new StringBuilder();
49 // Field to hold the Range objects in an array
50 sb.append("private static final ").append(arrayType(classImporter)).append(' ').append(fieldName).append(";\n");
52 // Static initializer block for the array
53 sb.append("static {\n");
54 sb.append(" @SuppressWarnings(\"unchecked\")\n");
55 sb.append(" final ").append(arrayType(classImporter)).append(" a = (").append(arrayType(classImporter))
56 .append(") ").append(classImporter.apply(Array.class)).append(".newInstance(").append(range(classImporter))
57 .append(".class, ").append(constraints.size()).append(");\n");
60 for (Range<? extends Number> r : constraints) {
61 final String min = format(getValue(r.lowerEndpoint()));
62 final String max = format(getValue(r.upperEndpoint()));
64 sb.append(" a[").append(offset++).append("] = ").append(range(classImporter)).append(".closed(")
65 .append(min).append(", ").append(max).append(");\n");
68 sb.append(" ").append(fieldName).append(" = a;\n");
71 // Static enforcement method
72 sb.append("private static void ").append(checkerName).append("(final ").append(getTypeName())
73 .append(" value) {\n");
74 sb.append(" for (").append(itemType(classImporter)).append(" r : ").append(fieldName).append(") {\n");
75 sb.append(" if (r.contains(value)) {\n");
76 sb.append(" return;\n");
80 sb.append(" ").append(classImporter.apply(CodeHelpers.class)).append(".throwInvalidRange(").append(fieldName)
81 .append(", value);\n");