Java 8: migrate to java.util.function.Function
[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     static {
42         final ImmutableMap.Builder<Class<? extends Number>, Function<Number, Number>> b = ImmutableMap.builder();
43         b.put(Byte.class, input -> {
44             if (input instanceof Byte) {
45                 return input;
46             }
47
48             return Byte.valueOf(input.toString());
49         });
50         b.put(Short.class, input -> {
51                 if (input instanceof Short) {
52                     return input;
53                 }
54                 if (input instanceof Byte) {
55                     return input.shortValue();
56                 }
57
58                 return Short.valueOf(input.toString());
59         });
60         b.put(Integer.class, input -> {
61             if (input instanceof Integer) {
62                 return input;
63             }
64             if (input instanceof Byte || input instanceof Short) {
65                 return input.intValue();
66             }
67
68             return Integer.valueOf(input.toString());
69         });
70         b.put(Long.class, input ->  {
71             if (input instanceof Long) {
72                 return input;
73             }
74             if (input instanceof Byte || input instanceof Short || input instanceof Integer) {
75                 return input.longValue();
76             }
77
78             return Long.valueOf(input.toString());
79         });
80         b.put(BigDecimal.class, input -> {
81             if (input instanceof BigDecimal) {
82                 return input;
83             }
84             if (input instanceof Byte || input instanceof Short ||
85                     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 ||
96                     input instanceof Integer || input instanceof Long) {
97                 return BigInteger.valueOf(input.longValue());
98             }
99
100             return new BigInteger(input.toString());
101         });
102         CONVERTERS = b.build();
103     }
104
105     private NumberUtil() {
106         throw new UnsupportedOperationException();
107     }
108
109     static Function<Number, Number> converterTo(final Class<? extends Number> clazz) {
110         return 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 }