1 /*******************************************************************************
2 * Copyright (c) 2012 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.handlers
;
16 import java
.lang
.reflect
.InvocationTargetException
;
17 import java
.util
.LinkedList
;
18 import java
.util
.List
;
21 import org
.eclipse
.core
.resources
.IFile
;
22 import org
.eclipse
.core
.resources
.IFolder
;
23 import org
.eclipse
.core
.resources
.IProject
;
24 import org
.eclipse
.core
.resources
.IResource
;
25 import org
.eclipse
.core
.resources
.IWorkspace
;
26 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
27 import org
.eclipse
.core
.runtime
.CoreException
;
28 import org
.eclipse
.core
.runtime
.IPath
;
29 import org
.eclipse
.core
.runtime
.IStatus
;
30 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
31 import org
.eclipse
.core
.runtime
.Path
;
32 import org
.eclipse
.core
.runtime
.QualifiedName
;
33 import org
.eclipse
.core
.runtime
.Status
;
34 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
35 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.TmfCommonConstants
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTrace
;
38 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.ITmfProjectModelElement
;
39 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfExperimentElement
;
40 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectElement
;
41 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectRegistry
;
42 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceElement
;
43 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceFolder
;
44 import org
.eclipse
.swt
.dnd
.DND
;
45 import org
.eclipse
.swt
.dnd
.DropTargetEvent
;
46 import org
.eclipse
.swt
.dnd
.FileTransfer
;
47 import org
.eclipse
.swt
.dnd
.TransferData
;
48 import org
.eclipse
.swt
.widgets
.MessageBox
;
49 import org
.eclipse
.ui
.PlatformUI
;
50 import org
.eclipse
.ui
.dialogs
.IOverwriteQuery
;
51 import org
.eclipse
.ui
.navigator
.CommonDropAdapter
;
52 import org
.eclipse
.ui
.navigator
.CommonDropAdapterAssistant
;
53 import org
.eclipse
.ui
.wizards
.datatransfer
.FileSystemStructureProvider
;
54 import org
.eclipse
.ui
.wizards
.datatransfer
.ImportOperation
;
57 * Drop adapter assistant for project explorer
59 public class DropAdapterAssistant
extends CommonDropAdapterAssistant
{
64 public DropAdapterAssistant() {
68 * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#isSupportedType(org.eclipse.swt.dnd.TransferData)
71 public boolean isSupportedType(TransferData aTransferType
) {
72 return super.isSupportedType(aTransferType
) || FileTransfer
.getInstance().isSupportedType(aTransferType
);
76 * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#validateDrop(java.lang.Object, int, org.eclipse.swt.dnd.TransferData)
79 public IStatus
validateDrop(Object target
, int operation
, TransferData transferType
) {
80 if (target
instanceof TmfTraceFolder
) {
81 getCommonDropAdapter().overrideOperation(DND
.DROP_COPY
);
82 return Status
.OK_STATUS
;
84 if (target
instanceof TmfExperimentElement
) {
85 getCommonDropAdapter().overrideOperation(DND
.DROP_LINK
);
86 return Status
.OK_STATUS
;
88 if (target
instanceof TmfTraceElement
) {
89 ITmfProjectModelElement parent
= ((TmfTraceElement
) target
).getParent();
90 if (parent
instanceof TmfTraceFolder
) {
91 getCommonDropAdapter().overrideOperation(DND
.DROP_COPY
);
92 return Status
.OK_STATUS
;
94 if (parent
instanceof TmfExperimentElement
) {
95 getCommonDropAdapter().overrideOperation(DND
.DROP_LINK
);
96 return Status
.OK_STATUS
;
99 if (target
instanceof IProject
) {
100 getCommonDropAdapter().overrideOperation(DND
.DROP_COPY
);
101 return Status
.OK_STATUS
;
103 return Status
.CANCEL_STATUS
;
107 * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#handleDrop(org.eclipse.ui.navigator.CommonDropAdapter, org.eclipse.swt.dnd.DropTargetEvent, java.lang.Object)
110 public IStatus
handleDrop(CommonDropAdapter aDropAdapter
, DropTargetEvent aDropTargetEvent
, Object aTarget
) {
113 // Use local variable to avoid parameter assignment
114 Object targetToUse
= aTarget
;
116 // If target is a trace, use its parent (either trace folder or experiment)
117 if (targetToUse
instanceof TmfTraceElement
) {
118 targetToUse
= ((TmfTraceElement
) targetToUse
).getParent();
121 // If target is a project, use its trace folder
122 if (targetToUse
instanceof IProject
) {
123 TmfProjectElement projectElement
= TmfProjectRegistry
.getProject((IProject
) targetToUse
);
124 if (projectElement
!= null) {
125 targetToUse
= projectElement
.getTracesFolder();
129 if (aDropTargetEvent
.data
instanceof IStructuredSelection
) {
130 IStructuredSelection selection
= (IStructuredSelection
) aDropTargetEvent
.data
;
131 for (Object source
: selection
.toArray()) {
132 if (source
instanceof IResource
) {
133 // If source resource is a trace, use the trace element
134 IResource sourceResource
= (IResource
) source
;
135 TmfProjectElement projectElement
= TmfProjectRegistry
.getProject(sourceResource
.getProject());
136 if (projectElement
!= null && projectElement
.getTracesFolder() != null) {
137 for (TmfTraceElement trace
: projectElement
.getTracesFolder().getTraces()) {
138 if (trace
.getResource().equals(sourceResource
)) {
145 if (source
instanceof TmfTraceElement
) {
146 TmfTraceElement sourceTrace
= (TmfTraceElement
) source
;
147 // If source trace is under an experiment, use the original trace from the traces folder
148 if (sourceTrace
.getParent() instanceof TmfExperimentElement
) {
149 for (TmfTraceElement trace
: sourceTrace
.getProject().getTracesFolder().getTraces()) {
150 if (trace
.getName().equals(sourceTrace
.getName())) {
156 if (targetToUse
instanceof TmfExperimentElement
) {
157 TmfExperimentElement targetExperiment
= (TmfExperimentElement
) targetToUse
;
158 ok
|= drop(sourceTrace
, targetExperiment
);
159 } else if (targetToUse
instanceof TmfTraceFolder
) {
160 TmfTraceFolder traceFolder
= (TmfTraceFolder
) targetToUse
;
161 ok
|= drop(sourceTrace
, traceFolder
);
163 } else if (source
instanceof IResource
) {
164 IResource sourceResource
= (IResource
) source
;
165 if (sourceResource
.getType() != IResource
.FILE
&& sourceResource
.getType() != IResource
.FOLDER
) {
168 if (targetToUse
instanceof TmfExperimentElement
) {
169 TmfExperimentElement targetExperiment
= (TmfExperimentElement
) targetToUse
;
170 ok
|= drop(sourceResource
, targetExperiment
);
171 } else if (targetToUse
instanceof TmfTraceFolder
) {
172 TmfTraceFolder traceFolder
= (TmfTraceFolder
) targetToUse
;
173 ok
|= drop(sourceResource
, traceFolder
);
177 } else if (aDropTargetEvent
.data
instanceof String
[]) {
178 String
[] sources
= (String
[]) aDropTargetEvent
.data
;
179 for (String source
: sources
) {
180 Path path
= new Path(source
);
181 if (targetToUse
instanceof TmfExperimentElement
) {
182 TmfExperimentElement targetExperiment
= (TmfExperimentElement
) targetToUse
;
183 ok
|= drop(path
, targetExperiment
);
184 } else if (targetToUse
instanceof TmfTraceFolder
) {
185 TmfTraceFolder traceFolder
= (TmfTraceFolder
) targetToUse
;
186 ok
|= drop(path
, traceFolder
);
190 return (ok ? Status
.OK_STATUS
: Status
.CANCEL_STATUS
);
195 * Drop a trace by copying a resource in a target experiment
197 * @param sourceTrace the source trace element to copy
198 * @param targetExperiment the target experiment
199 * @return true if successful
201 private static boolean drop(TmfTraceElement sourceTrace
,
202 TmfExperimentElement targetExperiment
) {
204 IResource sourceResource
= sourceTrace
.getResource();
206 if (drop(sourceResource
, targetExperiment
)) {
207 IFolder destinationSupplementaryFolder
= targetExperiment
.getTraceSupplementaryFolder(sourceResource
.getName());
208 if (!destinationSupplementaryFolder
.exists()) {
209 sourceTrace
.copySupplementaryFolder(destinationSupplementaryFolder
);
217 * Drop a trace by copying a resource in a target experiment
219 * @param sourceResource the source resource
220 * @param targetExperiment the target experiment
221 * @return true if successful
223 private static boolean drop(IResource sourceResource
,
224 TmfExperimentElement targetExperiment
) {
227 //Use local variable to avoid parameter assignment
228 IResource sourceResourceToUse
= sourceResource
;
230 TmfProjectElement projectElement
= TmfProjectRegistry
.getProject(sourceResourceToUse
.getProject());
231 for (TmfTraceElement trace
: targetExperiment
.getTraces()) {
232 if (trace
.getName().equals(sourceResourceToUse
.getName())) {
237 if (doit
&& !targetExperiment
.getProject().equals(projectElement
)) {
238 for (TmfTraceElement trace
: targetExperiment
.getProject().getTracesFolder().getTraces()) {
239 if (trace
.getName().equals(sourceResourceToUse
.getName())) {
246 IPath destination
= targetExperiment
.getProject().getTracesFolder().getResource().getFullPath().addTrailingSeparator().append(sourceResourceToUse
.getName());
247 sourceResourceToUse
.copy(destination
, false, null);
248 cleanupBookmarks(destination
);
249 // use the copied resource for the experiment
250 if (sourceResourceToUse
.getType() == IResource
.FILE
) {
251 sourceResourceToUse
= targetExperiment
.getProject().getTracesFolder().getResource().getFile(sourceResourceToUse
.getName());
252 } else if (sourceResourceToUse
.getType() == IResource
.FOLDER
) {
253 sourceResourceToUse
= targetExperiment
.getProject().getTracesFolder().getResource().getFolder(sourceResourceToUse
.getName());
255 } catch (CoreException e
) {
262 if (sourceResourceToUse
!= null && sourceResourceToUse
.exists()) {
263 createLink(targetExperiment
.getResource(), sourceResourceToUse
);
271 * Drop a trace by copying it's a trace element in a trace folder
273 * @param sourceTrace the source trace
274 * @param traceFolder the target trace folder
275 * @return true if successful
277 private static boolean drop(TmfTraceElement sourceTrace
, TmfTraceFolder traceFolder
) {
278 IResource sourceResource
= sourceTrace
.getResource();
279 if (drop(sourceResource
, traceFolder
)) {
280 IFolder destinationSupplementaryFolder
= traceFolder
.getTraceSupplementaryFolder(sourceResource
.getName());
281 sourceTrace
.copySupplementaryFolder(destinationSupplementaryFolder
);
288 * Drop a trace by copying a resource in a trace folder
290 * @param sourceResource the source resource
291 * @param traceFolder the target trace folder
292 * @return true if successful
294 private static boolean drop(IResource sourceResource
, TmfTraceFolder traceFolder
) {
297 for (TmfTraceElement trace
: traceFolder
.getTraces()) {
298 if (trace
.getName().equals(sourceResource
.getName())) {
305 IPath destination
= traceFolder
.getResource().getFullPath().addTrailingSeparator().append(sourceResource
.getName());
306 sourceResource
.copy(destination
, false, null);
308 cleanupBookmarks(destination
);
310 } catch (CoreException e
) {
318 * Drop a trace by importing a path in a target experiment
320 * @param path the source path
321 * @param targetExperiment the target experiment
322 * @return true if successful
324 private static boolean drop(Path path
, TmfExperimentElement targetExperiment
) {
327 // Use local variable to avoid parameter assignment
328 Path pathToUse
= path
;
330 for (TmfTraceElement trace
: targetExperiment
.getTraces()) {
331 if (trace
.getName().equals(pathToUse
.lastSegment())) {
336 if (doit
&& !pathToUse
.toString().startsWith(targetExperiment
.getProject().getResource().getLocation().toString())) {
337 for (TmfTraceElement trace
: targetExperiment
.getProject().getTracesFolder().getTraces()) {
338 if (trace
.getName().equals(pathToUse
.lastSegment())) {
344 importTrace(targetExperiment
.getProject().getTracesFolder().getResource(), pathToUse
);
345 // use the imported trace for the experiment
346 pathToUse
= new Path(targetExperiment
.getProject().getTracesFolder().getResource().getFile(pathToUse
.lastSegment()).getLocation().toString());
350 IResource resource
= null;
351 File file
= new File(pathToUse
.toString());
352 if (file
.exists() && file
.isFile()) {
353 resource
= targetExperiment
.getProject().getTracesFolder().getResource().getFile(pathToUse
.lastSegment());
354 } else if (file
.exists() && file
.isDirectory()) {
355 resource
= targetExperiment
.getProject().getTracesFolder().getResource().getFolder(pathToUse
.lastSegment());
357 if (resource
!= null && resource
.exists()) {
358 createLink(targetExperiment
.getResource(), resource
);
366 * Drop a trace by importing a path in a trace folder
368 * @param path the source path
369 * @param traceFolder the target trace folder
370 * @return true if successful
372 private static boolean drop(Path path
, TmfTraceFolder traceFolder
) {
374 for (TmfTraceElement trace
: traceFolder
.getTraces()) {
375 if (trace
.getName().equals(path
.lastSegment())) {
381 importTrace(traceFolder
.getResource(), path
);
388 * Import a trace to the trace folder
390 * @param resource the trace folder resource
391 * @param path the path to the trace to import
393 private static void importTrace(IFolder resource
, Path path
) {
394 IPath containerPath
= resource
.getFullPath();
395 File file
= new File(path
.toString());
396 File source
= file
.getParentFile();
397 IOverwriteQuery overwriteImplementor
= new IOverwriteQuery() {
399 public String
queryOverwrite(String pathString
) {
400 return IOverwriteQuery
.NO_ALL
;
403 List
<File
> filesToImport
= new LinkedList
<File
>();
404 filesToImport
.add(file
);
405 ImportOperation operation
= new ImportOperation(
408 FileSystemStructureProvider
.INSTANCE
,
409 overwriteImplementor
,
411 operation
.setCreateContainerStructure(false);
413 operation
.run(new NullProgressMonitor());
414 } catch (InvocationTargetException e
) {
416 } catch (InterruptedException e
) {
422 * Create a link to the actual trace and set the trace type
424 * @param parentFolder the parent folder
425 * @param resource the resource
427 private static void createLink(IFolder parentFolder
, IResource resource
) {
428 IPath location
= resource
.getLocation();
429 IWorkspace workspace
= ResourcesPlugin
.getWorkspace();
431 Map
<QualifiedName
, String
> properties
= resource
.getPersistentProperties();
432 String bundleName
= properties
.get(TmfCommonConstants
.TRACEBUNDLE
);
433 String traceType
= properties
.get(TmfCommonConstants
.TRACETYPE
);
434 String iconUrl
= properties
.get(TmfCommonConstants
.TRACEICON
);
435 String supplFolder
= properties
.get(TmfCommonConstants
.TRACE_SUPPLEMENTARY_FOLDER
);
437 if (resource
instanceof IFolder
) {
438 IFolder folder
= parentFolder
.getFolder(resource
.getName());
439 if (workspace
.validateLinkLocation(folder
, location
).isOK()) {
440 folder
.createLink(location
, IResource
.REPLACE
, null);
441 setProperties(folder
, bundleName
, traceType
, iconUrl
, supplFolder
);
444 Activator
.getDefault().logError("Invalid Trace Location"); //$NON-NLS-1$
447 IFile file
= parentFolder
.getFile(resource
.getName());
449 if (workspace
.validateLinkLocation(file
, location
).isOK()) {
450 file
.createLink(location
, IResource
.REPLACE
, null);
451 setProperties(file
, bundleName
, traceType
, iconUrl
, supplFolder
);
453 Activator
.getDefault().logError("Invalid Trace Location"); //$NON-NLS-1$
456 } catch (CoreException e
) {
462 * Cleanup bookmarks file in copied trace
464 private static void cleanupBookmarks(IPath path
) {
465 IFolder folder
= ResourcesPlugin
.getWorkspace().getRoot().getFolder(path
);
466 if (folder
.exists()) {
468 for (IResource member
: folder
.members()) {
469 if (TmfTrace
.class.getCanonicalName().equals(member
.getPersistentProperty(TmfCommonConstants
.TRACETYPE
))) {
470 member
.delete(true, null);
473 } catch (CoreException e
) {
480 * Set the trace persistent properties
482 * @param resource the trace resource
483 * @param bundleName the bundle name
484 * @param traceType the trace type
485 * @param iconUrl the icon URL
486 * @param supplFolder the directory of the directory for supplementary information or null to ignore the property
487 * @throws CoreException
489 private static void setProperties(IResource resource
, String bundleName
,
490 String traceType
, String iconUrl
, String supplFolder
)
491 throws CoreException
{
492 resource
.setPersistentProperty(TmfCommonConstants
.TRACEBUNDLE
, bundleName
);
493 resource
.setPersistentProperty(TmfCommonConstants
.TRACETYPE
, traceType
);
494 resource
.setPersistentProperty(TmfCommonConstants
.TRACEICON
, iconUrl
);
495 resource
.setPersistentProperty(TmfCommonConstants
.TRACE_SUPPLEMENTARY_FOLDER
, supplFolder
);
499 * Display an exception in a message box
501 * @param e the exception
503 private static void displayException(Exception e
) {
504 MessageBox mb
= new MessageBox(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell());
505 mb
.setText(e
.getClass().getName());
506 mb
.setMessage(e
.getMessage());