package hudson.plugins;
import java.util.Map;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.StaplerRequest;
import hudson.Extension;
import hudson.model.AbstractProject;
import hudson.model.Descriptor;
import hudson.model.Job;
import hudson.scm.NullSCM;
import hudson.scm.SCM;
import hudson.triggers.SCMTrigger;
import hudson.triggers.TimerTrigger;
import hudson.triggers.Trigger;
import hudson.triggers.TriggerDescriptor;
import hudson.views.ListViewColumn;
/**
* CronViewColumn
*
* Column plugin that adds a column to a jobs overview page.
*
* The column displays the cron expression of each Trigger on the Job.
*
* 03/03/2010
* @author Eelco de Vlieger
*/
public class CronViewColumn extends ListViewColumn{
private static final String CRON_EXPRESSION_COMMENT_START = "#";
private static final String CRON_EXPRESSION_COMMENT_COLOR = "#4a7b4a";
/**
* @return HTML String containing the cron expression of each Trigger on the Job (when available).
*/
public String getCronTrigger(Job job){
if( !(job instanceof AbstractProject<?, ?>) )
return "";
StringBuilder expression = new StringBuilder();
AbstractProject<?, ?> project = (AbstractProject<?, ?>)job;
// Check if source code management is enabled.
SCM sourceCodeManagement = project.getScm();
boolean hasSourceCodeManagement = sourceCodeManagement != null && !(sourceCodeManagement instanceof NullSCM);
Map<TriggerDescriptor, Trigger> triggers = project.getTriggers();
for(Trigger trigger : triggers.values()){
if(trigger == null)
continue;
String cronExpression = trigger.getSpec();
if( cronExpression == null || cronExpression.trim().length() == 0 )
continue;
cronExpression = formatComments(cronExpression);
// Display each entry on a separate line.
if(expression.length() > 0)
expression.append("\n<br/>\n");
// Cron expression can still be set when Source Code Management has been disabled.
if(!hasSourceCodeManagement && trigger instanceof SCMTrigger)
expression.append("<i>(Disabled) </i>");
// Add trigger name and cron expression.
expression.append( getTriggerName(trigger) ).append(": ").append( cronExpression );
}
return expression.toString();
}
/**
* Change the font color on the comment text within a cron expression.
*/
private String formatComments(String cronExpression){
if( !cronExpression.contains(CRON_EXPRESSION_COMMENT_START) )
return cronExpression; // No comment found.
StringBuilder formattedExpression = new StringBuilder();
String[] expressionLines = cronExpression.split("\n");
for(String expressionLine : expressionLines){
int commentStartIndex = expressionLine.indexOf(CRON_EXPRESSION_COMMENT_START);
if(commentStartIndex < 0){
// No comment, so just add the original expression line.
formattedExpression.append(expressionLine);
}else{
// Comment found, wrapping comment in font tags (setting the color).
formattedExpression.append( expressionLine.substring(0, commentStartIndex) );
formattedExpression.append("<b><i><font color=\"" + CRON_EXPRESSION_COMMENT_COLOR + "\">");
formattedExpression.append( expressionLine.substring(commentStartIndex) );
formattedExpression.append("</font></i></b>");
}
formattedExpression.append(" ");
}
return formattedExpression.toString().trim();
}
/**
* Determines the trigger name.
*
* @return Name of the trigger.
*/
private String getTriggerName(Trigger<?> trigger){
String type = trigger.getDescriptor().getDisplayName();
if(type == null || type.trim().length() == 0){
if(trigger instanceof SCMTrigger)
type = "SCM polling";
else if(trigger instanceof TimerTrigger)
type = "Build Trigger";
else
type = "Unknown Type";
}
return type;
}
@Extension
public static final Descriptor<ListViewColumn> DESCRIPTOR = new Descriptor<ListViewColumn>(){
@Override
public ListViewColumn newInstance(StaplerRequest req, JSONObject formData){
return new CronViewColumn();
}
@Override
public String getDisplayName(){
return "CronTrigger";
}
};
public Descriptor<ListViewColumn> getDescriptor(){
return DESCRIPTOR;
}
}