blob: 879ccabecc7eefd8931cd79b4150836121a56254 (
plain) (
tree)
|
|
/*******************************************************************************
* Copyright (c) 2011, 2016 SAP AG and others.
* All rights reserved. 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:
* Mathias Kinzler (SAP AG) - initial implementation
* Dariusz Luksza <dariusz@luksza.org> - add 'isSafe' implementation
* Thomas Wolf <thomas.wolf@paranor.ch> - Bug 493352
*******************************************************************************/
package org.eclipse.egit.ui.internal;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Locale;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.core.resources.IResource;
import org.eclipse.egit.core.internal.gerrit.GerritUtil;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryState;
import org.eclipse.jgit.transport.RemoteConfig;
/**
* Resource-based property tester.
* <p>
* Supported properties:
* <ul>
* <li>isShared <code>true</code> if the resource is mapped to EGit. EGit may
* still affect a resource if it belongs to the workspace of some shared
* project.</li>
* <li>isContainer <code>true</code> if the resource is a project or a folder</li>
* <li>is<em>repository state</em>
* <ul>
* <li>isSafe - see {@link RepositoryState#SAFE}</li>
* <li>isReverting - see {@link RepositoryState#REVERTING}</li>
* <li>isRevertingResolved - see {@link RepositoryState#REVERTING_RESOLVED}</li>
* <li>isCherryPicking - see {@link RepositoryState#CHERRY_PICKING}</li>
* <li>isCherryPickingResolved - see
* {@link RepositoryState#CHERRY_PICKING_RESOLVED}</li>
* <li>isMerging - see {@link RepositoryState#MERGING}</li>
* <li>isMergingResolved - see {@link RepositoryState#MERGING_RESOLVED}</li>
* <li>isRebasing - see {@link RepositoryState#REBASING}</li>
* <li>isRebasingRebasing - see {@link RepositoryState#REBASING_REBASING}</li>
* <li>isRebasingMerge - see {@link RepositoryState#REBASING_MERGE}</li>
* <li>isRebasingInteractive - see {@link RepositoryState#REBASING_INTERACTIVE}</li>
* <li>isApply - see {@link RepositoryState#APPLY}</li>
* <li>isBisecting - see {@link RepositoryState#BISECTING}</li>
* </ul>
* <li>Capabilities/properties of the current state:<ul>
* <li>canCheckout - see {@link RepositoryState#canCheckout()}</li>
* <li>canAmend - see {@link RepositoryState#canAmend()}</li>
* <li>canCommit - see {@link RepositoryState#canCommit()}</li>
* <li>canResetHead - see {@link RepositoryState#canResetHead()}</li>
* </ul>
* </ul>
*/
public class ResourcePropertyTester extends PropertyTester {
@Override
public boolean test(Object receiver, String property, Object[] args,
Object expectedValue) {
boolean value = internalTest(receiver, property);
boolean trace = GitTraceLocation.PROPERTIESTESTER.isActive();
if (trace)
GitTraceLocation
.getTrace()
.trace(GitTraceLocation.PROPERTIESTESTER.getLocation(),
"prop " + property + " of " + receiver + " = " + value + ", expected = " + expectedValue); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
return value;
}
private boolean internalTest(Object receiver, String property) {
if (!(receiver instanceof IResource))
return false;
IResource res = (IResource) receiver;
if ("isContainer".equals(property)) { //$NON-NLS-1$
int type = res.getType();
return type == IResource.FOLDER || type == IResource.PROJECT;
}
RepositoryMapping mapping = RepositoryMapping.getMapping(res);
if (mapping != null) {
Repository repository = mapping.getRepository();
return testRepositoryState(repository, property);
}
return false;
}
/**
* @param repository
* @param property
* @return true if the repository is in an appropriate state. See
* {@link ResourcePropertyTester}
*/
public static boolean testRepositoryState(Repository repository, String property) {
if ("isShared".equals(property)) //$NON-NLS-1$
return repository != null;
if (repository != null) {
if ("hasGerritConfiguration".equals(property)) { //$NON-NLS-1$
return hasGerritConfiguration(repository);
}
if ("canFetchFromGerrit".equals(property)) { //$NON-NLS-1$
return canFetchFromGerrit(repository);
}
if ("canPushToGerrit".equals(property)) { //$NON-NLS-1$
return canPushToGerrit(repository);
}
RepositoryState state = repository.getRepositoryState();
if ("canAbortRebase".equals(property)) //$NON-NLS-1$
switch (state) {
case REBASING_INTERACTIVE:
return true;
case REBASING_REBASING:
return true;
case REBASING_MERGE:
return true;
default:
return false;
}
if ("canContinueRebase".equals(property)) //$NON-NLS-1$
switch (state) {
case REBASING_INTERACTIVE:
return true;
case REBASING_MERGE:
return true;
default:
return false;
}
// isSTATE checks repository state where STATE is the CamelCase version
// of the RepositoryState enum values.
if (property.length() > 3 && property.startsWith("is")) { //$NON-NLS-1$
// e.g. isCherryPickingResolved => CHERRY_PICKING_RESOLVED
String lookFor = property.substring(2, 3)
+ property.substring(3).replaceAll("([A-Z])", "_$1") //$NON-NLS-1$//$NON-NLS-2$
.toUpperCase(Locale.ROOT);
if (state.toString().equals(lookFor))
return true;
}
// invokes test methods of RepositoryState, canCommit etc
try {
Method method = RepositoryState.class.getMethod(property);
if (method.getReturnType() == boolean.class) {
Boolean ret = (Boolean) method.invoke(state);
return ret.booleanValue();
}
} catch (Exception e) {
// ignore
}
}
return false;
}
/**
* @param repository
* @return {@code true} if repository has been configured for Gerrit
*/
public static boolean hasGerritConfiguration(
@NonNull Repository repository) {
Config config = repository.getConfig();
if (GerritUtil.getCreateChangeId(config)) {
return true;
}
try {
List<RemoteConfig> remoteConfigs = RemoteConfig.getAllRemoteConfigs(config);
for (RemoteConfig remoteConfig : remoteConfigs) {
if (GerritUtil.isGerritPush(remoteConfig)
|| GerritUtil.isGerritFetch(remoteConfig)) {
return true;
}
}
} catch (URISyntaxException e) {
// Assume it doesn't contain Gerrit configuration
return false;
}
return false;
}
/**
* @param repository
* @return {@code true} if repository has been configured to fetch from
* Gerrit
*/
public static boolean canFetchFromGerrit(@NonNull Repository repository) {
Config config = repository.getConfig();
try {
List<RemoteConfig> remoteConfigs = RemoteConfig
.getAllRemoteConfigs(config);
for (RemoteConfig remoteConfig : remoteConfigs) {
if (GerritUtil.isGerritFetch(remoteConfig)) {
return true;
}
}
} catch (URISyntaxException e) {
return false;
}
return false;
}
/**
* @param repository
* @return {@code true} if repository has been configured for pushing to
* Gerrit
*/
public static boolean canPushToGerrit(@NonNull Repository repository) {
Config config = repository.getConfig();
try {
List<RemoteConfig> remoteConfigs = RemoteConfig
.getAllRemoteConfigs(config);
for (RemoteConfig remoteConfig : remoteConfigs) {
if (GerritUtil.isGerritPush(remoteConfig)) {
return true;
}
}
} catch (URISyntaxException e) {
return false;
}
return false;
}
}
|