001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.workingsets;
011:
012: import java.util.ArrayList;
013: import java.util.Arrays;
014: import java.util.Iterator;
015: import java.util.List;
016:
017: import org.eclipse.core.runtime.IAdaptable;
018:
019: import org.eclipse.core.resources.IProject;
020: import org.eclipse.core.resources.IResource;
021: import org.eclipse.core.resources.IResourceDelta;
022: import org.eclipse.core.resources.ResourcesPlugin;
023:
024: import org.eclipse.ui.IWorkingSet;
025: import org.eclipse.ui.IWorkingSetUpdater;
026:
027: import org.eclipse.jdt.core.ElementChangedEvent;
028: import org.eclipse.jdt.core.IElementChangedListener;
029: import org.eclipse.jdt.core.IJavaElement;
030: import org.eclipse.jdt.core.IJavaElementDelta;
031: import org.eclipse.jdt.core.IJavaProject;
032: import org.eclipse.jdt.core.JavaCore;
033:
034: public class JavaWorkingSetUpdater implements IWorkingSetUpdater,
035: IElementChangedListener {
036:
037: public static final String ID = "org.eclipse.jdt.ui.JavaWorkingSetPage"; //$NON-NLS-1$
038:
039: private List fWorkingSets;
040:
041: private static class WorkingSetDelta {
042: private IWorkingSet fWorkingSet;
043: private List fElements;
044: private boolean fChanged;
045:
046: public WorkingSetDelta(IWorkingSet workingSet) {
047: fWorkingSet = workingSet;
048: fElements = new ArrayList(Arrays.asList(workingSet
049: .getElements()));
050: }
051:
052: public int indexOf(Object element) {
053: return fElements.indexOf(element);
054: }
055:
056: public void set(int index, Object element) {
057: fElements.set(index, element);
058: fChanged = true;
059: }
060:
061: public void remove(int index) {
062: if (fElements.remove(index) != null) {
063: fChanged = true;
064: }
065: }
066:
067: public void process() {
068: if (fChanged) {
069: fWorkingSet.setElements((IAdaptable[]) fElements
070: .toArray(new IAdaptable[fElements.size()]));
071: }
072: }
073: }
074:
075: public JavaWorkingSetUpdater() {
076: fWorkingSets = new ArrayList();
077: JavaCore.addElementChangedListener(this );
078: }
079:
080: /**
081: * {@inheritDoc}
082: */
083: public void add(IWorkingSet workingSet) {
084: checkElementExistence(workingSet);
085: synchronized (fWorkingSets) {
086: fWorkingSets.add(workingSet);
087: }
088: }
089:
090: /**
091: * {@inheritDoc}
092: */
093: public boolean remove(IWorkingSet workingSet) {
094: boolean result;
095: synchronized (fWorkingSets) {
096: result = fWorkingSets.remove(workingSet);
097: }
098: return result;
099: }
100:
101: /**
102: * {@inheritDoc}
103: */
104: public boolean contains(IWorkingSet workingSet) {
105: synchronized (fWorkingSets) {
106: return fWorkingSets.contains(workingSet);
107: }
108: }
109:
110: /**
111: * {@inheritDoc}
112: */
113: public void dispose() {
114: synchronized (fWorkingSets) {
115: fWorkingSets.clear();
116: }
117: JavaCore.removeElementChangedListener(this );
118: }
119:
120: /**
121: * {@inheritDoc}
122: */
123: public void elementChanged(ElementChangedEvent event) {
124: IWorkingSet[] workingSets;
125: synchronized (fWorkingSets) {
126: workingSets = (IWorkingSet[]) fWorkingSets
127: .toArray(new IWorkingSet[fWorkingSets.size()]);
128: }
129: for (int w = 0; w < workingSets.length; w++) {
130: WorkingSetDelta workingSetDelta = new WorkingSetDelta(
131: workingSets[w]);
132: processJavaDelta(workingSetDelta, event.getDelta());
133: IResourceDelta[] resourceDeltas = event.getDelta()
134: .getResourceDeltas();
135: if (resourceDeltas != null) {
136: for (int r = 0; r < resourceDeltas.length; r++) {
137: processResourceDelta(workingSetDelta,
138: resourceDeltas[r]);
139: }
140: }
141: workingSetDelta.process();
142: }
143: }
144:
145: private void processJavaDelta(WorkingSetDelta result,
146: IJavaElementDelta delta) {
147: IJavaElement jElement = delta.getElement();
148: int index = result.indexOf(jElement);
149: int type = jElement.getElementType();
150: int kind = delta.getKind();
151: int flags = delta.getFlags();
152: if (type == IJavaElement.JAVA_PROJECT
153: && kind == IJavaElementDelta.CHANGED) {
154: if (index != -1
155: && (flags & IJavaElementDelta.F_CLOSED) != 0) {
156: result.set(index, ((IJavaProject) jElement)
157: .getProject());
158: } else if ((flags & IJavaElementDelta.F_OPENED) != 0) {
159: index = result.indexOf(((IJavaProject) jElement)
160: .getProject());
161: if (index != -1)
162: result.set(index, jElement);
163: }
164: }
165: if (index != -1) {
166: if (kind == IJavaElementDelta.REMOVED) {
167: if ((flags & IJavaElementDelta.F_MOVED_TO) != 0) {
168: result.set(index, delta.getMovedToElement());
169: } else {
170: result.remove(index);
171: }
172: }
173: }
174: IResourceDelta[] resourceDeltas = delta.getResourceDeltas();
175: if (resourceDeltas != null) {
176: for (int i = 0; i < resourceDeltas.length; i++) {
177: processResourceDelta(result, resourceDeltas[i]);
178: }
179: }
180: IJavaElementDelta[] children = delta.getAffectedChildren();
181: for (int i = 0; i < children.length; i++) {
182: processJavaDelta(result, children[i]);
183: }
184: }
185:
186: private void processResourceDelta(WorkingSetDelta result,
187: IResourceDelta delta) {
188: IResource resource = delta.getResource();
189: int type = resource.getType();
190: int index = result.indexOf(resource);
191: int kind = delta.getKind();
192: int flags = delta.getFlags();
193: if (kind == IResourceDelta.CHANGED && type == IResource.PROJECT
194: && index != -1) {
195: if ((flags & IResourceDelta.OPEN) != 0) {
196: result.set(index, resource);
197: }
198: }
199: if (index != -1 && kind == IResourceDelta.REMOVED) {
200: if ((flags & IResourceDelta.MOVED_TO) != 0) {
201: result.set(index, ResourcesPlugin.getWorkspace()
202: .getRoot().findMember(delta.getMovedToPath()));
203: } else {
204: result.remove(index);
205: }
206: }
207:
208: // Don't dive into closed or opened projects
209: if (projectGotClosedOrOpened(resource, kind, flags))
210: return;
211:
212: IResourceDelta[] children = delta.getAffectedChildren();
213: for (int i = 0; i < children.length; i++) {
214: processResourceDelta(result, children[i]);
215: }
216: }
217:
218: private boolean projectGotClosedOrOpened(IResource resource,
219: int kind, int flags) {
220: return resource.getType() == IResource.PROJECT
221: && kind == IResourceDelta.CHANGED
222: && (flags & IResourceDelta.OPEN) != 0;
223: }
224:
225: private void checkElementExistence(IWorkingSet workingSet) {
226: List elements = new ArrayList(Arrays.asList(workingSet
227: .getElements()));
228: boolean changed = false;
229: for (Iterator iter = elements.iterator(); iter.hasNext();) {
230: IAdaptable element = (IAdaptable) iter.next();
231: boolean remove = false;
232: if (element instanceof IJavaElement) {
233: IJavaElement jElement = (IJavaElement) element;
234: // If we have directly a project then remove it when it
235: // doesn't exist anymore. However if we have a sub element
236: // under a project only remove the element if the parent
237: // project is open. Otherwise we would remove all elements
238: // in closed projects.
239: if (jElement instanceof IJavaProject) {
240: remove = !jElement.exists();
241: } else {
242: IProject project = jElement.getJavaProject()
243: .getProject();
244: remove = project.isOpen() && !jElement.exists();
245: }
246: } else if (element instanceof IResource) {
247: IResource resource = (IResource) element;
248: // See comments above
249: if (resource instanceof IProject) {
250: remove = !resource.exists();
251: } else {
252: IProject project = resource.getProject();
253: remove = (project != null ? project.isOpen() : true)
254: && !resource.exists();
255: }
256: }
257: if (remove) {
258: iter.remove();
259: changed = true;
260: }
261: }
262: if (changed) {
263: workingSet.setElements((IAdaptable[]) elements
264: .toArray(new IAdaptable[elements.size()]));
265: }
266: }
267: }
|