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
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
;
32 * Resource-based property tester.
34 * Supported properties:
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
39 * <li>isContainer <code>true</code> if the resource is a project or a folder</li>
40 * <li>is<em>repository state</em>
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>
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>
65 public class ResourcePropertyTester
extends PropertyTester
{
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();
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$
80 private boolean internalTest(Object receiver
, String property
) {
81 if (!(receiver
instanceof IResource
))
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
);
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$
114 case REBASING_INTERACTIVE
:
116 case REBASING_REBASING
:
124 if ("canContinueRebase".equals(property
)) //$NON-NLS-1$
126 case REBASING_INTERACTIVE
:
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
))
142 // invokes test methods of RepositoryState, canCommit etc
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
) {
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
))
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)
172 if (destination
.startsWith(GerritUtil
.REFS_FOR
))
175 for (RefSpec fetchSpec
: remoteConfig
.getFetchRefSpecs()) {
176 String source
= fetchSpec
.getSource();
177 String destination
= fetchSpec
.getDestination();
178 if (source
== null || destination
== null)
180 if (source
.startsWith(Constants
.R_NOTES
)
181 && destination
.startsWith(Constants
.R_NOTES
))
185 } catch (URISyntaxException e
) {
186 // Assume it doesn't contain Gerrit configuration