/*
* Copyright 2012 MeetMe, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hudson.plugins.jira;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Util;
import hudson.model.AbstractProject;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;
import hudson.util.FormValidation;
import jenkins.tasks.SimpleBuildStep;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import javax.servlet.ServletException;
import java.io.IOException;
/**
* Build step that will mass-update all issues matching a JQL query, using the specified workflow
* action name (e.g., "Resolve Issue", "Close Issue").
*
* @author Joe Hansche jhansche@myyearbook.com
*/
public class JiraIssueUpdateBuilder extends Builder implements SimpleBuildStep {
private final String jqlSearch;
private final String workflowActionName;
private final String comment;
@DataBoundConstructor
public JiraIssueUpdateBuilder(String jqlSearch, String workflowActionName, String comment) {
this.jqlSearch = Util.fixEmptyAndTrim(jqlSearch);
this.workflowActionName = Util.fixEmptyAndTrim(workflowActionName);
this.comment = Util.fixEmptyAndTrim(comment);
}
/**
* @return the jql
*/
public String getJqlSearch() {
return jqlSearch;
}
/**
* @return the workflowActionName
*/
public String getWorkflowActionName() {
return workflowActionName;
}
/**
* @return the comment
*/
public String getComment() {
return comment;
}
/**
* Performs the actual update based on job configuration.
*/
@Override
public void perform(Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener) throws InterruptedException, IOException {
String realComment = Util.fixEmptyAndTrim(run.getEnvironment(listener).expand(comment));
String realJql = Util.fixEmptyAndTrim(run.getEnvironment(listener).expand(jqlSearch));
String realWorkflowActionName = Util.fixEmptyAndTrim(run.getEnvironment(listener).expand(workflowActionName));
JiraSite site = JiraSite.get(run.getParent());
if (site == null) {
listener.getLogger().println(Messages.NoJiraSite());
run.setResult(Result.FAILURE);
}
if (StringUtils.isNotEmpty(realWorkflowActionName)) {
listener.getLogger().println(Messages.JiraIssueUpdateBuilder_UpdatingWithAction(realWorkflowActionName));
}
listener.getLogger().println("[JIRA] JQL: " + realJql);
try {
if (!site.progressMatchingIssues(realJql, realWorkflowActionName, realComment, listener.getLogger())) {
listener.getLogger().println(Messages.JiraIssueUpdateBuilder_SomeIssuesFailed());
run.setResult(Result.UNSTABLE);
}
} catch (IOException e) {
listener.getLogger().println(Messages.JiraIssueUpdateBuilder_Failed());
e.printStackTrace(listener.getLogger());
}
}
@Override
public DescriptorImpl getDescriptor() {
return (DescriptorImpl) super.getDescriptor();
}
/**
* Descriptor for {@link JiraIssueUpdateBuilder}.
*/
@Extension
public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {
/**
* Performs on-the-fly validation of the form field 'Jql'.
*
* @param value This parameter receives the value that the user has typed.
* @return Indicates the outcome of the validation. This is sent to the browser.
*/
public FormValidation doCheckJqlSearch(@QueryParameter String value) throws IOException, ServletException {
if (value.length() == 0) {
return FormValidation.error(Messages.JiraIssueUpdateBuilder_NoJqlSearch());
}
return FormValidation.ok();
}
public FormValidation doCheckWorkflowActionName(@QueryParameter String value) {
if (Util.fixNull(value).trim().length() == 0) {
return FormValidation.warning(Messages.JiraIssueUpdateBuilder_NoWorkflowAction());
}
return FormValidation.ok();
}
public boolean isApplicable(Class<? extends AbstractProject> klass) {
return true;
}
/**
* This human readable name is used in the configuration screen.
*/
public String getDisplayName() {
return Messages.JiraIssueUpdateBuilder_DisplayName();
}
}
}