Skip to content

Commit

Permalink
511840: DefaultMarketplaceService should not require an id on each Node
Browse files Browse the repository at this point in the history
Query all nodes with ids en bloc, all with urls one at a time, and
reassemble results in the order of the passed node list.

Bug: 511840
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=511840
  • Loading branch information
creckord committed Feb 22, 2017
1 parent caa0e57 commit 7a24e45
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 8 deletions.
Expand Up @@ -22,6 +22,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
Expand Down Expand Up @@ -314,23 +315,95 @@ public Node getNode(Node node, IProgressMonitor monitor) throws CoreException {
}

public List<INode> getNodes(Collection<? extends INode> nodes, IProgressMonitor monitor) throws CoreException {
SubMonitor progress = SubMonitor.convert(monitor, Messages.DefaultMarketplaceService_getNodesProgress, nodes.size());
if (nodes.isEmpty()) {
return new ArrayList<INode>();
}
StringBuilder nodeIds = new StringBuilder();
List<INode> nodesById = null;
List<INode> nodesByUrl = null;
for (INode node : nodes) {
if (node.getId() == null) {
throw new CoreException(createErrorStatus(Messages.DefaultMarketplaceService_missingNodeId, node));
if (node.getUrl() == null) {
throw new CoreException(createErrorStatus(Messages.DefaultMarketplaceService_invalidNode, node));
}
if (nodesByUrl == null) {
nodesByUrl = new ArrayList<INode>();
}
nodesByUrl.add(node);
} else {
if (nodesById == null) {
nodesById = new ArrayList<INode>(nodes.size());
}
nodesById.add(node);
}
}
Map<INode, INode> resolvedNodeMapping = new HashMap<INode, INode>(nodes.size());
if (nodesById != null) {
getNodesById(nodesById, resolvedNodeMapping, progress.newChild(nodesById.size()));
}
if (nodesByUrl != null) {
getNodesByUrl(nodesByUrl, resolvedNodeMapping, progress.newChild(nodesByUrl.size()));
}

List<INode> resultNodes = new ArrayList<INode>(nodes.size());
for (INode inputNode : nodes) {
INode resolvedNode = resolvedNodeMapping.get(inputNode);
if (resolvedNode != null) {
resultNodes.add(resolvedNode);
} else {
String query;
if (inputNode.getId() != null) {
query = inputNode.getId();
} else {
query = inputNode.getUrl();
}
throw new CoreException(
createErrorStatus(Messages.DefaultMarketplaceService_nodeNotFound, query));
}
}

return resultNodes;
}

private void getNodesById(Collection<? extends INode> nodes, Map<INode, INode> resolvedNodeMapping,
IProgressMonitor monitor) throws CoreException {
StringBuilder nodeIdQuery = new StringBuilder();
Map<String, INode> nodeIds = new HashMap<String, INode>(nodes.size());
for (INode node : nodes) {
if (node.getId() == null) {
continue;
}
nodeIds.put(node.getId(), node);
String encodedId = urlEncode(node.getId());
if (nodeIds.length() > 0) {
nodeIds.append(","); //$NON-NLS-1$
if (nodeIdQuery.length() > 0) {
nodeIdQuery.append(","); //$NON-NLS-1$
}
nodeIdQuery.append(encodedId);
}
Marketplace marketplace = processRequest(API_NODE_URI + '/' + nodeIdQuery + '/' + API_URI_SUFFIX, monitor);
List<Node> resolvedNodes = marketplace.getNode();
for (Node node : resolvedNodes) {
INode inputNode = nodeIds.get(node.getId());
if (inputNode != null) {
resolvedNodeMapping.put(inputNode, node);
} else {
throw new CoreException(
createErrorStatus(Messages.DefaultMarketplaceService_unexpectedResponse, nodeIdQuery));
}
}
}

private void getNodesByUrl(Collection<? extends INode> nodes, Map<INode, INode> resolvedNodeMapping,
IProgressMonitor monitor) throws CoreException {
SubMonitor progress = SubMonitor.convert(monitor, nodes.size());
int remaining = nodes.size();
for (INode node : nodes) {
if (node.getId() == null && node.getUrl() != null) {
Node resolvedNode = getNode(node, progress.newChild(1));
resolvedNodeMapping.put(node, resolvedNode);
}
nodeIds.append(encodedId);
progress.setWorkRemaining(--remaining);
}
Marketplace marketplace = processRequest(API_NODE_URI + '/' + nodeIds + '/' + API_URI_SUFFIX, monitor);
List<Node> resultNodes = marketplace.getNode();
return new ArrayList<INode>(resultNodes);
}

public SearchResult search(IMarket market, ICategory category, String queryText, IProgressMonitor monitor)
Expand Down
Expand Up @@ -29,8 +29,14 @@ class Messages extends NLS {
public static String DefaultMarketplaceService_FavoritesUpdate;


public static String DefaultMarketplaceService_getNodesProgress;


public static String DefaultMarketplaceService_invalidLocation;


public static String DefaultMarketplaceService_invalidNode;

public static String DefaultMarketplaceService_marketNotFound;


Expand Down
Expand Up @@ -13,7 +13,9 @@ DefaultMarketplaceService_categoryNotFound=Category not found: ''{0}''
DefaultMarketplaceService_FavoritesErrorRetrieving=Failed to retrieve user favorites
DefaultMarketplaceService_FavoritesRetrieve=Retrieving user favorites
DefaultMarketplaceService_FavoritesUpdate=Updating user favorites
DefaultMarketplaceService_getNodesProgress=Receiving node details
DefaultMarketplaceService_invalidLocation=Cannot complete request: Invalid location ''{0}'' specified
DefaultMarketplaceService_invalidNode=Invalid node {0}: either id or url is required
DefaultMarketplaceService_marketNotFound=Market not found: ''{0}''
DefaultMarketplaceService_missingNodeId=Node {0} has no node id
DefaultMarketplaceService_mustConfigureBaseUrl=Must configure Marketplace base url
Expand Down
Expand Up @@ -361,4 +361,27 @@ public void news() throws CoreException, ParseException, MalformedURLException {
assertNotNull(url);
new URL(url);
}

@Test
@org.junit.experimental.categories.Category(RemoteTests.class)
public void getNodes() throws CoreException {
INode idNode1 = QueryHelper.nodeById("206");//Mylyn
INode idNode2 = QueryHelper.nodeById("1139");//Subversive
INode idNode3 = QueryHelper.nodeById("252");//M2E
INode urlNode = QueryHelper.nodeByUrl("https://marketplace.eclipse.org/content/egit-git-integration-eclipse");
List<INode> query = Arrays.asList(idNode1, idNode2, urlNode, idNode3);

List<INode> result = marketplaceService.getNodes(query, new NullProgressMonitor());
assertEquals(query.size(), result.size());
for (int i = 0; i < query.size(); i++) {
INode queryNode = query.get(i);
INode resultNode = query.get(i);
if (queryNode.getId() != null) {
assertEquals(queryNode.getId(), resultNode.getId());
}
if (queryNode.getUrl() != null) {
assertEquals(queryNode.getUrl(), resultNode.getUrl());
}
}
}
}

0 comments on commit 7a24e45

Please sign in to comment.