package jenkins.branch;
import hudson.model.Item;
import hudson.model.ItemGroup;
import hudson.model.TopLevelItem;
import hudson.model.View;
import hudson.views.ViewJobFilter;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
/**
* Base class for a {@link ViewJobFilter} that will filter based on the {@link Branch} that a job in a
* {@link MultiBranchProject} belongs to.
*
* @since 2.0
*/
public abstract class SimpleViewBranchFilter extends ViewJobFilter {
/**
* Optimization to avoid processing the less common case of removing already added items.
*/
private final boolean processExclusions = isExcludedOverridden();
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public final List<TopLevelItem> filter(List<TopLevelItem> added, List<TopLevelItem> all, View filteringView) {
ItemGroup<? extends TopLevelItem> itemGroup = filteringView.getOwnerItemGroup();
if (itemGroup instanceof MultiBranchProject) {
// fast path
MultiBranchProject project = (MultiBranchProject) itemGroup;
BranchProjectFactory factory = project.getProjectFactory();
if (processExclusions) {
for (Iterator<TopLevelItem> iterator = added.iterator(); iterator.hasNext(); ) {
TopLevelItem i = iterator.next();
if (factory.isProject(i) && isExcluded(factory.getBranch(factory.asProject(i)))) {
iterator.remove();
}
}
}
for (TopLevelItem i : all) {
if (factory.isProject(i) && isIncluded(factory.getBranch(factory.asProject(i)))) {
added.add(i);
}
}
} else {
// ok this may be a view pulling in all child items, so we need to check each item as we go
if (processExclusions) {
for (Iterator<TopLevelItem> iterator = added.iterator(); iterator.hasNext(); ) {
TopLevelItem i = iterator.next();
ItemGroup<? extends Item> parent = i.getParent();
if (parent instanceof MultiBranchProject) {
BranchProjectFactory factory = ((MultiBranchProject) parent).getProjectFactory();
if (factory.isProject(i) && isExcluded(factory.getBranch(factory.asProject(i)))) {
iterator.remove();
}
}
}
}
for (TopLevelItem i : all) {
ItemGroup<? extends Item> parent = i.getParent();
if (parent instanceof MultiBranchProject) {
BranchProjectFactory factory = ((MultiBranchProject) parent).getProjectFactory();
if (factory.isProject(i) && isIncluded(factory.getBranch(factory.asProject(i)))) {
added.add(i);
}
}
}
}
return added;
}
/**
* Tests if the supplied branch should be excluded.
*
* @param branch the {@link Branch}.
* @return {@code true} to exclude the branch from the view.
*/
public boolean isExcluded(Branch branch) {
return false;
}
/**
* Tests if the supplied branch should be included. Inclusion wins over exclusion.
*
* @param branch the {@link Branch}.
* @return {@code true} to include the branch from the view.
*/
public abstract boolean isIncluded(Branch branch);
/**
* Checks if {@link #isExcluded(Branch)} has been overridden.
*
* @return {@code true} if we need to process the added list, {@code false} if we can safely assume
* {@link #isExcluded(Branch)} will always return {@code false}
*/
private boolean isExcludedOverridden() {
try {
Method isExcluded = getClass().getMethod("isExcluded", Branch.class);
return isExcluded.getDeclaringClass() != SimpleViewBranchFilter.class;
} catch (NoSuchMethodException e) {
return false;
}
}
}