Skip to content

Commit fbafe0f

Browse files
committed
adding the following methods to JsonNullable, based on methods
found in java.util.Optional. - isUndefined() - orElseGet(Supplier) - orElseThrow() - orElseThrow(Supplier) - ifPresentOrElse(Supplier, Runnable) - filter(Predicate) - map(Function) - flatMap(Function) - or(Supplier) - stream()
1 parent 09ee5fc commit fbafe0f

File tree

4 files changed

+1224
-1
lines changed

4 files changed

+1224
-1
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,7 @@ target
2121
*.iws
2222
.idea/
2323

24-
*.gpg
24+
# VS Code
25+
.vscode
26+
27+
*.gpg

pom.xml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
<javax-validation-api.version>2.0.1.Final</javax-validation-api.version>
4141
<jakarta-validation-api.version>3.1.1</jakarta-validation-api.version>
4242
<junit.version>5.13.4</junit.version>
43+
<hamcrest.version>1.3</hamcrest.version>
44+
<mockito.version>4.11.0</mockito.version>
4345
<!-- endregion -->
4446

4547
<!-- region Plugin Versions -->
@@ -102,7 +104,25 @@
102104
<artifactId>junit-jupiter-api</artifactId>
103105
<scope>test</scope>
104106
</dependency>
107+
<dependency>
108+
<groupId>org.junit.jupiter</groupId>
109+
<artifactId>junit-jupiter-params</artifactId>
110+
<scope>test</scope>
111+
</dependency>
112+
<dependency>
113+
<groupId>org.hamcrest</groupId>
114+
<artifactId>hamcrest-all</artifactId>
115+
<version>${hamcrest.version}</version>
116+
<scope>test</scope>
117+
</dependency>
118+
<dependency>
119+
<groupId>org.mockito</groupId>
120+
<artifactId>mockito-core</artifactId>
121+
<version>${mockito.version}</version>
122+
<scope>test</scope>
123+
</dependency>
105124
<!-- endregion -->
125+
106126
</dependencies>
107127

108128
<build>
@@ -126,6 +146,32 @@
126146
<target>${java.version}</target>
127147
</configuration>
128148
</plugin>
149+
<plugin>
150+
<groupId>org.apache.maven.plugins</groupId>
151+
<artifactId>maven-surefire-plugin</artifactId>
152+
<version>3.5.4</version>
153+
<configuration>
154+
<statelessTestsetReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5Xml30StatelessReporter">
155+
<disable>false</disable>
156+
<version>3.0</version>
157+
<usePhrasedFileName>false</usePhrasedFileName>
158+
<usePhrasedTestSuiteClassName>true</usePhrasedTestSuiteClassName>
159+
<usePhrasedTestCaseClassName>true</usePhrasedTestCaseClassName>
160+
<usePhrasedTestCaseMethodName>true</usePhrasedTestCaseMethodName>
161+
</statelessTestsetReporter>
162+
<consoleOutputReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5ConsoleOutputReporter">
163+
<disable>false</disable>
164+
<encoding>UTF-8</encoding>
165+
<usePhrasedFileName>false</usePhrasedFileName>
166+
</consoleOutputReporter>
167+
<statelessTestsetInfoReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoReporter">
168+
<disable>false</disable>
169+
<usePhrasedFileName>false</usePhrasedFileName>
170+
<usePhrasedClassNameInRunning>true</usePhrasedClassNameInRunning>
171+
<usePhrasedClassNameInTestCaseSummary>true</usePhrasedClassNameInTestCaseSummary>
172+
</statelessTestsetInfoReporter>
173+
</configuration>
174+
</plugin>
129175
<plugin>
130176
<groupId>org.apache.maven.plugins</groupId>
131177
<artifactId>maven-jar-plugin</artifactId>

src/main/java/org/openapitools/jackson/nullable/JsonNullable.java

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
import java.util.NoSuchElementException;
55
import java.util.Objects;
66
import java.util.function.Consumer;
7+
import java.util.function.Function;
8+
import java.util.function.Predicate;
9+
import java.util.function.Supplier;
10+
import java.util.stream.Stream;
711

812
public class JsonNullable<T> implements Serializable {
913

@@ -66,15 +70,86 @@ public T orElse(T other) {
6670
return this.isPresent ? this.value : other;
6771
}
6872

73+
/**
74+
* If a value is present, returns the value, otherwise returns the result
75+
* produced by the supplying function.
76+
*
77+
* @param supplier the supplying function that produces a value to be returned
78+
* @return the value, if present, otherwise the result produced by the supplying function
79+
* @throws NullPointerException if no value is present and the supplying function is null
80+
*
81+
* @since 0.2.8
82+
*/
83+
public T orElseGet(Supplier<? extends T> supplier) {
84+
return this.isPresent ? this.value : supplier.get();
85+
}
86+
87+
/**
88+
* If a value is present, returns the value, otherwise throws
89+
* NoSuchElementException.
90+
*
91+
* @return the value of this JsonNullable
92+
* @throws NoSuchElementException if no value if present
93+
*
94+
* @since 0.2.8
95+
*/
96+
public T orElseThrow() {
97+
if (!isPresent) {
98+
throw new NoSuchElementException("Value is undefined");
99+
}
100+
return value;
101+
}
102+
103+
/**
104+
* If a value is present, returns the value, otherwise throws an exception
105+
* produced by the exception supplying function.
106+
*
107+
* @param <X> type of the exception to be thrown
108+
* @param supplier the supplying function that produces an exception to be
109+
* thrown
110+
* @return the value, if present
111+
* @throws X if no value is present
112+
* @throws NullPointerException if no value is present and the exception
113+
* supplying function is {@code null}
114+
*
115+
* @since 0.2.8
116+
*/
117+
public <X extends Throwable> T orElseThrow(Supplier<? extends X> supplier)
118+
throws X
119+
{
120+
if( this.isPresent ) {
121+
return this.value;
122+
}
123+
throw supplier.get();
124+
}
125+
126+
/**
127+
* If a value is present, returns true, otherwise false.
128+
*
129+
* @return true if a value is present, otherwise false
130+
*/
69131
public boolean isPresent() {
70132
return isPresent;
71133
}
72134

135+
/**
136+
* If a value is not present, returns true, otherwise false.
137+
*
138+
* @return true if a value is not present, otherwise false
139+
*
140+
* @since 0.2.8
141+
*/
142+
public boolean isUndefined() {
143+
return !isPresent;
144+
}
145+
73146
/**
74147
* If a value is present, performs the given action with the value,
75148
* otherwise does nothing.
76149
*
77150
* @param action the action to be performed, if a value is present
151+
* @throws NullPointerException if a value is present and the given action
152+
* is null
78153
*/
79154
public void ifPresent(
80155
Consumer<? super T> action) {
@@ -84,6 +159,153 @@ public void ifPresent(
84159
}
85160
}
86161

162+
/**
163+
* If a value is present, performs the given action with the value,
164+
* otherwise performs the given empty-based action.
165+
*
166+
* @param action the action to be performed, if a value is present
167+
* @param undefinedAction the empty-based action to be performed, if no
168+
* value is present
169+
* @throws NullPointerException if a value is present and the given action
170+
* is null, or no value is present and the given empty-based action
171+
* is null
172+
*
173+
* @since 0.2.8
174+
*/
175+
public void ifPresentOrElse( Consumer<? super T> action, Runnable undefinedAction ) {
176+
if (this.isPresent) {
177+
action.accept(value);
178+
}
179+
else {
180+
undefinedAction.run();
181+
}
182+
}
183+
184+
/**
185+
* If a value is present, and the value matches the given predicate, returns
186+
* a JsonNullable describing the value, otherwise returns an undefined
187+
* JsonNullable.
188+
*
189+
* @param predicate the predicate to apply to a value, if present
190+
* @return a JsonNullable describing the value of this JsonNullable,
191+
* if a value is present and the value matches the given predicate,
192+
* otherwise an undefined JsonNullable
193+
* @throws NullPointerException if the predicate is null
194+
*
195+
* @since 0.2.8
196+
*/
197+
public JsonNullable<T> filter( Predicate<T> predicate ) {
198+
if (predicate == null) {
199+
throw new NullPointerException("filter predicate is null");
200+
}
201+
if (this.isPresent && predicate.test(value)) {
202+
return this;
203+
}
204+
else {
205+
return undefined();
206+
}
207+
}
208+
209+
/**
210+
* If a value is present, returns a JsonNullable describing the result of
211+
* applying the given mapping function to the value, otherwise returns an
212+
* undeined JsonNullable.
213+
*
214+
* @param <U> the type of the value returned from the mapping function
215+
* @param mapper the mapping function to apply to a value, if present
216+
* @return a JsonNullable describing the result of applying a mapping
217+
* function to the value of this JsonNullable, if a value is
218+
* present, otherwise an undefined JsonNullable
219+
* @throws NullPointerException if the mapping function is null
220+
*
221+
* @since 0.2.8
222+
*/
223+
public <U> JsonNullable<U> map( Function<T, U> mapper) {
224+
if (mapper == null) {
225+
throw new NullPointerException("mapping function is null");
226+
}
227+
if (this.isPresent) {
228+
return new JsonNullable<U>(mapper.apply(value), true);
229+
}
230+
return undefined();
231+
}
232+
233+
/**
234+
* If a value is present, returns the result of applying the given
235+
* JsonNullable-bearing mapping function to the value, otherwise returns an
236+
* undefined JsonNullable.
237+
*
238+
* @param <U> the type of value of the JsonNullable returned by the mapping
239+
* function
240+
* @param mapper the mapping function to apply to a value, if present
241+
* @return the result of applying a JsonNullable-bearing mapping function to
242+
* the value of this JsonNullable, if a value is present, otherwise
243+
* an undefined JsonNullable
244+
* @throws NullPointerException if the mapping function is null or returns a
245+
* null result
246+
*
247+
* @since 0.2.8
248+
*/
249+
@SuppressWarnings("unchecked")
250+
public <U> JsonNullable<U> flatMap( Function<? super T, ? extends JsonNullable<? extends U>> mapper ) {
251+
if (mapper == null) {
252+
throw new NullPointerException("mapping function is null");
253+
}
254+
if (!this.isPresent) {
255+
return undefined();
256+
}
257+
258+
JsonNullable<U> mapped = (JsonNullable<U>)mapper.apply(value);
259+
if (mapped == null) {
260+
throw new NullPointerException("mapped value is null");
261+
}
262+
return mapped;
263+
}
264+
265+
/**
266+
* If a value is present, returns a JsonNullable describing the value,
267+
* otherwise returns a JsonNullable produced by the supplying function.
268+
*
269+
* @param supplier the supplying function that produces a JsonNullable to be
270+
* returned
271+
* @return returns a JsonNullable describing the value of this JsonNullable,
272+
* if a value is present, otherwise a JsonNullable produced by the
273+
* supplying function.
274+
* @throws NullPointerException if the supplying function is null or
275+
* produces a null result
276+
*
277+
* @since 0.2.8
278+
*/
279+
@SuppressWarnings("unchecked")
280+
public JsonNullable<T> or( Supplier<? extends JsonNullable<? extends T>> supplier ) {
281+
if( supplier == null ) {
282+
throw new NullPointerException("or supplier is null");
283+
}
284+
if (this.isPresent) {
285+
return this;
286+
}
287+
JsonNullable<T> supplied = (JsonNullable<T>)supplier.get();
288+
if (supplied == null) {
289+
throw new NullPointerException("supplied value is null");
290+
}
291+
return supplied;
292+
}
293+
294+
/**
295+
* If a value is present, returns a sequential Stream containing only that
296+
* value, otherwise returns an empty Stream.
297+
*
298+
* @return the JsonNullable value as a Stream
299+
*
300+
* @since 0.2.8
301+
*/
302+
public Stream<T> stream() {
303+
if (this.isPresent) {
304+
return Stream.of(value);
305+
}
306+
return Stream.empty();
307+
}
308+
87309
@Override
88310
public boolean equals(Object obj) {
89311
if (this == obj) {

0 commit comments

Comments
 (0)