1 11 12 package org.eclipse.ui.internal.handlers; 13 14 import java.util.Map ; 15 16 import org.eclipse.core.commands.AbstractHandler; 17 import org.eclipse.core.commands.ExecutionEvent; 18 import org.eclipse.core.commands.ExecutionException; 19 import org.eclipse.core.commands.HandlerEvent; 20 import org.eclipse.core.commands.IHandler; 21 import org.eclipse.core.commands.IHandlerListener; 22 import org.eclipse.core.expressions.EvaluationResult; 23 import org.eclipse.core.expressions.Expression; 24 import org.eclipse.core.expressions.IEvaluationContext; 25 import org.eclipse.core.runtime.CoreException; 26 import org.eclipse.core.runtime.IConfigurationElement; 27 import org.eclipse.core.runtime.IStatus; 28 import org.eclipse.core.runtime.Status; 29 import org.eclipse.jface.util.IPropertyChangeListener; 30 import org.eclipse.jface.util.PropertyChangeEvent; 31 import org.eclipse.ui.commands.IElementUpdater; 32 import org.eclipse.ui.internal.WorkbenchPlugin; 33 import org.eclipse.ui.internal.services.IEvaluationReference; 34 import org.eclipse.ui.internal.services.IEvaluationService; 35 import org.eclipse.ui.internal.util.BundleUtility; 36 import org.eclipse.ui.menus.UIElement; 37 38 49 public final class HandlerProxy extends AbstractHandler implements 50 IElementUpdater { 51 52 55 private static final String PROP_ENABLED = "enabled"; 57 62 private IConfigurationElement configurationElement; 63 64 69 private final Expression enabledWhenExpression; 70 71 76 private IHandler handler = null; 77 78 82 private final String handlerAttributeName; 83 84 private IHandlerListener handlerListener; 85 86 92 private IEvaluationService evaluationService; 93 94 private IPropertyChangeListener enablementListener; 95 96 private IEvaluationReference enablementRef; 97 98 private boolean proxyEnabled; 99 100 111 public HandlerProxy(final IConfigurationElement configurationElement, 112 final String handlerAttributeName) { 113 this(configurationElement, handlerAttributeName, null, null); 114 } 115 116 139 public HandlerProxy(final IConfigurationElement configurationElement, 140 final String handlerAttributeName, 141 final Expression enabledWhenExpression, 142 final IEvaluationService evaluationService) { 143 if (configurationElement == null) { 144 throw new NullPointerException ( 145 "The configuration element backing a handler proxy cannot be null"); } 147 148 if (handlerAttributeName == null) { 149 throw new NullPointerException ( 150 "The attribute containing the handler class must be known"); } 152 153 if ((enabledWhenExpression != null) && (evaluationService == null)) { 154 throw new NullPointerException ( 155 "We must have a handler service and evaluation service to support the enabledWhen expression"); } 157 158 this.configurationElement = configurationElement; 159 this.handlerAttributeName = handlerAttributeName; 160 this.enabledWhenExpression = enabledWhenExpression; 161 this.evaluationService = evaluationService; 162 if (enabledWhenExpression != null) { 163 setProxyEnabled(false); 164 registerEnablement(); 165 } else { 166 setProxyEnabled(true); 167 } 168 } 169 170 173 private void registerEnablement() { 174 enablementRef = evaluationService.addEvaluationListener( 175 enabledWhenExpression, getEnablementListener(), PROP_ENABLED, 176 null); 177 } 178 179 void setEnabledFor(IEvaluationContext context) throws ExecutionException { 180 if (enabledWhenExpression != null) { 181 try { 182 setProxyEnabled(enabledWhenExpression.evaluate(context) == EvaluationResult.TRUE); 183 } catch (CoreException e) { 184 throw new ExecutionException(e.getMessage(), e); 185 } 186 } 187 } 188 189 void setProxyEnabled(boolean enabled) { 190 proxyEnabled = enabled; 191 } 192 193 boolean getProxyEnabled() { 194 return proxyEnabled; 195 } 196 197 200 private IPropertyChangeListener getEnablementListener() { 201 if (enablementListener == null) { 202 enablementListener = new IPropertyChangeListener() { 203 public void propertyChange(PropertyChangeEvent event) { 204 if (event.getProperty() == PROP_ENABLED) { 205 setProxyEnabled(event.getNewValue() == null ? false 206 : ((Boolean ) event.getNewValue()) 207 .booleanValue()); 208 fireHandlerChanged(new HandlerEvent(HandlerProxy.this, 209 true, false)); 210 } 211 } 212 }; 213 } 214 return enablementListener; 215 } 216 217 220 public final void dispose() { 221 if (handler != null) { 222 if (handlerListener != null) { 223 handler.removeHandlerListener(handlerListener); 224 handlerListener = null; 225 } 226 handler.dispose(); 227 handler = null; 228 } 229 if (enablementListener != null) { 230 evaluationService.removeEvaluationListener(enablementRef); 231 enablementRef = null; 232 enablementListener = null; 233 } 234 } 235 236 public final Object execute(final ExecutionEvent event) 237 throws ExecutionException { 238 if (loadHandler()) { 239 return handler.execute(event); 240 } 241 242 return null; 243 } 244 245 public final boolean isEnabled() { 246 if (enabledWhenExpression != null) { 247 if (!getProxyEnabled()) { 249 return false; 250 } 251 if (isOkToLoad() && loadHandler()) { 252 return handler.isEnabled(); 253 } 254 255 return true; 256 } 257 258 262 if (isOkToLoad() && loadHandler()) { 263 return handler.isEnabled(); 264 } 265 return true; 266 } 267 268 public final boolean isHandled() { 269 if (configurationElement != null) { 270 return true; 271 } 272 273 if (isOkToLoad() && loadHandler()) { 274 return handler.isHandled(); 275 } 276 277 return false; 278 } 279 280 287 private final boolean loadHandler() { 288 if (handler == null) { 289 try { 291 if (configurationElement != null) { 292 handler = (IHandler) configurationElement 293 .createExecutableExtension(handlerAttributeName); 294 configurationElement = null; 295 handler.addHandlerListener(getHandlerListener()); 296 return true; 297 } 298 299 } catch (final ClassCastException e) { 300 final String message = "The proxied handler was the wrong class"; final IStatus status = new Status(IStatus.ERROR, 302 WorkbenchPlugin.PI_WORKBENCH, 0, message, e); 303 WorkbenchPlugin.log(message, status); 304 configurationElement = null; 305 306 } catch (final CoreException e) { 307 final String message = "The proxied handler for '" + configurationElement.getAttribute(handlerAttributeName) + "' could not be loaded"; IStatus status = new Status(IStatus.ERROR, 310 WorkbenchPlugin.PI_WORKBENCH, 0, message, e); 311 WorkbenchPlugin.log(message, status); 312 configurationElement = null; 313 } 314 return false; 315 } 316 317 return true; 318 } 319 320 323 private IHandlerListener getHandlerListener() { 324 if (handlerListener == null) { 325 handlerListener = new IHandlerListener() { 326 public void handlerChanged(HandlerEvent handlerEvent) { 327 fireHandlerChanged(new HandlerEvent(HandlerProxy.this, 328 handlerEvent.isEnabledChanged(), handlerEvent 329 .isHandledChanged())); 330 } 331 }; 332 } 333 return handlerListener; 334 } 335 336 public final String toString() { 337 if (handler == null) { 338 if (configurationElement != null) { 339 return configurationElement.getAttribute(handlerAttributeName); 340 } 341 return "HandlerProxy()"; } 343 344 return handler.toString(); 345 } 346 347 private boolean isOkToLoad() { 348 if (configurationElement != null) { 349 final String bundleId = configurationElement.getContributor() 350 .getName(); 351 return BundleUtility.isActive(bundleId); 352 } 353 return true; 354 } 355 356 362 public void updateElement(UIElement element, Map parameters) { 363 if (handler != null && handler instanceof IElementUpdater) { 364 ((IElementUpdater) handler).updateElement(element, parameters); 365 } 366 } 367 } 368 | Popular Tags |