KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > text > source > projection > ProjectionSummary


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 package org.eclipse.jface.text.source.projection;
12
13 import org.eclipse.core.runtime.IProgressMonitor;
14
15 import java.util.ArrayList JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20
21 import org.eclipse.jface.text.IDocument;
22 import org.eclipse.jface.text.IRegion;
23 import org.eclipse.jface.text.ISynchronizable;
24 import org.eclipse.jface.text.Position;
25 import org.eclipse.jface.text.source.Annotation;
26 import org.eclipse.jface.text.source.IAnnotationAccess;
27 import org.eclipse.jface.text.source.IAnnotationAccessExtension;
28 import org.eclipse.jface.text.source.IAnnotationModel;
29 import org.eclipse.jface.text.source.IAnnotationModelExtension;
30
31 /**
32  * Strategy for managing annotation summaries for collapsed ranges.
33  *
34  * @since 3.0
35  */

36 class ProjectionSummary {
37
38     private class Summarizer extends Thread JavaDoc {
39
40         private boolean fReset= true;
41
42         /**
43          * Creates a new thread.
44          *
45          * @param monitor the progress monitor
46          */

47         public Summarizer(IProgressMonitor monitor) {
48             fProgressMonitor= monitor;
49             setDaemon(true);
50             start();
51         }
52
53         /**
54          * Resets the thread.
55          */

56         public void reset() {
57             fReset= true;
58         }
59
60         /*
61          * @see java.lang.Thread#run()
62          */

63         public void run() {
64             while (true) {
65                 synchronized (fLock) {
66                     if (!fReset)
67                         break;
68                     fReset= false;
69                 }
70                 internalUpdateSummaries(fProgressMonitor);
71             }
72
73             synchronized (fLock) {
74                 fSummarizer= null;
75             }
76         }
77     }
78
79
80     private ProjectionViewer fProjectionViewer;
81     private IAnnotationModel fAnnotationModel;
82     private IAnnotationAccess fAnnotationAccess;
83     private List JavaDoc fConfiguredAnnotationTypes;
84
85     private Object JavaDoc fLock= new Object JavaDoc();
86     private IProgressMonitor fProgressMonitor;
87     private volatile Summarizer fSummarizer;
88
89     /**
90      * Creates a new projection summary.
91      *
92      * @param projectionViewer the projection viewer
93      * @param annotationAccess the annotation access
94      */

95     public ProjectionSummary(ProjectionViewer projectionViewer, IAnnotationAccess annotationAccess) {
96         super();
97         fProjectionViewer= projectionViewer;
98         fAnnotationAccess= annotationAccess;
99     }
100
101     /**
102      * Adds the given annotation type. For now on, annotations of that type are
103      * also reflected in their enclosing collapsed regions.
104      *
105      * @param annotationType the annotation type to add
106      */

107     public void addAnnotationType(String JavaDoc annotationType) {
108         synchronized(fLock) {
109             if (fConfiguredAnnotationTypes == null) {
110                 fConfiguredAnnotationTypes= new ArrayList JavaDoc();
111                 fConfiguredAnnotationTypes.add(annotationType);
112             } else if (!fConfiguredAnnotationTypes.contains(annotationType))
113                 fConfiguredAnnotationTypes.add(annotationType);
114         }
115     }
116
117     /**
118      * Removes the given annotation. Annotation of that type are no
119      * longer reflected in their enclosing collapsed region.
120      *
121      * @param annotationType the annotation type to remove
122      */

123     public void removeAnnotationType(String JavaDoc annotationType) {
124         synchronized (fLock) {
125             if (fConfiguredAnnotationTypes != null) {
126                 fConfiguredAnnotationTypes.remove(annotationType);
127                 if (fConfiguredAnnotationTypes.size() == 0)
128                     fConfiguredAnnotationTypes= null;
129             }
130         }
131     }
132
133     /**
134      * Forces an updated of the annotation summary.
135      *
136      * @param monitor the progress monitor
137      */

138     public void updateSummaries(IProgressMonitor monitor) {
139         synchronized (fLock) {
140             if (fConfiguredAnnotationTypes != null) {
141                 if (fSummarizer == null)
142                     fSummarizer= new Summarizer(monitor);
143                 fSummarizer.reset();
144             }
145         }
146     }
147
148     private void internalUpdateSummaries(IProgressMonitor monitor) {
149
150         Object JavaDoc previousLockObject= null;
151         fAnnotationModel= fProjectionViewer.getVisualAnnotationModel();
152         if (fAnnotationModel == null)
153             return;
154
155         try {
156
157
158             IDocument document= fProjectionViewer.getDocument();
159             if (document instanceof ISynchronizable && fAnnotationModel instanceof ISynchronizable) {
160                 ISynchronizable sync= (ISynchronizable) fAnnotationModel;
161                 previousLockObject= sync.getLockObject();
162                 sync.setLockObject(((ISynchronizable) document).getLockObject());
163             }
164
165
166             removeSummaries(monitor);
167             createSummaries(monitor);
168
169         } finally {
170
171             if (fAnnotationModel instanceof ISynchronizable) {
172                 ISynchronizable sync= (ISynchronizable) fAnnotationModel;
173                 sync.setLockObject(previousLockObject);
174             }
175             fAnnotationModel= null;
176
177         }
178     }
179
180     private boolean isCanceled(IProgressMonitor monitor) {
181         return monitor != null && monitor.isCanceled();
182     }
183
184     private void removeSummaries(IProgressMonitor monitor) {
185         IAnnotationModelExtension extension= null;
186         List JavaDoc bags= null;
187
188         if (fAnnotationModel instanceof IAnnotationModelExtension) {
189             extension= (IAnnotationModelExtension) fAnnotationModel;
190             bags= new ArrayList JavaDoc();
191         }
192
193         Iterator JavaDoc e= fAnnotationModel.getAnnotationIterator();
194         while (e.hasNext()) {
195             Annotation annotation= (Annotation) e.next();
196             if (annotation instanceof AnnotationBag) {
197                 if (bags == null)
198                     fAnnotationModel.removeAnnotation(annotation);
199                 else
200                     bags.add(annotation);
201             }
202
203             if (isCanceled(monitor))
204                 return;
205         }
206
207         if (bags != null && bags.size() > 0) {
208             Annotation[] deletions= new Annotation[bags.size()];
209             bags.toArray(deletions);
210             if (!isCanceled(monitor))
211                 extension.replaceAnnotations(deletions, null);
212         }
213     }
214
215     private void createSummaries(IProgressMonitor monitor) {
216         ProjectionAnnotationModel model= fProjectionViewer.getProjectionAnnotationModel();
217         if (model == null)
218             return;
219
220         Map JavaDoc additions= new HashMap JavaDoc();
221
222         Iterator JavaDoc e= model.getAnnotationIterator();
223         while (e.hasNext()) {
224             ProjectionAnnotation projection= (ProjectionAnnotation) e.next();
225             if (projection.isCollapsed()) {
226                 Position position= model.getPosition(projection);
227                 if (position != null) {
228                     IRegion[] summaryRegions= fProjectionViewer.computeCollapsedRegions(position);
229                     if (summaryRegions != null) {
230                         Position summaryAnchor= fProjectionViewer.computeCollapsedRegionAnchor(position);
231                         if (summaryAnchor != null)
232                             createSummary(additions, summaryRegions, summaryAnchor);
233                     }
234                 }
235             }
236
237             if (isCanceled(monitor))
238                 return;
239         }
240
241         if (additions.size() > 0) {
242             if (fAnnotationModel instanceof IAnnotationModelExtension) {
243                 IAnnotationModelExtension extension= (IAnnotationModelExtension) fAnnotationModel;
244                 if (!isCanceled(monitor))
245                     extension.replaceAnnotations(null, additions);
246             } else {
247                 Iterator JavaDoc e1= additions.keySet().iterator();
248                 while (e1.hasNext()) {
249                     AnnotationBag bag= (AnnotationBag) e1.next();
250                     Position position= (Position) additions.get(bag);
251                     if (isCanceled(monitor))
252                         return;
253                     fAnnotationModel.addAnnotation(bag, position);
254                 }
255             }
256         }
257     }
258
259     private void createSummary(Map JavaDoc additions, IRegion[] summaryRegions, Position summaryAnchor) {
260
261         int size= 0;
262         Map JavaDoc map= null;
263
264         synchronized (fLock) {
265             if (fConfiguredAnnotationTypes != null) {
266                 size= fConfiguredAnnotationTypes.size();
267                 map= new HashMap JavaDoc();
268                 for (int i= 0; i < size; i++) {
269                     String JavaDoc type= (String JavaDoc) fConfiguredAnnotationTypes.get(i);
270                     map.put(type, new AnnotationBag(type));
271                 }
272             }
273         }
274
275         if (map == null)
276             return;
277
278         IAnnotationModel model= fProjectionViewer.getAnnotationModel();
279         if (model == null)
280             return;
281         Iterator JavaDoc e= model.getAnnotationIterator();
282         while (e.hasNext()) {
283             Annotation annotation= (Annotation) e.next();
284             AnnotationBag bag= findBagForType(map, annotation.getType());
285             if (bag != null) {
286                 Position position= model.getPosition(annotation);
287                 if (includes(summaryRegions, position))
288                     bag.add(annotation);
289             }
290         }
291
292         for (int i= 0; i < size; i++) {
293             AnnotationBag bag= (AnnotationBag) map.get(fConfiguredAnnotationTypes.get(i));
294             if (!bag.isEmpty())
295                 additions.put(bag, new Position(summaryAnchor.getOffset(), summaryAnchor.getLength()));
296         }
297     }
298
299     private AnnotationBag findBagForType(Map JavaDoc bagMap, String JavaDoc annotationType) {
300         AnnotationBag bag= (AnnotationBag) bagMap.get(annotationType);
301         if (bag == null && fAnnotationAccess instanceof IAnnotationAccessExtension) {
302             IAnnotationAccessExtension extension= (IAnnotationAccessExtension) fAnnotationAccess;
303             Object JavaDoc[] superTypes= extension.getSupertypes(annotationType);
304             for (int i= 0; i < superTypes.length && bag == null; i++) {
305                 bag= (AnnotationBag) bagMap.get(superTypes[i]);
306             }
307         }
308         return bag;
309     }
310
311     private boolean includes(IRegion[] regions, Position position) {
312         for (int i= 0; i < regions.length; i++) {
313             IRegion region= regions[i];
314             if (position != null && !position.isDeleted()
315                     && region.getOffset() <= position.getOffset() && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength())
316                 return true;
317         }
318         return false;
319     }
320 }
321
Popular Tags