package org.openlca.app.components; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.eclipse.swt.dnd.ByteArrayTransfer; import org.eclipse.swt.dnd.TransferData; import org.openlca.core.model.descriptors.BaseDescriptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The transfer type for model descriptors (subclasses of BaseDescriptor). The * allowed input is an array of base descriptors. Accordingly, the return type * is an array of these descriptors. */ public final class ModelTransfer extends ByteArrayTransfer { private Logger log = LoggerFactory.getLogger(this.getClass()); private static final String NAME = "model_component_transfer"; private static final int ID = registerType(NAME); private static ModelTransfer instance; private ModelTransfer() { } public static ModelTransfer getInstance() { if (instance == null) { instance = new ModelTransfer(); } return instance; } /** * Get the (first) model descriptor from the given transfer data. The given * data should be the data of a respective drop-event (event.data) using * this ModelTransfer class. */ public static BaseDescriptor getDescriptor(Object data) { if (data instanceof BaseDescriptor) return (BaseDescriptor) data; if (data instanceof Object[]) { Object[] objects = (Object[]) data; if (objects.length > 0 && (objects[0] instanceof BaseDescriptor)) return (BaseDescriptor) objects[0]; } return null; } /** * Get the model descriptors from the given transfer data. The given data * should be the data of a respective drop-event (event.data) using this * ModelTransfer class. */ public static List<BaseDescriptor> getBaseDescriptors(Object data) { if (data instanceof BaseDescriptor) return Arrays.asList((BaseDescriptor) data); if (data instanceof Object[]) { Object[] objects = (Object[]) data; ArrayList<BaseDescriptor> descriptors = new ArrayList<>(); for (int i = 0; i < objects.length; i++) { if (objects[i] instanceof BaseDescriptor) descriptors.add((BaseDescriptor) objects[i]); } return descriptors; } return Collections.emptyList(); } @Override protected int[] getTypeIds() { return new int[] { ID }; } @Override protected String[] getTypeNames() { return new String[] { NAME }; } @Override protected void javaToNative(Object object, TransferData transferData) { if (!validate(object) || !isSupportedType(transferData)) return; try (ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bytesOut)) { out.writeObject(object); byte[] buffer = bytesOut.toByteArray(); super.javaToNative(buffer, transferData); } catch (IOException e) { log.error("Java to native transfer failed", e); } } @Override protected Object nativeToJava(TransferData transferData) { if (!isSupportedType(transferData)) return new Object[0]; Object o = super.nativeToJava(transferData); if (!(o instanceof byte[])) return new Object[0]; byte[] bytes = (byte[]) o; try (ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes); ObjectInputStream in = new ObjectInputStream(bytesIn)) { return in.readObject(); } catch (Exception e) { log.error("Native to java transfer failed", e); return new Object[0]; } } @Override protected boolean validate(Object object) { if (!(object instanceof Object[])) return false; Object[] data = (Object[]) object; for (Object d : data) { if (!(d instanceof BaseDescriptor)) return false; } return true; } }