1 11 package org.eclipse.jface.text.source.projection; 12 13 import org.eclipse.core.runtime.IProgressMonitor; 14 15 import java.util.ArrayList ; 16 import java.util.HashMap ; 17 import java.util.Iterator ; 18 import java.util.List ; 19 import java.util.Map ; 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 36 class ProjectionSummary { 37 38 private class Summarizer extends Thread { 39 40 private boolean fReset= true; 41 42 47 public Summarizer(IProgressMonitor monitor) { 48 fProgressMonitor= monitor; 49 setDaemon(true); 50 start(); 51 } 52 53 56 public void reset() { 57 fReset= true; 58 } 59 60 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 fConfiguredAnnotationTypes; 84 85 private Object fLock= new Object (); 86 private IProgressMonitor fProgressMonitor; 87 private volatile Summarizer fSummarizer; 88 89 95 public ProjectionSummary(ProjectionViewer projectionViewer, IAnnotationAccess annotationAccess) { 96 super(); 97 fProjectionViewer= projectionViewer; 98 fAnnotationAccess= annotationAccess; 99 } 100 101 107 public void addAnnotationType(String annotationType) { 108 synchronized(fLock) { 109 if (fConfiguredAnnotationTypes == null) { 110 fConfiguredAnnotationTypes= new ArrayList (); 111 fConfiguredAnnotationTypes.add(annotationType); 112 } else if (!fConfiguredAnnotationTypes.contains(annotationType)) 113 fConfiguredAnnotationTypes.add(annotationType); 114 } 115 } 116 117 123 public void removeAnnotationType(String 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 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 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 bags= null; 187 188 if (fAnnotationModel instanceof IAnnotationModelExtension) { 189 extension= (IAnnotationModelExtension) fAnnotationModel; 190 bags= new ArrayList (); 191 } 192 193 Iterator 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 additions= new HashMap (); 221 222 Iterator 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 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 additions, IRegion[] summaryRegions, Position summaryAnchor) { 260 261 int size= 0; 262 Map map= null; 263 264 synchronized (fLock) { 265 if (fConfiguredAnnotationTypes != null) { 266 size= fConfiguredAnnotationTypes.size(); 267 map= new HashMap (); 268 for (int i= 0; i < size; i++) { 269 String type= (String ) 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 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 bagMap, String annotationType) { 300 AnnotationBag bag= (AnnotationBag) bagMap.get(annotationType); 301 if (bag == null && fAnnotationAccess instanceof IAnnotationAccessExtension) { 302 IAnnotationAccessExtension extension= (IAnnotationAccessExtension) fAnnotationAccess; 303 Object [] 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 |