Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ target
*.iws
.idea/

*.gpg
# VS Code
.vscode

*.gpg
46 changes: 46 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
<javax-validation-api.version>2.0.1.Final</javax-validation-api.version>
<jakarta-validation-api.version>3.1.1</jakarta-validation-api.version>
<junit.version>5.13.4</junit.version>
<hamcrest.version>1.3</hamcrest.version>
<mockito.version>4.11.0</mockito.version>
<!-- endregion -->

<!-- region Plugin Versions -->
Expand Down Expand Up @@ -102,7 +104,25 @@
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<!-- endregion -->

</dependencies>

<build>
Expand All @@ -126,6 +146,32 @@
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.4</version>
<configuration>
<statelessTestsetReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5Xml30StatelessReporter">
<disable>false</disable>
<version>3.0</version>
<usePhrasedFileName>false</usePhrasedFileName>
<usePhrasedTestSuiteClassName>true</usePhrasedTestSuiteClassName>
<usePhrasedTestCaseClassName>true</usePhrasedTestCaseClassName>
<usePhrasedTestCaseMethodName>true</usePhrasedTestCaseMethodName>
</statelessTestsetReporter>
<consoleOutputReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5ConsoleOutputReporter">
<disable>false</disable>
<encoding>UTF-8</encoding>
<usePhrasedFileName>false</usePhrasedFileName>
</consoleOutputReporter>
<statelessTestsetInfoReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoReporter">
<disable>false</disable>
<usePhrasedFileName>false</usePhrasedFileName>
<usePhrasedClassNameInRunning>true</usePhrasedClassNameInRunning>
<usePhrasedClassNameInTestCaseSummary>true</usePhrasedClassNameInTestCaseSummary>
</statelessTestsetInfoReporter>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
Expand Down
222 changes: 222 additions & 0 deletions src/main/java/org/openapitools/jackson/nullable/JsonNullable.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class JsonNullable<T> implements Serializable {

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

/**
* If a value is present, returns the value, otherwise returns the result
* produced by the supplying function.
*
* @param supplier the supplying function that produces a value to be returned
* @return the value, if present, otherwise the result produced by the supplying function
* @throws NullPointerException if no value is present and the supplying function is null
*
* @since 0.2.8
*/
public T orElseGet(Supplier<? extends T> supplier) {
return this.isPresent ? this.value : supplier.get();
}

/**
* If a value is present, returns the value, otherwise throws
* NoSuchElementException.
*
* @return the value of this JsonNullable
* @throws NoSuchElementException if no value if present
*
* @since 0.2.8
*/
public T orElseThrow() {
if (!isPresent) {
throw new NoSuchElementException("Value is undefined");
}
return value;
}

/**
* If a value is present, returns the value, otherwise throws an exception
* produced by the exception supplying function.
*
* @param <X> type of the exception to be thrown
* @param supplier the supplying function that produces an exception to be
* thrown
* @return the value, if present
* @throws X if no value is present
* @throws NullPointerException if no value is present and the exception
* supplying function is {@code null}
*
* @since 0.2.8
*/
public <X extends Throwable> T orElseThrow(Supplier<? extends X> supplier)
throws X
{
if( this.isPresent ) {
return this.value;
}
throw supplier.get();
}

/**
* If a value is present, returns true, otherwise false.
*
* @return true if a value is present, otherwise false
*/
public boolean isPresent() {
return isPresent;
}

/**
* If a value is not present, returns true, otherwise false.
*
* @return true if a value is not present, otherwise false
*
* @since 0.2.8
*/
public boolean isUndefined() {
return !isPresent;
}

/**
* If a value is present, performs the given action with the value,
* otherwise does nothing.
*
* @param action the action to be performed, if a value is present
* @throws NullPointerException if a value is present and the given action
* is null
*/
public void ifPresent(
Consumer<? super T> action) {
Expand All @@ -84,6 +159,153 @@ public void ifPresent(
}
}

/**
* If a value is present, performs the given action with the value,
* otherwise performs the given empty-based action.
*
* @param action the action to be performed, if a value is present
* @param undefinedAction the empty-based action to be performed, if no
* value is present
* @throws NullPointerException if a value is present and the given action
* is null, or no value is present and the given empty-based action
* is null
*
* @since 0.2.8
*/
public void ifPresentOrElse( Consumer<? super T> action, Runnable undefinedAction ) {
if (this.isPresent) {
action.accept(value);
}
else {
undefinedAction.run();
}
}

/**
* If a value is present, and the value matches the given predicate, returns
* a JsonNullable describing the value, otherwise returns an undefined
* JsonNullable.
*
* @param predicate the predicate to apply to a value, if present
* @return a JsonNullable describing the value of this JsonNullable,
* if a value is present and the value matches the given predicate,
* otherwise an undefined JsonNullable
* @throws NullPointerException if the predicate is null
*
* @since 0.2.8
*/
public JsonNullable<T> filter( Predicate<T> predicate ) {
if (predicate == null) {
throw new NullPointerException("filter predicate is null");
}
if (this.isPresent && predicate.test(value)) {
return this;
}
else {
return undefined();
}
}

/**
* If a value is present, returns a JsonNullable describing the result of
* applying the given mapping function to the value, otherwise returns an
* undeined JsonNullable.
*
* @param <U> the type of the value returned from the mapping function
* @param mapper the mapping function to apply to a value, if present
* @return a JsonNullable describing the result of applying a mapping
* function to the value of this JsonNullable, if a value is
* present, otherwise an undefined JsonNullable
* @throws NullPointerException if the mapping function is null
*
* @since 0.2.8
*/
public <U> JsonNullable<U> map( Function<T, U> mapper) {
if (mapper == null) {
throw new NullPointerException("mapping function is null");
}
if (this.isPresent) {
return new JsonNullable<U>(mapper.apply(value), true);
}
return undefined();
}

/**
* If a value is present, returns the result of applying the given
* JsonNullable-bearing mapping function to the value, otherwise returns an
* undefined JsonNullable.
*
* @param <U> the type of value of the JsonNullable returned by the mapping
* function
* @param mapper the mapping function to apply to a value, if present
* @return the result of applying a JsonNullable-bearing mapping function to
* the value of this JsonNullable, if a value is present, otherwise
* an undefined JsonNullable
* @throws NullPointerException if the mapping function is null or returns a
* null result
*
* @since 0.2.8
*/
@SuppressWarnings("unchecked")
public <U> JsonNullable<U> flatMap( Function<? super T, ? extends JsonNullable<? extends U>> mapper ) {
if (mapper == null) {
throw new NullPointerException("mapping function is null");
}
if (!this.isPresent) {
return undefined();
}

JsonNullable<U> mapped = (JsonNullable<U>)mapper.apply(value);
if (mapped == null) {
throw new NullPointerException("mapped value is null");
}
return mapped;
}

/**
* If a value is present, returns a JsonNullable describing the value,
* otherwise returns a JsonNullable produced by the supplying function.
*
* @param supplier the supplying function that produces a JsonNullable to be
* returned
* @return returns a JsonNullable describing the value of this JsonNullable,
* if a value is present, otherwise a JsonNullable produced by the
* supplying function.
* @throws NullPointerException if the supplying function is null or
* produces a null result
*
* @since 0.2.8
*/
@SuppressWarnings("unchecked")
public JsonNullable<T> or( Supplier<? extends JsonNullable<? extends T>> supplier ) {
if( supplier == null ) {
throw new NullPointerException("or supplier is null");
}
if (this.isPresent) {
return this;
}
JsonNullable<T> supplied = (JsonNullable<T>)supplier.get();
if (supplied == null) {
throw new NullPointerException("supplied value is null");
}
return supplied;
}

/**
* If a value is present, returns a sequential Stream containing only that
* value, otherwise returns an empty Stream.
*
* @return the JsonNullable value as a Stream
*
* @since 0.2.8
*/
public Stream<T> stream() {
if (this.isPresent) {
return Stream.of(value);
}
return Stream.empty();
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
Expand Down
Loading