Bug 1411-5 #3: MDSAL Binding2 Java API Generator
[mdsal.git] / binding2 / mdsal-binding2-java-api-generator / src / main / java / org / opendaylight / mdsal / binding2 / java / api / generator / rangeGenerators / AbstractBigRangeGenerator.java
1 /*
2  * Copyright (c) 2016 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.binding2.java.api.generator.rangeGenerators;
9
10 import com.google.common.collect.Range;
11 import java.util.Collection;
12 import javax.annotation.Nonnull;
13 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
14
15 /**
16  * Abstract base for generators which require instantiation of boundary values to check.
17  * These are implemented by generating an array constant within the class, which contains
18  * {@link Range} instances, which hold pre-instantiated boundary values.
19  *
20  * @param <T> type of the class
21  */
22 abstract class AbstractBigRangeGenerator<T extends Number & Comparable<T>> extends AbstractRangeGenerator<T> {
23     private static final String RANGE = Range.class.getName();
24
25     protected AbstractBigRangeGenerator(final Class<T> typeClass) {
26         super(typeClass);
27     }
28
29     private StringBuilder itemType() {
30         return new StringBuilder(RANGE).append('<').append(getTypeName()).append('>');
31     }
32
33     private StringBuilder arrayType() {
34         return new StringBuilder(itemType()).append("[]");
35     }
36
37     @Override
38     protected final String generateRangeCheckerImplementation(final String checkerName, @Nonnull final Collection<RangeConstraint> constraints) {
39         final String fieldName = checkerName.toUpperCase() + "_RANGES";
40         final StringBuilder sb = new StringBuilder();
41
42         // Field to hold the Range objects in an array
43         sb.append("private static final ").append(arrayType()).append(' ').append(fieldName).append(";\n");
44
45         // Static initializer block for the array
46         sb.append("static {\n");
47         sb.append("    @SuppressWarnings(\"unchecked\")\n");
48         sb.append("    final ").append(arrayType()).append(" a = (").append(arrayType())
49         .append(") java.lang.reflect.Array.newInstance(").append(RANGE).append(".class, ").append(constraints.size()).append(");\n");
50
51         int i = 0;
52         for (RangeConstraint r : constraints) {
53             final String min = format(getValue(r.getMin()));
54             final String max = format(getValue(r.getMax()));
55
56             sb.append("    a[").append(i++).append("] = ").append(RANGE).append(".closed(").append(min).append(", ").append(max).append(");\n");
57         }
58
59         sb.append("    ").append(fieldName).append(" = a;\n");
60         sb.append("}\n");
61
62         // Static enforcement method
63         sb.append("private static void ").append(checkerName).append("(final ").append(getTypeName()).append(" value) {\n");
64         sb.append("    for (").append(itemType()).append(" r : ").append(fieldName).append(") {\n");
65         sb.append("        if (r.contains(value)) {\n");
66         sb.append("            return;\n");
67         sb.append("        }\n");
68         sb.append("    }\n");
69         sb.append("    throw new IllegalArgumentException(String.format(\"Invalid range: %s, expected: %s.\", value, java.util.Arrays.asList(").append(fieldName).append(")));\n");
70         sb.append("}\n");
71
72         return sb.toString();
73     }
74 }