package hudson.plugins.templateproject;
import hudson.Extension;
import hudson.Launcher;
import hudson.console.HyperlinkNote;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.BuildListener;
import hudson.model.DependecyDeclarer;
import hudson.model.DependencyGraph;
import hudson.model.Hudson;
import hudson.model.Item;
import hudson.security.AccessControlled;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Messages;
import hudson.tasks.Publisher;
import hudson.tasks.Recorder;
import hudson.util.FormValidation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import jenkins.model.Jenkins;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
public class ProxyPublisher extends Recorder implements DependecyDeclarer {
private final String projectName;
@DataBoundConstructor
public ProxyPublisher(String projectName) {
this.projectName = projectName;
}
public String getProjectName() {
return projectName;
}
public String getExpandedProjectName(AbstractBuild<?, ?> build) {
return TemplateUtils.getExpandedProjectName(projectName, build);
}
public AbstractProject<?, ?> getProject() {
return TemplateUtils.getProject(projectName, null);
}
public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
}
@Override
public boolean needsToRunAfterFinalized() {
return false;
}
public List<Publisher> getProjectPublishersList(AbstractBuild<?, ?> build) {
// @TODO: exception handling
return TemplateUtils.getProject(projectName, build).getPublishersList().toList();
}
@Override
public boolean prebuild(AbstractBuild<?, ?> build, BuildListener listener) {
for (Publisher publisher : getProjectPublishersList(build)) {
if (!publisher.prebuild(build, listener)) {
return false;
}
}
return true;
}
@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
BuildListener listener) throws InterruptedException, IOException {
boolean publishersResult = true;
for (Publisher publisher : getProjectPublishersList(build)) {
AbstractProject p = TemplateUtils.getProject(getProjectName(), build);
listener.getLogger().println("[TemplateProject] Starting publishers from: " + HyperlinkNote.encodeTo('/'+ p.getUrl(), p.getFullDisplayName()));
if (!publisher.perform(build, launcher, listener)) {
listener.getLogger().println("[TemplateProject] FAILED performing publishers from: '" + p.getFullDisplayName() + "'");
publishersResult = false;
} else {
listener.getLogger().println("[TemplateProject] Successfully performed publishers from: '" + p.getFullDisplayName() + "'");
}
}
return publishersResult;
}
@Override
public Collection<? extends Action> getProjectActions(AbstractProject<?, ?> project) {
List<Action> actions = new ArrayList<Action>();
// project might not defined when loading the first time
AbstractProject<?, ?> templateProject = getProject();
if (templateProject != null) {
for (Publisher publisher : templateProject.getPublishersList().toList()) {
actions.addAll(publisher.getProjectActions(project));
}
}
return actions;
}
/**
* Any of the publisher could support the DependecyDeclarer interface,
* so proxy will handle it as well.
* {@inheritDoc}
*/
public void buildDependencyGraph(AbstractProject project, DependencyGraph graph) {
AbstractProject<?, ?> templateProject = getProject();
if (templateProject != null) {
for (Publisher publisher : templateProject.getPublishersList().toList()) {
if (publisher instanceof DependecyDeclarer) {
((DependecyDeclarer)publisher).buildDependencyGraph(project, graph);
}
}
}
}
@Extension
public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {
@Override
public String getDisplayName() {
return "Use publishers from another project";
}
@Override
public boolean isApplicable(Class<? extends hudson.model.AbstractProject> jobType) {
return true;
}
/**
* Form validation method.
*/
public FormValidation doCheckProjectName(@AncestorInPath AccessControlled anc, @QueryParameter String value) {
// Require CONFIGURE permission on this project
if (!anc.hasPermission(Item.CONFIGURE)) return FormValidation.ok();
Item item = Hudson.getInstance().getItemByFullName(
value, Item.class);
if (item == null) {
return FormValidation.error(Messages.BuildTrigger_NoSuchProject(value,
AbstractProject.findNearest(value)
.getName()));
}
if (!(item instanceof AbstractProject)) {
return FormValidation.error(Messages.BuildTrigger_NotBuildable(value));
}
return FormValidation.ok();
}
}
}