package hudson.plugins.parameterizedtrigger;
import hudson.Extension;
import hudson.model.Item;
import hudson.model.Hudson;
import hudson.model.Item;
import hudson.model.ItemGroup;
import hudson.model.Project;
import hudson.model.listeners.ItemListener;
import hudson.util.EnumConverter;
import java.io.IOException;
import java.util.List;
import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.model.Jenkins;
import org.jenkinsci.plugins.conditionalbuildstep.ConditionalBuildStepHelper;
import org.kohsuke.stapler.Stapler;
import static org.apache.commons.lang.StringUtils.isEmpty;
public class Plugin extends hudson.Plugin {
@Override
public void start() throws Exception {
Stapler.CONVERT_UTILS.register(new EnumConverter(),
ResultCondition.class);
}
/**
* If a job is renamed, update all parameterized-triggers with the new name.
*/
@Extension
public static final class RenameListener extends ItemListener {
@Override
public void onRenamed(Item item, String oldName, String newName) {
ItemGroup context = item.getParent();
String full = isEmpty(context.getFullName()) ? "" : context.getFullName() + '/';
String fullOldName = full + oldName;
String fullNewName = full + newName;
for (Project<?,?> p : Jenkins.getInstance().getAllItems(Project.class)) {
boolean changed = false;
//iterate over post build triggers
BuildTrigger bt = p.getPublishersList().get(BuildTrigger.class);
if (bt != null) {
for (BuildTriggerConfig c : bt.getConfigs()){
changed |= c.onJobRenamed(p.getParent(), fullOldName, fullNewName);
}
}
//iterate over build step triggers
TriggerBuilder tb = p.getBuildersList().get(TriggerBuilder.class);
if (tb != null) {
for (BuildTriggerConfig co : tb.getConfigs()){
changed |= co.onJobRenamed(p.getParent(), fullOldName, fullNewName);
}
}
//iterate the BuildTriggers within conditional buildsteps
if(isConditionalBuildStepInstalled()) {
changed |= renameInConditionalBuildStep(p, oldName, newName);
}
//if something changed, save the project
if (changed){
try {
p.save();
} catch (IOException e) {
Logger.getLogger(RenameListener.class.getName()).log(Level.WARNING,
"Failed to persist project setting during rename from "+fullOldName+" to "+fullNewName, e);
}
}
}
}
@Override
public void onDeleted(Item item) {
for (Project<?,?> p : Jenkins.getInstance().getAllItems(Project.class)) {
String oldName = item.getFullName();
boolean changed = false;
//iterate over post build triggers
BuildTrigger bt = p.getPublishersList().get(BuildTrigger.class);
if (bt != null) {
for (ListIterator<BuildTriggerConfig> btc = bt.getConfigs().listIterator(); btc.hasNext();) {
BuildTriggerConfig c = btc.next();
if (c.onDeleted(p.getParent(), oldName)) {
changed = true;
if (c.getProjects().length() == 0){
btc.remove();
}
}
}
}
//iterate over build step triggers
TriggerBuilder tb = p.getBuildersList().get(TriggerBuilder.class);
if (tb != null) {
for (ListIterator<BlockableBuildTriggerConfig> bbtc = tb.getConfigs().listIterator(); bbtc.hasNext();) {
BuildTriggerConfig c = bbtc.next();
if (c.onDeleted(p.getParent(), oldName)) {
changed = true;
if (c.getProjects().length() == 0){
bbtc.remove();
}
}
}
}
//iterate the BuildTriggers within conditional buildsteps
if(isConditionalBuildStepInstalled()) {
changed |= deleteInConditionalBuildStep(p, oldName);
}
//if something changed, save the project
if (changed){
try {
if (bt!=null && bt.getConfigs().isEmpty()){
p.getPublishersList().remove(bt);
}
if (tb!=null && tb.getConfigs().isEmpty()){
p.getBuildersList().remove(tb);
}
p.save();
} catch (IOException e) {
Logger.getLogger(RenameListener.class.getName()).log(Level.WARNING,
"Failed to persist project setting during remove of "+oldName, e);
}
}
}
}
/**
* renames the project references within all {@link TriggerBuilder}s which are wrapped by a conditional buildsteps
* @param p the project the check
* @param oldName the old project name
* @param newName the new project name
* @return whether a change has been made
*/
private boolean renameInConditionalBuildStep(Project<?,?> p, String oldName, String newName) {
boolean changed = false;
final List<TriggerBuilder> containedBuilders = ConditionalBuildStepHelper.getContainedBuilders(p, TriggerBuilder.class);
for (TriggerBuilder triggerBuilder : containedBuilders) {
for (BuildTriggerConfig co : triggerBuilder.getConfigs()){
changed |= co.onJobRenamed(p.getParent(), oldName, newName);
}
}
return changed;
}
/**
* removes the project references within all {@link TriggerBuilder}s which are wrapped by a conditional buildsteps
* @param p the project the check
* @param oldName the old project name
* @return whether a change has been made
*/
private boolean deleteInConditionalBuildStep(Project<?,?> p, String oldName) {
boolean changed = false;
final List<TriggerBuilder> containedBuilders = ConditionalBuildStepHelper.getContainedBuilders(p, TriggerBuilder.class);
for (TriggerBuilder triggerBuilder : containedBuilders) {
for (ListIterator<BlockableBuildTriggerConfig> bbtc = triggerBuilder.getConfigs().listIterator(); bbtc.hasNext();) {
BuildTriggerConfig c = bbtc.next();
if (c.onDeleted(p.getParent(), oldName)) {
changed = true;
if (c.getProjects().length() == 0){
bbtc.remove();
}
}
}
}
return changed;
}
}
public static boolean isConditionalBuildStepInstalled(){
final hudson.Plugin plugin = Jenkins.getInstance().getPlugin("conditional-buildstep");
return plugin != null ? plugin.getWrapper().isActive() : false;
}
}