package org.rascalmpl.value.io;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import org.rascalmpl.value.IValue;
import org.rascalmpl.value.IValueFactory;
/**
* Experimental wrapper class for serializable IValues.
* Your mileage may vary due to use of the BinaryWriter.
*/
public class SerializableValue<T extends IValue> implements Serializable {
private static final long serialVersionUID = -5507315290306212326L;
private IValueFactory vf;
private T value;
public SerializableValue(IValueFactory vf, T value) {
this.vf = vf;
this.value = value;
}
public T getValue() {
return value;
}
public void write(OutputStream out) throws IOException {
new ObjectOutputStream(out).writeObject(this);
}
@SuppressWarnings("unchecked")
public static <U extends IValue> SerializableValue<U> read(InputStream in) throws IOException {
try {
return (SerializableValue<U>) new ObjectInputStream(in).readObject();
} catch (ClassNotFoundException e) {
throw new IOException(e);
}
}
@SuppressWarnings("deprecation")
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
String factoryName = vf.getClass().getName();
out.write("factory".getBytes());
out.write(':');
out.writeInt(factoryName.length());
out.write(':');
out.write(factoryName.getBytes("UTF8"));
out.write(':');
new BinaryValueWriter().write(value, out);
}
@SuppressWarnings("unchecked")
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
try {
in.read(new byte["factory".length()], 0, "factory".length());
in.read(); // ':'
int length = in.readInt();
in.read(); // ':'
byte[] factoryName = new byte[length];
in.read(factoryName, 0, length);
in.read(); // ':'
Class<?> clazz = getClass().getClassLoader().loadClass(new String(factoryName, "UTF8"));
this.vf = (IValueFactory) clazz.getMethod("getInstance").invoke(null, new Object[0]);
this.value = (T) new BinaryValueReader().read(vf, in);
}
catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException | NoSuchMethodException | SecurityException | ClassCastException e) {
throw new IOException("Could not load IValueFactory", e);
}
}
}