Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: d93b040c0c41cab3bea44651199171b15c29e052 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/*******************************************************************************
 * 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 COMPATIBLE_LOCATIONS_COMPARATOR = (o1, o2) -> {
		if (o1 instanceof ICVSRepositoryLocation
				&& o2 instanceof ICVSRepositoryLocation) {
			ICVSRepositoryLocation rl1 = (ICVSRepositoryLocation) o1;
			ICVSRepositoryLocation rl2 = (ICVSRepositoryLocation) o2;
			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);
		}
		return 0;
	};

	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 = (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 matching = new ArrayList();
				List compatible = new ArrayList();
				List 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;
	}

}

Back to the top