Document that hasGerritConfiguration() needs non-null repository
[egit/eclipse.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / ResourcePropertyTester.java
blob36267f0f1d58aedef4f19cb0f3c0d0793ab3ee1a
1 /*******************************************************************************
2 * Copyright (c) 2011, 2013 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 v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
8 * Contributors:
9 * Mathias Kinzler (SAP AG) - initial implementation
10 * Dariusz Luksza <dariusz@luksza.org> - add 'isSafe' implementation
11 *******************************************************************************/
12 package org.eclipse.egit.ui.internal;
14 import java.lang.reflect.Method;
15 import java.net.URISyntaxException;
16 import java.util.List;
18 import org.eclipse.core.expressions.PropertyTester;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.egit.core.internal.gerrit.GerritUtil;
21 import org.eclipse.egit.core.project.RepositoryMapping;
22 import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
23 import org.eclipse.jgit.annotations.NonNull;
24 import org.eclipse.jgit.lib.Config;
25 import org.eclipse.jgit.lib.Constants;
26 import org.eclipse.jgit.lib.Repository;
27 import org.eclipse.jgit.lib.RepositoryState;
28 import org.eclipse.jgit.transport.RefSpec;
29 import org.eclipse.jgit.transport.RemoteConfig;
31 /**
32 * Resource-based property tester.
33 * <p>
34 * Supported properties:
35 * <ul>
36 * <li>isShared <code>true</code> if the resource is mapped to EGit. EGit may
37 * still affect a resource if it belongs to the workspace of some shared
38 * project.</li>
39 * <li>isContainer <code>true</code> if the resource is a project or a folder</li>
40 * <li>is<em>repository state</em>
41 * <ul>
42 * <li>isSafe - see {@link RepositoryState#SAFE}</li>
43 * <li>isReverting - see {@link RepositoryState#REVERTING}</li>
44 * <li>isRevertingResolved - see {@link RepositoryState#REVERTING_RESOLVED}</li>
45 * <li>isCherryPicking - see {@link RepositoryState#CHERRY_PICKING}</li>
46 * <li>isCherryPickingResolved - see
47 * {@link RepositoryState#CHERRY_PICKING_RESOLVED}</li>
48 * <li>isMerging - see {@link RepositoryState#MERGING}</li>
49 * <li>isMergingResolved - see {@link RepositoryState#MERGING_RESOLVED}</li>
50 * <li>isRebasing - see {@link RepositoryState#REBASING}</li>
51 * <li>isRebasingRebasing - see {@link RepositoryState#REBASING_REBASING}</li>
52 * <li>isRebasingMerge - see {@link RepositoryState#REBASING_MERGE}</li>
53 * <li>isRebasingInteractive - see {@link RepositoryState#REBASING_INTERACTIVE}</li>
54 * <li>isApply - see {@link RepositoryState#APPLY}</li>
55 * <li>isBisecting - see {@link RepositoryState#BISECTING}</li>
56 * </ul>
57 * <li>Capabilities/properties of the current state:<ul>
58 * <li>canCheckout - see {@link RepositoryState#canCheckout()}</li>
59 * <li>canAmend - see {@link RepositoryState#canAmend()}</li>
60 * <li>canCommit - see {@link RepositoryState#canCommit()}</li>
61 * <li>canResetHead - see {@link RepositoryState#canResetHead()}</li>
62 * </ul>
63 * </ul>
65 public class ResourcePropertyTester extends PropertyTester {
67 @Override
68 public boolean test(Object receiver, String property, Object[] args,
69 Object expectedValue) {
70 boolean value = internalTest(receiver, property);
71 boolean trace = GitTraceLocation.PROPERTIESTESTER.isActive();
72 if (trace)
73 GitTraceLocation
74 .getTrace()
75 .trace(GitTraceLocation.PROPERTIESTESTER.getLocation(),
76 "prop " + property + " of " + receiver + " = " + value + ", expected = " + expectedValue); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
77 return value;
80 private boolean internalTest(Object receiver, String property) {
81 if (!(receiver instanceof IResource))
82 return false;
83 IResource res = (IResource) receiver;
84 if ("isContainer".equals(property)) { //$NON-NLS-1$
85 int type = res.getType();
86 return type == IResource.FOLDER || type == IResource.PROJECT;
89 RepositoryMapping mapping = RepositoryMapping.getMapping(res);
90 if (mapping != null) {
91 Repository repository = mapping.getRepository();
92 return testRepositoryState(repository, property);
94 return false;
97 /**
98 * @param repository
99 * @param property
100 * @return true if the repository is in an appropriate state. See
101 * {@link ResourcePropertyTester}
103 public static boolean testRepositoryState(Repository repository, String property) {
104 if ("isShared".equals(property)) //$NON-NLS-1$
105 return repository != null;
106 if (repository != null) {
107 if ("hasGerritConfiguration".equals(property)) //$NON-NLS-1$
108 return hasGerritConfiguration(repository);
110 RepositoryState state = repository.getRepositoryState();
112 if ("canAbortRebase".equals(property)) //$NON-NLS-1$
113 switch (state) {
114 case REBASING_INTERACTIVE:
115 return true;
116 case REBASING_REBASING:
117 return true;
118 case REBASING_MERGE:
119 return true;
120 default:
121 return false;
124 if ("canContinueRebase".equals(property)) //$NON-NLS-1$
125 switch (state) {
126 case REBASING_INTERACTIVE:
127 return true;
128 case REBASING_MERGE:
129 return true;
130 default:
131 return false;
134 // isSTATE checks repository state where STATE is the CamelCase version
135 // of the RepositoryState enum values.
136 if (property.length() > 3 && property.startsWith("is")) { //$NON-NLS-1$
137 // e.g. isCherryPickingResolved => CHERRY_PICKING_RESOLVED
138 String lookFor = property.substring(2,3) + property.substring(3).replaceAll("([A-Z])","_$1").toUpperCase(); //$NON-NLS-1$//$NON-NLS-2$
139 if (state.toString().equals(lookFor))
140 return true;
142 // invokes test methods of RepositoryState, canCommit etc
143 try {
144 Method method = RepositoryState.class.getMethod(property);
145 if (method.getReturnType() == boolean.class) {
146 Boolean ret = (Boolean) method.invoke(state);
147 return ret.booleanValue();
149 } catch (Exception e) {
150 // ignore
153 return false;
157 * @param repository
158 * @return {@code true} if repository has been configured for Gerrit
160 public static boolean hasGerritConfiguration(
161 @NonNull Repository repository) {
162 Config config = repository.getConfig();
163 if (GerritUtil.getCreateChangeId(config))
164 return true;
165 try {
166 List<RemoteConfig> remoteConfigs = RemoteConfig.getAllRemoteConfigs(config);
167 for (RemoteConfig remoteConfig : remoteConfigs) {
168 for (RefSpec pushSpec : remoteConfig.getPushRefSpecs()) {
169 String destination = pushSpec.getDestination();
170 if (destination == null)
171 continue;
172 if (destination.startsWith(GerritUtil.REFS_FOR))
173 return true;
175 for (RefSpec fetchSpec : remoteConfig.getFetchRefSpecs()) {
176 String source = fetchSpec.getSource();
177 String destination = fetchSpec.getDestination();
178 if (source == null || destination == null)
179 continue;
180 if (source.startsWith(Constants.R_NOTES)
181 && destination.startsWith(Constants.R_NOTES))
182 return true;
185 } catch (URISyntaxException e) {
186 // Assume it doesn't contain Gerrit configuration
187 return false;
189 return false;