Update org.apache.commons:commons-compress to 1.25.0
[egit/eclipse.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / ResourcePropertyTester.java
blob4e59cdf14c5d42876d687ab711df3c261ecd4ddc
1 /*******************************************************************************
2 * Copyright (c) 2011, 2020 SAP AG and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License 2.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-2.0/
8 * SPDX-License-Identifier: EPL-2.0
10 * Contributors:
11 * Mathias Kinzler (SAP AG) - initial implementation
12 * Dariusz Luksza <dariusz@luksza.org> - add 'isSafe' implementation
13 * Thomas Wolf <thomas.wolf@paranor.ch> - Bug 493352
14 *******************************************************************************/
15 package org.eclipse.egit.ui.internal;
17 import java.lang.reflect.Method;
18 import java.net.URISyntaxException;
19 import java.util.List;
20 import java.util.Locale;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.egit.core.internal.gerrit.GerritUtil;
24 import org.eclipse.egit.core.internal.hosts.GitHosts;
25 import org.eclipse.egit.core.project.RepositoryMapping;
26 import org.eclipse.egit.ui.internal.expressions.AbstractPropertyTester;
27 import org.eclipse.egit.ui.internal.selection.SelectionRepositoryStateCache;
28 import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
29 import org.eclipse.jgit.annotations.NonNull;
30 import org.eclipse.jgit.lib.Config;
31 import org.eclipse.jgit.lib.Repository;
32 import org.eclipse.jgit.lib.RepositoryState;
33 import org.eclipse.jgit.transport.RemoteConfig;
35 /**
36 * Resource-based property tester.
37 * <p>
38 * Supported properties:
39 * <ul>
40 * <li>isShared <code>true</code> if the resource is mapped to EGit. EGit may
41 * still affect a resource if it belongs to the workspace of some shared
42 * project.</li>
43 * <li>isContainer <code>true</code> if the resource is a project or a
44 * folder</li>
45 * <li>hasHead <code>true</code> if the repository has a HEAD</li>
46 * <li>is<em>repository state</em>
47 * <ul>
48 * <li>isSafe - see {@link RepositoryState#SAFE}</li>
49 * <li>isReverting - see {@link RepositoryState#REVERTING}</li>
50 * <li>isRevertingResolved - see {@link RepositoryState#REVERTING_RESOLVED}</li>
51 * <li>isCherryPicking - see {@link RepositoryState#CHERRY_PICKING}</li>
52 * <li>isCherryPickingResolved - see
53 * {@link RepositoryState#CHERRY_PICKING_RESOLVED}</li>
54 * <li>isMerging - see {@link RepositoryState#MERGING}</li>
55 * <li>isMergingResolved - see {@link RepositoryState#MERGING_RESOLVED}</li>
56 * <li>isRebasing - see {@link RepositoryState#REBASING}</li>
57 * <li>isRebasingRebasing - see {@link RepositoryState#REBASING_REBASING}</li>
58 * <li>isRebasingMerge - see {@link RepositoryState#REBASING_MERGE}</li>
59 * <li>isRebasingInteractive - see
60 * {@link RepositoryState#REBASING_INTERACTIVE}</li>
61 * <li>isApply - see {@link RepositoryState#APPLY}</li>
62 * <li>isBisecting - see {@link RepositoryState#BISECTING}</li>
63 * </ul>
64 * </li>
65 * <li>Capabilities/properties of the current state:
66 * <ul>
67 * <li>canCheckout - see {@link RepositoryState#canCheckout()}</li>
68 * <li>canAmend - see {@link RepositoryState#canAmend()}</li>
69 * <li>canCommit - see {@link RepositoryState#canCommit()}</li>
70 * <li>canResetHead - see {@link RepositoryState#canResetHead()}</li>
71 * </ul>
72 * </li>
73 * </ul>
75 public class ResourcePropertyTester extends AbstractPropertyTester {
77 @Override
78 public boolean test(Object receiver, String property, Object[] args,
79 Object expectedValue) {
80 if (!(receiver instanceof IResource)) {
81 return false;
83 boolean value = internalTest((IResource) receiver, property);
84 boolean trace = GitTraceLocation.PROPERTIESTESTER.isActive();
85 if (trace)
86 GitTraceLocation
87 .getTrace()
88 .trace(GitTraceLocation.PROPERTIESTESTER.getLocation(),
89 "prop " + property + " of " + receiver + " = " + value + ", expected = " + expectedValue); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
90 return computeResult(expectedValue, value);
93 private boolean internalTest(@NonNull IResource res, String property) {
94 if ("isContainer".equals(property)) { //$NON-NLS-1$
95 int type = res.getType();
96 return type == IResource.FOLDER || type == IResource.PROJECT;
99 RepositoryMapping mapping = RepositoryMapping.getMapping(res);
100 if (mapping != null) {
101 Repository repository = mapping.getRepository();
102 return testRepositoryState(repository, property);
104 return false;
108 * @param repository
109 * @param property
110 * @return true if the repository is in an appropriate state. See
111 * {@link ResourcePropertyTester}
113 public static boolean testRepositoryState(Repository repository, String property) {
114 if ("isShared".equals(property)) { //$NON-NLS-1$
115 return repository != null;
117 if (repository != null) {
118 if ("hasHead".equals(property)) { //$NON-NLS-1$
119 return SelectionRepositoryStateCache.INSTANCE
120 .getHead(repository) != null;
122 if ("hasGitHubConfiguration".equals(property)) { //$NON-NLS-1$
123 return hasServerConfiguration(repository,
124 GitHosts.ServerType.GITHUB);
126 if ("hasGitLabConfiguration".equals(property)) { //$NON-NLS-1$
127 return hasServerConfiguration(repository,
128 GitHosts.ServerType.GITLAB);
130 if ("hasGiteaConfiguration".equals(property)) { //$NON-NLS-1$
131 return hasServerConfiguration(repository,
132 GitHosts.ServerType.GITEA);
134 if ("hasGerritConfiguration".equals(property)) { //$NON-NLS-1$
135 return hasGerritConfiguration(repository);
137 if ("canFetchFromGerrit".equals(property)) { //$NON-NLS-1$
138 return canFetchFromGerrit(repository);
140 if ("canPushToGerrit".equals(property)) { //$NON-NLS-1$
141 return canPushToGerrit(repository);
143 RepositoryState state = SelectionRepositoryStateCache.INSTANCE
144 .getRepositoryState(repository);
146 if ("canAbortRebase".equals(property)) { //$NON-NLS-1$
147 return canAbortRebase(state);
149 if ("canContinueRebase".equals(property)) { //$NON-NLS-1$
150 return canContinueRebase(state);
152 // isSTATE checks repository state where STATE is the CamelCase version
153 // of the RepositoryState enum values.
154 if (property.length() > 3 && property.startsWith("is")) { //$NON-NLS-1$
155 // e.g. isCherryPickingResolved => CHERRY_PICKING_RESOLVED
156 String lookFor = property.substring(2, 3)
157 + property.substring(3).replaceAll("([A-Z])", "_$1") //$NON-NLS-1$//$NON-NLS-2$
158 .toUpperCase(Locale.ROOT);
159 if (state.toString().equals(lookFor))
160 return true;
162 // invokes test methods of RepositoryState, canCommit etc
163 try {
164 Method method = RepositoryState.class.getMethod(property);
165 if (method.getReturnType() == boolean.class) {
166 Boolean ret = (Boolean) method.invoke(state);
167 return ret.booleanValue();
169 } catch (Exception e) {
170 // ignore
173 return false;
176 private static boolean hasServerConfiguration(Repository repository,
177 GitHosts.ServerType server) {
178 try {
179 return GitHosts
180 .hasServerConfig(SelectionRepositoryStateCache.INSTANCE
181 .getConfig(repository), server);
182 } catch (URISyntaxException e) {
183 // Assume no matching config.
184 return false;
189 * @param repository
190 * @return {@code true} if repository has been configured for Gerrit
192 public static boolean hasGerritConfiguration(
193 @NonNull Repository repository) {
194 Config config = SelectionRepositoryStateCache.INSTANCE.getConfig(repository);
195 if (GerritUtil.getCreateChangeId(config)) {
196 return true;
198 try {
199 List<RemoteConfig> remoteConfigs = RemoteConfig.getAllRemoteConfigs(config);
200 for (RemoteConfig remoteConfig : remoteConfigs) {
201 if (GerritUtil.isGerritPush(remoteConfig)
202 || GerritUtil.isGerritFetch(remoteConfig)) {
203 return true;
206 } catch (URISyntaxException e) {
207 // Assume it doesn't contain Gerrit configuration
208 return false;
210 return false;
214 * @param repository
215 * @return {@code true} if repository has been configured to fetch from
216 * Gerrit
218 public static boolean canFetchFromGerrit(@NonNull Repository repository) {
219 Config config = SelectionRepositoryStateCache.INSTANCE.getConfig(repository);
220 try {
221 List<RemoteConfig> remoteConfigs = RemoteConfig
222 .getAllRemoteConfigs(config);
223 for (RemoteConfig remoteConfig : remoteConfigs) {
224 if (GerritUtil.isGerritFetch(remoteConfig)) {
225 return true;
228 } catch (URISyntaxException e) {
229 return false;
231 return false;
235 * @param repository
236 * @return {@code true} if repository has been configured for pushing to
237 * Gerrit
239 public static boolean canPushToGerrit(@NonNull Repository repository) {
240 Config config = SelectionRepositoryStateCache.INSTANCE.getConfig(repository);
241 try {
242 List<RemoteConfig> remoteConfigs = RemoteConfig
243 .getAllRemoteConfigs(config);
244 for (RemoteConfig remoteConfig : remoteConfigs) {
245 if (GerritUtil.isGerritPush(remoteConfig)) {
246 return true;
249 } catch (URISyntaxException e) {
250 return false;
252 return false;
256 * @param state
257 * @return {@code true} if the repository state permits a rebase to be
258 * aborted
260 public static boolean canAbortRebase(@NonNull RepositoryState state) {
261 switch (state) {
262 case REBASING_INTERACTIVE:
263 return true;
264 case REBASING_REBASING:
265 return true;
266 case REBASING_MERGE:
267 return true;
268 default:
269 return false;
274 * @param state
275 * @return {@code true} if the repository state permits a rebase to be
276 * continued
278 public static boolean canContinueRebase(@NonNull RepositoryState state) {
279 switch (state) {
280 case REBASING_INTERACTIVE:
281 return true;
282 case REBASING_MERGE:
283 return true;
284 default:
285 return false;