KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > ModelUpdater


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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
12 package org.eclipse.jdt.internal.core;
13
14 import java.util.HashSet JavaDoc;
15 import java.util.Iterator JavaDoc;
16
17 import org.eclipse.jdt.core.*;
18
19 /**
20  * This class is used by <code>JavaModelManager</code> to update the JavaModel
21  * based on some <code>IJavaElementDelta</code>s.
22  */

23 public class ModelUpdater {
24
25     HashSet JavaDoc projectsToUpdate = new HashSet JavaDoc();
26
27     /**
28      * Adds the given child handle to its parent's cache of children.
29      */

30     protected void addToParentInfo(Openable child) {
31
32         Openable parent = (Openable) child.getParent();
33         if (parent != null && parent.isOpen()) {
34             try {
35                 JavaElementInfo info = (JavaElementInfo)parent.getElementInfo();
36                 info.addChild(child);
37             } catch (JavaModelException e) {
38                 // do nothing - we already checked if open
39
}
40         }
41     }
42
43     /**
44      * Closes the given element, which removes it from the cache of open elements.
45      */

46     protected static void close(Openable element) {
47
48         try {
49             element.close();
50         } catch (JavaModelException e) {
51             // do nothing
52
}
53     }
54
55     /**
56      * Processing for an element that has been added:<ul>
57      * <li>If the element is a project, do nothing, and do not process
58      * children, as when a project is created it does not yet have any
59      * natures - specifically a java nature.
60      * <li>If the elemet is not a project, process it as added (see
61      * <code>basicElementAdded</code>.
62      * </ul>
63      */

64     protected void elementAdded(Openable element) {
65
66         int elementType = element.getElementType();
67         if (elementType == IJavaElement.JAVA_PROJECT) {
68             // project add is handled by JavaProject.configure() because
69
// when a project is created, it does not yet have a java nature
70
addToParentInfo(element);
71             this.projectsToUpdate.add(element);
72         } else {
73             addToParentInfo(element);
74
75             // Force the element to be closed as it might have been opened
76
// before the resource modification came in and it might have a new child
77
// For example, in an IWorkspaceRunnable:
78
// 1. create a package fragment p using a java model operation
79
// 2. open package p
80
// 3. add file X.java in folder p
81
// When the resource delta comes in, only the addition of p is notified,
82
// but the package p is already opened, thus its children are not recomputed
83
// and it appears empty.
84
close(element);
85         }
86
87         switch (elementType) {
88             case IJavaElement.PACKAGE_FRAGMENT_ROOT :
89                 // when a root is added, and is on the classpath, the project must be updated
90
this.projectsToUpdate.add(element.getJavaProject());
91                 break;
92             case IJavaElement.PACKAGE_FRAGMENT :
93                 // get rid of package fragment cache
94
JavaProject project = (JavaProject) element.getJavaProject();
95                 project.resetCaches();
96                 break;
97         }
98     }
99
100     /**
101      * Generic processing for elements with changed contents:<ul>
102      * <li>The element is closed such that any subsequent accesses will re-open
103      * the element reflecting its new structure.
104      * </ul>
105      */

106     protected void elementChanged(Openable element) {
107
108         close(element);
109     }
110
111     /**
112      * Generic processing for a removed element:<ul>
113      * <li>Close the element, removing its structure from the cache
114      * <li>Remove the element from its parent's cache of children
115      * <li>Add a REMOVED entry in the delta
116      * </ul>
117      */

118     protected void elementRemoved(Openable element) {
119
120         if (element.isOpen()) {
121             close(element);
122         }
123         removeFromParentInfo(element);
124         int elementType = element.getElementType();
125
126         switch (elementType) {
127             case IJavaElement.JAVA_MODEL :
128                 JavaModelManager.getJavaModelManager().getIndexManager().reset();
129                 break;
130             case IJavaElement.JAVA_PROJECT :
131                 JavaModelManager manager = JavaModelManager.getJavaModelManager();
132                 JavaProject javaProject = (JavaProject) element;
133                 manager.removePerProjectInfo(javaProject);
134                 manager.containerRemove(javaProject);
135                 break;
136             case IJavaElement.PACKAGE_FRAGMENT_ROOT :
137                 this.projectsToUpdate.add(element.getJavaProject());
138                 break;
139             case IJavaElement.PACKAGE_FRAGMENT :
140                 // get rid of package fragment cache
141
JavaProject project = (JavaProject) element.getJavaProject();
142                 project.resetCaches();
143                 break;
144         }
145     }
146
147     /**
148      * Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code> into
149      * the corresponding set of <code>IJavaElementDelta</code>, rooted in the
150      * relevant <code>JavaModel</code>s.
151      */

152     public void processJavaDelta(IJavaElementDelta delta) {
153
154 // if (DeltaProcessor.VERBOSE){
155
// System.out.println("UPDATING Model with Delta: ["+Thread.currentThread()+":" + delta + "]:");
156
// }
157

158         try {
159             this.traverseDelta(delta, null, null); // traverse delta
160

161             // update package fragment roots of projects that were affected
162
Iterator JavaDoc iterator = this.projectsToUpdate.iterator();
163             while (iterator.hasNext()) {
164                 JavaProject project = (JavaProject) iterator.next();
165                 project.updatePackageFragmentRoots();
166             }
167         } finally {
168             this.projectsToUpdate = new HashSet JavaDoc();
169         }
170     }
171
172     /**
173      * Removes the given element from its parents cache of children. If the
174      * element does not have a parent, or the parent is not currently open,
175      * this has no effect.
176      */

177     protected void removeFromParentInfo(Openable child) {
178
179         Openable parent = (Openable) child.getParent();
180         if (parent != null && parent.isOpen()) {
181             try {
182                 JavaElementInfo info = (JavaElementInfo)parent.getElementInfo();
183                 info.removeChild(child);
184             } catch (JavaModelException e) {
185                 // do nothing - we already checked if open
186
}
187         }
188     }
189
190     /**
191      * Converts an <code>IResourceDelta</code> and its children into
192      * the corresponding <code>IJavaElementDelta</code>s.
193      * Return whether the delta corresponds to a resource on the classpath.
194      * If it is not a resource on the classpath, it will be added as a non-java
195      * resource by the sender of this method.
196      */

197     protected void traverseDelta(
198         IJavaElementDelta delta,
199         IPackageFragmentRoot root,
200         IJavaProject project) {
201
202         boolean processChildren = true;
203
204         Openable element = (Openable) delta.getElement();
205         switch (element.getElementType()) {
206             case IJavaElement.JAVA_PROJECT :
207                 project = (IJavaProject) element;
208                 break;
209             case IJavaElement.PACKAGE_FRAGMENT_ROOT :
210                 root = (IPackageFragmentRoot) element;
211                 break;
212             case IJavaElement.COMPILATION_UNIT :
213                 // filter out working copies that are not primary (we don't want to add/remove them to/from the package fragment
214
CompilationUnit cu = (CompilationUnit)element;
215                 if (cu.isWorkingCopy() && !cu.isPrimary()) {
216                     return;
217                 }
218             case IJavaElement.CLASS_FILE :
219                 processChildren = false;
220                 break;
221         }
222
223         switch (delta.getKind()) {
224             case IJavaElementDelta.ADDED :
225                 elementAdded(element);
226                 break;
227             case IJavaElementDelta.REMOVED :
228                 elementRemoved(element);
229                 break;
230             case IJavaElementDelta.CHANGED :
231                 if ((delta.getFlags() & IJavaElementDelta.F_CONTENT) != 0){
232                     elementChanged(element);
233                 }
234                 break;
235         }
236         if (processChildren) {
237             IJavaElementDelta[] children = delta.getAffectedChildren();
238             for (int i = 0; i < children.length; i++) {
239                 IJavaElementDelta childDelta = children[i];
240                 this.traverseDelta(childDelta, root, project);
241             }
242         }
243     }
244 }
245
Popular Tags