511216: Support central USS OAuth login in MPC

- Use correct shell for OAuth popup

Bug: 511216
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=511216
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/StorageConfigurer.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/StorageConfigurer.java
index c9a551c..6ab0cdc 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/StorageConfigurer.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/StorageConfigurer.java
@@ -113,6 +113,10 @@
 		instance = null;
 	}
 
+	public void setShellProvider(IStorage storage, Object value) {
+		//do nothing
+	}
+
 	public abstract void configure(IStorage storage) throws CoreException;
 
 	public abstract Object setInteractive(IStorage storage, boolean interactive) throws CoreException;
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/USS11NonInteractiveOAuthCredentialsProvider.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/USS11NonInteractiveOAuthCredentialsProvider.java
index d05a64e..1486b88 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/USS11NonInteractiveOAuthCredentialsProvider.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/USS11NonInteractiveOAuthCredentialsProvider.java
@@ -72,6 +72,10 @@
 		delegate.setStateCode(stateCode);
 	}
 
+	public OAuthCredentialsProvider getDelegate() {
+		return delegate;
+	}
+
 	public void setInteractive(boolean interactive) {
 		this.interactive = interactive;
 	}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/USS11OAuthStorageConfigurer.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/USS11OAuthStorageConfigurer.java
index 329f9a7..0083331 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/USS11OAuthStorageConfigurer.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/USS11OAuthStorageConfigurer.java
@@ -11,10 +11,12 @@
 package org.eclipse.epp.internal.mpc.core.service;
 
 import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Method;
 import java.net.URI;
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.Platform;
+import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
 import org.eclipse.userstorage.IStorage;
 import org.eclipse.userstorage.oauth.EclipseOAuthCredentialsProvider;
 import org.eclipse.userstorage.oauth.OAuthCredentialsProvider;
@@ -57,6 +59,34 @@
 	}
 
 	@Override
+	public void setShellProvider(IStorage storage, Object value) {
+		ICredentialsProvider credentialsProvider = storage.getCredentialsProvider();
+		if (credentialsProvider instanceof USS11NonInteractiveOAuthCredentialsProvider) {
+			USS11NonInteractiveOAuthCredentialsProvider p = (USS11NonInteractiveOAuthCredentialsProvider) credentialsProvider;
+			credentialsProvider = p.getDelegate();
+		}
+		if (!(credentialsProvider instanceof EclipseOAuthCredentialsProvider)) {
+			return;
+		}
+		Method[] methods = EclipseOAuthCredentialsProvider.class.getMethods();
+		Method shellProviderMethod = null;
+		for (Method method : methods) {
+			if ("setShell".equals(method.getName()) && method.getParameterTypes().length == 1 //$NON-NLS-1$
+					&& (value == null || method.getParameterTypes()[0].isInstance(value))) {
+				shellProviderMethod = method;
+				break;
+			}
+		}
+		if (shellProviderMethod != null) {
+			try {
+				shellProviderMethod.invoke(credentialsProvider, value);
+			} catch (Exception e) {
+				MarketplaceClientCore.error(e);
+			}
+		}
+	}
+
+	@Override
 	public void configure(IStorage storage) throws CoreException {
 		ICredentialsProvider provider = createCredentialsProvider();
 		storage.setCredentialsProvider(provider);
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceDiscoveryStrategy.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceDiscoveryStrategy.java
index 35dd590..c91c653 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceDiscoveryStrategy.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceDiscoveryStrategy.java
@@ -40,6 +40,7 @@
 import org.eclipse.epp.internal.mpc.core.model.Node;
 import org.eclipse.epp.internal.mpc.core.model.SearchResult;
 import org.eclipse.epp.internal.mpc.core.service.AbstractDataStorageService.NotAuthorizedException;
+import org.eclipse.epp.internal.mpc.core.service.StorageConfigurer;
 import org.eclipse.epp.internal.mpc.core.util.URLUtil;
 import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
 import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUiPlugin;
@@ -68,7 +69,10 @@
 import org.eclipse.equinox.internal.p2.discovery.model.Overview;
 import org.eclipse.equinox.internal.p2.discovery.model.Tag;
 import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.jface.window.IShellProvider;
 import org.eclipse.osgi.util.NLS;
+import org.eclipse.userstorage.IStorage;
+import org.eclipse.userstorage.spi.ICredentialsProvider;
 import org.osgi.framework.BundleContext;
 
 /**
@@ -91,6 +95,8 @@
 
 	private List<LoginListener> loginListeners;
 
+	private IShellProvider shellProvider;
+
 	public MarketplaceDiscoveryStrategy(CatalogDescriptor catalogDescriptor) {
 		if (catalogDescriptor == null) {
 			throw new IllegalArgumentException();
@@ -197,6 +203,26 @@
 		}
 	}
 
+	protected void applyShellProvider() {
+		IUserFavoritesService userFavoritesService = marketplaceService.getUserFavoritesService();
+		if (userFavoritesService == null) {
+			return;
+		}
+		IMarketplaceStorageService storageService = userFavoritesService.getStorageService();
+		if (storageService == null) {
+			return;
+		}
+		IStorage storage = storageService.getStorage();
+		ICredentialsProvider credentialsProvider = storage.getCredentialsProvider();
+		if (credentialsProvider != null) {
+			try {
+				StorageConfigurer.get().setShellProvider(storage, this.shellProvider);
+			} catch (CoreException e) {
+				//ignore
+			}
+		}
+	}
+
 	public boolean hasUserFavoritesService() {
 		return marketplaceService.getUserFavoritesService() != null;
 	}
@@ -241,6 +267,7 @@
 					userFavoritesSupported = true;
 				} else if (hasUserFavoritesService()) {
 					try {
+						applyShellProvider();
 						marketplaceService.userFavorites(result.getNodes(), progress.newChild(favoritesWork));
 						userFavoritesSupported = true;
 					} catch (NotAuthorizedException e1) {
@@ -643,6 +670,7 @@
 			IUserFavoritesService userFavoritesService = marketplaceService.getUserFavoritesService();
 			if (userFavoritesService != null) {
 				try {
+					applyShellProvider();
 					ISearchResult result;
 					if (promptLogin) {
 						IMarketplaceStorageService storageService = userFavoritesService.getStorageService();
@@ -693,6 +721,7 @@
 					return;
 				}
 				try {
+					applyShellProvider();
 					marketplaceService.userFavorites(new ArrayList<INode>(nodes.values()), progress.newChild(500));
 					for (CatalogItem catalogItem : items) {
 						if (catalogItem instanceof MarketplaceNodeCatalogItem) {
@@ -894,4 +923,13 @@
 	protected MarketplaceCatalogSource getCatalogSource() {
 		return source;
 	}
+
+	public void setShellProvider(IShellProvider shellProvider) {
+		this.shellProvider = shellProvider;
+		applyShellProvider();
+	}
+
+	public IShellProvider getShellProvider() {
+		return shellProvider;
+	}
 }
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceWizard.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceWizard.java
index 3dfffe5..a152078 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceWizard.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceWizard.java
@@ -889,7 +889,10 @@
 			}
 			discoveryStrategies.clear();
 			if (getConfiguration().getCatalogDescriptor() != null) {
-				discoveryStrategies.add(new MarketplaceDiscoveryStrategy(getConfiguration().getCatalogDescriptor()));
+				MarketplaceDiscoveryStrategy discoveryStrategy = new MarketplaceDiscoveryStrategy(
+						getConfiguration().getCatalogDescriptor());
+				discoveryStrategy.setShellProvider(this);
+				discoveryStrategies.add(discoveryStrategy);
 
 			}
 		}