package sk.stuba.fiit.perconik.utilities.constant; import java.io.InvalidObjectException; import java.io.Serializable; import java.util.Map; import java.util.Set; import com.google.common.base.Function; import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableBiMap; import static com.google.common.collect.Maps.newHashMapWithExpectedSize; abstract class AbstractConstantSupport<P, E extends Enum<E>> implements Serializable { private static final long serialVersionUID = -3235429686838483239L; final Class<E> type; final BiMap<P, E> map; AbstractConstantSupport(final Class<E> type) { if (!type.isEnum()) { throw new IllegalArgumentException(); } this.type = type; E[] constants = this.type.getEnumConstants(); Map<P, E> map = newHashMapWithExpectedSize(constants.length); Function<E, P> transformation = this.transformation(); for (E constant: constants) { P primitive = transformation.apply(constant); if (map.put(primitive, constant) != null) { throw new AssertionError("Primitive " + primitive + " or constant " + constant.name() + " already associated"); } } this.map = ImmutableBiMap.copyOf(map); } abstract Function<E, P> transformation(); abstract static class AbstractSerializationProxy<P, E extends Enum<E>, S extends AbstractConstantSupport<P, E>> implements Serializable { private static final long serialVersionUID = -72790832310176072L; private final Class<E> type; AbstractSerializationProxy(final AbstractConstantSupport<P, E> support) { this.type = support.type; } abstract AbstractConstantSupport<P, E> resolve(Class<E> type); final Object readResolve() throws InvalidObjectException { try { return resolve(this.type); } catch (Exception e) { throw new InvalidObjectException("Unknown deserialization error"); } } } public final Set<E> getConstants() { return this.map.values(); } }