blob: 3a5f41f862aa7a0620018549c6dc44b94ffe51e7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2010 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.team.internal.ccvs.core;
import java.util.*;
import org.eclipse.core.resources.IProject;
import org.eclipse.team.internal.ccvs.core.CVSProjectSetCapability.LoadInfo;
import org.eclipse.team.internal.ccvs.core.util.KnownRepositories;
public class CVSRepositoryLocationMatcher {
private static final String EXTSSH = "extssh"; //$NON-NLS-1$
private static final String PSERVER = "pserver"; //$NON-NLS-1$
private static final String EXT = "ext"; //$NON-NLS-1$
private static Comparator<ICVSRepositoryLocation> COMPATIBLE_LOCATIONS_COMPARATOR = (rl1, rl2) -> {
String name1 = rl1.getMethod().getName();
String name2 = rl2.getMethod().getName();
if (!name1.equals(name2) && isCompatible(rl1, rl2, false)) {
if (name1.equals(EXTSSH))
return -1;
if (name2.equals(EXTSSH))
return 1;
if (name1.equals(PSERVER))
return -1;
if (name2.equals(PSERVER))
return 1;
if (name1.equals(EXT))
return -1;
if (name2.equals(EXT))
return 1;
}
return name1.compareTo(name2);
};
public static Map<IProject, List<ICVSRepositoryLocation>> prepareSuggestedRepositoryLocations(
IProject[] projects, final Map<IProject, LoadInfo> infoMap) {
List<IProject> confirmedProjectsList = Arrays.asList(projects);
Set<ICVSRepositoryLocation> projectSetRepositoryLocations = new HashSet<>();
for (Iterator i = infoMap.keySet().iterator(); i.hasNext();) {
IProject project = (IProject) i.next();
if (confirmedProjectsList.contains(project)) {
LoadInfo loadInfo = infoMap.get(project);
projectSetRepositoryLocations.add(loadInfo.repositoryLocation);
}
}
// none of projects from project sets is confirmed to overwrite
if (projectSetRepositoryLocations.isEmpty()) {
return null;
}
List<ICVSRepositoryLocation> knownRepositories = Arrays
.asList(KnownRepositories.getInstance().getRepositories());
if (knownRepositories.isEmpty()) {
// There are no known repositories so use repository location from
// the project set.
Map result = new HashMap();
for (Iterator i = projectSetRepositoryLocations.iterator(); i
.hasNext();) {
ICVSRepositoryLocation projectSetRepositoryLocation = (ICVSRepositoryLocation) i
.next();
ArrayList<ICVSRepositoryLocation> list = new ArrayList<>(1);
list.add(projectSetRepositoryLocation);
result.put(projectSetRepositoryLocation, list);
}
return result;
} else if (knownRepositories.containsAll(projectSetRepositoryLocations)) {
// All repositories are known, no need to prompt for additional
// information.
return Collections.emptyMap();
} else {
// Not all repositories from the project set are known.
Map result = new HashMap();
for (Iterator i = projectSetRepositoryLocations.iterator(); i
.hasNext();) {
ICVSRepositoryLocation projectSetRepositoryLocation = (ICVSRepositoryLocation) i
.next();
List<ICVSRepositoryLocation> matching = new ArrayList<>();
List<ICVSRepositoryLocation> compatible = new ArrayList<>();
List<ICVSRepositoryLocation> list = new ArrayList<>();
for (Iterator j = knownRepositories.iterator(); j.hasNext();) {
ICVSRepositoryLocation knownRepositoryLocation = (ICVSRepositoryLocation) j
.next();
// There can be more than one perfect match (i.e. two
// known, matching repositories with different user names)
if (CVSRepositoryLocationMatcher.isMatching(
projectSetRepositoryLocation,
knownRepositoryLocation)) {
matching.add(knownRepositoryLocation);
} else if (CVSRepositoryLocationMatcher.isCompatible(
knownRepositoryLocation,
projectSetRepositoryLocation, false)) {
compatible.add(knownRepositoryLocation);
} else {
list.add(knownRepositoryLocation);
}
}
// Sort compatible repository locations starting from extssh,
// followed by pserver and finally ext.
Collections.sort(compatible, COMPATIBLE_LOCATIONS_COMPARATOR);
// Add compatible repos before others
list.addAll(0, compatible);
if (matching.isEmpty()) {
// If no matching repo locations found add the one
// from the project set first.
list.add(0, projectSetRepositoryLocation);
} else if (matching.size() == 1) {
// There is only one matching, known repository
// so there is no need to ask for any additional info.
// Don't add it to the 'resultMap'
list.clear();
list.addAll(matching);
result.put(projectSetRepositoryLocation, list);
continue;
} else {
// There is more than one matching, known repository, so
// ask which one we should use during the import
list.addAll(0, matching);
}
result.put(projectSetRepositoryLocation, list);
}
return result;
}
}
/**
* Same check as in
* org.eclipse.team.internal.ccvs.ui.CVSProjectPropertiesPage class.
*
* @see org.eclipse.team.internal.ccvs.ui.CVSProjectPropertiesPage#isCompatible
*
* @param location1
* First repository location to match
* @param location2
* Second repository location to match
* @param equalIsCompatible
* If equal means compatible
* @return <code>true</code> if given repository location are compatible,
* otherwise <code>false</code> is returned.
*/
public static boolean isCompatible(ICVSRepositoryLocation location1,
ICVSRepositoryLocation location2, boolean equalIsCompatible) {
if (!location1.getHost().equals(location2.getHost()))
return false;
if (!location1.getRootDirectory().equals(location2.getRootDirectory()))
return false;
if (!equalIsCompatible && location1.equals(location2))
return false;
return true;
}
/**
* Checks whether two repository locations match (i.e. they are compatible,
* they use the same connection method and they use the same port) .
*
* @param location1
* First repository location to match
* @param location2
* Second repository location to match
* @return <code>true</code> if given repository location are matching
* according to the rule above, otherwise <code>false</code> is
* returned.
*/
public static boolean isMatching(ICVSRepositoryLocation location1,
ICVSRepositoryLocation location2) {
if (isCompatible(location1, location2, true)
&& location2.getMethod() == location1.getMethod()
&& location2.getPort() == location1.getPort())
return true;
return false;
}
static boolean isPromptRequired(Map suggestedRepositoryLocations) {
if (suggestedRepositoryLocations == null)
return false;
for (Iterator i = suggestedRepositoryLocations.values().iterator(); i
.hasNext();) {
List list = (List) i.next();
if (!list.isEmpty())
return true;
}
return false;
}
}