From 1f69fad3e04670e5ab4d5a25ee8bb032c16beb1a Mon Sep 17 00:00:00 2001 From: Luís Copetti Date: Sun, 29 Jul 2018 19:57:45 -0300 Subject: SelectionUtils now contains methods to return multiple repositories The current API for the SelectionUtils only handled selections that contained a single repository, now it has been refactored so that it is as easy to get multiple repositories for an IStructuredSelection than it was for a single repository. Change-Id: Iec38362538aebd891cda74d366567de785d61f21 Signed-off-by: Luís Copetti --- .../internal/actions/RepositoryActionHandler.java | 114 +--------------- .../egit/ui/internal/selection/SelectionUtils.java | 144 ++++++++++++++++++++- 2 files changed, 146 insertions(+), 112 deletions(-) diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java index 897c318097..8e788eb3de 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java @@ -23,8 +23,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -35,12 +33,9 @@ import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.mapping.ResourceMapping; import org.eclipse.core.runtime.IPath; -import org.eclipse.egit.core.AdapterUtils; import org.eclipse.egit.core.internal.CompareCoreUtils; import org.eclipse.egit.core.project.RepositoryMapping; -import org.eclipse.egit.ui.internal.CommonUtils; import org.eclipse.egit.ui.internal.selection.SelectionUtils; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; @@ -83,51 +78,6 @@ abstract class RepositoryActionHandler extends AbstractHandler { mySelection = SelectionUtils.getStructuredSelection(selection); } - /** - * Retrieve the list of projects that contains the given resources. All - * resources must actually map to a project shared with egit, otherwise an - * empty array is returned. In case of a linked resource, the project - * returned is the one that contains the link target and is shared with - * egit, if any, otherwise an empty array is also returned. - * - * @param selection - * @return the projects hosting the selected resources - */ - private IProject[] getProjectsForSelectedResources( - IStructuredSelection selection) { - Set ret = new LinkedHashSet<>(); - for (IResource resource : getSelectedAdaptables(selection, - IResource.class)) { - RepositoryMapping mapping = RepositoryMapping.getMapping(resource); - if (mapping != null && (mapping.getContainer() instanceof IProject)) - ret.add((IProject) mapping.getContainer()); - else - return new IProject[0]; - } - ret.addAll(extractProjectsFromMappings(selection)); - - return ret.toArray(new IProject[0]); - } - - private Set extractProjectsFromMappings( - IStructuredSelection selection) { - Set ret = new LinkedHashSet<>(); - for (ResourceMapping mapping : getSelectedAdaptables(selection, - ResourceMapping.class)) { - IProject[] mappedProjects = mapping.getProjects(); - if (mappedProjects != null && mappedProjects.length != 0) { - // Some mappings (WorkingSetResourceMapping) return the projects - // in unpredictable order. Sort them like the navigator to - // correspond to the order the user usually sees. - List projects = new ArrayList<>( - Arrays.asList(mappedProjects)); - Collections - .sort(projects, CommonUtils.RESOURCE_NAME_COMPARATOR); - ret.addAll(projects); - } - } - return ret; - } /** * Retrieve the list of projects that contains the selected resources. All @@ -143,7 +93,7 @@ abstract class RepositoryActionHandler extends AbstractHandler { protected IProject[] getProjectsForSelectedResources(ExecutionEvent event) throws ExecutionException { IStructuredSelection selection = getSelection(event); - return getProjectsForSelectedResources(selection); + return SelectionUtils.getSelectedProjects(selection); } /** @@ -157,7 +107,7 @@ abstract class RepositoryActionHandler extends AbstractHandler { */ protected IProject[] getProjectsForSelectedResources() { IStructuredSelection selection = getSelection(); - return getProjectsForSelectedResources(selection); + return SelectionUtils.getSelectedProjects(selection); } /** @@ -246,22 +196,8 @@ abstract class RepositoryActionHandler extends AbstractHandler { */ protected Repository[] getRepositories(ExecutionEvent event) throws ExecutionException { - IProject[] selectedProjects = getProjectsForSelectedResources(event); - if (selectedProjects.length > 0) { - return getRepositoriesFor(selectedProjects); - } IStructuredSelection selection = getSelection(event); - if (!selection.isEmpty()) { - Set repos = new LinkedHashSet<>(); - for (Object o : selection.toArray()) { - Repository repo = AdapterUtils.adapt(o, Repository.class); - if (repo != null) { - repos.add(repo); - } - } - return repos.toArray(new Repository[0]); - } - return new Repository[0]; + return SelectionUtils.getRepositories(selection); } /** @@ -271,24 +207,8 @@ abstract class RepositoryActionHandler extends AbstractHandler { * @return repositories for selection, or an empty array */ public Repository[] getRepositories() { - IProject[] selectedProjects = getProjectsForSelectedResources(); - if (selectedProjects.length > 0) - return getRepositoriesFor(selectedProjects); IStructuredSelection selection = getSelection(); - if (!selection.isEmpty()) { - Set repos = new LinkedHashSet<>(); - for (Object o : selection.toArray()) { - Repository repo = AdapterUtils.adapt(o, Repository.class); - if (repo != null) { - repos.add(repo); - } else { - // no repository found for one of the objects! - return new Repository[0]; - } - } - return repos.toArray(new Repository[0]); - } - return new Repository[0]; + return SelectionUtils.getRepositories(selection); } /** @@ -323,32 +243,6 @@ abstract class RepositoryActionHandler extends AbstractHandler { this.evaluationContext = (IEvaluationContext) evaluationContext; } - /** - * Creates an array of the given class type containing all the objects in - * the selection that adapt to the given class. - * - * @param selection - * @param c - * @return the selected adaptables - */ - private List getSelectedAdaptables(ISelection selection, - Class c) { - List result; - if (selection != null && !selection.isEmpty()) { - result = new ArrayList<>(); - Iterator elements = ((IStructuredSelection) selection).iterator(); - while (elements.hasNext()) { - T adapter = AdapterUtils.adapt(elements.next(), c); - if (adapter != null) { - result.add(adapter); - } - } - } else { - result = Collections.emptyList(); - } - return result; - } - /** * @param event * @return the resources in the selection diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionUtils.java index cb3bb213ee..9729f0b735 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionUtils.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/selection/SelectionUtils.java @@ -13,6 +13,9 @@ *******************************************************************************/ package org.eclipse.egit.ui.internal.selection; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; @@ -20,11 +23,13 @@ import java.util.List; import java.util.Set; import org.eclipse.core.expressions.IEvaluationContext; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.mapping.ResourceMapping; import org.eclipse.core.runtime.IPath; import org.eclipse.egit.core.AdapterUtils; import org.eclipse.egit.core.internal.util.ResourceUtil; +import org.eclipse.egit.core.project.RepositoryMapping; import org.eclipse.egit.ui.internal.CommonUtils; import org.eclipse.egit.ui.internal.UIText; import org.eclipse.egit.ui.internal.history.HistoryPageInput; @@ -63,6 +68,51 @@ public class SelectionUtils { return getRepository(false, selection, null); } + /** + * @param evaluationContext + * @return array of selected repositories + */ + @NonNull + public static Repository[] getRepositories( + @Nullable IEvaluationContext evaluationContext) { + return getRepositories(getSelection(evaluationContext)); + } + + /** + * Retrieves all the repositories associated with the current selection. It + * attempts to first identify the selections as projects and if that yields + * an empty result, it then changes to adapt the selections to the + * repository class + * + * @param selection + * @return array of repositories + */ + @NonNull + public static Repository[] getRepositories( + @NonNull IStructuredSelection selection) { + + IProject[] selectedProjects = getSelectedProjects(selection); + + if (selectedProjects.length > 0) + return getRepositoriesFor(selectedProjects); + + if (selection.isEmpty()) { + return new Repository[0]; + } + + Set repos = new LinkedHashSet<>(); + for (Object o : selection.toArray()) { + Repository repo = AdapterUtils.adapt(o, Repository.class); + if (repo != null) { + repos.add(repo); + } else { + // no repository found for one of the objects! + return new Repository[0]; + } + } + return repos.toArray(new Repository[0]); + } + /** * @param evaluationContext * @return the single selected repository, or null @@ -243,8 +293,7 @@ public class SelectionUtils { } } - IResource[] resourceArray = resources.toArray(new IResource[resources - .size()]); + IResource[] resourceArray = resources.toArray(new IResource[0]); return new HistoryPageInput(repository, resourceArray); } @@ -422,4 +471,95 @@ public class SelectionUtils { return ctx; } + /** + * Retrieve the list of projects that contains the given resources. All + * resources must actually map to a project shared with egit, otherwise an + * empty array is returned. In case of a linked resource, the project + * returned is the one that contains the link target and is shared with + * egit, if any, otherwise an empty array is also returned. + * + * @param selection + * @return the projects hosting the selected resources + */ + public static IProject[] getSelectedProjects( + IStructuredSelection selection) { + Set ret = new LinkedHashSet<>(); + for (IResource resource : getSelectedAdaptables(selection, + IResource.class)) { + RepositoryMapping mapping = RepositoryMapping.getMapping(resource); + if (mapping != null && (mapping.getContainer() instanceof IProject)) + ret.add((IProject) mapping.getContainer()); + else + return new IProject[0]; + } + ret.addAll(extractProjectsFromMappings(selection)); + + return ret.toArray(new IProject[0]); + } + + private static Set extractProjectsFromMappings( + IStructuredSelection selection) { + Set ret = new LinkedHashSet<>(); + for (ResourceMapping mapping : getSelectedAdaptables(selection, + ResourceMapping.class)) { + IProject[] mappedProjects = mapping.getProjects(); + if (mappedProjects != null && mappedProjects.length != 0) { + // Some mappings (WorkingSetResourceMapping) return the projects + // in unpredictable order. Sort them like the navigator to + // correspond to the order the user usually sees. + List projects = new ArrayList<>( + Arrays.asList(mappedProjects)); + Collections.sort(projects, + CommonUtils.RESOURCE_NAME_COMPARATOR); + ret.addAll(projects); + } + } + return ret; + } + + /** + * Creates an array of the given class type containing all the objects in + * the selection that adapt to the given class. + * + * @param selection + * @param c + * @return the selected adaptables + */ + @NonNull + private static List getSelectedAdaptables(ISelection selection, + Class c) { + List result; + if (selection != null && !selection.isEmpty()) { + result = new ArrayList<>(); + Iterator elements = ((IStructuredSelection) selection).iterator(); + while (elements.hasNext()) { + T adapter = AdapterUtils.adapt(elements.next(), c); + if (adapter != null) { + result.add(adapter); + } + } + } else { + result = Collections.emptyList(); + } + return result; + } + + /** + * @param projects + * a list of projects + * @return the repositories that projects map to if all projects are mapped + */ + @NonNull + private static Repository[] getRepositoriesFor(final IProject[] projects) { + Set ret = new LinkedHashSet<>(); + for (IProject project : projects) { + RepositoryMapping repositoryMapping = RepositoryMapping + .getMapping(project); + if (repositoryMapping == null) { + return new Repository[0]; + } + ret.add(repositoryMapping.getRepository()); + } + return ret.toArray(new Repository[0]); + } } -- cgit v1.2.3