package org.archstudio.archipelago2;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.archstudio.bna.constants.DNDData;
import org.archstudio.bna.ui.IUITransferProvider;
import org.archstudio.xarchadt.ObjRef;
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.TransferData;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
public class OutlineElementTransfer extends ByteArrayTransfer implements IUITransferProvider {
private static Cache<ObjRef, Object> transferredObjRefs =
CacheBuilder.newBuilder().expireAfterWrite(12, TimeUnit.HOURS).build();
private static final String OUTLINE_ELEMENT_TYPE_NAME = OutlineElementTransfer.class.getName();
private static final int OUTLINE_ELEMENT_TYPE_ID = registerType(OUTLINE_ELEMENT_TYPE_NAME);
private static final String TRANSFER_PREFIX = OUTLINE_ELEMENT_TYPE_NAME + ":";
private static OutlineElementTransfer _instance = new OutlineElementTransfer();
private OutlineElementTransfer() {}
public static IUITransferProvider getInstance() {
return _instance;
}
@Override
public void addData(TransferData transferData, DNDData dndData) {
List<Object> element = nativeToJava(transferData);
if (element != null) {
dndData.addData(element);
for (Object node : element) {
dndData.addData(node);
}
}
}
@Override
public void javaToNative(Object object, TransferData transferData) {
if (object != null && isSupportedType(transferData)) {
if (object instanceof List<?>) {
List<?> list = (List<?>) object;
StringBuffer sb = new StringBuffer();
sb.append(TRANSFER_PREFIX);
for (Object item : list) {
sb.append("\t");
if (item == null) {
sb.append("null");
} else if (item instanceof String) {
sb.append("String:").append(((String) item).replace("\\", "\\\\").replace("\t", "\\t"));
} else if (item instanceof ObjRef) {
// hold the ObjRef so it is not garbage collected
transferredObjRefs.put((ObjRef) item, item);
sb.append("ObjRef:").append(((ObjRef) item).getUID());
} else {
throw new IllegalArgumentException("Unsupported object type: " + item);
}
}
super.javaToNative(sb.toString().getBytes(), transferData);
} else {
throw new IllegalArgumentException("Unsupported object type: " + object);
}
} else {
throw new IllegalArgumentException("Unsupported object type: " + object);
}
}
@Override
public List<Object> nativeToJava(TransferData transferData) {
if (isSupportedType(transferData)) {
byte[] buffer = (byte[]) super.nativeToJava(transferData);
if (buffer != null) {
String bufferString = new String(buffer);
if (bufferString.startsWith(TRANSFER_PREFIX + "\t")) {
List<Object> list = Lists.newArrayList();
for (String item : bufferString.split("\t")) {
if (item.equals(TRANSFER_PREFIX)) {
} else if (item.startsWith("String:")) {
list.add(
item.substring("String:".length()).replace("\\t", "\t").replace("\\\\", "\\"));
} else if (item.startsWith("ObjRef:")) {
list.add(ObjRef.lookupObjRef(Long.parseLong(item.substring("ObjRef:".length()))));
} else {
throw new IllegalArgumentException("Unsupported object type: " + item);
}
}
return list;
}
}
}
return null;
}
@Override
protected String[] getTypeNames() {
return new String[] {OUTLINE_ELEMENT_TYPE_NAME};
}
@Override
protected int[] getTypeIds() {
return new int[] {OUTLINE_ELEMENT_TYPE_ID};
}
}