com.offbytwo.jenkins.model.JobWithDetails Maven / Gradle / Ivy
/*
* Copyright (c) 2013 Rising Oak LLC.
*
* Distributed under the MIT license: http://opensource.org/licenses/MIT
*/
package com.offbytwo.jenkins.model;
import static com.google.common.collect.Lists.transform;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpResponseException;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.offbytwo.jenkins.client.util.EncodingUtils;
import com.offbytwo.jenkins.helper.Range;
public class JobWithDetails extends Job {
String displayName;
boolean buildable;
List builds;
Build firstBuild;
Build lastBuild;
Build lastCompletedBuild;
Build lastFailedBuild;
Build lastStableBuild;
Build lastSuccessfulBuild;
Build lastUnstableBuild;
Build lastUnsuccessfulBuild;
int nextBuildNumber;
boolean inQueue;
QueueItem queueItem;
List downstreamProjects;
List upstreamProjects;
public String getDisplayName() {
return displayName;
}
public boolean isBuildable() {
return buildable;
}
public boolean isInQueue() {
return inQueue;
}
/**
* This method will give you back the builds of a particular job.
* Note: Jenkins limits the number of results to a maximum of 100 builds
* which you will get back.. In case you have more than 100 build you
* won't get back all builds via this method. In such cases you need to use
* {@link #getAllBuilds()}.
*
* @return the list of {@link Build}. In case of no builds have been
* executed yet return {@link Collections#emptyList()}.
*/
public List getBuilds() {
if (builds == null) {
return Collections.emptyList();
}
else {
return transform(builds, new Function() {
@Override
public Build apply(Build from) {
return buildWithClient(from);
}
});
}
}
/**
* This method will give you back all builds which exists independent of the
* number. You should be aware that this can be much in some cases if you
* have more than 100 builds which is by default limited by Jenkins
* {@link #getBuilds()}. This method limits it to particular information
* which can be later used to get supplemental information about a
* particular build {@link Build#details()} to reduce the amount of data
* which needed to be transfered.
*
* @return the list of {@link Build}. In case of no builds have been
* executed yet return {@link Collections#emptyList()}.
* @throws IOException
* In case of failure.
* @see Jenkins
* Issue
*/
public List getAllBuilds() throws IOException {
String path = "/";
try {
List builds = client.get(path + "job/" + EncodingUtils.encode(this.getName())
+ "?tree=allBuilds[number[*],url[*],queueId[*]]", AllBuilds.class).getAllBuilds();
if (builds == null) {
return Collections.emptyList();
} else {
return transform(builds, new Function() {
@Override
public Build apply(Build from) {
return buildWithClient(from);
}
});
}
} catch (HttpResponseException e) {
// TODO: Thinks about a better handline if the job does not exist?
if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
// TODO: Check this if this is necessary or a good idea?
return null;
}
throw e;
}
}
/**
*
*
* - {M,N}: From the M-th element (inclusive) to the N-th element
* (exclusive).
* - {M,}: From the M-th element (inclusive) to the end.
* - {,N}: From the first element (inclusive) to the N-th element
* (exclusive). The same as {0,N}.
* - {N}: Just retrieve the N-th element. The same as {N,N+1}.
*
*
* Note: At the moment there seemed to be no option to get the number of
* existing builds for a job. The only option is to get all builds via
* {@link #getAllBuilds()}.
*
* @param range {@link Range}
* @return the list of {@link Build}. In case of no builds have been
* executed yet return {@link Collections#emptyList()}.
* @throws IOException in case of an error.
*/
public List getAllBuilds(Range range) throws IOException {
String path = "/" + "job/" + EncodingUtils.encode(this.getName())
+ "?tree=allBuilds[number[*],url[*],queueId[*]]";
try {
List builds = client.get(path + range.getRangeString(), AllBuilds.class).getAllBuilds();
if (builds == null) {
return Collections.emptyList();
} else {
return transform(builds, new Function() {
@Override
public Build apply(Build from) {
return buildWithClient(from);
}
});
}
} catch (HttpResponseException e) {
// TODO: Thinks about a better handline if the job does not exist?
if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
// TODO: Check this if this is necessary or a good idea?
return null;
}
throw e;
}
}
private Build buildWithClient(Build from) {
Build ret = from;
if (from != null) {
ret = new Build(from);
ret.setClient(client);
}
return ret;
}
/**
* @return the first build which has been executed or
* {@link Build#BUILD_HAS_NEVER_RAN} is this has never
* been executed.
*/
public Build getFirstBuild() {
if (firstBuild == null) {
return Build.BUILD_HAS_NEVER_RAN;
} else {
return buildWithClient(firstBuild);
}
}
public Build getLastBuild() {
if (lastBuild == null) {
return Build.BUILD_HAS_NEVER_RAN;
} else {
return buildWithClient(lastBuild);
}
}
public Build getLastCompletedBuild() {
if (lastCompletedBuild == null) {
return Build.BUILD_HAS_NEVER_RAN;
} else {
return buildWithClient(lastCompletedBuild);
}
}
public Build getLastFailedBuild() {
if (lastFailedBuild == null) {
return Build.BUILD_HAS_NEVER_RAN;
} else {
return buildWithClient(lastFailedBuild);
}
}
public Build getLastStableBuild() {
if (lastStableBuild == null) {
return Build.BUILD_HAS_NEVER_RAN;
} else {
return buildWithClient(lastStableBuild);
}
}
public Build getLastSuccessfulBuild() {
if (lastSuccessfulBuild == null) {
return Build.BUILD_HAS_NEVER_RAN;
} else {
return buildWithClient(lastSuccessfulBuild);
}
}
public Build getLastUnstableBuild() {
if (lastUnstableBuild == null) {
return Build.BUILD_HAS_NEVER_RAN;
} else {
return buildWithClient(lastUnstableBuild);
}
}
public Build getLastUnsuccessfulBuild() {
if (lastUnsuccessfulBuild == null) {
return Build.BUILD_HAS_NEVER_RAN;
} else {
return buildWithClient(lastUnsuccessfulBuild);
}
}
public int getNextBuildNumber() {
return nextBuildNumber;
}
/**
* @return the list of downstream projects.
* If no downstream projects exist just return
* an {@link Collections#emptyList()}
*/
public List getDownstreamProjects() {
if (downstreamProjects == null) {
return Collections.emptyList();
} else {
return transform(downstreamProjects, new JobWithClient());
}
}
/**
* @return the list of upstream projects.
* If no upstream projects exist just return
* an {@link Collections#emptyList()}
*/
public List getUpstreamProjects() {
if (upstreamProjects == null) {
return Collections.emptyList();
} else {
return transform(upstreamProjects, new JobWithClient());
}
}
public QueueItem getQueueItem() {
return this.queueItem;
}
public Build getBuildByNumber(final int buildNumber) {
Predicate isMatchingBuildNumber = new Predicate() {
@Override
public boolean apply(Build input) {
return input.getNumber() == buildNumber;
}
};
Optional optionalBuild = Iterables.tryFind(builds, isMatchingBuildNumber);
//TODO: Check if we could use Build#NO...instead of Null?
return optionalBuild.orNull() == null ? null : buildWithClient(optionalBuild.orNull());
}
private class JobWithClient implements Function {
@Override
public Job apply(Job job) {
job.setClient(client);
return job;
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + (buildable ? 1231 : 1237);
result = prime * result + ((builds == null) ? 0 : builds.hashCode());
result = prime * result + ((displayName == null) ? 0 : displayName.hashCode());
result = prime * result + ((downstreamProjects == null) ? 0 : downstreamProjects.hashCode());
result = prime * result + ((firstBuild == null) ? 0 : firstBuild.hashCode());
result = prime * result + (inQueue ? 1231 : 1237);
result = prime * result + ((lastBuild == null) ? 0 : lastBuild.hashCode());
result = prime * result + ((lastCompletedBuild == null) ? 0 : lastCompletedBuild.hashCode());
result = prime * result + ((lastFailedBuild == null) ? 0 : lastFailedBuild.hashCode());
result = prime * result + ((lastStableBuild == null) ? 0 : lastStableBuild.hashCode());
result = prime * result + ((lastSuccessfulBuild == null) ? 0 : lastSuccessfulBuild.hashCode());
result = prime * result + ((lastUnstableBuild == null) ? 0 : lastUnstableBuild.hashCode());
result = prime * result + ((lastUnsuccessfulBuild == null) ? 0 : lastUnsuccessfulBuild.hashCode());
result = prime * result + nextBuildNumber;
result = prime * result + ((queueItem == null) ? 0 : queueItem.hashCode());
result = prime * result + ((upstreamProjects == null) ? 0 : upstreamProjects.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
JobWithDetails other = (JobWithDetails) obj;
if (buildable != other.buildable)
return false;
if (builds == null) {
if (other.builds != null)
return false;
} else if (!builds.equals(other.builds))
return false;
if (displayName == null) {
if (other.displayName != null)
return false;
} else if (!displayName.equals(other.displayName))
return false;
if (downstreamProjects == null) {
if (other.downstreamProjects != null)
return false;
} else if (!downstreamProjects.equals(other.downstreamProjects))
return false;
if (firstBuild == null) {
if (other.firstBuild != null)
return false;
} else if (!firstBuild.equals(other.firstBuild))
return false;
if (inQueue != other.inQueue)
return false;
if (lastBuild == null) {
if (other.lastBuild != null)
return false;
} else if (!lastBuild.equals(other.lastBuild))
return false;
if (lastCompletedBuild == null) {
if (other.lastCompletedBuild != null)
return false;
} else if (!lastCompletedBuild.equals(other.lastCompletedBuild))
return false;
if (lastFailedBuild == null) {
if (other.lastFailedBuild != null)
return false;
} else if (!lastFailedBuild.equals(other.lastFailedBuild))
return false;
if (lastStableBuild == null) {
if (other.lastStableBuild != null)
return false;
} else if (!lastStableBuild.equals(other.lastStableBuild))
return false;
if (lastSuccessfulBuild == null) {
if (other.lastSuccessfulBuild != null)
return false;
} else if (!lastSuccessfulBuild.equals(other.lastSuccessfulBuild))
return false;
if (lastUnstableBuild == null) {
if (other.lastUnstableBuild != null)
return false;
} else if (!lastUnstableBuild.equals(other.lastUnstableBuild))
return false;
if (lastUnsuccessfulBuild == null) {
if (other.lastUnsuccessfulBuild != null)
return false;
} else if (!lastUnsuccessfulBuild.equals(other.lastUnsuccessfulBuild))
return false;
if (nextBuildNumber != other.nextBuildNumber)
return false;
if (queueItem == null) {
if (other.queueItem != null)
return false;
} else if (!queueItem.equals(other.queueItem))
return false;
if (upstreamProjects == null) {
if (other.upstreamProjects != null)
return false;
} else if (!upstreamProjects.equals(other.upstreamProjects))
return false;
return true;
}
}