package sk.stuba.fiit.perconik.utilities.constant;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.util.EnumSet;
import java.util.Set;
import javax.annotation.Nonnull;
import com.google.common.base.Function;
import static com.google.common.base.Preconditions.checkArgument;
public final class IntegralConstantSupport<E extends Enum<E> & IntegralConstant> extends AbstractConstantSupport<Integer, E> {
private static final long serialVersionUID = 6686975853072661262L;
private IntegralConstantSupport(final Class<E> type) {
super(type);
}
private enum Transformation implements Function<IntegralConstant, Integer> {
INSTANCE;
public Integer apply(@Nonnull final IntegralConstant constant) {
return constant.getValue();
}
}
@Override
@SuppressWarnings("unchecked")
Function<E, Integer> transformation() {
return (Function<E, Integer>) Transformation.INSTANCE;
}
public static <E extends Enum<E> & IntegralConstant> IntegralConstantSupport<E> of(final Class<E> type) {
return new IntegralConstantSupport<>(type);
}
public static <E extends Enum<E> & IntegralConstant> int constantsAsInteger(final Set<E> constants) {
int values = 0;
for (E constant: constants) {
values |= constant.getValue();
}
return values;
}
private static final class SerializationProxy<E extends Enum<E> & IntegralConstant> extends AbstractSerializationProxy<Integer, E, IntegralConstantSupport<E>> {
private static final long serialVersionUID = -8420579032363855266L;
SerializationProxy(final IntegralConstantSupport<E> support) {
super(support);
}
@Override
IntegralConstantSupport<E> resolve(final Class<E> type) {
return of(type);
}
}
@SuppressWarnings({"static-method", "unused"})
private void readObject(final ObjectInputStream in) throws InvalidObjectException {
throw new InvalidObjectException("Serialization proxy required");
}
private Object writeReplace() {
return new SerializationProxy<>(this);
}
public Set<Integer> getIntegers() {
return this.map.keySet();
}
public int getConstantsAsInteger() {
return constantsAsInteger(this.map.values());
}
public Set<E> getConstants(final int values) {
Set<E> flags = EnumSet.noneOf(this.type);
for (E constant: this.map.values()) {
if ((values & constant.getValue()) != 0) {
flags.add(constant);
}
}
return flags;
}
public E getConstant(final int value) {
E constant = this.map.get(value);
checkArgument(constant != null, "Constant for value %s not found", value);
return constant;
}
}