001package com.identityworksllc.iiq.common.vo;
002
003import com.fasterxml.jackson.annotation.JsonAutoDetect;
004import com.fasterxml.jackson.annotation.JsonInclude;
005import com.fasterxml.jackson.annotation.JsonProperty;
006import com.fasterxml.jackson.databind.annotation.JsonSerialize;
007
008import java.io.Serializable;
009
010/**
011 * A container object holding a failure, usually used in a threaded context. This
012 * indicates that the operation processing the given object of type `T` failed with
013 * an exception of type `E`.
014 *
015 * The {@link ThrowableSerializer} is used to make these objects JSON-friendly,
016 * but the output cannot be converted back to a Failure.
017 *
018 * If the object of type `T` is not null, it must be serializable by Jackson,
019 * either by default, via annotations, or via some mix-in.
020 *
021 * @param <T> The type of the object that failed to be processed
022 * @param <E> The error type
023 */
024public class Failure<T, E extends Exception> implements Serializable {
025    private final E exception;
026
027    private final T object;
028
029    /**
030     * Constructs a new Failure with an object but no exception
031     * @param object The object
032     */
033    public Failure(T object) {
034        this.object = object;
035        this.exception = null;
036    }
037
038    /**
039     * Constructs a new Failure with an exception but no object
040     * @param exception the exception
041     */
042    public Failure(E exception) {
043        this.object = null;
044        this.exception = exception;
045    }
046
047    /**
048     * Constructs a new failure with both an object and an exception
049     * @param object the object
050     * @param exception the exception
051     */
052    public Failure(T object, E exception) {
053        this.object = object;
054        this.exception = exception;
055    }
056
057    /**
058     * Gets the stored exception if one exists
059     * @return The stored exception
060     */
061    @JsonSerialize(using = ThrowableSerializer.class)
062    @JsonProperty("exception")
063    @JsonInclude(JsonInclude.Include.NON_NULL)
064    public E getException() {
065        return exception;
066    }
067
068    /**
069     * Gets the stored object if one exists
070     * @return The stored object
071     */
072    @JsonProperty("object")
073    @JsonInclude(JsonInclude.Include.NON_NULL)
074    public T getObject() {
075        return object;
076    }
077}