package hudson.plugins.sfee; 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.sfee.webservice.ArtifactDetailSoapList; import hudson.plugins.sfee.webservice.ArtifactDetailSoapRow; import hudson.plugins.sfee.webservice.FileStorageAppSoap; import hudson.plugins.sfee.webservice.FrsAppSoap; import hudson.plugins.sfee.webservice.FrsFileSoapDO; import hudson.plugins.sfee.webservice.FrsFileSoapList; import hudson.plugins.sfee.webservice.FrsFileSoapRow; import hudson.plugins.sfee.webservice.IllegalArgumentFault; import hudson.plugins.sfee.webservice.InvalidFilterFault; import hudson.plugins.sfee.webservice.InvalidSessionFault; import hudson.plugins.sfee.webservice.NoSuchObjectFault; import hudson.plugins.sfee.webservice.PackageSoapRow; import hudson.plugins.sfee.webservice.PermissionDeniedFault; import hudson.plugins.sfee.webservice.ProjectSoapRow; import hudson.plugins.sfee.webservice.ReleaseSoapDO; import hudson.plugins.sfee.webservice.ReleaseSoapList; import hudson.plugins.sfee.webservice.ReleaseSoapRow; import hudson.plugins.sfee.webservice.SearchQuerySyntaxFault; import hudson.plugins.sfee.webservice.SourceForgeSoap; import hudson.plugins.sfee.webservice.SystemFault; import hudson.plugins.sfee.webservice.TrackerAppSoap; import hudson.plugins.sfee.webservice.TrackerSoapRow; import hudson.plugins.sfee.webservice.UserSoapDO; import hudson.plugins.sfee.webservice.UserSoapRow; import hudson.plugins.sfee.webservice.VersionMismatchFault; import java.io.Serializable; import java.net.URL; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.List; import javax.activation.DataHandler; import net.sf.json.JSONObject; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; /** * Represents an external JIRA installation and configuration needed to access * this JIRA. * * @author Kohsuke Kawaguchi */ public class SourceForgeSite extends JobProperty<AbstractProject<?, ?>> implements Serializable { private transient FrsAppSoap frsApp; private transient SourceForgeSoap sfApp; private long lastSessionRequest; /** * URL of JIRA, like <tt>http://jira.codehaus.org/</tt>. Mandatory. * Normalized to end with '/' */ private String site; /** * User name needed to login. Optional. */ private String userName; /** * Password needed to login. Optional. */ private String password; private transient String sessionId; private transient TrackerAppSoap trackerApp; @Extension public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); @DataBoundConstructor public SourceForgeSite(String site, String userName, String password) { this.site = site; this.userName = Util.fixEmpty(userName); this.password = Util.fixEmpty(password); } public SourceForgeSite() { } public String getSite() { return site; } private ProjectSoapRow[] projects; private long lastProjectsUpdate; /** * returns all projects * * @return */ public synchronized ProjectSoapRow[] getProjects() { if (sessionId == null || (System.currentTimeMillis() - lastProjectsUpdate > 15000)) { projects = SFEE.getProjects(getSessionId(), site); lastProjectsUpdate = System.currentTimeMillis(); } return projects; } public synchronized String getSessionId() { if (sessionId == null || (System.currentTimeMillis() - lastSessionRequest > 15000)) { sessionId = SFEE.createSession(site, userName, password); lastSessionRequest = System.currentTimeMillis(); } return sessionId; } @Override public JobPropertyDescriptor getDescriptor() { return SourceForgeSite.DESCRIPTOR; } public static final class DescriptorImpl extends JobPropertyDescriptor { private SourceForgeSite site; protected DescriptorImpl() { super(SourceForgeSite.class); load(); } @Override public String getDisplayName() { return "SFEE"; } @Override public boolean isApplicable(Class<? extends Job> klazz) { return Hudson.class.isAssignableFrom(klazz); } @Override public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { site = req.bindParameters(SourceForgeSite.class, "sfee."); save(); return true; } public SourceForgeSite getSite() { return site; } } public FrsAppSoap getFrsApp() { if (frsApp == null) { frsApp = SFEE.getSourceForgeApp(site, FrsAppSoap.class); } return frsApp; } public SourceForgeSoap getSfApp() { if (sfApp == null) { sfApp = SFEE.getSourceForgeApp(site, SourceForgeSoap.class); } return sfApp; } public TrackerAppSoap getTrackerApp() { if (trackerApp == null) { trackerApp = SFEE.getSourceForgeApp(site, TrackerAppSoap.class); } return trackerApp; } public String getURL(String artifactId) { return String.format("http://%s/sf/go/%s", site, artifactId); } public FileStorageAppSoap getFileStorageApp() { return SFEE.getSourceForgeApp(site, FileStorageAppSoap.class); } /** * Updates the title of the release with the given name. * * @return the id of the release that was changed, or null is no such * release * @throws RemoteException * @throws PermissionDeniedFault * @throws SystemFault * @throws InvalidSessionFault * @throws NoSuchObjectFault */ public String updateReleaseName(String packageId, String oldName, String newName) throws NoSuchObjectFault, InvalidSessionFault, SystemFault, PermissionDeniedFault, RemoteException { FrsAppSoap frsApp = getFrsApp(); String sessionId = getSessionId(); ReleaseSoapList existingReleases = frsApp.getReleaseList(sessionId, packageId); for (ReleaseSoapRow row : existingReleases.getDataRows()) { if (oldName.equals(row.getTitle())) { String releaseId = row.getId(); ReleaseSoapDO releaseToReplace = frsApp.getReleaseData( sessionId, releaseId); releaseToReplace.setTitle(newName); frsApp.setReleaseData(sessionId, releaseToReplace); return releaseId; } } return null; } /** * Updates the title of the release with the given name. * * @return the id of the release that was changed, or null is no such * release * @throws RemoteException * @throws PermissionDeniedFault * @throws SystemFault * @throws InvalidSessionFault * @throws NoSuchObjectFault */ public String getReleaseId(String packageId, String name) throws NoSuchObjectFault, InvalidSessionFault, SystemFault, PermissionDeniedFault, RemoteException { String releaseId = null; FrsAppSoap frsApp = getFrsApp(); String sessionId = getSessionId(); ReleaseSoapList existingReleases = frsApp.getReleaseList(sessionId, packageId); for (ReleaseSoapRow row : existingReleases.getDataRows()) { if (name.equals(row.getTitle())) { releaseId = row.getId(); break; } } return releaseId; } public List<ArtifactDetailSoapRow> findArtifactsResolvedInRelease( String releaseTitle, String projectId) throws InvalidFilterFault, NoSuchObjectFault, InvalidSessionFault, SystemFault, PermissionDeniedFault, RemoteException { List<ArtifactDetailSoapRow> result = new ArrayList<ArtifactDetailSoapRow>(); String sessionId = getSessionId(); TrackerAppSoap trackerApp = getTrackerApp(); for (TrackerSoapRow trackerRow : getTrackers(projectId)) { ArtifactDetailSoapList artifactDetailList = trackerApp .getArtifactDetailList(sessionId, trackerRow.getId(), null); for (ArtifactDetailSoapRow row : artifactDetailList.getDataRows()) { if (releaseTitle.equals(row.getResolvedInReleaseTitle())) { result.add(row); } } } return result; } public String createRelease(String packageId, String releaseName, String description, String status, String maturity) throws IllegalArgumentFault, NoSuchObjectFault, InvalidSessionFault, SystemFault, PermissionDeniedFault, RemoteException { FrsAppSoap frsApp = getFrsApp(); String sessionId = getSessionId(); ReleaseSoapDO release = frsApp.createRelease(sessionId, packageId, releaseName, description, status, maturity); return release.getId(); } public String getFrsId(String releaseId, String fileName) throws InvalidSessionFault, SystemFault, RemoteException { String ret = null; String sessionId = getSessionId(); FrsAppSoap frsApp = getFrsApp(); FrsFileSoapList fileSoapList = frsApp.getFrsFileList(sessionId, releaseId); for (FrsFileSoapRow row : fileSoapList.getDataRows()) { if (fileName.equals(row.getFilename())) { ret = row.getId(); break; } } return ret; } public String uploadFileForRelease(String releaseId, String name, URL sourceURL, boolean forceUpdate) throws InvalidSessionFault, SystemFault, RemoteException { return uploadFileForRelease(releaseId, name, new DataHandler(sourceURL), forceUpdate); } public String uploadFileForRelease(String releaseId, String name, DataHandler dataHandler, boolean forceUpdate) throws InvalidSessionFault, SystemFault, RemoteException { String sessionId = getSessionId(); FileStorageAppSoap fileApp = getFileStorageApp(); String fileId = fileApp.uploadFile(sessionId, dataHandler); if (forceUpdate) { String frsId = getFrsId(releaseId, name); if (frsId != null) { getFrsApp().deleteFrsFile(sessionId, frsId); } } FrsFileSoapDO frsFile = getFrsApp().createFrsFile(sessionId, releaseId, name, dataHandler.getContentType(), fileId); return frsFile.getId(); } public PackageSoapRow[] getReleasePackages(String projectId) throws NoSuchObjectFault, InvalidSessionFault, SystemFault, PermissionDeniedFault, RemoteException { return getFrsApp().getPackageList(getSessionId(), projectId) .getDataRows(); } public TrackerSoapRow[] getTrackers(String projectId) throws NoSuchObjectFault, InvalidSessionFault, SystemFault, PermissionDeniedFault, RemoteException { return getTrackerApp().getTrackerList(getSessionId(), projectId) .getDataRows(); } public UserSoapRow[] getUsers() throws SearchQuerySyntaxFault, IllegalArgumentFault, InvalidSessionFault, SystemFault, PermissionDeniedFault, RemoteException { return getSfApp().getUserList(getSessionId(), null).getDataRows(); } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String createSession(String userName, String password) { return SFEE.createSession(site, userName, password); } public UserSoapDO getUserDetails(String username) throws InvalidSessionFault, NoSuchObjectFault, IllegalArgumentFault, RemoteException { return getSfApp().getUserData(getSessionId(), username); } /** * returns projects for user logged in with this session id * * @param sessionId * @return * @throws RemoteException * @throws SystemFault * @throws InvalidSessionFault */ public ProjectSoapRow[] getProjects(String sessionId) throws InvalidSessionFault, SystemFault, RemoteException { return getSfApp().getUserProjectList(sessionId).getDataRows(); } public void updateRelease(String releaseId, String maturity, String status) throws NoSuchObjectFault, InvalidSessionFault, SystemFault, PermissionDeniedFault, RemoteException { FrsAppSoap frsApp = getFrsApp(); String sessionId = getSessionId(); ReleaseSoapDO releaseData = frsApp.getReleaseData(sessionId, releaseId); if (maturity != null) { releaseData.setMaturity(maturity); } if (status != null) { releaseData.setStatus(status); } frsApp.setReleaseData(sessionId, releaseData); } public void obsoleteRelease(String releaseId) throws VersionMismatchFault, IllegalArgumentFault, NoSuchObjectFault, InvalidSessionFault, SystemFault, PermissionDeniedFault, RemoteException { FrsAppSoap frsApp = getFrsApp(); String sessionId = getSessionId(); ReleaseSoapDO releaseData = frsApp.getReleaseData(sessionId, releaseId); releaseData.setMaturity("Obsolete"); releaseData.setTitle("[obsolete] " + releaseData.getTitle()); frsApp.setReleaseData(sessionId, releaseData); } }