package hudson.plugins.jprt; import hudson.model.Run; import hudson.model.Result; import java.io.File; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; import java.net.URL; import JPRT.shared.transported.status.JobStatus; import JPRT.shared.transported.status.BuildTargetStatus; import JPRT.shared.transported.JobID; import JPRT.shared.transported.StateID; import JPRT.shared.JobLayout; /** * {@link Run} for {@link JPRTJob}. * * @author Kohsuke Kawaguchi */ public class JPRTRun extends Run<JPRTJob,JPRTRun> { private final File archiveDir; /** * JPRT's data model that represents the state of this job. * Lazily loaded. */ private volatile JobStatus jprtStatus; private final JobID jprtId; public JPRTRun(JPRTJob job, JPRTRun prevBuild, File archiveDir) throws ParseException { super(job, getTimestamp(archiveDir)); // TODO: think about a way to give a consistent build number this.number = prevBuild!=null ? prevBuild.number+1 : 1; this.archiveDir = archiveDir; jprtId = JobID.fromString(archiveDir.getName()); jprtStatus = JobStatus.fromXml(jprtId.getXmlFile()); switch (jprtStatus.getState().id().getPhase()) { case NOT_STARTED: // hasn't started yet break; case FAIL: onStartBuilding(); setResult(Result.FAILURE); onEndBuilding(); break; case PASS: // success onStartBuilding(); setResult(Result.SUCCESS); onEndBuilding(); break; case WORKING: onStartBuilding(); break; default: throw new IllegalStateException(jprtStatus.getState().toString()); } } // TODO: we need another constructor for jobs in the queue /** * Returns the Job ID in the JPRT sense. The archive directory name * is the job ID. */ @Override public String getId() { return jprtId.toString(); } @Override public String getDisplayName() { return jprtId.toString(); } /** * Use the JPRT ID as the URL. */ @Override public String getUrl() { return project.getUrl()+getId()+'/'; } /** * Gets the JPRT Job status. */ public JobStatus getStatus() { return jprtStatus; } /** * Helper code used in view to turn {@link StateID} into the appropriate color ball icon. */ public String _getStatusUrl(StateID state) { switch (state.id().getPhase()) { case NOT_STARTED: return "grey.gif"; case FAIL: return "red.gif"; case PASS: return "blue.gif"; case WORKING: return "grey_anime.gif"; default: throw new IllegalStateException(state.toString()); } } /** * Computes the log file URL of the given {@link BuildTargetStatus}. */ public URL getBuildLogURL(BuildTargetStatus status) throws IOException { getParent().prepareToTalkToJPRT(); String logPath = new JobLayout(jprtStatus.getJobID()).buildLog(status.getBuildTargetID()); return new URL(jprtStatus.jobUrl(logPath)); } /** * Computes the timestamp of the build from the JPRT archive directory name format. */ private static Calendar getTimestamp(File dir) throws ParseException { String name = dir.getName(); name = name.substring(0,17); synchronized(TIME_FORMATTER) { Calendar cal = new GregorianCalendar(); cal.setTime(TIME_FORMATTER.parse(name)); return cal; } } protected static final SimpleDateFormat TIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd-HHmmss"); }