Bug 366606 - [Compatibility] Failures in ContextsTestSuite
A change to allow the Workbench context service to calculate active
contexts, and then have it update the EContextService correctly. The
old way sometimes removed a context too eagerly.
Bug: 366606
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
index 0515c67..2d7c02c 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
@@ -131,7 +131,7 @@
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
import org.eclipse.ui.internal.actions.CommandAction;
-import org.eclipse.ui.internal.contexts.ContextService;
+import org.eclipse.ui.internal.contexts.SlaveContextService;
import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
import org.eclipse.ui.internal.e4.compatibility.CompatibilityPart;
import org.eclipse.ui.internal.e4.compatibility.E4Util;
@@ -222,6 +222,7 @@
private boolean shellActivated = false;
ProgressRegion progressRegion = null;
+ private SlaveContextService contextService = null;
private List<MTrimElement> workbenchTrimElements = new ArrayList<MTrimElement>();
@@ -2264,9 +2265,19 @@
serviceLocator.registerService(LegacyActionPersistence.class, actionPersistence);
actionPersistence.read();
- IContextService cxs = ContextInjectionFactory
- .make(ContextService.class, model.getContext());
- serviceLocator.registerService(IContextService.class, cxs);
+ windowContext.set(IContextService.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context) {
+ if (contextService == null) {
+ contextService = new SlaveContextService(context.getParent().get(
+ IContextService.class), new ActiveShellExpression(getShell()));
+ }
+ return contextService;
+ }
+ });
+ // IContextService cxs = ContextInjectionFactory
+ // .make(ContextService.class, model.getContext());
+ // serviceLocator.registerService(IContextService.class, cxs);
}
public final Object getService(final Class key) {
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java
index 8fb2bad..2b69319 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2012 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 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
@@ -11,26 +11,21 @@
package org.eclipse.ui.internal.contexts;
import java.util.Collection;
-import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.Set;
import javax.inject.Inject;
import org.eclipse.core.commands.contexts.Context;
import org.eclipse.core.commands.contexts.ContextManager;
+import org.eclipse.core.commands.contexts.ContextManagerEvent;
import org.eclipse.core.commands.contexts.IContextManagerListener;
-import org.eclipse.core.expressions.EvaluationResult;
import org.eclipse.core.expressions.Expression;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.e4.core.contexts.IEclipseContext;
-import org.eclipse.e4.core.contexts.RunAndTrack;
-import org.eclipse.e4.ui.di.UISynchronize;
import org.eclipse.e4.ui.services.EContextService;
-import org.eclipse.e4.ui.workbench.modeling.ExpressionContext;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISourceProvider;
import org.eclipse.ui.ISources;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
-import org.eclipse.ui.internal.WorkbenchPlugin;
/**
* <p>
@@ -42,8 +37,6 @@
*/
public final class ContextService implements IContextService {
- private HashMap<IContextActivation, UpdateExpression> activationToRat = new HashMap<IContextActivation, ContextService.UpdateExpression>();
-
/**
* The central authority for determining which context we should use.
*/
@@ -53,22 +46,36 @@
* The context manager that supports this service. This value is never
* <code>null</code>.
*/
- private ContextManager contextManager;
-
- @Inject
- private EContextService contextService;
-
- @Inject
- private IEclipseContext eclipseContext;
-
- @Inject
- private UISynchronize synchService;
+ private final ContextManager contextManager;
/**
* The persistence class for this context service.
*/
private final ContextPersistence contextPersistence;
+ @Inject
+ private EContextService contextService;
+
+ private IContextManagerListener syncToEclipse4 = new IContextManagerListener() {
+ public void contextManagerChanged(ContextManagerEvent contextManagerEvent) {
+ if (contextManagerEvent.isActiveContextsChanged()) {
+ final Set previouslyActiveContextIds = contextManagerEvent
+ .getPreviouslyActiveContextIds();
+ final Set activeContextIds = contextManager.getActiveContextIds();
+ final HashSet newlyActive = new HashSet(activeContextIds);
+ newlyActive.removeAll(previouslyActiveContextIds);
+ for (Object obj : newlyActive) {
+ contextService.activateContext((String) obj);
+ }
+ final HashSet noLongerActive = new HashSet(previouslyActiveContextIds);
+ noLongerActive.removeAll(activeContextIds);
+ for (Object obj : noLongerActive) {
+ contextService.deactivateContext((String) obj);
+ }
+ }
+ }
+ };
+
/**
* Constructs a new instance of <code>ContextService</code> using a
* context manager.
@@ -85,6 +92,7 @@
this.contextManager = contextManager;
this.contextAuthority = new ContextAuthority(contextManager, this);
this.contextPersistence = new ContextPersistence(contextManager);
+ contextManager.addContextManagerListener(syncToEclipse4);
}
/* (non-Javadoc)
@@ -103,47 +111,6 @@
return activateContext(contextId, null);
}
- private class UpdateExpression extends RunAndTrack {
- boolean updating = true;
-
- private String contextId;
- private Expression expression;
-
- public UpdateExpression(String contextId, Expression expression) {
- this.contextId = contextId;
- this.expression = expression;
- }
-
- @Override
- public boolean changed(IEclipseContext context) {
- if (!updating) {
- return false;
- }
- ExpressionContext ctx = new ExpressionContext(eclipseContext.getActiveLeaf());
- try {
- if (updating) {
- if (expression.evaluate(ctx) != EvaluationResult.FALSE) {
- runExternalCode(new Runnable() {
- public void run() {
- contextService.activateContext(contextId);
- }
- });
- } else {
- runExternalCode(new Runnable() {
- public void run() {
- contextService.deactivateContext(contextId);
- }
- });
- }
- }
- } catch (CoreException e) {
- // contextService.deactivateContext(contextId);
- WorkbenchPlugin.log("Failed to update " + contextId, e); //$NON-NLS-1$
- }
- return updating;
- }
- }
-
/*
* (non-Javadoc)
*
@@ -156,13 +123,6 @@
final IContextActivation activation = new ContextActivation(contextId,
expression, this);
contextAuthority.activateContext(activation);
- if (expression == null) {
- contextService.activateContext(contextId);
- } else {
- final UpdateExpression runnable = new UpdateExpression(contextId, expression);
- activationToRat.put(activation, runnable);
- eclipseContext.runAndTrack(runnable);
- }
return activation;
}
@@ -213,12 +173,7 @@
* @see org.eclipse.ui.contexts.IContextService#deactivateContext(org.eclipse.ui.contexts.IContextActivation)
*/
public final void deactivateContext(final IContextActivation activation) {
- if (activation != null && activation.getContextService() == this) {
- final UpdateExpression rat = activationToRat.remove(activation);
- if (rat != null) {
- rat.updating = false;
- }
- contextService.deactivateContext(activation.getContextId());
+ if (activation.getContextService() == this) {
contextAuthority.deactivateContext(activation);
}
}
@@ -243,6 +198,7 @@
* @see org.eclipse.ui.services.IDisposable#dispose()
*/
public final void dispose() {
+ contextManager.removeContextManagerListener(syncToEclipse4);
contextPersistence.dispose();
contextAuthority.dispose();
}
@@ -298,7 +254,7 @@
* @see org.eclipse.ui.contexts.IContextService#readRegistry()
*/
public final void readRegistry() {
- // contextPersistence.read();
+ contextPersistence.read();
}
/*