KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > workingsets > WorkingSetModel


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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 JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.Collections JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.IdentityHashMap JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
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 JavaDoc CHANGE_WORKING_SET_MODEL_CONTENT= "workingSetModelChanged"; //$NON-NLS-1$
46

47     public static final IElementComparer COMPARER= new WorkingSetComparar();
48
49     private static final String JavaDoc TAG_LOCAL_WORKING_SET_MANAGER= "localWorkingSetManager"; //$NON-NLS-1$
50
private static final String JavaDoc TAG_ACTIVE_WORKING_SET= "activeWorkingSet"; //$NON-NLS-1$
51
private static final String JavaDoc TAG_WORKING_SET_NAME= "workingSetName"; //$NON-NLS-1$
52
private static final String JavaDoc TAG_CONFIGURED= "configured"; //$NON-NLS-1$
53

54     private ILocalWorkingSetManager fLocalWorkingSetManager;
55     private List JavaDoc fActiveWorkingSets;
56     private ListenerList fListeners;
57     private IPropertyChangeListener fWorkingSetManagerListener;
58     private OthersWorkingSetUpdater fOthersWorkingSetUpdater;
59
60     private ElementMapper fElementMapper= new ElementMapper();
61
62     private boolean fConfigured;
63
64     private static class WorkingSetComparar implements IElementComparer {
65         public boolean equals(Object JavaDoc o1, Object JavaDoc o2) {
66             IWorkingSet w1= o1 instanceof IWorkingSet ? (IWorkingSet)o1 : null;
67             IWorkingSet w2= o2 instanceof IWorkingSet ? (IWorkingSet)o2 : null;
68             if (w1 == null || w2 == null)
69                 return o1.equals(o2);
70             return w1 == w2;
71         }
72         public int hashCode(Object JavaDoc element) {
73             if (element instanceof IWorkingSet)
74                 return System.identityHashCode(element);
75             return element.hashCode();
76         }
77     }
78
79     private static class ElementMapper {
80         private Map JavaDoc fElementToWorkingSet= new HashMap JavaDoc();
81         private Map JavaDoc fWorkingSetToElement= new IdentityHashMap JavaDoc();
82
83         private Map JavaDoc fResourceToWorkingSet= new HashMap JavaDoc();
84         private List JavaDoc fNonProjectTopLevelElements= new ArrayList JavaDoc();
85
86         public void clear() {
87             fElementToWorkingSet.clear();
88             fWorkingSetToElement.clear();
89             fResourceToWorkingSet.clear();
90             fNonProjectTopLevelElements.clear();
91         }
92         public void rebuild(IWorkingSet[] workingSets) {
93             clear();
94             for (int i= 0; i < workingSets.length; i++) {
95                 put(workingSets[i]);
96             }
97         }
98         public IAdaptable[] remove(IWorkingSet ws) {
99             IAdaptable[] elements= (IAdaptable[])fWorkingSetToElement.remove(ws);
100             if (elements != null) {
101                 for (int i= 0; i < elements.length; i++) {
102                     removeElement(elements[i], ws);
103                 }
104             }
105             return elements;
106         }
107         public IAdaptable[] refresh(IWorkingSet ws) {
108             IAdaptable[] oldElements= (IAdaptable[])fWorkingSetToElement.get(ws);
109             if (oldElements == null)
110                 return null;
111             IAdaptable[] newElements= ws.getElements();
112             List JavaDoc toRemove= new ArrayList JavaDoc(Arrays.asList(oldElements));
113             List JavaDoc toAdd= new ArrayList JavaDoc(Arrays.asList(newElements));
114             computeDelta(toRemove, toAdd, oldElements, newElements);
115             for (Iterator JavaDoc iter= toAdd.iterator(); iter.hasNext();) {
116                 addElement((IAdaptable)iter.next(), ws);
117             }
118             for (Iterator JavaDoc iter= toRemove.iterator(); iter.hasNext();) {
119                 removeElement((IAdaptable)iter.next(), ws);
120             }
121             if (toRemove.size() > 0 || toAdd.size() > 0)
122                 fWorkingSetToElement.put(ws, newElements);
123             return oldElements;
124         }
125         private void computeDelta(List JavaDoc toRemove, List JavaDoc toAdd, IAdaptable[] oldElements, IAdaptable[] newElements) {
126             for (int i= 0; i < oldElements.length; i++) {
127                 toAdd.remove(oldElements[i]);
128             }
129             for (int i= 0; i < newElements.length; i++) {
130                 toRemove.remove(newElements[i]);
131             }
132
133         }
134         public IWorkingSet getFirstWorkingSet(Object JavaDoc element) {
135             return (IWorkingSet)getFirstElement(fElementToWorkingSet, element);
136         }
137         public List JavaDoc getAllWorkingSets(Object JavaDoc element) {
138              List JavaDoc allElements= getAllElements(fElementToWorkingSet, element);
139              if (allElements.isEmpty() && element instanceof IJavaElement) {
140                  // try a second time in case the working set was manually updated (bug 168032)
141
allElements= getAllElements(fElementToWorkingSet, ((IJavaElement) element).getResource());
142              }
143              return allElements;
144         }
145         public IWorkingSet getFirstWorkingSetForResource(IResource resource) {
146             return (IWorkingSet)getFirstElement(fResourceToWorkingSet, resource);
147         }
148         public List JavaDoc getAllWorkingSetsForResource(IResource resource) {
149             return getAllElements(fResourceToWorkingSet, resource);
150         }
151         public List JavaDoc getNonProjectTopLevelElements() {
152             return fNonProjectTopLevelElements;
153         }
154         private void put(IWorkingSet ws) {
155             if (fWorkingSetToElement.containsKey(ws))
156                 return;
157             IAdaptable[] elements= ws.getElements();
158             fWorkingSetToElement.put(ws, elements);
159             for (int i= 0; i < elements.length; i++) {
160                 IAdaptable element= elements[i];
161                 addElement(element, ws);
162                 if (!(element instanceof IProject) && !(element instanceof IJavaProject)) {
163                     fNonProjectTopLevelElements.add(element);
164                 }
165             }
166         }
167         private void addElement(IAdaptable element, IWorkingSet ws) {
168             addToMap(fElementToWorkingSet, element, ws);
169             IResource resource= (IResource)element.getAdapter(IResource.class);
170             if (resource != null) {
171                 addToMap(fResourceToWorkingSet, resource, ws);
172             }
173         }
174         private void removeElement(IAdaptable element, IWorkingSet ws) {
175             removeFromMap(fElementToWorkingSet, element, ws);
176             IResource resource= (IResource)element.getAdapter(IResource.class);
177             if (resource != null) {
178                 removeFromMap(fResourceToWorkingSet, resource, ws);
179             }
180         }
181         private void addToMap(Map JavaDoc map, IAdaptable key, IWorkingSet value) {
182             Object JavaDoc obj= map.get(key);
183             if (obj == null) {
184                 map.put(key, value);
185             } else if (obj instanceof IWorkingSet) {
186                 List JavaDoc l= new ArrayList JavaDoc(2);
187                 l.add(obj);
188                 l.add(value);
189                 map.put(key, l);
190             } else if (obj instanceof List JavaDoc) {
191                 ((List JavaDoc)obj).add(value);
192             }
193         }
194         private void removeFromMap(Map JavaDoc map, IAdaptable key, IWorkingSet value) {
195             Object JavaDoc current= map.get(key);
196             if (current == null) {
197                 return;
198             } else if (current instanceof List JavaDoc) {
199                 List JavaDoc list= (List JavaDoc)current;
200                 list.remove(value);
201                 switch (list.size()) {
202                     case 0:
203                         map.remove(key);
204                         break;
205                     case 1:
206                         map.put(key, list.get(0));
207                         break;
208                 }
209             } else if (current == value) {
210                 map.remove(key);
211             }
212         }
213         private Object JavaDoc getFirstElement(Map JavaDoc map, Object JavaDoc key) {
214             Object JavaDoc obj= map.get(key);
215             if (obj instanceof List JavaDoc)
216                 return ((List JavaDoc)obj).get(0);
217             return obj;
218         }
219         private List JavaDoc getAllElements(Map JavaDoc map, Object JavaDoc key) {
220             Object JavaDoc obj= map.get(key);
221             if (obj instanceof List JavaDoc)
222                 return (List JavaDoc)obj;
223             if (obj == null)
224                 return Collections.EMPTY_LIST;
225             List JavaDoc result= new ArrayList JavaDoc(1);
226             result.add(obj);
227             return result;
228         }
229     }
230
231     /**
232      * @param memento a memento, or <code>null</code>
233      */

234     public WorkingSetModel(IMemento memento) {
235         fLocalWorkingSetManager= PlatformUI.getWorkbench().createLocalWorkingSetManager();
236         addListenersToWorkingSetManagers();
237         fActiveWorkingSets= new ArrayList JavaDoc(2);
238         
239         if (memento == null || ! restoreState(memento)) {
240             IWorkingSet others= fLocalWorkingSetManager.createWorkingSet(WorkingSetMessages.WorkingSetModel_others_name, new IAdaptable[0]);
241             others.setId(OthersWorkingSetUpdater.ID);
242             fLocalWorkingSetManager.addWorkingSet(others);
243             fActiveWorkingSets.add(others);
244         }
245         Assert.isNotNull(fOthersWorkingSetUpdater);
246         
247         fElementMapper.rebuild(getActiveWorkingSets());
248         fOthersWorkingSetUpdater.updateElements();
249     }
250
251     private void addListenersToWorkingSetManagers() {
252         fListeners= new ListenerList(ListenerList.IDENTITY);
253         fWorkingSetManagerListener= new IPropertyChangeListener() {
254             public void propertyChange(PropertyChangeEvent event) {
255                 workingSetManagerChanged(event);
256             }
257         };
258         PlatformUI.getWorkbench().getWorkingSetManager().addPropertyChangeListener(fWorkingSetManagerListener);
259         fLocalWorkingSetManager.addPropertyChangeListener(fWorkingSetManagerListener);
260     }
261
262     public void dispose() {
263         if (fWorkingSetManagerListener != null) {
264             PlatformUI.getWorkbench().getWorkingSetManager().removePropertyChangeListener(fWorkingSetManagerListener);
265             fLocalWorkingSetManager.removePropertyChangeListener(fWorkingSetManagerListener);
266             fLocalWorkingSetManager.dispose();
267             fWorkingSetManagerListener= null;
268         }
269     }
270
271     //---- model relationships ---------------------------------------
272

273     public IAdaptable[] getChildren(IWorkingSet workingSet) {
274         return workingSet.getElements();
275     }
276
277     public Object JavaDoc getParent(Object JavaDoc element) {
278         if (element instanceof IWorkingSet && fActiveWorkingSets.contains(element))
279             return this;
280         return fElementMapper.getFirstWorkingSet(element);
281     }
282
283     public Object JavaDoc[] getAllParents(Object JavaDoc element) {
284         if (element instanceof IWorkingSet && fActiveWorkingSets.contains(element))
285             return new Object JavaDoc[] {this};
286         return fElementMapper.getAllWorkingSets(element).toArray();
287     }
288
289     public Object JavaDoc[] addWorkingSets(Object JavaDoc[] elements) {
290         List JavaDoc result= null;
291         for (int i= 0; i < elements.length; i++) {
292             Object JavaDoc element= elements[i];
293             List JavaDoc sets= null;
294             if (element instanceof IResource) {
295                 sets= fElementMapper.getAllWorkingSetsForResource((IResource)element);
296             } else {
297                 sets= fElementMapper.getAllWorkingSets(element);
298             }
299             if (sets != null && sets.size() > 0) {
300                 if (result == null)
301                     result= new ArrayList JavaDoc(Arrays.asList(elements));
302                 result.addAll(sets);
303             }
304         }
305         if (result == null)
306             return elements;
307         return result.toArray();
308     }
309
310     public boolean needsConfiguration() {
311         return !fConfigured && fActiveWorkingSets.size() == 1 &&
312         OthersWorkingSetUpdater.ID.equals(((IWorkingSet)fActiveWorkingSets.get(0)).getId());
313     }
314
315     public void configured() {
316         fConfigured= true;
317     }
318
319     //---- working set management -----------------------------------
320

321     /**
322      * Adds a property change listener.
323      *
324      * @param listener the property change listener to add
325      */

326     public void addPropertyChangeListener(IPropertyChangeListener listener) {
327         fListeners.add(listener);
328     }
329
330     /**
331      * Removes the property change listener.
332      *
333      * @param listener the property change listener to remove
334      */

335     public void removePropertyChangeListener(IPropertyChangeListener listener) {
336         fListeners.remove(listener);
337     }
338
339     public IWorkingSet[] getActiveWorkingSets() {
340         return (IWorkingSet[])fActiveWorkingSets.toArray(new IWorkingSet[fActiveWorkingSets.size()]);
341     }
342
343     public IWorkingSet[] getAllWorkingSets() {
344         List JavaDoc result= new ArrayList JavaDoc();
345         result.addAll(fActiveWorkingSets);
346         IWorkingSet[] locals= fLocalWorkingSetManager.getWorkingSets();
347         for (int i= 0; i < locals.length; i++) {
348             if (!result.contains(locals[i]))
349                 result.add(locals[i]);
350         }
351         IWorkingSet[] globals= PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSets();
352         for (int i= 0; i < globals.length; i++) {
353             if (!result.contains(globals[i]))
354                 result.add(globals[i]);
355         }
356         return (IWorkingSet[])result.toArray(new IWorkingSet[result.size()]);
357     }
358
359     public void setActiveWorkingSets(IWorkingSet[] workingSets) {
360         fActiveWorkingSets= new ArrayList JavaDoc(Arrays.asList(workingSets));
361         fElementMapper.rebuild(getActiveWorkingSets());
362         fOthersWorkingSetUpdater.updateElements();
363         fireEvent(new PropertyChangeEvent(this, CHANGE_WORKING_SET_MODEL_CONTENT, null, null));
364     }
365
366     public void saveState(IMemento memento) {
367         memento.putString(TAG_CONFIGURED, Boolean.toString(fConfigured));
368         fLocalWorkingSetManager.saveState(memento.createChild(TAG_LOCAL_WORKING_SET_MANAGER));
369         for (Iterator JavaDoc iter= fActiveWorkingSets.iterator(); iter.hasNext();) {
370             IMemento active= memento.createChild(TAG_ACTIVE_WORKING_SET);
371             IWorkingSet workingSet= (IWorkingSet)iter.next();
372             active.putString(TAG_WORKING_SET_NAME, workingSet.getName());
373         }
374     }
375     
376     public List JavaDoc getNonProjectTopLevelElements() {
377         return fElementMapper.getNonProjectTopLevelElements();
378     }
379
380     /**
381      * Restore localWorkingSetManager and active working sets
382      * @param memento
383      * @return whether the restore was successful
384      */

385     private boolean restoreState(IMemento memento) {
386         String JavaDoc configured= memento.getString(TAG_CONFIGURED);
387         if (configured == null)
388             return false;
389         
390         fConfigured= Boolean.valueOf(configured).booleanValue();
391         fLocalWorkingSetManager.restoreState(memento.getChild(TAG_LOCAL_WORKING_SET_MANAGER));
392
393         IMemento[] actives= memento.getChildren(TAG_ACTIVE_WORKING_SET);
394         for (int i= 0; i < actives.length; i++) {
395             String JavaDoc name= actives[i].getString(TAG_WORKING_SET_NAME);
396             if (name != null) {
397                 IWorkingSet ws= fLocalWorkingSetManager.getWorkingSet(name);
398                 if (ws == null) {
399                     ws= PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(name);
400                 }
401                 if (ws != null) {
402                     fActiveWorkingSets.add(ws);
403                 }
404             }
405         }
406         return true;
407     }
408     private void workingSetManagerChanged(PropertyChangeEvent event) {
409         String JavaDoc property= event.getProperty();
410         if (IWorkingSetManager.CHANGE_WORKING_SET_UPDATER_INSTALLED.equals(property) && event.getSource() == fLocalWorkingSetManager) {
411             IWorkingSetUpdater updater= (IWorkingSetUpdater)event.getNewValue();
412             if (updater instanceof OthersWorkingSetUpdater) {
413                 fOthersWorkingSetUpdater= (OthersWorkingSetUpdater)updater;
414                 fOthersWorkingSetUpdater.init(this);
415             }
416             return;
417         }
418         // don't handle working sets not managed by the model
419
if (!isAffected(event))
420             return;
421
422         if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE.equals(property)) {
423             IWorkingSet workingSet= (IWorkingSet)event.getNewValue();
424             IAdaptable[] elements= fElementMapper.refresh(workingSet);
425             if (elements != null) {
426                 fireEvent(event);
427             }
428         } else if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)) {
429             IWorkingSet workingSet= (IWorkingSet)event.getOldValue();
430             List JavaDoc elements= new ArrayList JavaDoc(fActiveWorkingSets);
431             elements.remove(workingSet);
432             setActiveWorkingSets((IWorkingSet[])elements.toArray(new IWorkingSet[elements.size()]));
433         } else if (IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE.equals(property)) {
434             fireEvent(event);
435         }
436     }
437
438     private void fireEvent(PropertyChangeEvent event) {
439         Object JavaDoc[] listeners= fListeners.getListeners();
440         for (int i= 0; i < listeners.length; i++) {
441             ((IPropertyChangeListener)listeners[i]).propertyChange(event);
442         }
443     }
444
445     private boolean isAffected(PropertyChangeEvent event) {
446         if (fActiveWorkingSets == null)
447             return false;
448         Object JavaDoc oldValue= event.getOldValue();
449         Object JavaDoc newValue= event.getNewValue();
450         if ((oldValue != null && fActiveWorkingSets.contains(oldValue))
451                 || (newValue != null && fActiveWorkingSets.contains(newValue))) {
452             return true;
453         }
454         return false;
455     }
456
457     public boolean isActiveWorkingSet(IWorkingSet changedWorkingSet) {
458         return fActiveWorkingSets.contains(changedWorkingSet);
459     }
460 }
461
Popular Tags