36efe2d10ad03e9b5cd4d78f50f14061b022565a
[yangtools.git] / common / util / src / main / java / org / opendaylight / yangtools / util / OptionalBoolean.java
1 /*
2  * Copyright (c) 2017 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.util;
9
10 import com.google.common.annotations.Beta;
11 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
12 import java.util.Optional;
13 import org.eclipse.jdt.annotation.Nullable;
14
15 /**
16  * Utility class for storing an optional boolean in a single byte value. This cuts down the memory requirement quite
17  * at very small computational cost.
18  *
19  * <p>
20  * Note: fields do not have to be explicitly initialized, as default initialization value for 'byte', 0, is used to
21  *       represent 'absent' condition.
22  *
23  * @author Robert Varga
24  */
25 @Beta
26 public final class OptionalBoolean {
27     private static final byte ABSENT = 0;
28     private static final byte FALSE = 1;
29     private static final byte TRUE = 2;
30
31     private OptionalBoolean() {
32         throw new UnsupportedOperationException();
33     }
34
35     /**
36      * Check if a field value has been set, just like {@link Optional#isPresent()}.
37      *
38      * @param value field value
39      * @return True if the value is set.
40      * @throws IllegalArgumentException if value is invalid
41      */
42     public static boolean isPresent(final byte value) {
43         switch (value) {
44             case ABSENT:
45                 return false;
46             case FALSE:
47             case TRUE:
48                 return true;
49             default:
50                 throw invalidValue(value);
51         }
52     }
53
54     /**
55      * Decode boolean from a field value, just like {@link Optional#get()}.
56      *
57      * @param value Field value
58      * @return Decoded boolean.
59      * @throws IllegalArgumentException if value is invalid
60      * @throws IllegalStateException if value has not been set
61      */
62     public static boolean get(final byte value) {
63         switch (value) {
64             case ABSENT:
65                 throw new IllegalStateException("Field has not been initialized");
66             case FALSE:
67                 return false;
68             case TRUE:
69                 return true;
70             default:
71                 throw invalidValue(value);
72         }
73     }
74
75     /**
76      * Encode a boolean to a field value, just like {@link Optional#of(Object)}.
77      *
78      * @param bool Boolean value.
79      * @return Field value.
80      */
81     public static byte of(final boolean bool) {
82         return bool ? TRUE : FALSE;
83     }
84
85     /**
86      * Convert a nullable {@link Boolean} into a field value, just like {@link Optional#ofNullable(Object)}.
87      *
88      * @param bool Boolean value.
89      * @return Field value.
90      */
91     public static byte ofNullable(final @Nullable Boolean bool) {
92         return bool == null ? ABSENT : of(bool.booleanValue());
93     }
94
95     /**
96      * Convert a field value to a nullable {@link Boolean}. Similar to {@code Optional.orElse(null)}.
97      *
98      * @param value Field value.
99      * @return Nullable Boolean.
100      */
101     @SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL")
102     public static @Nullable Boolean toNullable(final byte value) {
103         switch (value) {
104             case ABSENT:
105                 return null;
106             case FALSE:
107                 return Boolean.FALSE;
108             case TRUE:
109                 return Boolean.TRUE;
110             default:
111                 throw invalidValue(value);
112         }
113     }
114
115     /**
116      * Convert a field value into an {@link Optional} {@link Boolean}.
117      *
118      * @param value Field value.
119      * @return Optional {@link Boolean}.
120      * @throws IllegalArgumentException if value is invalid.
121      */
122     public static Optional<Boolean> toOptional(final byte value) {
123         switch (value) {
124             case ABSENT:
125                 return Optional.empty();
126             case FALSE:
127                 return Optional.of(Boolean.FALSE);
128             case TRUE:
129                 return Optional.of(Boolean.TRUE);
130             default:
131                 throw invalidValue(value);
132         }
133     }
134
135     /**
136      * Convert a field value into a String representation.
137      *
138      * @param value Field value.
139      * @return Boolean-compatible string, or "absent".
140      * @throws IllegalArgumentException if value is invalid.
141      */
142     public static String toString(final byte value) {
143         switch (value) {
144             case ABSENT:
145                 return "absent";
146             case FALSE:
147                 return Boolean.toString(false);
148             case TRUE:
149                 return Boolean.toString(true);
150             default:
151                 throw invalidValue(value);
152         }
153     }
154
155     private static IllegalArgumentException invalidValue(final byte value) {
156         throw new IllegalArgumentException("Invalid field value " + value);
157     }
158 }