blob: 3e7d944cc81ccc66aec22e4bfa71496b761cf47c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pivot.functional.monad;
import java.util.Iterator;
import org.apache.pivot.annotations.UnsupportedOperation;
/**
* Definition of a generic Option container, to hold an invariant value (derived from Monad).
*/
public abstract class Option<T> extends Monad<T> implements Iterable<T> {
protected final T value;
/**
* Default constructor, do not use because it set null as invariant value to hold.
*/
public Option() {
this(null);
}
/**
* Constructor with a value to set in the Option.
* @param val the value to set in the Option
*/
public Option(final T val) {
this.value = val;
}
/**
* Tell if the value has been set in the Option.
* @return true if set, otherwise false
*/
public abstract boolean hasValue();
/**
* Return the value contained in the Option.
* @return the value (if set)
*/
public abstract T getValue();
/**
* Return the value contained in the Option, or an alternative value if not set.
* @param alternativeValue the value to return as alternative (if value wasn't set in the Option)
* @return value if set, otherwise alternativeValue
*/
public T getValueOrElse(final T alternativeValue) {
return hasValue() ? getValue() : alternativeValue;
}
/**
* Return the value contained in the Option, or null if it hasn't a value set.
* @return value if set, otherwise null
*/
public T getValueOrNull() {
return getValueOrElse(null);
}
@Override
public String toString() {
return "Option(" + ((value != null) ? value.toString() : "null") + ")";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@SuppressWarnings("rawtypes")
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Option)) {
return false;
}
Option other = (Option) obj;
if (value == null) {
if (other.value != null) {
return false;
}
} else if (!value.equals(other.value)) {
return false;
}
return true;
}
/**
* Return an Iterator over this option.
* @see java.lang.Iterable#iterator()
*/
@Override
public Iterator<T> iterator() {
return new OptionIterator();
}
/**
* Immutable iterator on the value contained in the Option (if any).
*/
private class OptionIterator implements Iterator<T> {
private int cursor = 0;
@Override
public boolean hasNext() {
return (hasValue() && cursor == 0);
}
@Override
public T next() {
cursor++;
return getValue();
}
@Override
@UnsupportedOperation
public void remove() {
throw new UnsupportedOperationException();
}
}
}