/******************************************************************************* * Copyright (c) 2013, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation ******************************************************************************/ package org.eclipse.e4.core.commands.internal; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.HandlerEvent; import org.eclipse.core.commands.IHandler; import org.eclipse.core.commands.NotHandledException; import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.e4.core.commands.ExpressionContext; import org.eclipse.e4.core.commands.internal.HandlerServiceImpl.ExecutionContexts; import org.eclipse.e4.core.contexts.ContextInjectionFactory; import org.eclipse.e4.core.contexts.EclipseContextFactory; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.di.annotations.CanExecute; import org.eclipse.e4.core.di.annotations.Execute; /** * Provide an IHandler to delegate calls to. */ public class HandlerServiceHandler extends AbstractHandler { private static final String FAILED_TO_FIND_HANDLER_DURING_EXECUTION = "Failed to find handler during execution"; //$NON-NLS-1$ private static final String HANDLER_MISSING_EXECUTE_ANNOTATION = "Handler is missing @Execute"; //$NON-NLS-1$ private static final Object missingExecute = new Object(); protected String commandId; public HandlerServiceHandler(String commandId) { this.commandId = commandId; } @Override public boolean isEnabled() { ExecutionContexts contexts = HandlerServiceImpl.peek(); // setEnabled(contexts); IEclipseContext executionContext = contexts != null ? contexts.context : null; // getExecutionContext(contexts); if (executionContext == null) { return super.isEnabled(); } Object handler = HandlerServiceImpl.lookUpHandler(executionContext, commandId); if (handler == null) { setBaseEnabled(false); return super.isEnabled(); } IEclipseContext staticContext = contexts.staticContext; // getStaticContext(contexts); Boolean result = (Boolean) ContextInjectionFactory.invoke(handler, CanExecute.class, executionContext, staticContext, Boolean.TRUE); setBaseEnabled(result.booleanValue()); return super.isEnabled(); } @Override public void setEnabled(Object evaluationContext) { boolean createContext = false; IEclipseContext executionContext = getExecutionContext(evaluationContext); if (executionContext == null) { return; } Object handler = HandlerServiceImpl.lookUpHandler(executionContext, commandId); if (handler == null) { return; } IEclipseContext staticContext = getStaticContext(executionContext); if (staticContext == null) { staticContext = EclipseContextFactory.create(); createContext = true; } ContextInjectionFactory.invoke(handler, SetEnabled.class, executionContext, staticContext, Boolean.TRUE); if (createContext) { staticContext.dispose(); } } private IEclipseContext getStaticContext(IEclipseContext executionContext) { final ExecutionContexts pair = HandlerServiceImpl.peek(); if (pair != null) { if (pair.context != executionContext) { // log this } return pair.staticContext; } return null; } protected IEclipseContext getExecutionContext(Object evalObj) { // if (evalObj instanceof ExecutionContexts) { // return ((ExecutionContexts) evalObj).context; // } if (evalObj instanceof IEclipseContext) { return (IEclipseContext) evalObj; } if (evalObj instanceof ExpressionContext) { return ((ExpressionContext) evalObj).eclipseContext; } if (evalObj instanceof IEvaluationContext) { return getExecutionContext(((IEvaluationContext) evalObj).getParent()); } final ExecutionContexts pair = HandlerServiceImpl.peek(); if (pair != null) { return pair.context; } return null; } @Override public boolean isHandled() { ExecutionContexts contexts = HandlerServiceImpl.peek(); if (contexts != null) { Object handler = HandlerServiceImpl.lookUpHandler(contexts.context, commandId); if (handler instanceof IHandler) { return ((IHandler) handler).isHandled(); } return handler != null; } return false; } @Override public Object execute(ExecutionEvent event) throws ExecutionException { IEclipseContext executionContext = getExecutionContext(event.getApplicationContext()); if (executionContext == null) { throw new ExecutionException(FAILED_TO_FIND_HANDLER_DURING_EXECUTION, new NotHandledException(FAILED_TO_FIND_HANDLER_DURING_EXECUTION)); } Object handler = HandlerServiceImpl.lookUpHandler(executionContext, commandId); if (handler == null) { return null; } IEclipseContext staticContext = getStaticContext(executionContext); IEclipseContext localStaticContext = null; try { if (staticContext == null) { staticContext = localStaticContext = EclipseContextFactory .create(HandlerServiceImpl.TMP_STATIC_CONTEXT); staticContext.set(HandlerServiceImpl.PARM_MAP, event.getParameters()); } Object result = ContextInjectionFactory.invoke(handler, Execute.class, executionContext, staticContext, missingExecute); if (result == missingExecute) { throw new ExecutionException(HANDLER_MISSING_EXECUTE_ANNOTATION, new NotHandledException(getClass().getName())); } return result; } finally { if (localStaticContext != null) { localStaticContext.dispose(); } } } @Override public void fireHandlerChanged(HandlerEvent handlerEvent) { super.fireHandlerChanged(handlerEvent); } public void overrideEnabled(boolean b) { setBaseEnabled(b); } }