/*******************************************************************************
* Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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
*
* Contributors:
* Exadel, Inc. and Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.common.model.ui.editors.dnd.context;
import java.io.File;
import java.net.MalformedURLException;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.HTMLTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.events.TypedEvent;
import org.jboss.tools.common.model.XModelObject;
import org.jboss.tools.common.model.XModelTransferBuffer;
import org.jboss.tools.common.model.options.PreferenceModelUtilities;
import org.jboss.tools.common.model.ui.ModelUIPlugin;
import org.jboss.tools.common.model.ui.dnd.ModelTransfer;
import org.jboss.tools.common.model.ui.dnd.VpeDnDEvent;
import org.jboss.tools.common.model.ui.dnd.VpeTextDropAction;
import org.jboss.tools.common.model.ui.editors.dnd.DropUtils;
import org.jboss.tools.common.model.util.EclipseResourceUtil;
/**
* @author glory
*/
public class DropContext {
private boolean isOverAttributeValue = false;
private String attributeName = null;
private String flavor = null;
private String mimeData = null;
private TypedEvent event;
public void setFlavor(String flavor) {
this.flavor = flavor;
}
public void setMimeData(String mimeData) {
this.mimeData = mimeData;
}
public void clean() {
isOverAttributeValue = false;
flavor = null;
mimeData = null;
attributeName = null;
}
public boolean isOverAttributeValue() {
return isOverAttributeValue;
}
public void setOverAttributeValue(boolean b) {
isOverAttributeValue = b;
}
public void setAttributeName(String attr) {
this.attributeName = attr;
}
public String getAttributeName() {
return attributeName;
}
public String getFlavor() {
return flavor;
}
public String getMimeData() {
return mimeData;
}
TransferHolder[] TRANSFERS = {
new TransferHolder(LocalSelectionTransfer.getTransfer(), new LocalTransferProcessor()),
new TransferHolder(ModelTransfer.getInstance(), new ModelTransferProcessor()),
new TransferHolder(HTMLTransfer.getInstance(), new HTMLTransferProcessor()),
new TransferHolder(FileTransfer.getInstance(), new FileTransferProcessor()),
new TransferHolder(TextTransfer.getInstance(), new TextTransferProcessor()),
};
public boolean isDropAllowed(){
if(this.event instanceof DropTargetEvent){
TransferData dataType = ((DropTargetEvent)event).currentDataType;
for(TransferHolder th : TRANSFERS){
if(th.transfer.isSupportedType(dataType)){
return true;
}
}
}
return false;
}
public void setDropTargetEvent(TypedEvent event) {
this.event = event;
TransferData[] ds = null;
if(this.event instanceof DropTargetEvent){
ds = ((DropTargetEvent)event).dataTypes;
}else if(this.event instanceof VpeDnDEvent){
ds = ((VpeDnDEvent)this.event).getDataTypes();
}
if(ds!=null){
for (int i = 0; i < TRANSFERS.length; i++) {
TransferData data = TRANSFERS[i].getSupportedData(ds);
if(data != null) {
TRANSFERS[i].process(data);
break;
}
}
}
}
private String getURL(TypedEvent event) {
String[] s = (String[])event.data;
if(s == null || s.length == 0) {
return null;
} else {
return DropUtils.convertPathToUrl(s[0]);
}
}
private File getFile(TypedEvent event) {
String[] s = (String[])event.data;
return(s == null || s.length == 0) ? null : new File(s[0]);
}
private String getURL(XModelObject o) {
if(o.getFileType() == XModelObject.FILE) {
IFile f = (IFile)EclipseResourceUtil.getResource(o);
if(f == null || !f.exists()) return null;
try {
return f.getLocation().toFile().toURL().toString();
} catch (MalformedURLException e) {
ModelUIPlugin.getPluginLog().logError(e);
}
}
return null;
}
public void runDropCommand(IDNDTextEditor editor, TypedEvent event) {
setDropTargetEvent(event);
runDropCommand(editor);
}
public void runDropCommand(IDNDTextEditor editor) {
if(event == null) return;
if(getFlavor() == null) {
return;
} else if (getFlavor().equals("text/html")) { //$NON-NLS-1$
new VpeTextDropAction().run(event, editor);
} else {
editor.runDropCommand(getFlavor(), getMimeData());
}
event = null;
}
//see FileTagProposalLoader
public static Set<String> mappedExtensions = new HashSet<String>();
public static boolean isExtensionMapped(String extension) {
return extension != null && mappedExtensions.contains(extension.toLowerCase());
}
private boolean dropAsFileObject(XModelObject o) {
if(o == null) return false;
if(o.getFileType() != XModelObject.FILE || isOverAttributeValue) return false;
if(isTaglib(o)) return false;
String extension = o.getAttributeValue("extension"); //$NON-NLS-1$
return extension != null && isExtensionMapped(extension);
}
//TODO do not reference tld here
//TLDUtil.isTaglib(o)
static String FILE_ENTITIES = ".FileTLD_PRO.FileTLD_1_2.FileTLD_2_0.FileTLD_2_1."; //$NON-NLS-1$
public static boolean isTaglib(XModelObject o) {
return isOfEntity(o, FILE_ENTITIES);
}
private static boolean isOfEntity(XModelObject o, String entities) {
return entities.indexOf("." + o.getModelEntity().getName() + ".") >= 0; //$NON-NLS-1$//$NON-NLS-2$
}
class TransferHolder {
Transfer transfer;
TransferProcessor processor;
public TransferHolder(Transfer transfer, TransferProcessor processor) {
this.transfer = transfer;
this.processor = processor;
}
public TransferData getSupportedData(TransferData[] data) {
for (int i = 0; i < data.length; i++) {
if(transfer.isSupportedType(data[i])) return data[i];
}
return null;
}
public void process(TransferData data) {
processor.process(data);
}
}
abstract class TransferProcessor {
abstract void process(TransferData data);
}
class ModelTransferProcessor extends TransferProcessor {
public void process(TransferData data) {
if(!XModelTransferBuffer.getInstance().isEnabled()) return;
XModelObject o = PreferenceModelUtilities.getPreferenceModel().getModelBuffer().source();
if(dropAsFileObject(o)) {
flavor = "application/x-moz-file"; //$NON-NLS-1$
mimeData = getURL(o);
if(mimeData == null) flavor = ModelTransfer.MODEL;
} else {
flavor = ModelTransfer.MODEL;
}
}
}
class HTMLTransferProcessor extends TransferProcessor {
public void process(TransferData data) {
flavor = "text/html"; //$NON-NLS-1$
TransferData currentDataType = null;
if(event instanceof DropTargetEvent){
currentDataType = (( DropTargetEvent)event).currentDataType;
}else if(event instanceof VpeDnDEvent){
currentDataType = ((VpeDnDEvent)event).currentDataType;
}
Object ooo = HTMLTransfer.getInstance().nativeToJava(currentDataType);
mimeData = ooo == null ? null : ooo.toString();
if(mimeData == null) {
flavor = null;
}
}
}
class LocalTransferProcessor extends TransferProcessor {
public void process(TransferData data) {
flavor = "application/x-moz-file"; //$NON-NLS-1$
Object ooo = LocalSelectionTransfer.getTransfer().getSelection();
if(ooo instanceof StructuredSelection) {
ooo = ((StructuredSelection)ooo).getFirstElement();
// commented by yradtsevich, see JBIDE-6439 (InnerDragBuffer is removed,
// nodes are transfered through vpe/xpath flavor now)
//InnerDragBuffer.setInnerDragObject(ooo);
}
mimeData = ooo == null ? null : ooo.toString();
}
}
class FileTransferProcessor extends TransferProcessor {
public void process(TransferData data) {
ISelection s = LocalSelectionTransfer.getTransfer().getSelection();
if(s != null) {
if(s.isEmpty() || !(s instanceof IStructuredSelection)) return;
Object o = ((IStructuredSelection)s).getFirstElement();
boolean ok = o instanceof IFile;
if(!ok && (o instanceof IAdaptable)) {
ok = ((IAdaptable)o).getAdapter(IFile.class) != null
&& ((IAdaptable)o).getAdapter(IResource.class) != null;
}
if(!ok) return;
}
mimeData = getURL(event);
flavor = "application/x-moz-file"; //$NON-NLS-1$
if(mimeData != null && isOverAttributeValue) {
String path = getFile(event).getAbsolutePath();
IFile f = EclipseResourceUtil.getFile(path);
XModelObject fo = (f == null) ? null : EclipseResourceUtil.getObjectByResource(f);
if(fo != null) {
fo.getModel().getModelBuffer().clear();
fo.getModel().getModelBuffer().addSource(fo);
flavor = ModelTransfer.MODEL;
}
}
}
}
class TextTransferProcessor extends TransferProcessor {
public void process(TransferData data) {
flavor = "text/html"; //$NON-NLS-1$
}
}
}