package hudson.plugins.mavensnapshottrigger;
import antlr.ANTLRException;
import hudson.Extension;
import hudson.model.AbstractBuild;
import static hudson.Util.fixNull;
import hudson.model.BuildableItem;
import hudson.model.Hudson;
import hudson.model.Item;
import hudson.scheduler.CronTabList;
import hudson.util.FormValidation;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import java.net.URL;
import hudson.model.Project;
import hudson.triggers.Trigger;
import hudson.triggers.TriggerDescriptor;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.io.File;
/**
* {@link Trigger} that detects changes in Maven 1.x SNAPSHOT dependencies.
*
* @author Jarkko Viinam�ki
*/
public class MavenSnapshotTrigger extends Trigger<BuildableItem> {
private static final Logger LOGGER = Logger.getLogger(MavenSnapshotTrigger.class.getName());
public MavenSnapshotTrigger(String cronTabSpec) throws ANTLRException {
super(cronTabSpec);
}
@Override
public void run() {
try {
Project project = (Project)job;
AbstractBuild build = (AbstractBuild)project.getLastBuild();
LOGGER.fine("Polling SNAPSHOT changes for "+project.getName());
if( build != null ) {
MavenSnapshotScanner scanner = new MavenSnapshotScanner();
// We assume that the project.xml is in the project root
URL url = new URL(build.getModuleRoot().toURI() + "/project.xml");
File projectXml = new File(url.getFile());
scanner.setProjectFile(projectXml.getAbsolutePath());
Date lastBuild = new Date(build.getTimestamp().getTimeInMillis());
List<File> modifications = scanner.getModifications(lastBuild);
if( modifications.size() > 0 ) {
LOGGER.info(project.getName()+": "+modifications.size() + " modifications found. Triggering a build.");
// TODO: how to report dependency changes to Hudson (change set)?
// trigger a build
job.scheduleBuild(new MavenSnapshotCause(modifications));
}
}
}
catch(Exception ex) {
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
}
}
@Override
public TriggerDescriptor getDescriptor() {
return DESCRIPTOR;
}
@Extension
public static final TriggerDescriptor DESCRIPTOR = new DescriptorImpl();
public static class DescriptorImpl extends TriggerDescriptor {
// private class attributes are automatically persisted
public DescriptorImpl() {
super(MavenSnapshotTrigger.class);
load(); // load private attribute values from disk
}
public boolean isApplicable(Item item) {
return item instanceof BuildableItem;
}
public String getDisplayName() {
return "Maven 1.x SNAPSHOT dependency trigger";
}
/**
* Returns the resource path to the help screen HTML, if any.
*
* <p>
* This value is relative to the context root of Hudson, so normally
* the values are something like <tt>"/plugin/emma/help.html"</tt> to
* refer to static resource files in a plugin, or <tt>"/publisher/EmmaPublisher/abc"</tt>
* to refer to Jelly script <tt>abc.jelly</tt> or a method <tt>EmmaPublisher.doAbc()</tt>.
*
* @return
* "" to indicate that there's no help.
*/
@Override
public String getHelpFile() {
return "/plugin/maven-snapshot-plugin/help-projectConfig.html";
}
/**
* Invoked when the global configuration page is submitted.
*
* Can be overriden to store descriptor-specific information.
*
* @return false
* to keep the client in the same config page.
*/
@Override
public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
// to persist global configuration information,
// set that to properties and call save().
// myParam = req.getParameter("mavensnapshotplugin.myParam")!=null;
save();
return super.configure(req, formData);
}
/**
* Performs syntax check.
*/
public FormValidation doCheck(@QueryParameter final String mavensnapshotplugin_spec) {
if (!Hudson.getInstance().hasPermission(Hudson.ADMINISTER)) return FormValidation.ok();
try {
CronTabList.create(fixNull(mavensnapshotplugin_spec));
return FormValidation.ok();
} catch (ANTLRException e) {
return FormValidation.error(e.getMessage());
}
}
/**
* Creates a configured instance from the submitted form.
* <p>
* Hudson only invokes this method when the user wants an instance of <tt>T</tt>.
* So there's no need to check that in the implementation.
*
* @param req
* Always non-null. This object includes all the submitted form values.
*
* @throws FormException
* Signals a problem in the submitted form.
*/
@Override
public Trigger newInstance(StaplerRequest req, JSONObject formData) throws FormException {
try {
return new MavenSnapshotTrigger(req.getParameter("mavensnapshotplugin_spec"));
} catch (ANTLRException e) {
throw new FormException(e.toString(), e, "mavensnapshotplugin_spec");
}
}
};
}