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.common.Decimal64;
17 import org.opendaylight.yangtools.yang.common.Uint16;
18 import org.opendaylight.yangtools.yang.common.Uint8;
19 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
22 * Decimal64 boundary check generator. It requires instantiation of boundary values -- these are implemented by
23 * generating an array constant within the class, which contains {@link Range} instances, which hold pre-instantiated
26 final class Decimal64RangeGenerator extends AbstractRangeGenerator<Decimal64> {
27 Decimal64RangeGenerator() {
28 super(Decimal64.class);
31 private static String range(final Function<Class<?>, String> classImporter) {
32 return classImporter.apply(Range.class);
35 private static String itemType(final Function<Class<?>, String> classImporter) {
36 return range(classImporter) + '<' + classImporter.apply(Decimal64.class) + '>';
39 private static String arrayType(final Function<Class<?>, String> classImporter) {
40 return itemType(classImporter) + "[]";
43 private static String format(final Function<Class<?>, String> classImporter, final Decimal64 value) {
44 return classImporter.apply(Decimal64.class) + ".of(" + value.scale() + ", " + value.unscaledValue() + "L)";
49 protected Decimal64 convert(final Number value) {
50 if (value instanceof Byte || value instanceof Short || value instanceof Integer
51 || value instanceof Uint8 || value instanceof Uint16) {
52 // FIXME: this is not quite right
53 return Decimal64.valueOf(1, value.intValue());
55 // FIXME: this is not quite right
56 return Decimal64.valueOf(1, value.longValue());
61 protected String generateRangeCheckerImplementation(final String checkerName,
62 final RangeConstraint<?> constraint, final Function<Class<?>, String> classImporter) {
63 final Set<? extends Range<? extends Number>> constraints = constraint.getAllowedRanges().asRanges();
64 final String fieldName = checkerName.toUpperCase(Locale.ENGLISH) + "_RANGES";
65 final StringBuilder sb = new StringBuilder();
67 // Field to hold the Range objects in an array
68 sb.append("private static final ").append(arrayType(classImporter)).append(' ').append(fieldName).append(";\n");
70 // Static initializer block for the array
71 sb.append("static {\n");
72 sb.append(" @SuppressWarnings(\"unchecked\")\n");
73 sb.append(" final ").append(arrayType(classImporter)).append(" a = (").append(arrayType(classImporter))
74 .append(") ").append(classImporter.apply(Array.class)).append(".newInstance(").append(range(classImporter))
75 .append(".class, ").append(constraints.size()).append(");\n");
78 for (Range<? extends Number> r : constraints) {
79 final String min = format(classImporter, getValue(r.lowerEndpoint()));
80 final String max = format(classImporter, getValue(r.upperEndpoint()));
82 sb.append(" a[").append(offset++).append("] = ").append(range(classImporter)).append(".closed(")
83 .append(min).append(", ").append(max).append(");\n");
86 sb.append(" ").append(fieldName).append(" = a;\n");
89 // Static enforcement method
90 sb.append("private static void ").append(checkerName).append("(final ").append(getTypeName())
91 .append(" value) {\n");
92 sb.append(" for (").append(itemType(classImporter)).append(" r : ").append(fieldName).append(") {\n");
93 sb.append(" if (r.contains(value)) {\n");
94 sb.append(" return;\n");
98 sb.append(" ").append(classImporter.apply(CodeHelpers.class)).append(".throwInvalidRange(").append(fieldName)
99 .append(", value);\n");
102 return sb.toString();