/******************************************************************************* * Copyright (c) 2011 Oak Ridge National Laboratory. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html ******************************************************************************/ package org.csstudio.ui.util.dnd; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.csstudio.ui.util.ReflectUtil; import org.eclipse.swt.dnd.ByteArrayTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.dnd.TransferData; /** * Drag-and-Drop Transfer for any serializable object. * * @author Gabriele Carcassi * @author Kay Kasemir */ @SuppressWarnings("nls") public class SerializableItemTransfer extends ByteArrayTransfer { /** Type handled by this Transfer */ final private String className; /** Name of the type handled by this Transfer ('java:' + class name) */ final private String typeName; /** Drag-and-Drop type ID for the <code>typeName</code> */ final private int typeId; /** Cache of types to the SerializableItemTransfer for that type */ final private static Map<String, SerializableItemTransfer> instances = new HashMap<String, SerializableItemTransfer>(); /** @param classes Types to be transferred * @return Transfers for those types */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static Transfer[] getTransfers(Class[] classes) { final Transfer[] transfers = new Transfer[classes.length]; for (int i = 0; i < classes.length ; i++) { Transfer transfer = getTransfer(classes[i]); transfers[i] = transfer; } return transfers; } public static Collection<Transfer> getTransfers(Collection<String> classeNames) { Collection<Transfer> transfers = new ArrayList<Transfer>(); for (String className : classeNames) { transfers.add(getTransfer(className)); } return transfers; } public static SerializableItemTransfer getTransfer(Class<? extends Serializable> clazz) { return getTransfer(clazz.getName()); } /** @param clazz Type to be transferred * @return Transfer for that type */ public static SerializableItemTransfer getTransfer(String className) { SerializableItemTransfer transfer = instances.get(className); if (transfer == null) { transfer = new SerializableItemTransfer(className); instances.put(className, transfer); } return transfer; } /** Initialize * @param clazz Type handled by this Transfer */ private SerializableItemTransfer(final String className) { this.className = className; typeName = "java:" + className; typeId = registerType(typeName); } /** {@inheritDoc} */ @Override protected int[] getTypeIds() { return new int[] { typeId }; } /** {@inheritDoc} */ @Override protected String[] getTypeNames() { return new String[] { typeName }; } public String getClassName() { return className; } /** Serialize item * {@inheritDoc} */ @Override public void javaToNative (final Object object, final TransferData transferData) { // Check that it's an object of the right type if (!ReflectUtil.isInstance(object, getClassName())) { throw new IllegalArgumentException("Trying to serialize and object of the wrong type"); } try { // Write data to a byte array final ByteArrayOutputStream out = new ByteArrayOutputStream(); final ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject(object); final byte[] buffer = out.toByteArray(); oos.close(); // ByteArrayTransfer converts to medium super.javaToNative(buffer, transferData); } catch (IOException ex) { Logger.getLogger(getClass().getName()).log(Level.WARNING, "Serialization failed", ex); } } /** De-serialize items * {@inheritDoc} */ @Override public Object nativeToJava(final TransferData transferData) { if (!isSupportedType(transferData)) return null; final byte[] buffer = (byte[]) super.nativeToJava(transferData); if (buffer == null) return null; final Object obj; try { final ByteArrayInputStream in = new ByteArrayInputStream(buffer); final ObjectInputStream readIn = new ObjectInputStreamWithOsgiClassResolution(in); obj = readIn.readObject(); readIn.close(); return obj; } catch (Exception ex) { Logger.getLogger(getClass().getName()).log(Level.WARNING, "De-Serialization failed", ex); } return null; } @Override public String toString() { return "SerializableItemTransfer for " + typeName; } }