/*******************************************************************************
* Copyright (C) 2015, 2016 Thomas Wolf <thomas.wolf@paranor.ch>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.egit.ui.internal.resources;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.core.runtime.IPath;
import org.eclipse.egit.core.internal.util.ResourceUtil;
import org.eclipse.egit.ui.internal.selection.SelectionUtils;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.annotations.Nullable;
/**
* A property tester testing the {@IResourceState} of a file under EGit control.
* Assumes a {@link Collection} of elements, typically a selection. Skips any
* resources not in a repository.
*/
public class ResourceStatePropertyTester extends PropertyTester {
private enum Property {
/**
* {@code true} if the collection contains at least one item with staged
* changes.
*/
HAS_STAGED_CHANGES,
/**
* {@code true} if the collection contains at least one item with
* unstaged changes.
*/
HAS_UNSTAGED_CHANGES,
/**
* {@code true} if the collection contains at least one item that is not
* ignored.
*/
HAS_NOT_IGNORED_RESOURCES,
/**
* {@code true} if the collection contains at least one item that is
* tracked (i.e., that is neither ignored nor untracked).
*/
HAS_TRACKED_RESOURCES
}
@Override
public boolean test(Object receiver, String property, Object[] args,
Object expectedValue) {
Property prop = property != null ? toProperty(property) : null;
if (prop == null || receiver == null) {
return false;
}
boolean result = internalTest(receiver, prop);
if (expectedValue != null) {
return expectedValue.equals(Boolean.valueOf(result));
} else {
return result;
}
}
private boolean internalTest(@NonNull Object receiver,
@NonNull Property property) {
Collection<?> collection = (Collection<?>) receiver;
if (collection.isEmpty()) {
return false;
}
IStructuredSelection selection = null;
Object first = collection.iterator().next();
if (collection.size() == 1 && first instanceof ITextSelection) {
selection = SelectionUtils
.getStructuredSelection((ITextSelection) first);
} else {
selection = new StructuredSelection(new ArrayList<>(collection));
}
for (IPath path : SelectionUtils.getSelectedLocations(selection)) {
if (path == null || ResourceUtil.getRepository(path) == null) {
continue;
}
IResourceState state = ResourceStateFactory.getInstance()
.get(path.toFile());
switch (property) {
case HAS_STAGED_CHANGES:
if (state.isStaged()) {
return true;
}
break;
case HAS_UNSTAGED_CHANGES:
if (state.hasUnstagedChanges()) {
return true;
}
break;
case HAS_NOT_IGNORED_RESOURCES:
if (!state.isIgnored()) {
return true;
}
break;
case HAS_TRACKED_RESOURCES:
if (state.isTracked()) {
return true;
}
break;
}
}
return false;
}
@Nullable
private Property toProperty(@NonNull String value) {
if ("hasStagedChanges".equals(value)) { //$NON-NLS-1$
return Property.HAS_STAGED_CHANGES;
} else if ("hasUnstagedChanges".equals(value)) { //$NON-NLS-1$
return Property.HAS_UNSTAGED_CHANGES;
} else if ("hasNotIgnoredResources".equals(value)) { //$NON-NLS-1$
return Property.HAS_NOT_IGNORED_RESOURCES;
} else if ("hasTrackedResources".equals(value)) { //$NON-NLS-1$
return Property.HAS_TRACKED_RESOURCES;
}
return null;
}
}