package edu.ualberta.med.biobank.widgets.multiselect;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.TransferData;
import edu.ualberta.med.biobank.SessionManager;
import edu.ualberta.med.biobank.common.wrappers.ModelWrapper;
import gov.nih.nci.system.applicationservice.WritableApplicationService;
public class MultiSelectNodeTransfer extends ByteArrayTransfer {
private static final MultiSelectNodeTransfer INSTANCE = new MultiSelectNodeTransfer();
public static MultiSelectNodeTransfer getInstance() {
return INSTANCE;
}
private MultiSelectNodeTransfer() {
super();
}
private static final String TYPE_NAME = "favorites-transfer-format:" //$NON-NLS-1$
+ System.currentTimeMillis() + ":" + INSTANCE.hashCode(); //$NON-NLS-1$
private static final int TYPEID = registerType(TYPE_NAME);
@Override
protected int[] getTypeIds() {
return new int[] { TYPEID };
}
@Override
protected String[] getTypeNames() {
return new String[] { TYPE_NAME };
}
@Override
protected void javaToNative(Object data, TransferData transferData) {
if (!(data instanceof MultiSelectNode<?>[]))
return;
MultiSelectNode<?>[] items = (MultiSelectNode<?>[]) data;
/**
* The serialization format is: (int) number of items Then, the
* following for each item: (String) the id (String) the model wrapper
* class name
*/
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
DataOutputStream dataOut = new DataOutputStream(out);
dataOut.writeInt(items.length);
for (int i = 0; i < items.length; i++) {
MultiSelectNode<?> item = items[i];
if (item.getNodeObject() instanceof ModelWrapper<?>) {
ModelWrapper<?> mw = (ModelWrapper<?>) item.getNodeObject();
dataOut.writeUTF(mw.getId().toString());
dataOut.writeUTF(mw.getClass().getName());
}
}
dataOut.close();
out.close();
super.javaToNative(out.toByteArray(), transferData);
} catch (IOException e) {
// Send nothing if there were problems.
}
}
@Override
protected Object nativeToJava(TransferData transferData) {
/**
* The serialization format is: (int) number of items Then, the
* following for each item: (String) id (String) class name
*/
byte[] bytes = (byte[]) super.nativeToJava(transferData);
if (bytes == null)
return null;
DataInputStream in = new DataInputStream(
new ByteArrayInputStream(bytes));
try {
int count = in.readInt();
List<MultiSelectNode<?>> items = new ArrayList<MultiSelectNode<?>>(
count);
for (int i = 0; i < count; i++) {
Integer id = Integer.valueOf(in.readUTF());
String clazz = in.readUTF();
ModelWrapper<?> wrapper;
wrapper = getModelWrapper(clazz, id);
items.add(new MultiSelectNode<ModelWrapper<?>>(null, wrapper));
}
return items.toArray(new MultiSelectNode<?>[items.size()]);
} catch (Exception e) {
return null;
}
}
@SuppressWarnings("unchecked")
private ModelWrapper<?> getModelWrapper(String clazzName, Integer id)
throws Exception {
Class<ModelWrapper<?>> clazz = (Class<ModelWrapper<?>>) Class
.forName(clazzName);
Constructor<ModelWrapper<?>> constructor = clazz
.getConstructor(WritableApplicationService.class);
ModelWrapper<?> wrapper = constructor.newInstance(SessionManager
.getAppService());
while (clazz != null && !clazz.equals(ModelWrapper.class)) {
clazz = (Class<ModelWrapper<?>>) clazz.getSuperclass();
}
if (clazz != null) {
Method setIdMethod = clazz
.getDeclaredMethod("setId", Integer.class); //$NON-NLS-1$
setIdMethod.setAccessible(true);
setIdMethod.invoke(wrapper, id);
wrapper.reload();
return wrapper;
}
return null;
}
}