package hudson.plugins.jira;
import hudson.Extension;
import hudson.Util;
import hudson.model.AbstractProject;
import hudson.model.Hudson;
import hudson.model.Job;
import hudson.model.JobProperty;
import hudson.model.JobPropertyDescriptor;
import hudson.plugins.jira.soap.RemoteGroup;
import hudson.plugins.jira.soap.RemoteValidationException;
import hudson.util.CopyOnWriteList;
import hudson.util.FormValidation;
import org.apache.axis.AxisFault;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.DataBoundConstructor;
import javax.servlet.ServletException;
import javax.xml.rpc.ServiceException;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.QueryParameter;
/**
* Associates {@link AbstractProject} with {@link JiraSite}.
*
* @author Kohsuke Kawaguchi
*/
public class JiraProjectProperty extends JobProperty<AbstractProject<?, ?>> {
/**
* Used to find {@link JiraSite}. Matches {@link JiraSite#getName()}. Always
* non-null (but beware that this value might become stale if the system
* config is changed.)
*/
public final String siteName;
@DataBoundConstructor
public JiraProjectProperty(String siteName) {
if (siteName == null) {
// defaults to the first one
JiraSite[] sites = DESCRIPTOR.getSites();
if (sites.length > 0)
siteName = sites[0].getName();
}
this.siteName = siteName;
}
/**
* Gets the {@link JiraSite} that this project belongs to.
*
* @return null if the configuration becomes out of sync.
*/
public JiraSite getSite() {
JiraSite[] sites = DESCRIPTOR.getSites();
if (siteName == null && sites.length > 0)
// default
return sites[0];
for (JiraSite site : sites) {
if (site.getName().equals(siteName))
return site;
}
return null;
}
@Override
public DescriptorImpl getDescriptor() {
return DESCRIPTOR;
}
@Extension
public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();
public static final class DescriptorImpl extends JobPropertyDescriptor {
private final CopyOnWriteList<JiraSite> sites = new CopyOnWriteList<JiraSite>();
public DescriptorImpl() {
super(JiraProjectProperty.class);
load();
}
@Override
@SuppressWarnings("unchecked")
public boolean isApplicable(Class<? extends Job> jobType) {
return AbstractProject.class.isAssignableFrom(jobType);
}
@Override
public String getDisplayName() {
return Messages.JiraProjectProperty_DisplayName();
}
public void setSites(JiraSite site) {
sites.add(site);
}
public JiraSite[] getSites() {
return sites.toArray(new JiraSite[0]);
}
@Override
public JobProperty<?> newInstance(StaplerRequest req)
throws FormException {
JiraProjectProperty jpp = req.bindParameters(
JiraProjectProperty.class, "jira.");
if (jpp.siteName == null)
jpp = null; // not configured
return jpp;
}
@Override
public boolean configure(StaplerRequest req, JSONObject formData) {
sites.replaceBy(req.bindParametersToList(JiraSite.class, "jira."));
save();
return true;
}
/**
* Checks if the JIRA URL is accessible and exists.
*/
public FormValidation doUrlCheck(@QueryParameter final String value)
throws IOException, ServletException {
// this can be used to check existence of any file in any URL, so
// admin only
if (!Hudson.getInstance().hasPermission(Hudson.ADMINISTER))
return FormValidation.ok();
return new FormValidation.URLCheck() {
@Override
protected FormValidation check() throws IOException,
ServletException {
String url = Util.fixEmpty(value);
if (url == null) {
return FormValidation.error(Messages
.JiraProjectProperty_JiraUrlMandatory());
}
try {
if (findText(open(new URL(url)), "Atlassian JIRA"))
return FormValidation.ok();
else
return FormValidation.error(Messages
.JiraProjectProperty_NotAJiraUrl());
} catch (IOException e) {
LOGGER.log(Level.WARNING,
"Unable to connect to " + url, e);
return handleIOException(url, e);
}
}
}.check();
}
/**
* Checks if the user name and password are valid.
*/
public FormValidation doLoginCheck(StaplerRequest request)
throws IOException {
String url = Util.fixEmpty(request.getParameter("url"));
if (url == null) {// URL not entered yet
return FormValidation.ok();
}
JiraSite site = new JiraSite(new URL(url), request
.getParameter("user"), request.getParameter("pass"), false,
false, null, false, request.getParameter("groupVisibility"));
try {
site.createSession();
return FormValidation.ok();
} catch (AxisFault e) {
LOGGER.log(Level.WARNING, "Failed to login to JIRA at " + url,
e);
return FormValidation.error(e.getFaultString());
} catch (ServiceException e) {
LOGGER.log(Level.WARNING, "Failed to login to JIRA at " + url,
e);
return FormValidation.error(e.getMessage());
}
}
public FormValidation doUserPatternCheck(StaplerRequest request)
throws IOException {
String userPattern = Util.fixEmpty(request
.getParameter("userPattern"));
if (userPattern == null) {// userPattern not entered yet
return FormValidation.ok();
}
try {
Pattern.compile(userPattern);
return FormValidation.ok();
} catch (PatternSyntaxException e) {
return FormValidation.error(e.getMessage());
}
}
}
private static final Logger LOGGER = Logger
.getLogger(JiraProjectProperty.class.getName());
}