458573: Offer to registered users to install favourites from marketplace

API cleanup: we only want to support favorite URLs

Bug: 458573
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=458573
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CachingMarketplaceService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CachingMarketplaceService.java
index 2f89509..a200a84 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CachingMarketplaceService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CachingMarketplaceService.java
@@ -14,6 +14,7 @@
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.SoftReference;
+import java.net.URI;
 import java.net.URL;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -371,8 +372,8 @@
 		return delegate.getUserFavoritesService();
 	}
 
-	public ISearchResult userFavorites(String user, IProgressMonitor monitor) throws CoreException {
-		return delegate.userFavorites(user, monitor);
+	public ISearchResult userFavorites(URI favoritesUri, IProgressMonitor monitor) throws CoreException {
+		return delegate.userFavorites(favoritesUri, monitor);
 	}
 
 }
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java
index 244ba2e..01c9525 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java
@@ -482,7 +482,7 @@
 		return resolveFavoriteNodes(favorites, progress.newChild(9000), true);
 	}
 
-	public ISearchResult userFavorites(String user, IProgressMonitor monitor) throws CoreException {
+	public ISearchResult userFavorites(URI favoritesUri, IProgressMonitor monitor) throws CoreException {
 		SubMonitor progress = SubMonitor.convert(monitor, Messages.DefaultMarketplaceService_FavoritesRetrieve, 10000);
 		IUserFavoritesService userFavoritesService = getUserFavoritesService();
 		if (userFavoritesService == null) {
@@ -490,7 +490,7 @@
 		}
 		final List<INode> favorites;
 		try {
-			favorites = userFavoritesService.getFavorites(user, progress.newChild(1000));
+			favorites = userFavoritesService.getFavorites(favoritesUri, progress.newChild(1000));
 		} catch (Exception e) {
 			throw new CoreException(MarketplaceClientCore.computeStatus(e,
 					Messages.DefaultMarketplaceService_FavoritesErrorRetrieving));
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/UserFavoritesService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/UserFavoritesService.java
index a033208..eb0ce84 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/UserFavoritesService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/UserFavoritesService.java
@@ -40,11 +40,9 @@
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.SubMonitor;
 import org.eclipse.epp.internal.mpc.core.transport.httpclient.RequestTemplate;
-import org.eclipse.epp.internal.mpc.core.util.URLUtil;
 import org.eclipse.epp.mpc.core.model.INode;
 import org.eclipse.epp.mpc.core.service.IUserFavoritesService;
 import org.eclipse.epp.mpc.core.service.QueryHelper;
-import org.eclipse.osgi.util.NLS;
 import org.eclipse.userstorage.IBlob;
 import org.eclipse.userstorage.internal.Session;
 import org.eclipse.userstorage.internal.util.IOUtil;
@@ -291,44 +289,24 @@
 		setFavorites(favorites, progress.newChild(700));
 	}
 
-	public List<INode> getFavorites(String user, IProgressMonitor monitor) throws IOException {
-		List<String> nodeIds = getFavoriteIds(user, monitor);
+	public List<INode> getFavorites(URI uri, IProgressMonitor monitor) throws IOException {
+		List<String> nodeIds = getFavoriteIds(uri, monitor);
 		return toNodes(nodeIds);
 	}
 
-	public List<String> getFavoriteIds(String user, IProgressMonitor monitor) throws IOException {
-		if (user.toLowerCase().startsWith("http:") || user.toLowerCase().startsWith("https:")) { //$NON-NLS-1$ //$NON-NLS-2$
-			return importUserFavoriteIds(toURI(user));
-		}
-		Matcher matcher = USER_MAIL_PATTERN.matcher(user);
-		if (matcher.find()) {
-			return importUserFavoriteIds(FAVORITES_API__USER_MAIL, user);
-		}
-		return importUserFavoriteIds(FAVORITES_API__USER_NAME, user);
-	}
-
-	private static URI toURI(String user) {
-		try {
-			URI uri = URLUtil.toURI(user);
-			if ((uri.getHost() == null || "".equals(uri.getHost())) && "/".equals(uri.getPath()) //$NON-NLS-1$//$NON-NLS-2$
-					&& uri.getScheme() != null
-					&& uri.getScheme().toLowerCase().startsWith("http")) { //$NON-NLS-1$
-				//incomplete uri
-				throw new IllegalArgumentException(new URISyntaxException(user, Messages.UserFavoritesService_uriMissingHost));
-			}
-			return uri;
-		} catch (URISyntaxException e) {
-			throw new IllegalArgumentException(e);
+	public static void validateURI(URI uri) {
+		if ("".equals(uri.toString()) //$NON-NLS-1$
+				|| ((uri.getHost() == null || "".equals(uri.getHost())) //$NON-NLS-1$
+						&& (uri.getScheme() != null && uri.getScheme().toLowerCase().startsWith("http"))) //$NON-NLS-1$
+				|| (uri.getScheme() == null && (uri.getPath() == null || "".equals(uri.getPath())))) { //$NON-NLS-1$
+			//incomplete uri
+			throw new IllegalArgumentException(
+					new URISyntaxException(uri.toString(), Messages.UserFavoritesService_uriMissingHost));
 		}
 	}
 
-	private List<String> importUserFavoriteIds(String userIdParam, String userId) throws IOException {
-		return importUserFavoriteIds(
-				getStorageService().getServiceUri()
-				.resolve(NLS.bind(FAVORITES_API__ENDPOINT, userIdParam, userId)));
-	}
-
-	private List<String> importUserFavoriteIds(final URI endpoint) throws IOException {
+	public List<String> getFavoriteIds(URI uri, IProgressMonitor monitor) throws IOException {
+		validateURI(uri);
 		try {
 			return new RequestTemplate<List<String>>() {
 
@@ -354,7 +332,7 @@
 								favoriteIds.add(id);
 							}
 						} else {
-							throw malformedContentException(endpoint, body);
+							throw malformedContentException(uri, body);
 						}
 					}
 					return favoriteIds;
@@ -364,7 +342,7 @@
 				protected Request createRequest(URI uri) {
 					return Request.Get(uri);
 				}
-			}.execute(endpoint);
+			}.execute(uri);
 		} catch (FileNotFoundException e) {
 			return new ArrayList<String>();
 		}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceService.java
index 3978919..dfec47e 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceService.java
@@ -11,6 +11,7 @@
  *******************************************************************************/
 package org.eclipse.epp.mpc.core.service;
 
+import java.net.URI;
 import java.net.URL;
 import java.util.List;
 import java.util.Set;
@@ -176,16 +177,15 @@
 			throws CoreException, NotAuthorizedException;
 
 	/**
-	 * Retrieve the favorite nodes for the given user identifier. The user identifier can either be an email or a
-	 * marketplace user url of the form &lt;marketplace base url&gt;/user/&lt;user id&gt;
+	 * Retrieve the favorite nodes for the given favorites uri.
 	 *
-	 * @param user
-	 *            an email or marketplace url identifying the user
+	 * @param favoritesUri
+	 *            a url pointing to a favorites list
 	 * @param monitor
 	 *            progress and cancellation
 	 * @throws CoreException
 	 */
-	ISearchResult userFavorites(String user, IProgressMonitor monitor) throws CoreException;
+	ISearchResult userFavorites(URI favoritesUri, IProgressMonitor monitor) throws CoreException;
 
 	/**
 	 * Get the news configuration for the marketplace
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IUserFavoritesService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IUserFavoritesService.java
index e78617b..706be69 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IUserFavoritesService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IUserFavoritesService.java
@@ -11,6 +11,7 @@
 package org.eclipse.epp.mpc.core.service;
 
 import java.io.IOException;
+import java.net.URI;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
@@ -43,8 +44,8 @@
 	void removeFavorites(Collection<? extends INode> nodes, IProgressMonitor monitor)
 			throws NotAuthorizedException, ConflictException, IOException;
 
-	List<String> getFavoriteIds(String user, IProgressMonitor monitor) throws IOException;
+	List<String> getFavoriteIds(URI user, IProgressMonitor monitor) throws IOException;
 
-	List<INode> getFavorites(String user, IProgressMonitor monitor) throws IOException;
+	List<INode> getFavorites(URI user, IProgressMonitor monitor) throws IOException;
 
 }
\ No newline at end of file
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/UserFavoritesServiceTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/UserFavoritesServiceTest.java
index 71062d2..38d3b46 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/UserFavoritesServiceTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/UserFavoritesServiceTest.java
@@ -38,7 +38,7 @@
 @org.junit.experimental.categories.Category(RemoteTests.class)
 public class UserFavoritesServiceTest {
 
-	private static final URI USERSTORAGE_SERVICE_URI = URI.create("https://api-staging.eclipse.org");
+	private static final URI USERSTORAGE_SERVICE_URI = URI.create("https://api-staging.eclipse.org/");
 
 	protected IMarketplaceStorageService marketplaceStorageService;
 
@@ -103,6 +103,6 @@
 	@Test
 	public void testImportFavorites() throws Exception {
 		//TODO
-		favoritesService.getFavoriteIds("creckord", null);
+		favoritesService.getFavoriteIds(URI.create("https://marketplace.eclipse.org/user/creckord/favorites"), null);
 	}
 }
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/FavoritesDiscoveryStrategy.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/FavoritesDiscoveryStrategy.java
index 79d541e..96f0873 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/FavoritesDiscoveryStrategy.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/FavoritesDiscoveryStrategy.java
@@ -10,11 +10,17 @@
  *******************************************************************************/
 package org.eclipse.epp.internal.mpc.ui.catalog;
 
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.Collections;
 import java.util.Map;
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.epp.internal.mpc.core.util.URLUtil;
+import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
 import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCategory.Contents;
 import org.eclipse.epp.internal.mpc.ui.catalog.UserActionCatalogItem.UserAction;
 import org.eclipse.epp.mpc.core.model.ISearchResult;
@@ -22,6 +28,7 @@
 import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
 import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
 import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.osgi.util.NLS;
 
 public class FavoritesDiscoveryStrategy extends MarketplaceDiscoveryStrategy {
 
@@ -65,12 +72,18 @@
 			return null;
 		}
 		try {
-			return marketplaceService.userFavorites(favoritesReference, monitor);
+			URI uri = URLUtil.toURI(favoritesReference);
+			return marketplaceService.userFavorites(uri, monitor);
 		} catch (CoreException ex) {
 			//if we don't want an error dialog to pop up for discovery errors, we have
 			//to handle errors here...
 			handleDiscoveryError(ex);
 			return null;
+		} catch (URISyntaxException e) {
+			IStatus error = new Status(IStatus.ERROR, MarketplaceClientUi.BUNDLE_ID,
+					NLS.bind(Messages.FavoritesDiscoveryStrategy_invalidUrl, favoritesReference, e), e);
+			handleDiscoveryError(new CoreException(error));
+			return null;
 		} finally {
 			postDiscovery();
 		}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/Messages.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/Messages.java
index 950d15b..c43dc33 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/Messages.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/Messages.java
@@ -17,6 +17,8 @@
 
 	public static String FavoritesDiscoveryStrategy_enterFavoritesUrlMessage;
 
+	public static String FavoritesDiscoveryStrategy_invalidUrl;
+
 	public static String FavoritesDiscoveryStrategy_noFavoritesMessage;
 
 	public static String MarketplaceCatalog_addedNullEntry;
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/messages.properties b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/messages.properties
index 960e2a9..1a0bc8a 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/messages.properties
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/messages.properties
@@ -10,6 +10,7 @@
 # 	The Eclipse Foundation - initial API and implementation
 ###############################################################################
 FavoritesDiscoveryStrategy_enterFavoritesUrlMessage=Please enter the URL to another user's Favorites list that you wish to import
+FavoritesDiscoveryStrategy_invalidUrl=Invalid favorites URL: {0} - {1}
 MarketplaceCatalog_addedNullEntry={0} added a null item
 MarketplaceCatalog_Checking_News=Checking news
 MarketplaceCatalog_checkingForUpdates=Checking for updates