1 11 package org.eclipse.ui.internal.navigator.actions; 12 13 import java.util.ArrayList ; 14 import java.util.Collection ; 15 import java.util.HashSet ; 16 import java.util.Iterator ; 17 import java.util.LinkedHashMap ; 18 import java.util.LinkedHashSet ; 19 import java.util.Map ; 20 import java.util.Set ; 21 22 import org.eclipse.core.runtime.Assert; 23 import org.eclipse.core.runtime.IConfigurationElement; 24 import org.eclipse.core.runtime.ISafeRunnable; 25 import org.eclipse.core.runtime.IStatus; 26 import org.eclipse.core.runtime.SafeRunner; 27 import org.eclipse.jface.viewers.IStructuredSelection; 28 import org.eclipse.jface.viewers.StructuredSelection; 29 import org.eclipse.ui.actions.ActionContext; 30 import org.eclipse.ui.internal.navigator.NavigatorPlugin; 31 import org.eclipse.ui.internal.navigator.extensions.NavigatorContentRegistryReader; 32 import org.eclipse.ui.navigator.INavigatorContentService; 33 import org.eclipse.ui.navigator.Priority; 34 35 42 public class CommonActionDescriptorManager { 43 44 private static final CommonActionProviderDescriptor[] NO_DESCRIPTORS = new CommonActionProviderDescriptor[0]; 45 46 private static final CommonActionDescriptorManager INSTANCE = new CommonActionDescriptorManager(); 47 48 private CommonActionDescriptorManager() { 49 50 new ActionProviderRegistry().readRegistry(); 51 } 52 53 56 public static CommonActionDescriptorManager getInstance() { 57 return INSTANCE; 58 } 59 60 61 private final Map dependentDescriptors = new LinkedHashMap (); 62 63 64 private final Set overridingDescriptors = new LinkedHashSet (); 65 66 67 private final Map rootDescriptors = new LinkedHashMap (); 68 69 74 protected void addActionDescriptor( 75 CommonActionProviderDescriptor aDescriptor) { 76 77 if (aDescriptor.getDependsOnId() == null) { 78 rootDescriptors.put(aDescriptor.getDefinedId(), aDescriptor); 79 } else { 80 dependentDescriptors.put(aDescriptor.getDefinedId(), aDescriptor); 81 } 82 83 if (aDescriptor.getOverridesId() != null) { 84 overridingDescriptors.add(aDescriptor); 85 } 86 } 87 88 94 protected void computeOrdering() { 95 CommonActionProviderDescriptor dependentDescriptor; 96 CommonActionProviderDescriptor requiredDescriptor; 97 98 CommonActionProviderDescriptor descriptor; 99 CommonActionProviderDescriptor overriddenDescriptor; 100 for (Iterator iter = overridingDescriptors.iterator(); iter.hasNext();) { 101 descriptor = (CommonActionProviderDescriptor) iter.next(); 102 if (rootDescriptors.containsKey(descriptor.getOverridesId())) { 103 overriddenDescriptor = (CommonActionProviderDescriptor) rootDescriptors 104 .get(descriptor.getOverridesId()); 105 overriddenDescriptor.addOverridingDescriptor(descriptor); 106 } else if (dependentDescriptors.containsKey(descriptor 107 .getOverridesId())) { 108 overriddenDescriptor = (CommonActionProviderDescriptor) dependentDescriptors 109 .get(descriptor.getOverridesId()); 110 overriddenDescriptor.addOverridingDescriptor(descriptor); 111 } 112 113 } 114 115 Collection unresolvedDependentDescriptors = new ArrayList ( 116 dependentDescriptors.values()); 117 118 for (Iterator iter = dependentDescriptors.values().iterator(); iter 119 .hasNext();) { 120 dependentDescriptor = (CommonActionProviderDescriptor) iter.next(); 121 requiredDescriptor = (CommonActionProviderDescriptor) rootDescriptors 122 .get(dependentDescriptor.getDependsOnId()); 123 if (requiredDescriptor == null) { 124 requiredDescriptor = (CommonActionProviderDescriptor) dependentDescriptors 125 .get(dependentDescriptor.getDependsOnId()); 126 } 127 if (requiredDescriptor != null) { 128 requiredDescriptor.addDependentDescriptor(dependentDescriptor); 129 unresolvedDependentDescriptors.remove(dependentDescriptor); 130 } 131 132 } 133 134 dependentDescriptors.clear(); 135 136 if (!unresolvedDependentDescriptors.isEmpty()) { 137 StringBuffer errorMessage = new StringBuffer ( 138 "There were unresolved dependencies for action provider extensions to a Common Navigator.\n" + "Verify that the \"dependsOn\" attribute for each <actionProvider /> element is valid."); 141 CommonActionProviderDescriptor[] unresolvedDescriptors = (CommonActionProviderDescriptor[]) unresolvedDependentDescriptors 142 .toArray(new CommonActionProviderDescriptor[unresolvedDependentDescriptors 143 .size()]); 144 for (int i = 0; i < unresolvedDescriptors.length; i++) { 145 errorMessage 146 .append( 147 "\nUnresolved dependency specified for actionProvider: ").append(unresolvedDescriptors[i].getDefinedId()); } 149 150 NavigatorPlugin.log(IStatus.WARNING, 0, errorMessage.toString(), 151 null); 152 153 } 154 unresolvedDependentDescriptors.clear(); 155 156 } 157 158 170 public CommonActionProviderDescriptor[] findRelevantActionDescriptors( 171 INavigatorContentService aContentService, ActionContext aContext) { 172 Assert.isNotNull(aContext); 173 IStructuredSelection structuredSelection = null; 174 if (aContext.getSelection() instanceof IStructuredSelection) { 175 structuredSelection = (IStructuredSelection) aContext 176 .getSelection(); 177 } else { 178 structuredSelection = StructuredSelection.EMPTY; 179 } 180 181 Set blockedProviders = new HashSet (); 182 CommonActionProviderDescriptor actionDescriptor = null; 183 Set providers = new LinkedHashSet (); 184 for (Iterator providerItr = rootDescriptors.values().iterator(); providerItr 185 .hasNext();) { 186 actionDescriptor = (CommonActionProviderDescriptor) providerItr 187 .next(); 188 addProviderIfRelevant(aContentService, structuredSelection, 189 actionDescriptor, providers, blockedProviders); 190 } 191 if (providers.size() > 0) { 192 providers.removeAll(blockedProviders); 193 return (CommonActionProviderDescriptor[]) providers 194 .toArray(new CommonActionProviderDescriptor[providers 195 .size()]); 196 } 197 return NO_DESCRIPTORS; 198 } 199 200 206 private boolean addProviderIfRelevant( 207 INavigatorContentService aContentService, 208 IStructuredSelection structuredSelection, 209 CommonActionProviderDescriptor actionDescriptor, Set providers, Set blockedProviders) { 210 if (isVisible(aContentService, actionDescriptor) 211 && actionDescriptor.isEnabledFor(structuredSelection)) { 212 213 if(actionDescriptor.hasOverridingDescriptors()) { 214 for (Iterator iter = actionDescriptor.overridingDescriptors(); iter.hasNext();) { 215 CommonActionProviderDescriptor descriptor = (CommonActionProviderDescriptor) iter.next(); 216 if(addProviderIfRelevant(aContentService, structuredSelection, descriptor, providers, blockedProviders)) { 217 while(iter.hasNext()) 218 blockedProviders.add(iter.next()); 219 return true; 220 } 221 222 } 223 } 224 providers.add(actionDescriptor); 225 if (actionDescriptor.hasDependentDescriptors()) { 226 for (Iterator iter = actionDescriptor.dependentDescriptors(); iter 227 .hasNext();) { 228 addProviderIfRelevant(aContentService, structuredSelection, 229 (CommonActionProviderDescriptor) iter.next(), 230 providers, blockedProviders); 231 } 232 } 233 return true; 234 } 235 return false; 236 } 237 238 private boolean isVisible(INavigatorContentService aContentService, 239 CommonActionProviderDescriptor descriptor) { 240 if (descriptor.isNested()) { 241 return aContentService.isActive(descriptor.getId()) 242 && aContentService.isVisible(descriptor.getId()); 243 } 244 return aContentService.getViewerDescriptor().isVisibleActionExtension( 245 descriptor.getId()); 246 } 247 248 private class ActionProviderRegistry extends NavigatorContentRegistryReader { 249 250 public void readRegistry() { 251 super.readRegistry(); 252 computeOrdering(); 253 } 254 255 protected boolean readElement(IConfigurationElement anElement) { 256 if (TAG_ACTION_PROVIDER.equals(anElement.getName())) { 257 addActionDescriptor(new CommonActionProviderDescriptor( 258 anElement)); 259 return true; 260 } else if (TAG_NAVIGATOR_CONTENT.equals(anElement.getName())) { 261 262 IConfigurationElement[] actionProviders = anElement.getChildren(TAG_ACTION_PROVIDER); 263 264 if (actionProviders.length > 0) { 265 266 IConfigurationElement defaultEnablement = null; 267 IConfigurationElement[] inheritedEnablement = anElement.getChildren(TAG_ENABLEMENT); 268 if (inheritedEnablement.length == 0) { 269 inheritedEnablement = anElement.getChildren(TAG_POSSIBLE_CHILDREN); 270 } 271 272 defaultEnablement = inheritedEnablement.length == 1 ? inheritedEnablement[0] : null; 273 274 Priority defaultPriority = Priority.get(anElement.getAttribute(ATT_PRIORITY)); 275 276 277 if(defaultEnablement == null) { 278 NavigatorPlugin.logError(0, 279 "An actionProvider has been defined as the child " + "of a navigatorContent extension that does not specify " + "an <enablement/> or <possibleChildren /> expression. Please " + "review the documenation and correct this error.", null); } 284 for (int i = 0; i < actionProviders.length; i++) { 285 if(defaultEnablement == null) { 286 NavigatorPlugin.logError(0, 287 "Disabling actionProvider: " + actionProviders[i].getAttribute(ATT_ID), null); } else { 289 SafeRunner.run(new AddProviderSafeRunner(actionProviders[i], defaultEnablement, defaultPriority, anElement)); 290 } 291 } 292 } 293 return true; 294 } 295 return super.readElement(anElement); 296 } 297 298 private class AddProviderSafeRunner implements ISafeRunnable { 299 300 private IConfigurationElement parentElement; 301 private IConfigurationElement defaultEnablement; 302 private IConfigurationElement actionProvider; 303 private Priority defaultPriority; 304 305 protected AddProviderSafeRunner(IConfigurationElement actionProvider, 306 IConfigurationElement defaultEnablement, 307 Priority defaultPriority, 308 IConfigurationElement parentElement) { 309 this.actionProvider = actionProvider; 310 this.defaultEnablement = defaultEnablement; 311 this.defaultPriority = defaultPriority; 312 this.parentElement = parentElement; 313 } 314 315 318 public void run() throws Exception { 319 addActionDescriptor(new CommonActionProviderDescriptor( 320 actionProvider, defaultEnablement, defaultPriority, parentElement 321 .getAttribute(ATT_ID), true)); 322 } 323 324 327 public void handleException(Throwable t) { 328 NavigatorPlugin.logError(0, "Recovering from error while parsing actionProviders.", t); } 330 331 332 } 333 } 334 335 336 } 337 | Popular Tags |