BUG-8043: correct LengthConstraint definition
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / type / NumberUtil.java
1 /*
2  * Copyright (c) 2015 Pantheon Technologies s.r.o. 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.yangtools.yang.model.util.type;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.ImmutableMap;
12 import java.math.BigDecimal;
13 import java.math.BigInteger;
14 import java.util.Comparator;
15 import java.util.Map;
16 import java.util.function.Function;
17
18 final class NumberUtil {
19     private static final Comparator<Number> NUMBER_COMPARATOR = (o1, o2) -> {
20         Preconditions.checkArgument(o1.getClass().equals(o2.getClass()), "Incompatible Number classes %s and %s",
21             o1.getClass(), o2.getClass());
22
23         if (o1 instanceof Byte) {
24             return ((Byte)o1).compareTo((Byte) o2);
25         } else if (o1 instanceof Short) {
26             return ((Short)o1).compareTo((Short) o2);
27         } else if (o1 instanceof Integer) {
28             return ((Integer)o1).compareTo((Integer) o2);
29         } else if (o1 instanceof Long) {
30             return ((Long)o1).compareTo((Long) o2);
31         } else if (o1 instanceof BigDecimal) {
32             return ((BigDecimal)o1).compareTo((BigDecimal) o2);
33         } else if (o1 instanceof BigInteger) {
34             return ((BigInteger)o1).compareTo((BigInteger) o2);
35         } else {
36             throw new IllegalArgumentException("Unsupported Number class " + o1.getClass());
37         }
38     };
39
40     private static final Map<Class<? extends Number>, Function<Number, Number>> CONVERTERS;
41
42     static {
43         final ImmutableMap.Builder<Class<? extends Number>, Function<Number, Number>> b = ImmutableMap.builder();
44         b.put(Byte.class, input -> {
45             if (input instanceof Byte) {
46                 return input;
47             }
48
49             return Byte.valueOf(input.toString());
50         });
51         b.put(Short.class, input -> {
52             if (input instanceof Short) {
53                 return input;
54             }
55             if (input instanceof Byte) {
56                 return input.shortValue();
57             }
58
59             return Short.valueOf(input.toString());
60         });
61         b.put(Integer.class, input -> {
62             if (input instanceof Integer) {
63                 return input;
64             }
65             if (input instanceof Byte || input instanceof Short) {
66                 return input.intValue();
67             }
68
69             return Integer.valueOf(input.toString());
70         });
71         b.put(Long.class, input ->  {
72             if (input instanceof Long) {
73                 return input;
74             }
75             if (input instanceof Byte || input instanceof Short || input instanceof Integer) {
76                 return input.longValue();
77             }
78
79             return Long.valueOf(input.toString());
80         });
81         b.put(BigDecimal.class, input -> {
82             if (input instanceof BigDecimal) {
83                 return input;
84             }
85             if (input instanceof Byte || input instanceof Short || input instanceof Integer || input instanceof Long) {
86                 return BigDecimal.valueOf(input.longValue());
87             }
88
89             return new BigDecimal(input.toString());
90         });
91         b.put(BigInteger.class, input -> {
92             if (input instanceof BigInteger) {
93                 return input;
94             }
95             if (input instanceof Byte || input instanceof Short || input instanceof Integer || input instanceof Long) {
96                 return BigInteger.valueOf(input.longValue());
97             }
98
99             return new BigInteger(input.toString());
100         });
101         CONVERTERS = b.build();
102     }
103
104     private NumberUtil() {
105         throw new UnsupportedOperationException();
106     }
107
108     @SuppressWarnings("unchecked")
109     static <T extends Number> Function<Number, T> converterTo(final Class<T> clazz) {
110         return (Function<Number, T>) CONVERTERS.get(clazz);
111     }
112
113     static boolean isRangeCovered(final Number min, final Number max, final Number superMin, final Number superMax) {
114         return NumberUtil.NUMBER_COMPARATOR.compare(min, superMin) >= 0
115             && NumberUtil.NUMBER_COMPARATOR.compare(max, superMax) <= 0;
116     }
117 }