package org.jenkinsci.plugins.github.util;
import com.cloudbees.jenkins.GitHubRepositoryName;
import com.cloudbees.jenkins.GitHubRepositoryNameContributor;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import hudson.model.AbstractProject;
import hudson.model.BuildableItem;
import hudson.model.Item;
import hudson.model.Job;
import hudson.triggers.Trigger;
import jenkins.model.ParameterizedJobMixIn;
import org.jenkinsci.plugins.github.extension.GHEventsSubscriber;
import javax.annotation.CheckForNull;
import java.util.Collection;
import static org.jenkinsci.plugins.github.extension.GHEventsSubscriber.isApplicableFor;
import static org.jenkinsci.plugins.github.util.FluentIterableWrapper.from;
/**
* Utility class which holds converters or predicates (matchers) to filter or convert job lists
*
* @author lanwen (Merkushev Kirill)
* @since 1.12.0
*/
public final class JobInfoHelpers {
private JobInfoHelpers() {
throw new IllegalAccessError("Do not instantiate it");
}
/**
* @param clazz trigger class to check in job
*
* @return predicate with true on apply if job contains trigger of given class
*/
public static <ITEM extends Item> Predicate<ITEM> withTrigger(final Class<? extends Trigger> clazz) {
return new Predicate<ITEM>() {
public boolean apply(Item item) {
return triggerFrom(item, clazz) != null;
}
};
}
/**
* Can be useful to ignore disabled jobs on reregistering hooks
*
* @return predicate with true on apply if item is buildable
*/
public static <ITEM extends Item> Predicate<ITEM> isBuildable() {
return new Predicate<ITEM>() {
public boolean apply(ITEM item) {
return item instanceof Job ? ((Job<?, ?>) item).isBuildable() : item instanceof BuildableItem;
}
};
}
/**
* @return function which helps to convert job to repo names associated with this job
*/
public static <ITEM extends Item> Function<ITEM, Collection<GitHubRepositoryName>> associatedNames() {
return new Function<ITEM, Collection<GitHubRepositoryName>>() {
public Collection<GitHubRepositoryName> apply(ITEM item) {
return GitHubRepositoryNameContributor.parseAssociatedNames(item);
}
};
}
/**
* If any of event subscriber interested in hook for item, then return true
* By default, push hook subscriber is interested in job with gh-push-trigger
*
* @return predicate with true if item alive and should have hook
*/
public static <ITEM extends Item> Predicate<ITEM> isAlive() {
return new Predicate<ITEM>() {
@Override
public boolean apply(ITEM item) {
return !from(GHEventsSubscriber.all()).filter(isApplicableFor(item)).toList().isEmpty();
}
};
}
/**
* @param job job to search trigger in
* @param tClass trigger with class which we want to receive from job
* @param <T> type of trigger
*
* @return Trigger instance with required class or null
* TODO use standard method in 1.621+
* @deprecated use {@link #triggerFrom(Item, Class)}
*/
@Deprecated
@CheckForNull
public static <T extends Trigger> T triggerFrom(Job<?, ?> job, Class<T> tClass) {
return triggerFrom((Item) job, tClass);
}
/**
* @param item job to search trigger in
* @param tClass trigger with class which we want to receive from job
* @param <T> type of trigger
*
* @return Trigger instance with required class or null
* @since 1.25.0
* TODO use standard method in 1.621+
*/
@CheckForNull
public static <T extends Trigger> T triggerFrom(Item item, Class<T> tClass) {
if (item instanceof ParameterizedJobMixIn.ParameterizedJob) {
ParameterizedJobMixIn.ParameterizedJob pJob = (ParameterizedJobMixIn.ParameterizedJob) item;
for (Trigger candidate : pJob.getTriggers().values()) {
if (tClass.isInstance(candidate)) {
return tClass.cast(candidate);
}
}
}
return null;
}
/**
* Converts any child class of {@link Job} (such as {@link AbstractProject}
* to {@link ParameterizedJobMixIn} to use it for workflow
*
* @param job to wrap
* @param <T> any child type of Job
*
* @return ParameterizedJobMixIn
* TODO use standard method in 1.621+
*/
public static <T extends Job> ParameterizedJobMixIn asParameterizedJobMixIn(final T job) {
return new ParameterizedJobMixIn() {
@Override
protected Job asJob() {
return job;
}
};
}
}