// Copyright (C) 2013 GerritForge www.gerritforge.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package mobi.jenkinsci.ci.model;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import mobi.jenkinsci.ci.addon.Utils;
import mobi.jenkinsci.ci.client.JenkinsClient;
import mobi.jenkinsci.model.HeaderNode;
import mobi.jenkinsci.model.ItemNode;
import mobi.jenkinsci.model.Layout;
import mobi.jenkinsci.plugin.Plugin;
import org.apache.log4j.Logger;
import com.google.common.base.Strings;
public class Job extends JobName {
private static final Logger LOG = Logger.getLogger(Job.class);
public boolean buildable;
public String nextBuildNumber;
public List<HealthReport> healthReport;
public Build lastSuccessfulBuild;
public Build lastCompletedBuild;
public Build lastBuild;
public Build lastStableBuild;
public Build lastUnstBuildBuild;
public List<MavenMobule> modules;
public List<Build> builds;
transient Plugin plugin;
public enum Command {
BUILD, STOP;
@Override
public String toString() {
return super.toString().toLowerCase();
};
};
public enum Detail {
CHANGES, FAILEDTESTS, MODULES, ARTIFACTS, BUILDS, INSTALL;
@Override
public String toString() {
return super.toString().toLowerCase();
};
}
@Override
public void init(final JenkinsClient client) {
super.init(client);
init(client, lastBuild);
init(client, lastCompletedBuild);
init(client, lastStableBuild);
init(client, lastSuccessfulBuild);
init(client, lastUnstBuildBuild);
for (final Build build : builds) {
init(client, build);
}
lazyLoad = true;
}
private void init(final JenkinsClient client, final Build build) {
if (build == null) {
return;
}
build.setJob(this);
build.init(client);
}
public List<HealthReport> getHealthReport() {
return healthReport;
}
public Build getLastCompletedBuild() {
return lastCompletedBuild;
}
public List<MavenMobule> getModules() {
return modules;
}
public String getNextBuildNumber() {
return nextBuildNumber;
}
@Override
public ItemNode toAbstractNode(final String urlPrefix) throws IOException {
final ItemNode result = new ItemNode(Layout.LIST);
result.setTitle(name);
result.setViewTitle(name);
result.setPath(getNodePathFromFullJenkinsURL(urlPrefix, url));
result.setVersion(ItemNode.API_VERSION);
Utils.setIconByLabel(result, color);
ItemNode currentNode = new ItemNode();
Utils.setIconByLabel(currentNode, color);
currentNode.setPath("image");
currentNode.setAction("?web=" + urlEncode(url));
if (lastCompletedBuild != null) {
currentNode.setTitle("Build #" + lastCompletedBuild.number);
} else {
currentNode.setTitle("Never built");
}
result.addNode(currentNode);
if (lastCompletedBuild != null) {
currentNode = new ItemNode();
if (isBuilding()) {
currentNode.setTitle("Build in progress from "
+ lastCompletedBuild.builtSinceHumanReadable());
} else {
currentNode.setTitle("Last build was "
+ lastCompletedBuild.builtSinceHumanReadable() + " and took "
+ lastCompletedBuild.durationeHumanReadable());
}
result.addNode(currentNode);
}
if (!isBuilding()) {
if (getHealthReport() != null && getHealthReport().size() > 0) {
currentNode = new ItemNode();
currentNode.setTitle(getHealthReport().get(0).description);
currentNode.setIcon(result.getPath() + "?image=icons/"
+ getHealthReport().get(0).getIconUrl());
result.addNode(currentNode);
if (getHealthReport().size() > 1) {
currentNode = new ItemNode();
currentNode.setIcon(result.getPath() + "?image=icons/"
+ getHealthReport().get(1).getIconUrl());
currentNode.setTitle(getHealthReport().get(1).description);
result.addNode(currentNode);
}
}
}
if (!isBuilding() && lastCompletedBuild != null) {
final ItemNode h1 = new HeaderNode("Last build");
result.addNode(h1);
result.addNodes(lastBuild.getBuildSubNodes(this, urlPrefix, lazyLoad));
}
result.addNode(getDetail(Detail.MODULES).toAbstractNode(urlPrefix));
result.addNode(new HeaderNode("History"));
result.addNode(getDetail(Detail.BUILDS).toAbstractNode(urlPrefix));
final ItemNode menuEntry = new ItemNode();
if (isBuilding()) {
menuEntry.setTitle("Stop build");
menuEntry.setAction("?cmd=" + Command.STOP);
result.addMenuNode(menuEntry);
} else {
menuEntry.setTitle("Start build");
menuEntry.setAction("?cmd=" + Command.BUILD);
result.addMenuNode(menuEntry);
}
result.setLeaf(true);
return result;
}
@Override
public boolean isBuilding() {
if (builds == null || builds.size() <= 0) {
return false;
}
return builds.get(0).building;
}
public JobDetail getDetail(final Detail detail) {
switch (detail) {
case ARTIFACTS:
return new JobArtifacts(this);
case CHANGES:
return new JobChanges(this);
case FAILEDTESTS:
return new JobFailedTests(this);
case MODULES:
return new JobModules(this);
case BUILDS:
return new JobBuilds(this);
case INSTALL:
return new JobInstallPackage(this);
default:
throw new IllegalArgumentException("Unsupported job detail " + detail);
}
}
public Build getBuild(final String buildName) {
try {
if (!Character.isDigit(buildName.charAt(0))) {
final Field buildField = Job.class.getField(buildName);
final Build build = (Build) buildField.get(this);
return build;
} else {
final int buildNumber = Integer.parseInt(buildName);
for (final Build build : builds) {
if (build.number == buildNumber) {
return build;
}
}
}
} catch (final Exception e) {
LOG.error("Cannot find build " + buildName + " in job " + name);
return null;
}
return null;
}
@Override
public JenkinsItem getSubItem(final Plugin plugin, final String subItemPath)
throws IOException {
final JenkinsItem subItem = super.getSubItem(plugin, subItemPath);
if (Strings.isNullOrEmpty(subItemPath)) {
return subItem;
}
final JobDetail jobDetail =
getDetail(Job.Detail.valueOf(getHeadPath(subItemPath).toUpperCase()));
return jobDetail.getSubItem(plugin, getTailPath(subItemPath));
}
}