0e1394231d28804e7b92ed1301f53a03d924882c
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / main / java / org / opendaylight / mdsal / binding / java / api / generator / AbstractBigRangeGenerator.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.mdsal.binding.java.api.generator;
9
10 import com.google.common.collect.Range;
11 import java.lang.reflect.Array;
12 import java.util.Set;
13 import java.util.function.Function;
14 import org.opendaylight.yangtools.yang.binding.CodeHelpers;
15 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
16
17 /**
18  * Abstract base for generators which require instantiation of boundary values
19  * to check. These are implemented by generating an array constant within the
20  * class, which contains {@link Range} instances, which hold pre-instantiated
21  * boundary values.
22  *
23  * @param <T> type of the class
24  */
25 abstract class AbstractBigRangeGenerator<T extends Number & Comparable<T>> extends AbstractRangeGenerator<T> {
26     protected AbstractBigRangeGenerator(final Class<T> typeClass) {
27         super(typeClass);
28     }
29
30     private static String range(final Function<Class<?>, String> classImporter) {
31         return classImporter.apply(Range.class);
32     }
33
34     private String itemType(final Function<Class<?>, String> classImporter) {
35         return range(classImporter) + '<' + getTypeName() + '>';
36     }
37
38     private String arrayType(final Function<Class<?>, String> classImporter) {
39         return itemType(classImporter) + "[]";
40     }
41
42     @Override
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() + "_RANGES";
47         final StringBuilder sb = new StringBuilder();
48
49         // Field to hold the Range objects in an array
50         sb.append("private static final ").append(arrayType(classImporter)).append(' ').append(fieldName).append(";\n");
51
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)).append(") ")
56         .append(classImporter.apply(Array.class)).append(".newInstance(").append(range(classImporter)).append(".class, ")
57         .append(constraints.size()).append(");\n");
58
59         int i = 0;
60         for (Range<? extends Number> r : constraints) {
61             final String min = format(getValue(r.lowerEndpoint()));
62             final String max = format(getValue(r.upperEndpoint()));
63
64             sb.append("    a[").append(i++).append("] = ").append(range(classImporter)).append(".closed(").append(min).append(", ")
65             .append(max).append(");\n");
66         }
67
68         sb.append("    ").append(fieldName).append(" = a;\n");
69         sb.append("}\n");
70
71         // Static enforcement method
72         sb.append("private static void ").append(checkerName).append("(final ").append(getTypeName()).append(" value) {\n");
73         sb.append("    for (").append(itemType(classImporter)).append(" r : ").append(fieldName).append(") {\n");
74         sb.append("        if (r.contains(value)) {\n");
75         sb.append("            return;\n");
76         sb.append("        }\n");
77         sb.append("    }\n");
78
79         sb.append("    ").append(classImporter.apply(CodeHelpers.class)).append(".throwInvalidRange(").append(fieldName).append(", value);\n");
80         sb.append("}\n");
81
82         return sb.toString();
83     }
84 }