package xapi.util.api;
import xapi.except.NotImplemented;
import xapi.fu.In2Out1;
import xapi.fu.X_Fu;
import java.io.Serializable;
import java.util.Arrays;
/**
* Created by James X. Nelson (james @wetheinter.net) on 7/17/16.
*/
public class SerializableWrapper<T extends Serializable> implements Serializable {
private final T id;
private final int hash;
private final In2Out1<T, T, Boolean> filter;
public SerializableWrapper(T id, int hash, In2Out1<T, T, Boolean> filter) {
this.id = id;
this.hash = hash;
this.filter = filter;
}
public T getValue() {
return id;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof SerializableWrapper) {
obj = ((SerializableWrapper) obj).id;
if (!id.getClass().isAssignableFrom(obj.getClass())) {
return false;
}
return filter.io(id, (T) obj);
}
return false;
}
@Override
public int hashCode() {
return hash;
}
public static Serializable serializableId(Serializable id) {
if (id == null) {
return "null";
}
final Class<? extends Serializable> cls = id.getClass();
if (!cls.isArray()) {
if (X_Fu.isLambda(id)) {
String name = X_Fu.getLambdaMethodName(id);
if (name != null) {
return name;
}
}
return id;
}
if (!cls.getComponentType().isPrimitive()) {
// an array of arrays...
return new SerializableWrapper<>((Object[]) id, Arrays.deepHashCode((Object[]) id), Arrays::deepEquals);
}
if (id instanceof int[]) {
return new SerializableWrapper<>((int[]) id, Arrays.hashCode((int[]) id), Arrays::equals);
} else if (id instanceof double[]) {
return new SerializableWrapper<>((double[]) id, Arrays.hashCode((double[]) id), Arrays::equals);
} else if (id instanceof boolean[]) {
return new SerializableWrapper<>((boolean[]) id, Arrays.hashCode((boolean[]) id), Arrays::equals);
} else if (id instanceof byte[]) {
return new SerializableWrapper<>((byte[]) id, Arrays.hashCode((byte[]) id), Arrays::equals);
} else if (id instanceof char[]) {
return new SerializableWrapper<>((char[]) id, Arrays.hashCode((char[]) id), Arrays::equals);
} else if (id instanceof float[]) {
return new SerializableWrapper<>((float[]) id, Arrays.hashCode((float[]) id), Arrays::equals);
} else if (id instanceof long[]) {
return new SerializableWrapper<>((long[]) id, Arrays.hashCode((long[]) id), Arrays::equals);
} else if (id instanceof short[]) {
return new SerializableWrapper<>((short[]) id, Arrays.hashCode((short[]) id), Arrays::equals);
} else {
throw new NotImplemented("Cannot create a serializable wrapper for " + id);
}
}
}