]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
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.workingsets; | |
12 | ||
13 | import java.util.ArrayList; | |
14 | import java.util.Arrays; | |
15 | import java.util.Collections; | |
16 | import java.util.HashMap; | |
17 | import java.util.IdentityHashMap; | |
18 | import java.util.Iterator; | |
19 | import java.util.List; | |
20 | import java.util.Map; | |
21 | ||
22 | import org.eclipse.core.runtime.Assert; | |
23 | import org.eclipse.core.runtime.IAdaptable; | |
24 | import org.eclipse.core.runtime.ListenerList; | |
25 | ||
26 | import org.eclipse.core.resources.IProject; | |
27 | import org.eclipse.core.resources.IResource; | |
28 | ||
29 | import org.eclipse.jface.util.IPropertyChangeListener; | |
30 | import org.eclipse.jface.util.PropertyChangeEvent; | |
31 | import org.eclipse.jface.viewers.IElementComparer; | |
32 | ||
33 | import org.eclipse.ui.ILocalWorkingSetManager; | |
34 | import org.eclipse.ui.IMemento; | |
35 | import org.eclipse.ui.IWorkingSet; | |
36 | import org.eclipse.ui.IWorkingSetManager; | |
37 | import org.eclipse.ui.IWorkingSetUpdater; | |
38 | import org.eclipse.ui.PlatformUI; | |
39 | ||
40 | import org.eclipse.jdt.core.IJavaElement; | |
41 | import org.eclipse.jdt.core.IJavaProject; | |
42 | ||
43 | public class WorkingSetModel { | |
44 | ||
45 | public static final String CHANGE_WORKING_SET_MODEL_CONTENT= "workingSetModelChanged"; //$NON-NLS-1$ | |
46 | ||
47 | public static final IElementComparer COMPARER= new WorkingSetComparar(); | |
48 | ||
49 | private static final String TAG_LOCAL_WORKING_SET_MANAGER= "localWorkingSetManager"; //$NON-NLS-1$ | |
50 | ||
51 | /** | |
52 | * Key associated with the state of all working sets. | |
53 | * @since 3.7 | |
54 | */ | |
55 | private static final String TAG_ALL_WORKING_SETS= "allWorkingSets"; //$NON-NLS-1$ | |
56 | private static final String TAG_ACTIVE_WORKING_SET= "activeWorkingSet"; //$NON-NLS-1$ | |
57 | private static final String TAG_WORKING_SET_NAME= "workingSetName"; //$NON-NLS-1$ | |
58 | private static final String TAG_CONFIGURED= "configured"; //$NON-NLS-1$ | |
59 | ||
60 | /** | |
61 | * Key associated with the sort state of working sets. | |
62 | * | |
63 | * @since 3.5 | |
64 | */ | |
65 | private static final String TAG_SORT_WORKING_SETS= "sortWorkingSets"; //$NON-NLS-1$ | |
66 | ||
67 | private final ILocalWorkingSetManager fLocalWorkingSetManager; | |
68 | private List<IWorkingSet> fActiveWorkingSets; | |
69 | private ListenerList fListeners; | |
70 | private IPropertyChangeListener fWorkingSetManagerListener; | |
71 | private OthersWorkingSetUpdater fOthersWorkingSetUpdater; | |
72 | ||
73 | private final ElementMapper fElementMapper= new ElementMapper(); | |
74 | ||
75 | private boolean fConfigured; | |
76 | ||
77 | /** | |
78 | * Value of the sorted state of working sets. | |
79 | * | |
80 | * @since 3.5 | |
81 | */ | |
82 | private boolean fIsSortingEnabled; | |
83 | ||
84 | /** | |
85 | * List of all working sets. | |
86 | * @since 3.7 | |
87 | */ | |
88 | private List<IWorkingSet> fAllWorkingSets; | |
89 | ||
90 | private static class WorkingSetComparar implements IElementComparer { | |
91 | public boolean equals(Object o1, Object o2) { | |
92 | IWorkingSet w1= o1 instanceof IWorkingSet ? (IWorkingSet)o1 : null; | |
93 | IWorkingSet w2= o2 instanceof IWorkingSet ? (IWorkingSet)o2 : null; | |
94 | if (w1 == null || w2 == null) | |
95 | return o1.equals(o2); | |
96 | return w1 == w2; | |
97 | } | |
98 | public int hashCode(Object element) { | |
99 | if (element instanceof IWorkingSet) | |
100 | return System.identityHashCode(element); | |
101 | return element.hashCode(); | |
102 | } | |
103 | } | |
104 | ||
105 | private static class ElementMapper { | |
106 | private final Map<IAdaptable, Object> fElementToWorkingSet= new HashMap<IAdaptable, Object>(); | |
107 | private final Map<IWorkingSet, IAdaptable[]> fWorkingSetToElement= new IdentityHashMap<IWorkingSet, IAdaptable[]>(); | |
108 | ||
109 | private final Map<IAdaptable, Object> fResourceToWorkingSet= new HashMap<IAdaptable, Object>(); | |
110 | private final List<IAdaptable> fNonProjectTopLevelElements= new ArrayList<IAdaptable>(); | |
111 | ||
112 | public void clear() { | |
113 | fElementToWorkingSet.clear(); | |
114 | fWorkingSetToElement.clear(); | |
115 | fResourceToWorkingSet.clear(); | |
116 | fNonProjectTopLevelElements.clear(); | |
117 | } | |
118 | public void rebuild(IWorkingSet[] workingSets) { | |
119 | clear(); | |
120 | for (int i= 0; i < workingSets.length; i++) { | |
121 | put(workingSets[i]); | |
122 | } | |
123 | } | |
124 | public IAdaptable[] refresh(IWorkingSet ws) { | |
125 | IAdaptable[] oldElements= fWorkingSetToElement.get(ws); | |
126 | if (oldElements == null) | |
127 | return null; | |
128 | IAdaptable[] newElements= ws.getElements(); | |
129 | List<IAdaptable> toRemove= new ArrayList<IAdaptable>(Arrays.asList(oldElements)); | |
130 | List<IAdaptable> toAdd= new ArrayList<IAdaptable>(Arrays.asList(newElements)); | |
131 | computeDelta(toRemove, toAdd, oldElements, newElements); | |
132 | for (Iterator<IAdaptable> iter= toAdd.iterator(); iter.hasNext();) { | |
133 | addElement(iter.next(), ws); | |
134 | } | |
135 | for (Iterator<IAdaptable> iter= toRemove.iterator(); iter.hasNext();) { | |
136 | removeElement(iter.next(), ws); | |
137 | } | |
138 | if (toRemove.size() > 0 || toAdd.size() > 0) | |
139 | fWorkingSetToElement.put(ws, newElements); | |
140 | return oldElements; | |
141 | } | |
142 | private void computeDelta(List<IAdaptable> toRemove, List<IAdaptable> toAdd, IAdaptable[] oldElements, IAdaptable[] newElements) { | |
143 | for (int i= 0; i < oldElements.length; i++) { | |
144 | toAdd.remove(oldElements[i]); | |
145 | } | |
146 | for (int i= 0; i < newElements.length; i++) { | |
147 | toRemove.remove(newElements[i]); | |
148 | } | |
149 | ||
150 | } | |
151 | public IWorkingSet getFirstWorkingSet(Object element) { | |
152 | return (IWorkingSet)getFirstElement(fElementToWorkingSet, element); | |
153 | } | |
154 | public List<IWorkingSet> getAllWorkingSets(Object element) { | |
155 | List<IWorkingSet> allElements= getAllElements(fElementToWorkingSet, element); | |
156 | if (allElements.isEmpty() && element instanceof IJavaElement) { | |
157 | // try a second time in case the working set was manually updated (bug 168032) | |
158 | allElements= getAllElements(fElementToWorkingSet, ((IJavaElement) element).getResource()); | |
159 | } | |
160 | return allElements; | |
161 | } | |
162 | public List<IWorkingSet> getAllWorkingSetsForResource(IResource resource) { | |
163 | return getAllElements(fResourceToWorkingSet, resource); | |
164 | } | |
165 | public List<IAdaptable> getNonProjectTopLevelElements() { | |
166 | return fNonProjectTopLevelElements; | |
167 | } | |
168 | private void put(IWorkingSet ws) { | |
169 | if (fWorkingSetToElement.containsKey(ws)) | |
170 | return; | |
171 | IAdaptable[] elements= ws.getElements(); | |
172 | fWorkingSetToElement.put(ws, elements); | |
173 | for (int i= 0; i < elements.length; i++) { | |
174 | IAdaptable element= elements[i]; | |
175 | addElement(element, ws); | |
176 | if (!(element instanceof IProject) && !(element instanceof IJavaProject)) { | |
177 | fNonProjectTopLevelElements.add(element); | |
178 | } | |
179 | } | |
180 | } | |
181 | private void addElement(IAdaptable element, IWorkingSet ws) { | |
182 | addToMap(fElementToWorkingSet, element, ws); | |
183 | IResource resource= (IResource)element.getAdapter(IResource.class); | |
184 | if (resource != null) { | |
185 | addToMap(fResourceToWorkingSet, resource, ws); | |
186 | } | |
187 | } | |
188 | private void removeElement(IAdaptable element, IWorkingSet ws) { | |
189 | removeFromMap(fElementToWorkingSet, element, ws); | |
190 | IResource resource= (IResource)element.getAdapter(IResource.class); | |
191 | if (resource != null) { | |
192 | removeFromMap(fResourceToWorkingSet, resource, ws); | |
193 | } | |
194 | } | |
195 | private void addToMap(Map<IAdaptable, Object> map, IAdaptable key, IWorkingSet value) { | |
196 | Object obj= map.get(key); | |
197 | if (obj == null) { | |
198 | map.put(key, value); | |
199 | } else if (obj instanceof IWorkingSet) { | |
200 | List<IWorkingSet> l= new ArrayList<IWorkingSet>(2); | |
201 | l.add((IWorkingSet) obj); | |
202 | l.add(value); | |
203 | map.put(key, l); | |
204 | } else if (obj instanceof List) { | |
205 | @SuppressWarnings("unchecked") | |
206 | List<IWorkingSet> sets= (List<IWorkingSet>)obj; | |
207 | sets.add(value); | |
208 | } | |
209 | } | |
210 | private void removeFromMap(Map<IAdaptable, Object> map, IAdaptable key, IWorkingSet value) { | |
211 | Object current= map.get(key); | |
212 | if (current == null) { | |
213 | return; | |
214 | } else if (current instanceof List) { | |
215 | @SuppressWarnings("unchecked") | |
216 | List<IWorkingSet> sets= (List<IWorkingSet>)current; | |
217 | sets.remove(value); | |
218 | switch (sets.size()) { | |
219 | case 0: | |
220 | map.remove(key); | |
221 | break; | |
222 | case 1: | |
223 | map.put(key, sets.get(0)); | |
224 | break; | |
225 | } | |
226 | } else if (current == value) { | |
227 | map.remove(key); | |
228 | } | |
229 | } | |
230 | private Object getFirstElement(Map<IAdaptable, Object> map, Object key) { | |
231 | Object obj= map.get(key); | |
232 | if (obj instanceof List) { | |
233 | @SuppressWarnings("unchecked") | |
234 | List<IWorkingSet> sets= (List<IWorkingSet>)obj; | |
235 | return sets.get(0); | |
236 | } | |
237 | return obj; | |
238 | } | |
239 | private List<IWorkingSet> getAllElements(Map<IAdaptable, Object> map, Object key) { | |
240 | Object obj= map.get(key); | |
241 | if (obj instanceof List) { | |
242 | @SuppressWarnings("unchecked") | |
243 | List<IWorkingSet> sets= (List<IWorkingSet>)obj; | |
244 | return sets; | |
245 | } | |
246 | if (obj == null) | |
247 | return Collections.emptyList(); | |
248 | List<IWorkingSet> result= new ArrayList<IWorkingSet>(1); | |
249 | result.add((IWorkingSet) obj); | |
250 | return result; | |
251 | } | |
252 | } | |
253 | ||
254 | /** | |
255 | * @param memento a memento, or <code>null</code> | |
256 | */ | |
257 | public WorkingSetModel(IMemento memento) { | |
258 | fLocalWorkingSetManager= PlatformUI.getWorkbench().createLocalWorkingSetManager(); | |
259 | addListenersToWorkingSetManagers(); | |
260 | fActiveWorkingSets= new ArrayList<IWorkingSet>(); | |
261 | fAllWorkingSets= new ArrayList<IWorkingSet>(); | |
262 | ||
263 | if (memento == null || ! restoreState(memento)) { | |
264 | IWorkingSet others= fLocalWorkingSetManager.createWorkingSet(WorkingSetMessages.WorkingSetModel_others_name, new IAdaptable[0]); | |
265 | others.setId(IWorkingSetIDs.OTHERS); | |
266 | fLocalWorkingSetManager.addWorkingSet(others); | |
267 | fActiveWorkingSets.add(others); | |
268 | fAllWorkingSets.add(others); | |
269 | } | |
270 | Assert.isNotNull(fOthersWorkingSetUpdater); | |
271 | ||
272 | fElementMapper.rebuild(getActiveWorkingSets()); | |
273 | fOthersWorkingSetUpdater.updateElements(); | |
274 | } | |
275 | ||
276 | private void addListenersToWorkingSetManagers() { | |
277 | fListeners= new ListenerList(ListenerList.IDENTITY); | |
278 | fWorkingSetManagerListener= new IPropertyChangeListener() { | |
279 | public void propertyChange(PropertyChangeEvent event) { | |
280 | workingSetManagerChanged(event); | |
281 | } | |
282 | }; | |
283 | PlatformUI.getWorkbench().getWorkingSetManager().addPropertyChangeListener(fWorkingSetManagerListener); | |
284 | fLocalWorkingSetManager.addPropertyChangeListener(fWorkingSetManagerListener); | |
285 | } | |
286 | ||
287 | public void dispose() { | |
288 | if (fWorkingSetManagerListener != null) { | |
289 | PlatformUI.getWorkbench().getWorkingSetManager().removePropertyChangeListener(fWorkingSetManagerListener); | |
290 | fLocalWorkingSetManager.removePropertyChangeListener(fWorkingSetManagerListener); | |
291 | fLocalWorkingSetManager.dispose(); | |
292 | fWorkingSetManagerListener= null; | |
293 | } | |
294 | } | |
295 | ||
296 | //---- model relationships --------------------------------------- | |
297 | ||
298 | public IAdaptable[] getChildren(IWorkingSet workingSet) { | |
299 | return workingSet.getElements(); | |
300 | } | |
301 | ||
302 | public Object getParent(Object element) { | |
303 | if (element instanceof IWorkingSet && fActiveWorkingSets.contains(element)) | |
304 | return this; | |
305 | return fElementMapper.getFirstWorkingSet(element); | |
306 | } | |
307 | ||
308 | public Object[] getAllParents(Object element) { | |
309 | if (element instanceof IWorkingSet && fActiveWorkingSets.contains(element)) | |
310 | return new Object[] {this}; | |
311 | return fElementMapper.getAllWorkingSets(element).toArray(); | |
312 | } | |
313 | ||
314 | public Object[] addWorkingSets(Object[] elements) { | |
315 | List<? super IWorkingSet> result= null; | |
316 | for (int i= 0; i < elements.length; i++) { | |
317 | Object element= elements[i]; | |
318 | List<IWorkingSet> sets= null; | |
319 | if (element instanceof IResource) { | |
320 | sets= fElementMapper.getAllWorkingSetsForResource((IResource)element); | |
321 | } else { | |
322 | sets= fElementMapper.getAllWorkingSets(element); | |
323 | } | |
324 | if (sets != null && sets.size() > 0) { | |
325 | if (result == null) | |
326 | result= new ArrayList<Object>(Arrays.asList(elements)); | |
327 | result.addAll(sets); | |
328 | } | |
329 | } | |
330 | if (result == null) | |
331 | return elements; | |
332 | return result.toArray(); | |
333 | } | |
334 | ||
335 | public boolean needsConfiguration() { | |
336 | return !fConfigured && fActiveWorkingSets.size() == 1 && | |
337 | IWorkingSetIDs.OTHERS.equals(fActiveWorkingSets.get(0).getId()); | |
338 | } | |
339 | ||
340 | public void configured() { | |
341 | fConfigured= true; | |
342 | } | |
343 | ||
344 | //---- working set management ----------------------------------- | |
345 | ||
346 | /** | |
347 | * Adds a property change listener. | |
348 | * | |
349 | * @param listener the property change listener to add | |
350 | */ | |
351 | public void addPropertyChangeListener(IPropertyChangeListener listener) { | |
352 | fListeners.add(listener); | |
353 | } | |
354 | ||
355 | /** | |
356 | * Removes the property change listener. | |
357 | * | |
358 | * @param listener the property change listener to remove | |
359 | */ | |
360 | public void removePropertyChangeListener(IPropertyChangeListener listener) { | |
361 | fListeners.remove(listener); | |
362 | } | |
363 | ||
364 | public IWorkingSet[] getActiveWorkingSets() { | |
365 | return fActiveWorkingSets.toArray(new IWorkingSet[fActiveWorkingSets.size()]); | |
366 | } | |
367 | ||
368 | /** | |
369 | * Returns the array of all working sets. | |
370 | * | |
371 | * @return the array of all working sets | |
372 | * @since 3.7 | |
373 | */ | |
374 | public IWorkingSet[] getAllWorkingSets() { | |
375 | if (fAllWorkingSets.size() == 1 && IWorkingSetIDs.OTHERS.equals(fAllWorkingSets.get(0).getId())) | |
376 | fAllWorkingSets= getActiveAndAllWorkingSetsFromManagers(); | |
377 | return fAllWorkingSets.toArray(new IWorkingSet[fAllWorkingSets.size()]); | |
378 | } | |
379 | ||
380 | /** | |
381 | * Returns the list containing active and all working sets from the working set managers. | |
382 | * | |
383 | * @return the list of all the working sets | |
384 | * @since 3.7 | |
385 | */ | |
386 | private List<IWorkingSet> getActiveAndAllWorkingSetsFromManagers() { | |
387 | List<IWorkingSet> result= new ArrayList<IWorkingSet>(); | |
388 | result.addAll(fActiveWorkingSets); | |
389 | IWorkingSet[] locals= fLocalWorkingSetManager.getWorkingSets(); | |
390 | for (int i= 0; i < locals.length; i++) { | |
391 | if (!result.contains(locals[i]) && isSupportedAsTopLevelElement(locals[i])) | |
392 | result.add(locals[i]); | |
393 | } | |
394 | IWorkingSet[] globals= PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSets(); | |
395 | for (int i= 0; i < globals.length; i++) { | |
396 | if (!result.contains(globals[i]) && isSupportedAsTopLevelElement(globals[i])) | |
397 | result.add(globals[i]); | |
398 | } | |
399 | ||
400 | if (fIsSortingEnabled) | |
401 | Collections.sort(result, new WorkingSetComparator(true)); | |
402 | return result; | |
403 | } | |
404 | ||
405 | /** | |
406 | * Adds newly created working sets to the list of all working sets. | |
407 | * | |
408 | * @param result the list of all working sets from the working set managers | |
409 | * @since 3.7 | |
410 | */ | |
411 | private void addNewlyCreatedWorkingSets(List<IWorkingSet> result) { | |
412 | for (Iterator<IWorkingSet> iter= result.iterator(); iter.hasNext();) { | |
413 | IWorkingSet set= iter.next(); | |
414 | if (!fAllWorkingSets.contains(set)) | |
415 | fAllWorkingSets.add(set); | |
416 | } | |
417 | } | |
418 | ||
419 | /** | |
420 | * Sets the working sets lists. | |
421 | * <p> | |
422 | * Note : All the active working sets must be contained in allWorkingSets and the relative | |
423 | * ordering of the active working sets must be same in both allWorkingSets and activeWorkingSets | |
424 | * arrays, else the method throws an <code>IllegalArgumentException</code. | |
425 | * </p> | |
426 | * | |
427 | * @param allWorkingSets the array of all working sets | |
428 | * @param isSortingEnabled <code>true</code> if sorting is enabled, <code>false</code> otherwise | |
429 | * @param activeWorkingSets the array of active working sets | |
430 | * @since 3.7 | |
431 | */ | |
432 | public void setWorkingSets(IWorkingSet[] allWorkingSets, boolean isSortingEnabled, IWorkingSet[] activeWorkingSets) { | |
433 | Assert.isLegal(Arrays.asList(allWorkingSets).containsAll(Arrays.asList(activeWorkingSets))); | |
434 | Assert.isLegal(!isOrderDifferentInWorkingSetLists(Arrays.asList(allWorkingSets), Arrays.asList(activeWorkingSets))); | |
435 | if (isSortingEnabled) | |
436 | Arrays.sort(allWorkingSets, new WorkingSetComparator(true)); | |
437 | fAllWorkingSets= new ArrayList<IWorkingSet>(Arrays.asList(allWorkingSets)); | |
438 | setActiveWorkingSets(activeWorkingSets, isSortingEnabled); | |
439 | } | |
440 | ||
441 | /** | |
442 | * Sets the active working sets. | |
443 | * <p> | |
444 | * Note: If the relative ordering of the active working sets is not same in both fAllWorkingSets | |
445 | * and fActiveWorkingSets, fAllWorkingSets is re-ordered according to fActiveWorkingSets. | |
446 | * </p> | |
447 | * | |
448 | * @param workingSets the active working sets to be set | |
449 | * | |
450 | */ | |
451 | public void setActiveWorkingSets(IWorkingSet[] workingSets) { | |
452 | Assert.isLegal(Arrays.asList(getAllWorkingSets()).containsAll(Arrays.asList(workingSets))); | |
453 | if (fIsSortingEnabled) { | |
454 | Arrays.sort(workingSets, new WorkingSetComparator(true)); | |
455 | } | |
456 | fActiveWorkingSets= new ArrayList<IWorkingSet>(Arrays.asList(workingSets)); | |
457 | if (isOrderDifferentInWorkingSetLists(fAllWorkingSets, fActiveWorkingSets)) { //see bug 338531 | |
458 | adjustOrderingOfAllWorkingSets(); | |
459 | } | |
460 | fElementMapper.rebuild(getActiveWorkingSets()); | |
461 | fOthersWorkingSetUpdater.updateElements(); | |
462 | fireEvent(new PropertyChangeEvent(this, CHANGE_WORKING_SET_MODEL_CONTENT, null, null)); | |
463 | } | |
464 | ||
465 | /** | |
466 | * Adjusts the relative ordering of the active working sets in fAllWorkingSets according to | |
467 | * fActiveWorkingSets. | |
468 | * | |
469 | * @since 3.7 | |
470 | */ | |
471 | private void adjustOrderingOfAllWorkingSets() { | |
472 | int countActive= 0; | |
473 | for (Iterator<IWorkingSet> iter= fAllWorkingSets.iterator(); iter.hasNext();) { | |
474 | IWorkingSet set= iter.next(); | |
475 | if (fActiveWorkingSets.contains(set)) { | |
476 | IWorkingSet workingSet= fActiveWorkingSets.get(countActive++); | |
477 | if (!workingSet.equals(set)) { | |
478 | int index= fAllWorkingSets.indexOf(workingSet); | |
479 | fAllWorkingSets.set(fAllWorkingSets.indexOf(set), workingSet); | |
480 | fAllWorkingSets.set(index, set); | |
481 | } | |
482 | if (countActive == fActiveWorkingSets.size()) | |
483 | return; | |
484 | } | |
485 | } | |
486 | } | |
487 | ||
488 | /** | |
489 | * Checks if the order of active working sets is different in the active and all working set | |
490 | * lists. | |
491 | * | |
492 | * @param allWorkingSets the list of all working sets | |
493 | * @param activeWorkingSets the list of active working sets | |
494 | * @return <code>true</code> if the order is different, <code>false</code> otherwise | |
495 | * @since 3.7 | |
496 | */ | |
497 | private boolean isOrderDifferentInWorkingSetLists(List<IWorkingSet> allWorkingSets, List<IWorkingSet> activeWorkingSets) { | |
498 | int count= 0; | |
499 | for (Iterator<IWorkingSet> iter= allWorkingSets.iterator(); iter.hasNext();) { | |
500 | IWorkingSet set= iter.next(); | |
501 | if (activeWorkingSets.contains(set)) { | |
502 | if (!activeWorkingSets.get(count++).equals(set)) | |
503 | return true; | |
504 | } | |
505 | } | |
506 | return false; | |
507 | } | |
508 | ||
509 | /** | |
510 | * Sets the active working sets. | |
511 | * | |
512 | * @param workingSets the array of working sets | |
513 | * @param isSortingEnabled <code>true</code> if sorting is enabled, <code>false</code> otherwise | |
514 | * @since 3.5 | |
515 | */ | |
516 | public void setActiveWorkingSets(IWorkingSet[] workingSets, boolean isSortingEnabled) { | |
517 | fIsSortingEnabled= isSortingEnabled; | |
518 | setActiveWorkingSets(workingSets); | |
519 | } | |
520 | ||
521 | public void saveState(IMemento memento) { | |
522 | memento.putBoolean(TAG_SORT_WORKING_SETS, fIsSortingEnabled); | |
523 | memento.putBoolean(TAG_CONFIGURED, fConfigured); | |
524 | fLocalWorkingSetManager.saveState(memento.createChild(TAG_LOCAL_WORKING_SET_MANAGER)); | |
525 | for (Iterator<IWorkingSet> iter= fActiveWorkingSets.iterator(); iter.hasNext();) { | |
526 | IMemento active= memento.createChild(TAG_ACTIVE_WORKING_SET); | |
527 | IWorkingSet workingSet= iter.next(); | |
528 | active.putString(TAG_WORKING_SET_NAME, workingSet.getName()); | |
529 | } | |
530 | for (Iterator<IWorkingSet> iter= Arrays.asList(getAllWorkingSets()).iterator(); iter.hasNext();) { | |
531 | IMemento allWorkingSet= memento.createChild(TAG_ALL_WORKING_SETS); | |
532 | IWorkingSet workingSet= iter.next(); | |
533 | if (isSupportedAsTopLevelElement(workingSet)) | |
534 | allWorkingSet.putString(TAG_WORKING_SET_NAME, workingSet.getName()); | |
535 | } | |
536 | } | |
537 | ||
538 | public List<IAdaptable> getNonProjectTopLevelElements() { | |
539 | return fElementMapper.getNonProjectTopLevelElements(); | |
540 | } | |
541 | ||
542 | /** | |
543 | * Restore localWorkingSetManager and active working sets. | |
544 | * | |
545 | * @param memento a memento | |
546 | * @return whether the restore was successful | |
547 | */ | |
548 | private boolean restoreState(IMemento memento) { | |
549 | String configured= memento.getString(TAG_CONFIGURED); | |
550 | if (configured == null) | |
551 | return false; | |
552 | ||
553 | fConfigured= Boolean.valueOf(configured).booleanValue(); | |
554 | fLocalWorkingSetManager.restoreState(memento.getChild(TAG_LOCAL_WORKING_SET_MANAGER)); | |
555 | IWorkingSet[] allLocalWorkingSets= fLocalWorkingSetManager.getAllWorkingSets(); | |
556 | for (int i= 0; i < allLocalWorkingSets.length; i++) { | |
557 | IWorkingSet ws= allLocalWorkingSets[i]; | |
558 | if (IWorkingSetIDs.OTHERS.equals(ws.getId())) { | |
559 | // have to set the label again, since the locale could have been changed (bug 272737) | |
560 | String otherProjectsLabel= WorkingSetMessages.WorkingSetModel_others_name; | |
561 | if (! otherProjectsLabel.equals(ws.getLabel())) { | |
562 | ws.setLabel(otherProjectsLabel); | |
563 | } | |
564 | } | |
565 | } | |
566 | ||
567 | String isSortingEnabled= memento.getString(TAG_SORT_WORKING_SETS); | |
568 | if (isSortingEnabled == null) { | |
569 | fIsSortingEnabled= false; | |
570 | } else { | |
571 | fIsSortingEnabled= Boolean.valueOf(isSortingEnabled).booleanValue(); | |
572 | } | |
573 | ||
574 | IMemento[] actives= memento.getChildren(TAG_ACTIVE_WORKING_SET); | |
575 | for (int i= 0; i < actives.length; i++) { | |
576 | String name= actives[i].getString(TAG_WORKING_SET_NAME); | |
577 | if (name != null) { | |
578 | IWorkingSet ws= fLocalWorkingSetManager.getWorkingSet(name); | |
579 | if (ws == null) { | |
580 | ws= PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(name); | |
581 | } | |
582 | if (ws != null) { | |
583 | fActiveWorkingSets.add(ws); | |
584 | } | |
585 | } | |
586 | } | |
587 | IMemento[] allWorkingSets= memento.getChildren(TAG_ALL_WORKING_SETS); | |
588 | for (int i= 0; i < allWorkingSets.length; i++) { | |
589 | String name= allWorkingSets[i].getString(TAG_WORKING_SET_NAME); | |
590 | if (name != null) { | |
591 | IWorkingSet ws= fLocalWorkingSetManager.getWorkingSet(name); | |
592 | if (ws == null) { | |
593 | ws= PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(name); | |
594 | } | |
595 | if (ws != null) { | |
596 | fAllWorkingSets.add(ws); | |
597 | } | |
598 | } | |
599 | } | |
600 | ||
601 | List<IWorkingSet> result= getActiveAndAllWorkingSetsFromManagers(); | |
602 | if (!fAllWorkingSets.containsAll(result)) | |
603 | addNewlyCreatedWorkingSets(result); | |
604 | return true; | |
605 | } | |
606 | private void workingSetManagerChanged(PropertyChangeEvent event) { | |
607 | String property= event.getProperty(); | |
608 | if (IWorkingSetManager.CHANGE_WORKING_SET_UPDATER_INSTALLED.equals(property) && event.getSource() == fLocalWorkingSetManager) { | |
609 | IWorkingSetUpdater updater= (IWorkingSetUpdater)event.getNewValue(); | |
610 | if (updater instanceof OthersWorkingSetUpdater) { | |
611 | fOthersWorkingSetUpdater= (OthersWorkingSetUpdater)updater; | |
612 | fOthersWorkingSetUpdater.init(this); | |
613 | } | |
614 | return; | |
615 | } | |
616 | ||
617 | // Add new working set to the list of active working sets and all working sets | |
618 | if (IWorkingSetManager.CHANGE_WORKING_SET_ADD.equals(property)) { | |
619 | IWorkingSet workingSet= (IWorkingSet)event.getNewValue(); | |
620 | if (isSupportedAsTopLevelElement(workingSet)) { | |
621 | IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager(); | |
622 | List<IWorkingSet> allWorkingSets= new ArrayList<IWorkingSet>(Arrays.asList(manager.getAllWorkingSets())); | |
623 | if (allWorkingSets.contains(workingSet)) { | |
624 | List<IWorkingSet> elements= new ArrayList<IWorkingSet>(fActiveWorkingSets); | |
625 | if (workingSet.isVisible() && !fActiveWorkingSets.contains(workingSet)) | |
626 | elements.add(workingSet); | |
627 | List<IWorkingSet> allElements= new ArrayList<IWorkingSet>(Arrays.asList(getAllWorkingSets())); | |
628 | if (!allElements.contains(workingSet)) | |
629 | allElements.add(workingSet); | |
630 | setWorkingSets(allElements.toArray(new IWorkingSet[allElements.size()]), fIsSortingEnabled, elements.toArray(new IWorkingSet[elements.size()])); | |
631 | } | |
632 | } | |
633 | } | |
634 | ||
635 | // don't handle working sets not managed by the model | |
636 | if (!isAffected(event)) | |
637 | return; | |
638 | ||
639 | if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE.equals(property)) { | |
640 | IWorkingSet workingSet= (IWorkingSet)event.getNewValue(); | |
641 | IAdaptable[] elements= fElementMapper.refresh(workingSet); | |
642 | if (elements != null) { | |
643 | fireEvent(event); | |
644 | } | |
645 | } else if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)) { | |
646 | IWorkingSet workingSet= (IWorkingSet)event.getOldValue(); | |
647 | List<IWorkingSet> elements= new ArrayList<IWorkingSet>(fActiveWorkingSets); | |
648 | elements.remove(workingSet); | |
649 | List<IWorkingSet> allElements= new ArrayList<IWorkingSet>(Arrays.asList(getAllWorkingSets())); | |
650 | allElements.remove(workingSet); | |
651 | setWorkingSets(allElements.toArray(new IWorkingSet[allElements.size()]), fIsSortingEnabled, elements.toArray(new IWorkingSet[elements.size()])); | |
652 | } else if (IWorkingSetManager.CHANGE_WORKING_SET_LABEL_CHANGE.equals(property)) { | |
653 | IWorkingSet workingSet= (IWorkingSet)event.getNewValue(); | |
654 | if (isSortingEnabled() && Arrays.asList(getAllWorkingSets()).contains(workingSet)) { | |
655 | setWorkingSets(getAllWorkingSets(), isSortingEnabled(), fActiveWorkingSets.toArray(new IWorkingSet[fActiveWorkingSets.size()])); | |
656 | } else { | |
657 | fireEvent(event); | |
658 | } | |
659 | } | |
660 | ||
661 | } | |
662 | ||
663 | /** | |
664 | * Tells whether the given working set is supported as top-level element | |
665 | * | |
666 | * @param workingSet the working set to test | |
667 | * @return <code>true</code> if the given working set is supported as top-level element | |
668 | * @since 3.6 | |
669 | */ | |
670 | public static boolean isSupportedAsTopLevelElement(IWorkingSet workingSet) { | |
671 | Object id= workingSet.getId(); | |
672 | if (IWorkingSetIDs.OTHERS.equals(id) || IWorkingSetIDs.JAVA.equals(id) || IWorkingSetIDs.RESOURCE.equals(id)) | |
673 | return true; | |
674 | ||
675 | if (!workingSet.isSelfUpdating() || workingSet.isAggregateWorkingSet()) | |
676 | return false; | |
677 | ||
678 | IAdaptable[] elements= workingSet.getElements(); | |
679 | for (int i= 0; i < elements.length; i++) { | |
680 | IAdaptable element= elements[i]; | |
681 | IProject p= (IProject)element.getAdapter(IProject.class); | |
682 | if (p != null && p.exists()) | |
683 | return true; | |
684 | } | |
685 | return false; | |
686 | } | |
687 | ||
688 | ||
689 | private void fireEvent(PropertyChangeEvent event) { | |
690 | Object[] listeners= fListeners.getListeners(); | |
691 | for (int i= 0; i < listeners.length; i++) { | |
692 | ((IPropertyChangeListener)listeners[i]).propertyChange(event); | |
693 | } | |
694 | } | |
695 | ||
696 | private boolean isAffected(PropertyChangeEvent event) { | |
697 | if (fActiveWorkingSets == null) | |
698 | return false; | |
699 | Object oldValue= event.getOldValue(); | |
700 | Object newValue= event.getNewValue(); | |
701 | if ((oldValue != null && fActiveWorkingSets.contains(oldValue)) | |
702 | || (newValue != null && fActiveWorkingSets.contains(newValue))) { | |
703 | return true; | |
704 | } | |
705 | return false; | |
706 | } | |
707 | ||
708 | public boolean isActiveWorkingSet(IWorkingSet changedWorkingSet) { | |
709 | return fActiveWorkingSets.contains(changedWorkingSet); | |
710 | } | |
711 | ||
712 | public void addActiveWorkingSet(IWorkingSet workingSet) { | |
713 | IWorkingSet[] workingSets= getActiveWorkingSets(); | |
714 | IWorkingSet[] activeWorkingSets= new IWorkingSet[workingSets.length+ 1]; | |
715 | System.arraycopy(workingSets, 0, activeWorkingSets, 0, workingSets.length); | |
716 | activeWorkingSets[workingSets.length]= workingSet; | |
717 | setActiveWorkingSets(activeWorkingSets); | |
718 | } | |
719 | ||
720 | /** | |
721 | * Returns whether sorting is enabled for working sets. | |
722 | * | |
723 | * @return <code>true</code> if sorting is enabled, <code>false</code> otherwise | |
724 | * @since 3.5 | |
725 | */ | |
726 | public boolean isSortingEnabled() { | |
727 | return fIsSortingEnabled; | |
728 | } | |
729 | } |