package hudson.plugins.googlecode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import hudson.Extension;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Job;
import hudson.model.JobProperty;
import hudson.model.JobPropertyDescriptor;
import hudson.scm.SubversionChangeLogSet.LogEntry;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
/**
* Property for {@link AbstractProject} that stores the associated Google Code website URL.
*
* @author Kohsuke Kawaguchi
* @author Erik Ramfelt
*/
public final class GoogleCodeProjectProperty extends JobProperty<AbstractProject<?,?>> {
/**
* Google Code website URL that this project uses.
*
* This value is normalized and therefore it always ends with '/'.
* Null if this is not configured yet.
*/
public final String googlecodeWebsite;
private transient String projectName;
@DataBoundConstructor
public GoogleCodeProjectProperty(String googlecodeWebsite) {
// normalize
if(googlecodeWebsite==null || googlecodeWebsite.length()==0)
googlecodeWebsite=null;
else {
if(!googlecodeWebsite.endsWith("/"))
googlecodeWebsite += '/';
}
this.googlecodeWebsite = googlecodeWebsite;
}
/**
* Returns the project name for the google code property
* "Project's name must consist of a lowercase letter, followed by lowercase letters, digits,
* and dashes, with no spaces."
* @return the project name
*/
public String getProjectName() {
if (projectName == null) {
Matcher matcher = Pattern.compile(".*\\/p\\/([\\w-]*)").matcher(googlecodeWebsite);
matcher.find();
projectName = matcher.group(1);
}
return projectName;
}
/**
* Returns the subversion root URL for this Google Code project.
* @return string containing a Subversion URL
*/
public String getSubversionRootUrl() {
return "https://" + getProjectName() + ".googlecode.com/svn/";
}
@Extension
public static final class DescriptorImpl extends JobPropertyDescriptor {
public DescriptorImpl() {
super(GoogleCodeProjectProperty.class);
load();
}
@Override
public boolean isApplicable(Class<? extends Job> jobType) {
return AbstractProject.class.isAssignableFrom(jobType);
}
@Override
public String getDisplayName() {
return "Associated Google Code website";
}
@Override
public GoogleCodeProjectProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException {
return req.bindJSON(GoogleCodeProjectProperty.class, formData);
}
}
/**
* Interface needed to remove the dependency of AbstractBuild and Project classes which
* are quite difficult to mock out.
*/
public interface PropertyRetriever {
GoogleCodeProjectProperty getProperty(AbstractBuild<?,?> build);
GoogleCodeProjectProperty getProperty(LogEntry entry);
}
public static class PropertyRetrieverImpl implements PropertyRetriever {
public GoogleCodeProjectProperty getProperty(AbstractBuild<?, ?> build) {
return build.getProject().getProperty(GoogleCodeProjectProperty.class);
}
public GoogleCodeProjectProperty getProperty(LogEntry entry) {
return getProperty(entry.getParent().build);
}
}
}