blob: b4ddf55b49ceab6d8baa2fc4c08fca2ee43d35b1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2014 Markus Knittig and others.
* 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
*
* Contributors:
* Markus Knittig - initial API and implementation
* Tasktop Technologies - improvements
* Eike Stepper - improvements for bug 323759
* Benjamin Muskalla - 324039: [build] tests fail with NPE
*******************************************************************************/
package org.eclipse.mylyn.internal.hudson.core;
import java.io.Reader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.mylyn.builds.core.BuildState;
import org.eclipse.mylyn.builds.core.BuildStatus;
import org.eclipse.mylyn.builds.core.EditType;
import org.eclipse.mylyn.builds.core.IArtifact;
import org.eclipse.mylyn.builds.core.IBooleanParameterDefinition;
import org.eclipse.mylyn.builds.core.IBuild;
import org.eclipse.mylyn.builds.core.IBuildCause;
import org.eclipse.mylyn.builds.core.IBuildFactory;
import org.eclipse.mylyn.builds.core.IBuildParameterDefinition;
import org.eclipse.mylyn.builds.core.IBuildPlan;
import org.eclipse.mylyn.builds.core.IBuildReference;
import org.eclipse.mylyn.builds.core.IChange;
import org.eclipse.mylyn.builds.core.IChangeArtifact;
import org.eclipse.mylyn.builds.core.IChangeSet;
import org.eclipse.mylyn.builds.core.IChoiceParameterDefinition;
import org.eclipse.mylyn.builds.core.IFileParameterDefinition;
import org.eclipse.mylyn.builds.core.IHealthReport;
import org.eclipse.mylyn.builds.core.IParameterDefinition;
import org.eclipse.mylyn.builds.core.IPasswordParameterDefinition;
import org.eclipse.mylyn.builds.core.IStringParameterDefinition;
import org.eclipse.mylyn.builds.core.ITestCase;
import org.eclipse.mylyn.builds.core.ITestResult;
import org.eclipse.mylyn.builds.core.ITestSuite;
import org.eclipse.mylyn.builds.core.IUser;
import org.eclipse.mylyn.builds.core.TestCaseResult;
import org.eclipse.mylyn.builds.core.spi.BuildPlanRequest;
import org.eclipse.mylyn.builds.core.spi.BuildServerBehaviour;
import org.eclipse.mylyn.builds.core.spi.BuildServerConfiguration;
import org.eclipse.mylyn.builds.core.spi.GetBuildsRequest;
import org.eclipse.mylyn.builds.core.spi.GetBuildsRequest.Kind;
import org.eclipse.mylyn.builds.core.spi.GetBuildsRequest.Scope;
import org.eclipse.mylyn.builds.core.spi.RunBuildRequest;
import org.eclipse.mylyn.builds.internal.core.BuildFactory;
import org.eclipse.mylyn.commons.core.operations.IOperationMonitor;
import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation;
import org.eclipse.mylyn.internal.hudson.core.client.HudsonConfigurationCache;
import org.eclipse.mylyn.internal.hudson.core.client.HudsonException;
import org.eclipse.mylyn.internal.hudson.core.client.HudsonResourceNotFoundException;
import org.eclipse.mylyn.internal.hudson.core.client.HudsonServerInfo;
import org.eclipse.mylyn.internal.hudson.core.client.HudsonTestReport;
import org.eclipse.mylyn.internal.hudson.core.client.RestfulHudsonClient;
import org.eclipse.mylyn.internal.hudson.core.client.RestfulHudsonClient.BuildId;
import org.eclipse.mylyn.internal.hudson.model.HudsonModelAbstractBuild;
import org.eclipse.mylyn.internal.hudson.model.HudsonModelBallColor;
import org.eclipse.mylyn.internal.hudson.model.HudsonModelBuild;
import org.eclipse.mylyn.internal.hudson.model.HudsonModelHealthReport;
import org.eclipse.mylyn.internal.hudson.model.HudsonModelJob;
import org.eclipse.mylyn.internal.hudson.model.HudsonModelRun;
import org.eclipse.mylyn.internal.hudson.model.HudsonModelRunArtifact;
import org.eclipse.mylyn.internal.hudson.model.HudsonModelUser;
import org.eclipse.mylyn.internal.hudson.model.HudsonScmChangeLogSet;
import org.eclipse.mylyn.internal.hudson.model.HudsonTasksJunitCaseResult;
import org.eclipse.mylyn.internal.hudson.model.HudsonTasksJunitSuiteResult;
import org.eclipse.mylyn.internal.hudson.model.HudsonTasksJunitTestResult;
import org.eclipse.mylyn.internal.hudson.model.HudsonTasksTestAggregatedTestResultAction;
import org.eclipse.mylyn.internal.hudson.model.HudsonTasksTestAggregatedTestResultActionChildReport;
import org.eclipse.osgi.util.NLS;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* @author Markus Knittig
* @author Steffen Pingel
* @author Eike Stepper
*/
public class HudsonServerBehaviour extends BuildServerBehaviour {
private final RestfulHudsonClient client;
private final RepositoryLocation location;
public HudsonServerBehaviour(RepositoryLocation location, HudsonConfigurationCache cache) {
this.location = location;
this.client = new RestfulHudsonClient(location, cache);
}
public RepositoryLocation getLocation() {
return location;
}
protected HudsonModelBuild createBuildParameter(IBuild build) {
HudsonModelBuild hudsonBuild = new HudsonModelBuild();
hudsonBuild.setNumber(build.getBuildNumber());
return hudsonBuild;
}
protected HudsonModelJob createJobParameter(IBuildPlan plan) {
HudsonModelJob job = new HudsonModelJob();
job.setName(plan.getId());
return job;
}
@Override
public List<IBuild> getBuilds(GetBuildsRequest request, IOperationMonitor monitor) throws CoreException {
try {
if (request.getKind() == Kind.LAST || request.getKind() == Kind.SELECTED) {
HudsonModelJob job = createJobParameter(request.getPlan());
// FIXME this is way too complicated and brittle
HudsonModelBuild requestBuild;
if (request.getKind() == Kind.LAST) {
requestBuild = BuildId.LAST.getBuild();
} else {
requestBuild = new HudsonModelBuild();
requestBuild.setNumber(Integer.parseInt(request.getIds().iterator().next()));
}
HudsonModelBuild hudsonBuild = client.getBuild(job, requestBuild, monitor);
IBuild build = parseBuild(job, hudsonBuild);
try {
HudsonTestReport hudsonTestReport = client.getTestReport(job, hudsonBuild, monitor);
ITestResult testResult;
if (hudsonTestReport.getJunitResult() != null) {
testResult = parseTestResult(hudsonTestReport.getJunitResult());
} else {
testResult = parseTestResult(hudsonTestReport.getAggregatedResult());
}
testResult.setBuild(build); // FIXME remove, should not be necessary
build.setTestResult(testResult);
} catch (HudsonResourceNotFoundException e) {
// ignore
}
return Collections.singletonList(build);
}
if (request.getKind() == Kind.ALL && request.getScope() == Scope.HISTORY) {
HudsonModelJob job = createJobParameter(request.getPlan());
List<HudsonModelRun> hudsonBuilds = client.getBuilds(job, monitor);
ArrayList<IBuild> builds = new ArrayList<IBuild>(hudsonBuilds.size());
for (HudsonModelRun hudsonBuild : hudsonBuilds) {
builds.add(parseBuild(job, hudsonBuild));
}
return builds;
}
} catch (HudsonResourceNotFoundException e) {
return null;
} catch (HudsonException e) {
throw HudsonCorePlugin.toCoreException(e);
}
// unsupported kind
throw new UnsupportedOperationException("Unsupported request kind and scope combination: kind=" //$NON-NLS-1$
+ request.getKind() + ",scope=" + request.getScope()); //$NON-NLS-1$
}
@Override
public BuildServerConfiguration getConfiguration() {
Map<String, String> jobNameById = client.getConfiguration().jobNameById;
List<IBuildPlan> plans = new ArrayList<IBuildPlan>(jobNameById.size());
for (Entry<String, String> entry : jobNameById.entrySet()) {
IBuildPlan plan = createBuildPlan();
plan.setId(entry.getKey());
plan.setName(entry.getValue());
plans.add(plan);
}
return new BuildServerConfiguration(plans);
}
@Override
public Reader getConsole(IBuild build, IOperationMonitor monitor) throws CoreException {
try {
HudsonModelJob job = createJobParameter(build.getPlan());
HudsonModelBuild hudsonBuild = createBuildParameter(build);
return client.getConsole(job, hudsonBuild, monitor);
} catch (HudsonException e) {
throw HudsonCorePlugin.toCoreException(e);
}
}
/**
* Looks for a child named <code>name</code> that has a text value or a nested <code>value</code> tag.
*/
private String getDefaultValue(Element element) throws HudsonException {
// parsed from job config
String value = getElementContent(element, "defaultValue", false); //$NON-NLS-1$
if (value != null) {
return value;
}
// parsed from job actions
NodeList nodes = element.getElementsByTagName("defaultParameterValue"); //$NON-NLS-1$
if (nodes.getLength() == 1) {
NodeList children = nodes.item(0).getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Element child = (Element) children.item(i);
String tagName = child.getTagName();
if ("value".equals(tagName)) { //$NON-NLS-1$
return child.getTextContent();
}
}
}
return null;
}
private String getElementContent(Element element, String name, boolean required) throws HudsonException {
NodeList elements = element.getElementsByTagName(name);
if (elements.getLength() == 0) {
if (required) {
throw new HudsonException("No " + name + " element"); //$NON-NLS-1$ //$NON-NLS-2$
} else {
return null;
}
}
if (elements.getLength() > 1) {
throw new HudsonException("More than one " + name + " element"); //$NON-NLS-1$ //$NON-NLS-2$
}
return ((Element) elements.item(0)).getTextContent();
}
@Override
public List<IBuildPlan> getPlans(BuildPlanRequest request, IOperationMonitor monitor) throws CoreException {
try {
List<HudsonModelJob> jobs = client.getJobs(request.getPlanIds(), monitor);
List<IBuildPlan> plans = new ArrayList<IBuildPlan>(jobs.size());
for (HudsonModelJob job : jobs) {
IBuildPlan plan = parseJob(job);
plans.add(plan);
// parsed from job now, see bug 328204
// if (client.getInfo(monitor).getType() == Type.JENKINS) {
// try {
// Document document = client.getJobConfig(job, monitor);
// parseParametersFromJobConfig(document, plan.getParameterDefinitions());
// } catch (HudsonException e) {
// // ignore, might not have permission to read config
// } catch (ParserConfigurationException e) {
// // ignore
// } catch (SAXException e) {
// // ignore
// } catch (IOException e) {
// // ignore
// }
// }
}
return plans;
} catch (HudsonException e) {
throw HudsonCorePlugin.toCoreException(e);
}
}
private IArtifact parseArtifact(HudsonModelRunArtifact hudsonArtifact) {
IArtifact artifact = createArtifact();
artifact.setName(hudsonArtifact.getFileName());
artifact.setRelativePath(hudsonArtifact.getRelativePath());
return artifact;
}
private IBuild parseBuild(HudsonModelJob hudsonJob, HudsonModelRun hudsonBuild) {
IBuild build = createBuild();
build.setId(hudsonBuild.getId());
build.setName(hudsonBuild.getFullDisplayName());
build.setBuildNumber(hudsonBuild.getNumber());
build.setLabel(hudsonBuild.getNumber() + ""); //$NON-NLS-1$
build.setDuration(hudsonBuild.getDuration());
build.setTimestamp(hudsonBuild.getTimestamp());
build.setUrl(hudsonBuild.getUrl());
build.setState(hudsonBuild.isBuilding() ? BuildState.RUNNING : BuildState.STOPPED);
build.setStatus(parseResult((Node) hudsonBuild.getResult()));
build.setSummary(parseActions(build.getCause(), hudsonBuild.getAction()));
if (hudsonBuild instanceof HudsonModelAbstractBuild) {
for (HudsonModelUser hudsonUser : ((HudsonModelAbstractBuild) hudsonBuild).getCulprit()) {
build.getCulprits().add(parseUser(hudsonUser));
}
}
for (HudsonModelRunArtifact hudsonArtifact : hudsonBuild.getArtifact()) {
IArtifact artifact = parseArtifact(hudsonArtifact);
try {
artifact.setUrl(client.getArtifactUrl(hudsonJob, hudsonBuild, hudsonArtifact));
} catch (HudsonException e) {
// ignore
}
build.getArtifacts().add(artifact);
}
if (hudsonBuild instanceof HudsonModelAbstractBuild) {
build.setChangeSet(parseChangeSet(((HudsonModelAbstractBuild) hudsonBuild).getChangeSet()));
}
return build;
}
private String parseActions(List<IBuildCause> causes, List<Object> actions) {
int failCount = 0;
int skipCount = 0;
int totalCount = 0;
Set<String> causeDescriptions = new LinkedHashSet<String>();
for (Object action : actions) {
Node node = (Node) action;
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Element child = (Element) children.item(i);
String tagName = child.getTagName();
try {
if ("cause".equals(tagName)) { //$NON-NLS-1$
IBuildCause cause = parseCause(child);
causes.add(cause);
if (cause.getDescription() != null) {
causeDescriptions.add(cause.getDescription());
}
} else if ("failCount".equals(tagName)) { //$NON-NLS-1$
failCount = Integer.parseInt(child.getTextContent());
} else if ("skipCount".equals(tagName)) { //$NON-NLS-1$
skipCount = Integer.parseInt(child.getTextContent());
} else if ("totalCount".equals(tagName)) { //$NON-NLS-1$
totalCount = Integer.parseInt(child.getTextContent());
}
} catch (NumberFormatException e) {
// ignore
}
}
}
StringBuilder sb = new StringBuilder();
for (String string : causeDescriptions) {
append(sb, string);
}
if (failCount != 0 || totalCount != 0 || skipCount != 0) {
append(sb,
NLS.bind("{0} tests: {1} failed, {2} skipped", new Object[] { totalCount, failCount, skipCount }));
}
if (sb.length() > 0) {
return sb.toString();
}
return null;
}
private void append(StringBuilder sb, String text) {
if (text != null) {
if (sb.length() > 0) {
sb.append(", "); //$NON-NLS-1$
}
sb.append(text);
}
}
private IBuildCause parseCause(Node node) {
IBuildCause cause = createBuildCause();
String userName = null;
String upstreamBuild = null;
String upstreamProject = null;
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Element child = (Element) children.item(i);
String tagName = child.getTagName();
if ("shortDescription".equals(tagName)) { //$NON-NLS-1$
cause.setDescription(child.getTextContent());
} else if ("userName".equals(tagName)) { //$NON-NLS-1$
userName = child.getTextContent();
} else if ("upstreamProject".equals(tagName)) { //$NON-NLS-1$
upstreamProject = child.getTextContent();
} else if ("upstreamBuild".equals(tagName)) { //$NON-NLS-1$
upstreamBuild = child.getTextContent();
}
}
if (userName != null) {
IUser user = createUser();
user.setId(userName);
cause.setUser(user);
}
if (upstreamProject != null && upstreamBuild != null) {
IBuildReference reference = createBuildReference();
reference.setPlan(upstreamProject);
reference.setBuild(upstreamBuild);
cause.setBuild(reference);
}
return cause;
}
private IChange parseChange(Node node) {
// addedPath* [M]
// author [C, G, M]
// comment [G]: full commit message
// date [C:2010-09-02, G:2010-08-26 17:43:17 -0700, M:1283761613.0-7200, S:2010-07-28T09:11:55.720801Z]
// file*: dead, editType, fullName, name, prerevision?, revision [C]
// id [G] (SHA1)
// merge [M] (Boolean)
// modifiedPath* [M]
// msg [C, G, M, S]: shortened commit message
// node [M] (SHA1?)
// path*: editType, file [G, S]
// rev [M]
// revision [S]
// time [C:05:15]
// user [C, S]
IChange change = createChange();
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Element child = (Element) children.item(i);
String tagName = child.getTagName();
if ("addedPath".equals(tagName)) { //$NON-NLS-1$
IChangeArtifact artifact = createChangeArtifact();
artifact.setFile(child.getTextContent());
artifact.setEditType(EditType.ADD);
change.getArtifacts().add(artifact);
} else if ("author".equals(tagName)) { //$NON-NLS-1$
change.setAuthor(parseUser(child));
} else if ("comment".equals(tagName)) { //$NON-NLS-1$
change.setMessage(child.getTextContent());
} else if ("date".equals(tagName)) { //$NON-NLS-1$
change.setDate(parseDate(child));
} else if ("file".equals(tagName)) { //$NON-NLS-1$
change.getArtifacts().add(parseArtifact(child));
} else if ("id".equals(tagName)) { //$NON-NLS-1$
change.setRevision(child.getTextContent());
} else if ("modifiedPath".equals(tagName)) { //$NON-NLS-1$
IChangeArtifact artifact = createChangeArtifact();
artifact.setFile(child.getTextContent());
artifact.setEditType(EditType.EDIT);
change.getArtifacts().add(artifact);
} else if ("msg".equals(tagName)) { //$NON-NLS-1$
// check if full comment was already retrieved from "comment" tag
if (change.getMessage() == null) {
change.setMessage(child.getTextContent());
}
} else if ("node".equals(tagName)) { //$NON-NLS-1$
change.setRevision(child.getTextContent());
} else if ("rev".equals(tagName)) { //$NON-NLS-1$
change.setRevision(child.getTextContent());
} else if ("path".equals(tagName)) { //$NON-NLS-1$
change.getArtifacts().add(parseArtifact(child));
} else if ("revision".equals(tagName)) { //$NON-NLS-1$
change.setRevision(child.getTextContent());
} else if ("user".equals(tagName) && change.getAuthor() == null) { //$NON-NLS-1$
IUser user = createUser();
user.setId(child.getTextContent());
change.setAuthor(user);
}
}
return change;
}
private IUser parseUser(Node node) {
if (node != null) {
IUser user = createUser();
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Element child = (Element) children.item(i);
String tagName = child.getTagName();
if ("absoluteUrl".equals(tagName)) { //$NON-NLS-1$
user.setUrl(child.getTextContent());
} else if ("fullName".equals(tagName)) { //$NON-NLS-1$
user.setName(child.getTextContent());
user.setId(child.getTextContent());
}
}
return user;
}
return null;
}
private IChangeArtifact parseArtifact(Node node) {
IChangeArtifact artifact = createChangeArtifact();
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Element child = (Element) children.item(i);
String tagName = child.getTagName();
if ("editType".equals(tagName)) { //$NON-NLS-1$
artifact.setEditType(parseEditType(child));
} else if ("file".equals(tagName)) { //$NON-NLS-1$
artifact.setFile(child.getTextContent());
} else if ("fullName".equals(tagName)) { //$NON-NLS-1$
artifact.setFile(child.getTextContent());
} else if ("prevrevision".equals(tagName)) { //$NON-NLS-1$
artifact.setPrevRevision(child.getTextContent());
} else if ("revision".equals(tagName)) { //$NON-NLS-1$
artifact.setRevision(child.getTextContent());
}
}
return artifact;
}
private EditType parseEditType(Element node) {
if (node != null) {
String text = node.getTextContent();
if ("add".equals(text)) { //$NON-NLS-1$
return EditType.ADD;
} else if ("edit".equals(text)) { //$NON-NLS-1$
return EditType.EDIT;
}
if ("delete".equals(text)) { //$NON-NLS-1$
return EditType.DELETE;
}
}
return null;
}
private long parseDate(Element node) {
if (node != null) {
String[] patterns = { //
"yyyy-MM-dd", // cvs //$NON-NLS-1$
"yyyy-MM-dd HH:mm:ss Z", // git //$NON-NLS-1$
//"1283761613.0-7200" // mercurial
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" // svn //$NON-NLS-1$
};
String text = node.getTextContent();
for (String pattern : patterns) {
try {
return new SimpleDateFormat(pattern).parse(text).getTime();
} catch (ParseException e) {
// fall through
}
}
}
return 0L;
}
private IChangeSet parseChangeSet(HudsonScmChangeLogSet hudsonChangeSet) {
IChangeSet changeSet = createChangeSet();
// none (git), cvs, hg, svn
changeSet.setKind(hudsonChangeSet.getKind());
// changeSet.getRevisions() [S]
for (Object item : hudsonChangeSet.getItem()) {
changeSet.getChanges().add(parseChange((Node) item));
}
return changeSet;
}
private long parseDuration(Node node) {
if (node != null) {
String text = node.getTextContent();
try {
return (long) (Double.parseDouble(text) * 1000);
} catch (NumberFormatException e) {
// fall through
}
}
return -1L;
}
private IHealthReport parseHealthReport(HudsonModelHealthReport hudsonHealthReport) {
IHealthReport healthReport = createHealthReport();
healthReport.setHealth(hudsonHealthReport.getScore());
healthReport.setDescription(hudsonHealthReport.getDescription());
return healthReport;
}
public IBuildPlan parseJob(HudsonModelJob job) {
IBuildPlan plan = createBuildPlan();
plan.setId(job.getName());
if (job.getDisplayName() != null && job.getDisplayName().length() > 0) {
plan.setName(job.getDisplayName());
} else {
plan.setName(job.getName());
}
plan.setDescription(job.getDescription());
plan.setUrl(job.getUrl());
updateStateAndStatus(job, plan);
updateHealth(job, plan);
if (job.getLastBuild() != null) {
IBuild build = createBuild();
build.setId(job.getLastBuild().getNumber() + ""); //$NON-NLS-1$
build.setLabel(job.getLastBuild().getNumber() + ""); //$NON-NLS-1$
build.setBuildNumber(job.getLastBuild().getNumber());
build.setUrl(job.getLastBuild().getUrl());
plan.setLastBuild(build);
}
parseJobActions(plan.getParameterDefinitions(), job.getAction());
// TODO parse up/down stream projects from HudsonModelAbstractProject
return plan;
}
private void parseJobActions(List<IParameterDefinition> parameterDefinitions, List<Object> actions) {
for (Object action : actions) {
Node node = (Node) action;
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Element child = (Element) children.item(i);
String tagName = child.getTagName();
if ("parameterDefinition".equals(tagName)) { //$NON-NLS-1$
try {
IParameterDefinition parameterDefinition = parseParameter(child);
parameterDefinitions.add(parameterDefinition);
} catch (HudsonException e) {
// unknown parameter type, ignore
}
}
}
}
}
private IParameterDefinition parseParameter(Element element) throws HudsonException {
String tagName = element.getTagName();
if ("hudson.model.ChoiceParameterDefinition".equals(tagName) || "ChoiceParameterDefinition".equals(getElementContent(element, "type", false))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
IChoiceParameterDefinition definition = BuildFactory.eINSTANCE.createChoiceParameterDefinition();
definition.setName(getElementContent(element, "name", true)); //$NON-NLS-1$
definition.setDescription(getElementContent(element, "description", false)); //$NON-NLS-1$
// parsed from job config
NodeList options = element.getElementsByTagName("string"); //$NON-NLS-1$
for (int i = 0; i < options.getLength(); i++) {
Element option = (Element) options.item(i);
definition.getOptions().add(option.getTextContent());
}
// parsed from job actions
options = element.getElementsByTagName("choice"); //$NON-NLS-1$
for (int i = 0; i < options.getLength(); i++) {
Element option = (Element) options.item(i);
definition.getOptions().add(option.getTextContent());
}
definition.setDefaultValue(getDefaultValue(element));
return definition;
}
if ("hudson.model.BooleanParameterDefinition".equals(tagName) || "BooleanParameterDefinition".equals(getElementContent(element, "type", false))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
IBooleanParameterDefinition definition = IBuildFactory.INSTANCE.createBooleanParameterDefinition();
definition.setName(getElementContent(element, "name", true)); //$NON-NLS-1$
definition.setDescription(getElementContent(element, "description", false)); //$NON-NLS-1$
String defaultValue = getDefaultValue(element);
if (defaultValue != null) {
definition.setDefaultValue(Boolean.parseBoolean(defaultValue));
}
return definition;
}
if ("hudson.model.StringParameterDefinition".equals(tagName) || "StringParameterDefinition".equals(getElementContent(element, "type", false))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
IStringParameterDefinition definition = IBuildFactory.INSTANCE.createStringParameterDefinition();
definition.setName(getElementContent(element, "name", true)); //$NON-NLS-1$
definition.setDescription(getElementContent(element, "description", false)); //$NON-NLS-1$
definition.setDefaultValue(getDefaultValue(element));
return definition;
}
if ("hudson.model.PasswordParameterDefinition".equals(tagName) || "PasswordParameterDefinition".equals(getElementContent(element, "type", false))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
IPasswordParameterDefinition definition = IBuildFactory.INSTANCE.createPasswordParameterDefinition();
definition.setName(getElementContent(element, "name", true)); //$NON-NLS-1$
definition.setDescription(getElementContent(element, "description", false)); //$NON-NLS-1$
definition.setDefaultValue(getDefaultValue(element));
return definition;
}
if ("hudson.model.RunParameterDefinition".equals(tagName) || "RunParameterDefinition".equals(getElementContent(element, "type", false))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
IBuildParameterDefinition definition = IBuildFactory.INSTANCE.createBuildParameterDefinition();
definition.setName(getElementContent(element, "name", true)); //$NON-NLS-1$
definition.setDescription(getElementContent(element, "description", false)); //$NON-NLS-1$
definition.setBuildPlanId(getElementContent(element, "projectName", false)); //$NON-NLS-1$
return definition;
}
if ("hudson.model.FileParameterDefinition".equals(tagName) || "FileParameterDefinition".equals(getElementContent(element, "type", false))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
IFileParameterDefinition definition = IBuildFactory.INSTANCE.createFileParameterDefinition();
definition.setName(getElementContent(element, "name", true)); //$NON-NLS-1$
definition.setDescription(getElementContent(element, "description", false)); //$NON-NLS-1$
return definition;
}
throw new HudsonException(NLS.bind("Unexpected parameter ''{0}'' with type ''{1}''", tagName,
getElementContent(element, "type", false))); //$NON-NLS-1$
}
// private void parseParametersFromJobConfig(Document document, List<IParameterDefinition> definitions)
// throws ParserConfigurationException, SAXException, IOException, HudsonException {
// NodeList containers = document.getElementsByTagName("parameterDefinitions"); //$NON-NLS-1$
// for (int i = 0; i < containers.getLength(); i++) {
// Element container = (Element) containers.item(i);
// NodeList elements = container.getChildNodes();
// for (int j = 0; j < elements.getLength(); j++) {
// Node node = elements.item(j);
// if (node instanceof Element) {
// Element element = (Element) elements.item(j);
// IParameterDefinition definition = parseParameter(element);
// definitions.add(definition);
// }
// }
// }
// }
private BuildStatus parseResult(Node node) {
if (node != null) {
String text = node.getTextContent();
if ("FAILURE".equals(text)) { //$NON-NLS-1$
return BuildStatus.FAILED;
}
try {
return BuildStatus.valueOf(text);
} catch (IllegalArgumentException e) {
// fall through
}
}
return null;
}
private ITestResult parseTestResult(HudsonTasksJunitTestResult hudsonTestReport) {
ITestResult testResult = createTestResult();
testResult.setFailCount(hudsonTestReport.getFailCount());
testResult.setIgnoredCount(hudsonTestReport.getSkipCount());
testResult.setPassCount(hudsonTestReport.getPassCount());
testResult.setDuration(parseDuration((Node) hudsonTestReport.getDuration()));
for (HudsonTasksJunitSuiteResult hudsonSuite : hudsonTestReport.getSuite()) {
ITestSuite testSuite = createTestSuite();
testSuite.setLabel(hudsonSuite.getName());
testSuite.setDuration(parseDuration((Node) hudsonSuite.getDuration()));
testSuite.setOutput(hudsonSuite.getStdout());
testSuite.setErrorOutput(hudsonSuite.getStderr());
for (HudsonTasksJunitCaseResult hudsonCase : hudsonSuite.getCase()) {
ITestCase testCase = createTestCase();
testCase.setLabel(hudsonCase.getName());
testCase.setClassName(hudsonCase.getClassName());
testCase.setDuration(parseDuration((Node) hudsonCase.getDuration()));
testCase.setSkipped(hudsonCase.isSkipped());
// XXX seems redundant with testResult output
//testCase.setOutput(hudsonCase.getStdout());
//testCase.setErrorOutput(hudsonCase.getStderr());
testCase.setMessage(hudsonCase.getErrorDetails());
testCase.setStackTrace(hudsonCase.getErrorStackTrace());
switch (hudsonCase.getStatus()) {
case PASSED:
testCase.setStatus(TestCaseResult.PASSED);
break;
case SKIPPED:
testCase.setStatus(TestCaseResult.SKIPPED);
break;
case FAILED:
testCase.setStatus(TestCaseResult.FAILED);
break;
case FIXED:
testCase.setStatus(TestCaseResult.FIXED);
break;
case REGRESSION:
testCase.setStatus(TestCaseResult.REGRESSION);
break;
}
testCase.setSuite(testSuite);
}
testSuite.setResult(testResult);
}
return testResult;
}
private ITestResult parseTestResult(HudsonTasksTestAggregatedTestResultAction hudsonTestReport) {
ITestResult testResult = createTestResult();
testResult.setFailCount(hudsonTestReport.getFailCount());
testResult.setIgnoredCount(hudsonTestReport.getSkipCount());
testResult.setPassCount(hudsonTestReport.getTotalCount() - hudsonTestReport.getFailCount()
- hudsonTestReport.getSkipCount());
for (HudsonTasksTestAggregatedTestResultActionChildReport child : hudsonTestReport.getChildReport()) {
ITestResult childResult = parseTestResult((HudsonTasksJunitTestResult) child.getResult());
testResult.getSuites().addAll(childResult.getSuites());
}
return testResult;
}
private IUser parseUser(HudsonModelUser hudsonUser) {
IUser user = createUser();
user.setId(hudsonUser.getId());
user.setName(hudsonUser.getFullName());
user.setUrl(hudsonUser.getAbsoluteUrl());
return user;
}
@Override
public BuildServerConfiguration refreshConfiguration(IOperationMonitor monitor) throws CoreException {
try {
client.getJobs(null, monitor);
} catch (HudsonException e) {
throw HudsonCorePlugin.toCoreException(e);
}
return getConfiguration();
}
@Override
public void runBuild(RunBuildRequest request, IOperationMonitor monitor) throws CoreException {
try {
HudsonModelJob job = createJobParameter(request.getPlan());
client.runBuild(job, request.getParameters(), monitor);
} catch (HudsonException e) {
throw HudsonCorePlugin.toCoreException(e);
}
}
protected void updateHealth(HudsonModelJob job, IBuildPlan plan) {
String testResult = null;
String buildResult = null;
String result = null;
List<HudsonModelHealthReport> husonHealthReports = job.getHealthReport();
if (husonHealthReports.size() > 0) {
plan.setHealth(husonHealthReports.get(0).getScore());
for (HudsonModelHealthReport hudsonHealthReport : husonHealthReports) {
plan.getHealthReports().add(parseHealthReport(hudsonHealthReport));
// compute summary
if (hudsonHealthReport.getScore() < plan.getHealth()) {
plan.setHealth(hudsonHealthReport.getScore());
}
String description = hudsonHealthReport.getDescription();
if (description != null) {
if (hudsonHealthReport.getDescription().startsWith("Test Result: ")) { //$NON-NLS-1$
if (testResult == null) {
testResult = description.substring(13);
}
} else if (hudsonHealthReport.getDescription().startsWith("Build stability: ")) { //$NON-NLS-1$
if (buildResult == null) {
buildResult = description.substring(17);
}
} else if (result == null) {
int i = description.indexOf(": "); //$NON-NLS-1$
if (i != -1) {
result = description.substring(i + 2);
} else {
result = description;
}
}
}
}
if (testResult != null) {
plan.setSummary(testResult);
} else if (buildResult != null) {
plan.setSummary(buildResult);
} else {
plan.setSummary(result);
}
} else {
plan.setHealth(-1);
}
}
protected void updateStateAndStatus(HudsonModelJob job, IBuildPlan plan) {
HudsonModelBallColor color = job.getColor();
if (color == null) {
plan.setStatus(null);
plan.setState(null);
} else {
switch (color) {
case BLUE:
case GREEN:
plan.setStatus(BuildStatus.SUCCESS);
plan.setState(BuildState.STOPPED);
break;
case BLUE_ANIME:
case GREEN_ANIME:
plan.setStatus(BuildStatus.SUCCESS);
plan.setState(BuildState.RUNNING);
break;
case RED:
plan.setStatus(BuildStatus.FAILED);
plan.setState(BuildState.STOPPED);
break;
case RED_ANIME:
plan.setStatus(BuildStatus.FAILED);
plan.setState(BuildState.RUNNING);
break;
case YELLOW:
plan.setStatus(BuildStatus.UNSTABLE);
plan.setState(BuildState.STOPPED);
break;
case YELLOW_ANIME:
plan.setStatus(BuildStatus.UNSTABLE);
plan.setState(BuildState.RUNNING);
break;
case GREY:
plan.setStatus(BuildStatus.DISABLED);
plan.setState(BuildState.STOPPED);
break;
case GREY_ANIME:
plan.setStatus(BuildStatus.DISABLED);
plan.setState(BuildState.RUNNING);
break;
case DISABLED:
plan.setStatus(BuildStatus.DISABLED);
plan.setState(BuildState.STOPPED);
break;
case DISABLED_ANIME:
plan.setStatus(BuildStatus.DISABLED);
plan.setState(BuildState.RUNNING);
break;
case ABORTED:
plan.setStatus(BuildStatus.ABORTED);
plan.setState(BuildState.STOPPED);
break;
case ABORTED_ANIME:
plan.setStatus(BuildStatus.ABORTED);
plan.setState(BuildState.RUNNING);
break;
default:
plan.setStatus(null);
plan.setState(null);
}
}
EnumSet<BuildState> flags = EnumSet.noneOf(BuildState.class);
if (plan.getState() != null) {
flags.add(plan.getState());
}
if (job.isInQueue()) {
flags.add(BuildState.QUEUED);
}
if (job.isBuildable()) {
flags.add(BuildState.BUILDABLE);
}
plan.getFlags().addAll(flags);
}
@Override
public IStatus validate(IOperationMonitor monitor) throws CoreException {
try {
HudsonServerInfo info = client.validate(monitor);
HudsonStatus status = new HudsonStatus(IStatus.OK, HudsonCorePlugin.ID_PLUGIN, NLS.bind(
Messages.HudsonServerBehaviour_Validation_succesful, info.getVersion()));
status.setInfo(info);
return status;
} catch (HudsonException e) {
throw HudsonCorePlugin.toCoreException(e);
}
}
}