]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/packageview/WorkingSetDropAdapter.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / ui / org / eclipse / jdt / internal / ui / packageview / WorkingSetDropAdapter.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2011 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.ui.packageview;
12
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Set;
21
22 import org.eclipse.swt.dnd.DND;
23 import org.eclipse.swt.dnd.DropTargetEvent;
24 import org.eclipse.swt.dnd.Transfer;
25 import org.eclipse.swt.dnd.TransferData;
26
27 import org.eclipse.core.runtime.IAdaptable;
28
29 import org.eclipse.core.resources.IResource;
30
31 import org.eclipse.jface.util.TransferDropTargetListener;
32 import org.eclipse.jface.viewers.ISelection;
33 import org.eclipse.jface.viewers.IStructuredSelection;
34 import org.eclipse.jface.viewers.ITreeSelection;
35 import org.eclipse.jface.viewers.TreePath;
36
37 import org.eclipse.ui.IWorkingSet;
38 import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
39
40 import org.eclipse.jdt.core.IJavaElement;
41
42 import org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgUtils;
43
44 import org.eclipse.jdt.internal.ui.dnd.JdtViewerDropAdapter;
45 import org.eclipse.jdt.internal.ui.workingsets.IWorkingSetIDs;
46 import org.eclipse.jdt.internal.ui.workingsets.WorkingSetModel;
47
48 public class WorkingSetDropAdapter extends JdtViewerDropAdapter implements TransferDropTargetListener {
49
50         private PackageExplorerPart fPackageExplorer;
51
52         private IStructuredSelection fSelection;
53         private Object[] fElementsToAdds;
54         private Set<IAdaptable> fCurrentElements;
55         private IWorkingSet fWorkingSet;
56
57         private int fLocation;
58
59         public WorkingSetDropAdapter(PackageExplorerPart part) {
60                 super(part.getTreeViewer());
61                 fPackageExplorer= part;
62
63                 fLocation= -1;
64
65                 setScrollEnabled(true);
66                 setExpandEnabled(true);
67                 setFeedbackEnabled(false);
68         }
69
70         //---- TransferDropTargetListener interface ---------------------------------------
71
72         /**
73          * {@inheritDoc}
74          */
75         public Transfer getTransfer() {
76                 return LocalSelectionTransfer.getInstance();
77         }
78
79         /**
80          * {@inheritDoc}
81          */
82         public boolean isEnabled(DropTargetEvent event) {
83                 Object target= event.item != null ? event.item.getData() : null;
84                 if (target == null)
85                         return false;
86                 ISelection selection= LocalSelectionTransfer.getInstance().getSelection();
87                 if (!isValidSelection(selection)) {
88                         return false;
89                 }
90                 if (!isValidTarget(target))
91                         return false;
92
93                 initializeState(target, selection);
94                 return true;
95         }
96
97         //---- Actual DND -----------------------------------------------------------------
98
99         /**
100          * {@inheritDoc}
101          */
102         @Override
103         public boolean validateDrop(Object target, int operation, TransferData transferType) {
104                 return determineOperation(target, operation, transferType, DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY) != DND.DROP_NONE;
105         }
106
107         /**
108          * {@inheritDoc}
109          */
110         @Override
111         protected int determineOperation(Object target, int operation, TransferData transferType, int operations) {
112                 switch(operation) {
113                         case DND.DROP_DEFAULT:
114                         case DND.DROP_COPY:
115                         case DND.DROP_MOVE:
116                                 return validateTarget(target, operation);
117                         default:
118                                 return DND.DROP_NONE;
119                 }
120
121         }
122
123         private int validateTarget(Object target, int operation) {
124                 setFeedbackEnabled(false);
125                 setScrollEnabled(true);
126                 setExpandEnabled(true);
127                 if (!isValidTarget(target))
128                         return DND.DROP_NONE;
129                 ISelection s= LocalSelectionTransfer.getInstance().getSelection();
130                 if (!isValidSelection(s)) {
131                         return DND.DROP_NONE;
132                 }
133
134                 initializeState(target, s);
135
136                 if (isWorkingSetSelection()) {
137                         setExpandEnabled(false);
138                         if ((getCurrentLocation() == LOCATION_BEFORE || getCurrentLocation() == LOCATION_AFTER) &&
139                                         !fPackageExplorer.getWorkingSetModel().isSortingEnabled()) {
140                                 setFeedbackEnabled(true);
141                                 return DND.DROP_MOVE;
142                         }
143                         return DND.DROP_NONE;
144                 } else {
145                         if (isOthersWorkingSet(fWorkingSet) && operation == DND.DROP_COPY)
146                                 return DND.DROP_NONE;
147
148                         List<IJavaElement> realJavaElements= new ArrayList<IJavaElement>();
149                         List<IResource> realResource= new ArrayList<IResource>();
150                         ReorgUtils.splitIntoJavaElementsAndResources(fElementsToAdds, realJavaElements, realResource);
151                         if (fElementsToAdds.length != realJavaElements.size() + realResource.size())
152                                 return DND.DROP_NONE;
153                         for (Iterator<IJavaElement> iter= realJavaElements.iterator(); iter.hasNext();) {
154                                 IJavaElement element= iter.next();
155                                 if (ReorgUtils.containsElementOrParent(fCurrentElements, element))
156                                         return DND.DROP_NONE;
157                         }
158                         for (Iterator<IResource> iter= realResource.iterator(); iter.hasNext();) {
159                                 IResource element= iter.next();
160                                 if (ReorgUtils.containsElementOrParent(fCurrentElements, element))
161                                         return DND.DROP_NONE;
162                         }
163                         if (!(fSelection instanceof ITreeSelection)) {
164                                 return DND.DROP_COPY;
165                         }
166                         ITreeSelection treeSelection= (ITreeSelection)fSelection;
167                         TreePath[] paths= treeSelection.getPaths();
168                         for (int i= 0; i < paths.length; i++) {
169                                 TreePath path= paths[i];
170                                 if (path.getSegmentCount() != 2)
171                                         return DND.DROP_COPY;
172                                 if (!(path.getSegment(0) instanceof IWorkingSet))
173                                         return DND.DROP_COPY;
174                                 if (paths.length == 1) {
175                                         IWorkingSet ws= (IWorkingSet)path.getSegment(0);
176                                         if (isOthersWorkingSet(ws))
177                                                 return DND.DROP_MOVE;
178                                 }
179                         }
180                 }
181                 if (operation == DND.DROP_DEFAULT)
182                         return DND.DROP_MOVE;
183                 return operation;
184         }
185
186         private boolean isValidTarget(Object target) {
187                 return target instanceof IWorkingSet;
188         }
189
190         private boolean isValidSelection(ISelection selection) {
191                 return selection instanceof IStructuredSelection;
192         }
193
194         private boolean isOthersWorkingSet(IWorkingSet ws) {
195                 return IWorkingSetIDs.OTHERS.equals(ws.getId());
196         }
197
198         private void initializeState(Object target, ISelection s) {
199                 fWorkingSet= (IWorkingSet)target;
200                 fSelection= (IStructuredSelection)s;
201                 fElementsToAdds= fSelection.toArray();
202                 fCurrentElements= new HashSet<IAdaptable>(Arrays.asList(fWorkingSet.getElements()));
203         }
204
205         private boolean isWorkingSetSelection() {
206                 for (int i= 0; i < fElementsToAdds.length; i++) {
207                         if (!(fElementsToAdds[i] instanceof IWorkingSet))
208                                 return false;
209                 }
210                 return true;
211         }
212
213         /**
214          * {@inheritDoc}
215          */
216         @Override
217         public boolean performDrop(Object data) {
218                 if (isWorkingSetSelection()) {
219                         performWorkingSetReordering();
220                 } else {
221                         performElementRearrange(getCurrentOperation());
222                 }
223                 return true;
224         }
225
226         private void performWorkingSetReordering() {
227                 WorkingSetModel model= fPackageExplorer.getWorkingSetModel();
228                 List<IWorkingSet> allWorkingSets= new ArrayList<IWorkingSet>(Arrays.asList(model.getAllWorkingSets()));
229                 int index= allWorkingSets.indexOf(fWorkingSet);
230                 if (index != -1) {
231                         if (getCurrentLocation() == LOCATION_AFTER)
232                                 index++;
233                         List<IWorkingSet> result= new ArrayList<IWorkingSet>(allWorkingSets.size());
234                         @SuppressWarnings("unchecked") // isWorkingSetSelection() ensures that all elements are IWorkingSets
235                         List<IWorkingSet> selected= new ArrayList<IWorkingSet>((List<IWorkingSet>) (List<?>) Arrays.asList(fElementsToAdds));
236                         model.generated_7210376127521455312(allWorkingSets, index, result, selected);
237                 }
238         }
239
240         private void performElementRearrange(int eventDetail) {
241                 // only move if target isn't the other working set. If this is the case
242                 // the move will happenn automatically by refreshing the other working set
243                 if (!isOthersWorkingSet(fWorkingSet)) {
244                         List<Object> elements= new ArrayList<Object>(Arrays.asList(fWorkingSet.getElements()));
245                         elements.addAll(Arrays.asList(fElementsToAdds));
246                         fWorkingSet.setElements(elements.toArray(new IAdaptable[elements.size()]));
247                 }
248                 if (eventDetail == DND.DROP_MOVE) {
249                         ITreeSelection treeSelection= (ITreeSelection)fSelection;
250                         Map<IWorkingSet, List<Object>> workingSets= groupByWorkingSets(treeSelection.getPaths());
251                         for (Iterator<IWorkingSet> iter= workingSets.keySet().iterator(); iter.hasNext();) {
252                                 IWorkingSet ws= iter.next();
253                                 List<Object> toRemove= workingSets.get(ws);
254                                 List<IAdaptable> currentElements= new ArrayList<IAdaptable>(Arrays.asList(ws.getElements()));
255                                 currentElements.removeAll(toRemove);
256                                 ws.setElements(currentElements.toArray(new IAdaptable[currentElements.size()]));
257                         }
258                 }
259         }
260
261         private Map<IWorkingSet, List<Object>> groupByWorkingSets(TreePath[] paths) {
262                 Map<IWorkingSet, List<Object>> result= new HashMap<IWorkingSet, List<Object>>();
263                 for (int i= 0; i < paths.length; i++) {
264                         TreePath path= paths[i];
265                         IWorkingSet ws= (IWorkingSet)path.getSegment(0);
266                         List<Object> l= result.get(ws);
267                         if (l == null) {
268                                 l= new ArrayList<Object>();
269                                 result.put(ws, l);
270                         }
271                         l.add(path.getSegment(1));
272                 }
273                 return result;
274         }
275
276         //---- test methods for JUnit test since DnD is hard to simulate
277
278         public int internalTestValidateTarget(Object target, int operation) {
279                 return validateTarget(target, operation);
280         }
281
282         public void internalTestDrop(Object target, int eventDetail) {
283                 if (isWorkingSetSelection()) {
284                         performWorkingSetReordering();
285                 } else {
286                         performElementRearrange(eventDetail);
287                 }
288         }
289
290         public void internalTestSetLocation(int location) {
291                 fLocation= location;
292         }
293
294         /**
295          * {@inheritDoc}
296          */
297         @Override
298         protected int getCurrentLocation() {
299                 if (fLocation == -1)
300                         return super.getCurrentLocation();
301
302                 return fLocation;
303         }
304 }