1 11 package org.eclipse.ui.internal.navigator.extensions; 12 13 import java.lang.ref.SoftReference ; 14 import java.util.Arrays ; 15 import java.util.HashMap ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.Map ; 19 import java.util.Set ; 20 import java.util.TreeSet ; 21 import java.util.WeakHashMap ; 22 23 import org.eclipse.core.runtime.IConfigurationElement; 24 import org.eclipse.jface.resource.ImageDescriptor; 25 import org.eclipse.jface.resource.ImageRegistry; 26 import org.eclipse.swt.graphics.Image; 27 import org.eclipse.ui.WorkbenchException; 28 import org.eclipse.ui.internal.navigator.NavigatorPlugin; 29 import org.eclipse.ui.internal.navigator.VisibilityAssistant; 30 import org.eclipse.ui.internal.navigator.VisibilityAssistant.VisibilityListener; 31 import org.eclipse.ui.navigator.INavigatorContentDescriptor; 32 import org.eclipse.ui.plugin.AbstractUIPlugin; 33 34 44 public class NavigatorContentDescriptorManager { 45 46 private static final NavigatorContentDescriptorManager INSTANCE = new NavigatorContentDescriptorManager(); 47 48 private final Map firstClassDescriptorsMap = new HashMap (); 49 50 private final Map allDescriptors = new HashMap (); 51 52 private class EvaluationCache implements VisibilityListener { 53 54 private final Map evaluations = new HashMap (); 55 private final Map evaluationsWithOverrides = new HashMap (); 56 57 EvaluationCache(VisibilityAssistant anAssistant) { 58 anAssistant.addListener(this); 59 } 60 61 protected final NavigatorContentDescriptor[] getDescriptors(Object anElement) { 62 return getDescriptors(anElement, true); 63 } 64 65 protected final void setDescriptors(Object anElement, NavigatorContentDescriptor[] theDescriptors) { 66 setDescriptors(anElement, theDescriptors, true); 67 } 68 69 protected final NavigatorContentDescriptor[] getDescriptors(Object anElement, boolean toComputeOverrides) { 70 71 if(anElement == null) 72 return null; 73 74 NavigatorContentDescriptor[] cachedDescriptors = null; 75 if(toComputeOverrides) { 76 SoftReference cache = (SoftReference ) evaluations.get(anElement); 77 if( cache != null && (cachedDescriptors = (NavigatorContentDescriptor[]) cache.get()) == null) 78 evaluations.remove(anElement); 79 return cachedDescriptors; 80 } 81 SoftReference cache = (SoftReference ) evaluationsWithOverrides.get(anElement); 82 if( cache != null && (cachedDescriptors = (NavigatorContentDescriptor[]) cache.get()) == null) 83 evaluationsWithOverrides.remove(anElement); 84 return cachedDescriptors; 85 86 } 87 88 protected final void setDescriptors(Object anElement, NavigatorContentDescriptor[] theDescriptors, boolean toComputeOverrides) { 89 if(anElement != null) { 90 if(toComputeOverrides) 91 evaluations.put(new EvalutationReference(anElement), new SoftReference (theDescriptors)); 92 else 93 evaluationsWithOverrides.put(new EvalutationReference(anElement), new SoftReference (theDescriptors)); 94 } 95 } 96 97 102 public void onVisibilityOrActivationChange() { 103 evaluations.clear(); 104 evaluationsWithOverrides.clear(); 105 } 106 } 107 108 109 private final Map cachedTriggerPointEvaluations = new WeakHashMap (); 110 111 112 private final Map cachedPossibleChildrenEvaluations = new WeakHashMap (); 113 114 private ImageRegistry imageRegistry; 115 116 private final Set overridingDescriptors = new HashSet (); 117 118 private final Set saveablesProviderDescriptors = new HashSet (); 119 120 private final Set firstClassDescriptorsSet = new HashSet (); 121 122 125 public static NavigatorContentDescriptorManager getInstance() { 126 return INSTANCE; 127 } 128 129 private NavigatorContentDescriptorManager() { 130 new NavigatorContentDescriptorRegistry().readRegistry(); 131 } 132 133 137 public NavigatorContentDescriptor[] getAllContentDescriptors() { 138 NavigatorContentDescriptor[] finalDescriptors = new NavigatorContentDescriptor[allDescriptors 139 .size()]; 140 finalDescriptors = (NavigatorContentDescriptor[]) allDescriptors.values().toArray(finalDescriptors); 141 Arrays.sort(finalDescriptors, ExtensionPriorityComparator.INSTANCE); 142 return finalDescriptors; 143 } 144 145 149 public NavigatorContentDescriptor[] getContentDescriptorsWithSaveables() { 150 NavigatorContentDescriptor[] finalDescriptors = new NavigatorContentDescriptor[saveablesProviderDescriptors 151 .size()]; 152 saveablesProviderDescriptors.toArray(finalDescriptors); 153 Arrays.sort(finalDescriptors, ExtensionPriorityComparator.INSTANCE); 154 return finalDescriptors; 155 } 156 157 169 public Set findDescriptorsForTriggerPoint(Object anElement, 170 VisibilityAssistant aVisibilityAssistant) { 171 EvaluationCache cache = getEvaluationCache( 172 cachedTriggerPointEvaluations, aVisibilityAssistant); 173 174 Set descriptors = new TreeSet (ExtensionPriorityComparator.INSTANCE); 175 NavigatorContentDescriptor[] cachedDescriptors = null; 176 if ( (cachedDescriptors = cache.getDescriptors(anElement)) != null) { 177 descriptors.addAll(Arrays.asList(cachedDescriptors)); 178 } 179 180 181 for (Iterator contentDescriptorsItr = firstClassDescriptorsMap.values() 182 .iterator(); contentDescriptorsItr.hasNext();) { 183 NavigatorContentDescriptor descriptor = (NavigatorContentDescriptor) contentDescriptorsItr 184 .next(); 185 186 if (aVisibilityAssistant.isActive(descriptor) 187 && aVisibilityAssistant.isVisible(descriptor) 188 && descriptor.isTriggerPoint(anElement)) { 189 descriptors.add(descriptor); 190 } 191 } 192 193 cache.setDescriptors(anElement, (NavigatorContentDescriptor[]) descriptors.toArray(new NavigatorContentDescriptor[descriptors.size()])); 194 195 return descriptors; 196 } 197 198 private EvaluationCache getEvaluationCache(Map anEvaluationMap, 199 VisibilityAssistant aVisibilityAssistant) { 200 EvaluationCache c = (EvaluationCache) anEvaluationMap 201 .get(aVisibilityAssistant); 202 if (c == null) { 203 anEvaluationMap.put(aVisibilityAssistant, c = new EvaluationCache( 204 aVisibilityAssistant)); 205 } 206 return c; 207 208 } 209 210 222 public Set findDescriptorsForPossibleChild(Object anElement, 223 VisibilityAssistant aVisibilityAssistant) { 224 return findDescriptorsForPossibleChild(anElement, aVisibilityAssistant, true); 225 } 226 227 239 public Set findDescriptorsForPossibleChild(Object anElement, 240 VisibilityAssistant aVisibilityAssistant, boolean toComputeOverrides) { 241 242 EvaluationCache cache = getEvaluationCache( 243 cachedPossibleChildrenEvaluations, aVisibilityAssistant); 244 245 Set descriptors = new TreeSet (ExtensionPriorityComparator.INSTANCE); 246 NavigatorContentDescriptor[] cachedDescriptors = null; 247 if ( (cachedDescriptors = cache.getDescriptors(anElement, toComputeOverrides)) != null) { 248 descriptors.addAll(Arrays.asList(cachedDescriptors)); 249 } 250 251 if(toComputeOverrides) { 252 addDescriptorsForPossibleChild(anElement, firstClassDescriptorsSet, 253 aVisibilityAssistant, descriptors); 254 } else { 255 256 NavigatorContentDescriptor descriptor; 257 258 for (Iterator contentDescriptorsItr = allDescriptors.values().iterator(); contentDescriptorsItr 259 .hasNext();) { 260 descriptor = (NavigatorContentDescriptor) contentDescriptorsItr 261 .next(); 262 263 boolean isApplicable = aVisibilityAssistant.isActive(descriptor) 264 && aVisibilityAssistant.isVisible(descriptor) 265 && descriptor.isPossibleChild(anElement); 266 267 if (isApplicable) { 268 descriptors.add(descriptor); 269 } 270 271 } 272 } 273 cache.setDescriptors(anElement, (NavigatorContentDescriptor[]) descriptors.toArray(new NavigatorContentDescriptor[descriptors.size()]), toComputeOverrides); 274 275 return descriptors; 276 } 277 278 private boolean addDescriptorsForPossibleChild(Object anElement, 279 Set theChildDescriptors, VisibilityAssistant aVisibilityAssistant, 280 Set theFoundDescriptors) { 281 int initialSize = theFoundDescriptors.size(); 282 283 NavigatorContentDescriptor descriptor; 284 285 for (Iterator contentDescriptorsItr = theChildDescriptors.iterator(); contentDescriptorsItr 286 .hasNext();) { 287 descriptor = (NavigatorContentDescriptor) contentDescriptorsItr 288 .next(); 289 290 boolean isApplicable = aVisibilityAssistant.isActive(descriptor) 291 && aVisibilityAssistant.isVisible(descriptor) 292 && descriptor.isPossibleChild(anElement); 293 294 if (descriptor.hasOverridingExtensions()) { 295 296 boolean isOverridden = addDescriptorsForPossibleChild( 297 anElement, descriptor.getOverriddingExtensions(), 298 aVisibilityAssistant, theFoundDescriptors); 299 300 if (!isOverridden && isApplicable) { 301 theFoundDescriptors.add(descriptor); 302 } 303 304 } else if (isApplicable) { 305 theFoundDescriptors.add(descriptor); 306 } 307 308 } 309 return initialSize < theFoundDescriptors.size(); 310 311 } 312 313 320 public NavigatorContentDescriptor getContentDescriptor(String id) { 321 return (NavigatorContentDescriptor) allDescriptors.get(id); 322 } 323 324 330 public String getText(String descriptorId) { 331 INavigatorContentDescriptor descriptor = getContentDescriptor(descriptorId); 332 if (descriptor != null) { 333 return descriptor.getName(); 334 } 335 return descriptorId; 336 } 337 338 345 public Image getImage(String descriptorId) { 346 return retrieveAndStoreImage(descriptorId); 347 } 348 349 protected Image retrieveAndStoreImage(String descriptorId) { 350 NavigatorContentDescriptor contentDescriptor = getContentDescriptor(descriptorId); 351 352 Image image = null; 353 if (contentDescriptor != null) { 354 String icon = contentDescriptor.getIcon(); 355 if (icon != null) { 356 image = getImageRegistry().get(icon); 357 if (image == null || image.isDisposed()) { 358 ImageDescriptor imageDescriptor = AbstractUIPlugin 359 .imageDescriptorFromPlugin(contentDescriptor 360 .getContribution().getPluginId(), icon); 361 if (imageDescriptor != null) { 362 image = imageDescriptor.createImage(); 363 if (image != null) { 364 getImageRegistry().put(icon, image); 365 } 366 } 367 } 368 } 369 } 370 return image; 371 } 372 373 376 private void addNavigatorContentDescriptor(NavigatorContentDescriptor desc) { 377 if (desc == null) { 378 return; 379 } 380 synchronized (firstClassDescriptorsMap) { 381 if (firstClassDescriptorsMap.containsKey(desc.getId())) { 382 NavigatorPlugin 383 .logError( 384 0, 385 "An extension already exists with id \"" + desc.getId() + "\".", null); } else { 387 if (desc.getSuppressedExtensionId() == null) { 388 firstClassDescriptorsMap.put(desc.getId(), desc); 389 firstClassDescriptorsSet.add(desc); 390 } else { 391 overridingDescriptors.add(desc); 392 } 393 allDescriptors.put(desc.getId(), desc); 394 if (desc.hasSaveablesProvider()) { 395 saveablesProviderDescriptors.add(desc); 396 } 397 } 398 } 399 } 400 401 404 private void computeOverrides() { 405 if (overridingDescriptors.size() > 0) { 406 NavigatorContentDescriptor descriptor; 407 NavigatorContentDescriptor overriddenDescriptor; 408 for (Iterator overridingIterator = overridingDescriptors.iterator(); overridingIterator 409 .hasNext();) { 410 descriptor = (NavigatorContentDescriptor) overridingIterator 411 .next(); 412 overriddenDescriptor = (NavigatorContentDescriptor) allDescriptors 413 .get(descriptor.getSuppressedExtensionId()); 414 if (overriddenDescriptor != null) { 415 416 420 overriddenDescriptor.getOverriddingExtensions().add( 421 descriptor); 422 descriptor.setOverriddenDescriptor(overriddenDescriptor); 423 427 if (descriptor.getOverridePolicy() == OverridePolicy.InvokeAlwaysRegardlessOfSuppressedExt) { 428 firstClassDescriptorsMap.put(descriptor.getId(), 429 descriptor); 430 firstClassDescriptorsSet.add(descriptor); 431 } 432 433 } else { 434 NavigatorPlugin.logError(0, 435 "Invalid suppressedExtensionId (\"" + descriptor.getSuppressedExtensionId() 437 + "\" specified from " + descriptor.getContribution() 439 .getPluginId() 440 + ". No extension with matching id found.", null); 442 } 443 } 444 } 445 } 446 447 private ImageRegistry getImageRegistry() { 448 if (imageRegistry == null) { 449 imageRegistry = new ImageRegistry(); 450 } 451 return imageRegistry; 452 } 453 454 private class NavigatorContentDescriptorRegistry extends 455 NavigatorContentRegistryReader { 456 457 462 public void readRegistry() { 463 super.readRegistry(); 464 computeOverrides(); 465 } 466 467 protected boolean readElement(IConfigurationElement anElement) { 468 if (TAG_NAVIGATOR_CONTENT.equals(anElement.getName())) { 469 try { 470 addNavigatorContentDescriptor(new NavigatorContentDescriptor( 471 anElement)); 472 473 } catch (WorkbenchException e) { 474 NavigatorPlugin.log(e.getStatus()); 476 } 477 } 478 return super.readElement(anElement); 479 } 480 } 481 482 } 483 | Popular Tags |