//
// This file is part of the Prose Development Tools for Eclipse package.
//
// The contents of this file are subject to the Mozilla Public License
// Version 1.1 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// The Original Code is Prose Development Tools for Eclipse.
//
// The Initial Developer of the Original Code is Angela Nicoara. Portions
// created by Angela Nicoara are Copyright (C) 2006 Angela Nicoara.
// All Rights Reserved.
//
// Contributor(s):
// $Id: RunNodeDropAdapter.java,v 1.1 2008/11/18 12:27:11 anicoara Exp $
// ==============================================================================
//
package ch.ethz.prose.eclipse.internal.run.dnd;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.util.SelectionUtil;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
import ch.ethz.prose.eclipse.internal.core.ProsePlugin;
import ch.ethz.prose.eclipse.internal.run.AspectManagerNode;
import ch.ethz.prose.eclipse.internal.run.AspectNode;
import ch.ethz.prose.eclipse.internal.run.UnreachableException;
/**
* Drop listener for aspect nodes.
*
* @author Angela Nicoara
* @author Johann Gyger
* @version $Id: RunNodeDropAdapter.java,v 1.1 2008/11/18 12:27:11 anicoara Exp $
*/
public class RunNodeDropAdapter extends DropTargetAdapter {
protected TreeViewer viewer;
protected int lastValidOperation = DND.DROP_NONE;
/**
* Create a new aspect drop adapter.
*
* @param viewer
*/
public RunNodeDropAdapter(TreeViewer viewer) {
this.viewer = viewer;
}
/* (non-Javadoc)
* @see org.eclipse.swt.dnd.DropTargetListener#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
*/
public void dragEnter(DropTargetEvent event) {
validateDrop(event);
}
/* (non-Javadoc)
* @see org.eclipse.swt.dnd.DropTargetListener#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent)
*/
public void dragOperationChanged(DropTargetEvent event) {
validateDrop(event);
}
/* (non-Javadoc)
* @see org.eclipse.swt.dnd.DropTargetListener#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
*/
public void dragOver(DropTargetEvent event) {
validateDrop(event);
}
/* (non-Javadoc)
* @see org.eclipse.swt.dnd.DropTargetListener#dropAccept(org.eclipse.swt.dnd.DropTargetEvent)
*/
public void dropAccept(DropTargetEvent event) {
validateDrop(event);
}
/**
* Validate this drop.
*
* @param event Drop target event to validate
*/
protected void validateDrop(DropTargetEvent event) {
if (event.detail != DND.DROP_NONE)
lastValidOperation = event.detail;
LocalSelectionTransfer transfer = LocalSelectionTransfer.getInstance();
Object source = SelectionUtil.getSingleElement(transfer.getSelection());
Object target = getTarget(event);
if ((event.currentDataType != null)
&& (transfer.isSupportedType(event.currentDataType))
&& (target instanceof AspectManagerNode)) {
if (source instanceof AspectNode) {
AspectNode aspect = (AspectNode) source;
// Allow drag operations on a different aspect manager node.
if (target != aspect.getAspectManager()) {
event.detail = lastValidOperation;
return;
}
// Allow copy drag operations on the same aspect manager node.
if (event.detail == DND.DROP_COPY) {
event.detail = lastValidOperation;
return;
}
} else if (source instanceof ICompilationUnit && (event.operations & DND.DROP_COPY) != 0) {
event.detail = DND.DROP_COPY;
return;
}
}
event.detail = DND.DROP_NONE;
}
/* (non-Javadoc)
* @see org.eclipse.swt.dnd.DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent)
*/
public void drop(DropTargetEvent event) {
IType type = null;
AspectManagerNode targetManager = (AspectManagerNode) getTarget(event);
Object source = SelectionUtil.getSingleElement(LocalSelectionTransfer.getInstance().getSelection());
if (source instanceof AspectNode) {
AspectNode aspect = (AspectNode) source;
// Since there is no classpath information in an AspectSurrogate, we
// have to seek the aspect class.
IJavaProject[] projects = getJavaProjects();
for (int i = 0; i < projects.length; i++) {
try {
type = projects[i].findType(aspect.getAspect().getAspectClassName());
if (type != null)
break;
} catch (JavaModelException e) {
ProsePlugin.log(e.getStatus());
break;
}
}
if (type == null) {
ProsePlugin.openErrorDialog("No aspect found", "No project contains an aspect named "
+ aspect.getAspect().getAspectClassName() + '.');
event.detail = DND.DROP_NONE;
return;
}
} else if (source instanceof ICompilationUnit){
type = ((ICompilationUnit) source).findPrimaryType();
if (type == null) {
ProsePlugin.openErrorDialog("No type found", "Compilation unit does not contain a type: " + source + '.');
event.detail = DND.DROP_NONE;
return;
}
}
try {
targetManager.insertAspect(type);
} catch (UnreachableException e) {
ProsePlugin.openErrorDialog("Aspect insertion failed",
"Could not insert aspect because Prose application is not reachable.");
event.detail = DND.DROP_NONE;
}
}
/**
* @param event Drop target event
* @return Drop target
*/
protected Object getTarget(DropTargetEvent event) {
return event.item == null ? null : event.item.getData();
}
/**
* @return All java projects of the current workbench
*/
protected IJavaProject[] getJavaProjects() {
try {
return JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()).getJavaProjects();
} catch (JavaModelException e) {
ProsePlugin.log(e.getStatus());
return new IJavaProject[0];
}
}
}