package sk.stuba.fiit.perconik.utilities;
import java.io.Serializable;
import javax.annotation.Nullable;
import com.google.common.base.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
public abstract class Exceptional<T> implements Serializable {
private static final long serialVersionUID = 0L;
Exceptional() {}
public static final <T> Exceptional<T> of(final T reference) {
return new Success<>(reference);
}
public static final <T> Exceptional<T> failure(final Throwable reference) {
return new Failure<>(reference);
}
private static final class Success<T> extends Exceptional<T> {
private static final long serialVersionUID = 0L;
private final T reference;
Success(final T reference) {
this.reference = reference;
}
@Override
public T or(final T other) {
checkNotNull(other);
return this.reference;
}
@Override
public Exceptional<T> or(final Exceptional<T> other) {
checkNotNull(other);
return this;
}
@Override
public T orNull() {
return this.reference;
}
@Override
public boolean equals(@Nullable final Object o) {
if (o == this) {
return true;
}
if (!(o instanceof Success)) {
return false;
}
Success<?> other = (Success<?>) o;
return this.reference.equals(other.reference);
}
@Override
public int hashCode() {
return 0x598df91c + this.reference.hashCode();
}
@Override
public String toString() {
return "Exceptional.of(" + this.reference + ")";
}
@Override
public Optional<T> toOptional() {
return Optional.of(this.reference);
}
@Override
public T get() {
return this.reference;
}
@Override
public Throwable failure() {
throw new IllegalStateException();
}
@Override
public boolean isSuccess() {
return true;
}
@Override
public boolean isFailure() {
return false;
}
}
private static final class Failure<T> extends Exceptional<T> {
private static final long serialVersionUID = 0L;
private final Throwable reference;
Failure(final Throwable reference) {
this.reference = reference;
}
@Override
public T or(final T other) {
return checkNotNull(other);
}
@Override
public Exceptional<T> or(final Exceptional<T> other) {
return checkNotNull(other);
}
@Override
public T orNull() {
return null;
}
@Override
public boolean equals(@Nullable final Object o) {
if (o == this) {
return true;
}
if (!(o instanceof Failure)) {
return false;
}
Failure<?> other = (Failure<?>) o;
return this.reference.equals(other.reference);
}
@Override
public int hashCode() {
return 0x598df91c + this.reference.hashCode();
}
@Override
public String toString() {
return "Exceptional.of(" + this.reference + ")";
}
@Override
public Optional<T> toOptional() {
return Optional.absent();
}
@Override
public T get() {
throw new IllegalStateException();
}
@Override
public Throwable failure() {
return this.reference;
}
@Override
public boolean isSuccess() {
return false;
}
@Override
public boolean isFailure() {
return true;
}
}
public abstract T or(T other);
public abstract Exceptional<T> or(Exceptional<T> other);
@Nullable
public abstract T orNull();
@Override
public abstract boolean equals(@Nullable Object object);
@Override
public abstract int hashCode();
@Override
public abstract String toString();
public abstract Optional<T> toOptional();
public abstract T get();
public abstract Throwable failure();
public abstract boolean isSuccess();
public abstract boolean isFailure();
}