/**
*
* Copyright (C) norad.fr
*
* 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 fr.norad.visuwall.plugin.continuum;
import static fr.norad.visuwall.plugin.continuum.States.asVisuwallState;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import fr.norad.visuwall.api.domain.BuildState;
import fr.norad.visuwall.api.domain.BuildTime;
import fr.norad.visuwall.api.domain.Commiter;
import fr.norad.visuwall.api.domain.ProjectKey;
import fr.norad.visuwall.api.domain.SoftwareProjectId;
import fr.norad.visuwall.api.exception.BuildIdNotFoundException;
import fr.norad.visuwall.api.exception.BuildNotFoundException;
import fr.norad.visuwall.api.exception.ConnectionException;
import fr.norad.visuwall.api.exception.MavenIdNotFoundException;
import fr.norad.visuwall.api.exception.ProjectNotFoundException;
import fr.norad.visuwall.api.exception.ViewNotFoundException;
import fr.norad.visuwall.api.plugin.capability.BuildCapability;
import fr.norad.visuwall.api.plugin.capability.ViewCapability;
import org.apache.maven.continuum.xmlrpc.client.ContinuumXmlRpcClient;
import org.apache.maven.continuum.xmlrpc.project.BuildResult;
import org.apache.maven.continuum.xmlrpc.project.ProjectGroupSummary;
import org.apache.maven.continuum.xmlrpc.project.ProjectSummary;
import org.apache.maven.continuum.xmlrpc.scm.ChangeSet;
import org.apache.maven.continuum.xmlrpc.scm.ScmResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ContinuumConnection implements BuildCapability, ViewCapability {
private static final Logger LOG = LoggerFactory.getLogger(ContinuumConnection.class);
private ContinuumXmlRpcClient client;
private boolean connected;
@Override
public String getMavenId(SoftwareProjectId softwareProjectId) throws ProjectNotFoundException,
MavenIdNotFoundException {
try {
ProjectSummary projectSummary = client.getProjectSummary(getId(softwareProjectId));
return projectSummary.getGroupId() + ":" + projectSummary.getArtifactId();
} catch (Exception e) {
throw new MavenIdNotFoundException("Cannot find Maven Id for " + softwareProjectId, e);
}
}
private int getId(SoftwareProjectId softwareProjectId) {
return Integer.parseInt(softwareProjectId.getProjectId());
}
@Override
public void connect(String url, String login, String password) throws ConnectionException {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
try {
client = new ContinuumXmlRpcClient(new URL(url + "/xmlrpc"));
connected = true;
} catch (MalformedURLException e) {
throw new ConnectionException("Cannot open a connection to " + url, e);
} finally {
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
}
@Override
public void close() {
}
@Override
public boolean isClosed() {
return !connected;
}
@Override
public String getDescription(SoftwareProjectId softwareProjectId) throws ProjectNotFoundException {
try {
ProjectSummary project = findProject(softwareProjectId);
return project.getDescription();
} catch (Exception e) {
throw new ProjectNotFoundException(e);
}
}
@Override
public String getName(SoftwareProjectId softwareProjectId) throws ProjectNotFoundException {
try {
ProjectSummary project = findProject(softwareProjectId);
return project.getName();
} catch (Exception e) {
throw new ProjectNotFoundException(e);
}
}
private ProjectSummary findProject(SoftwareProjectId softwareProjectId) throws ProjectNotFoundException {
try {
return client.getProjectSummary(getId(softwareProjectId));
} catch (Exception e) {
throw new ProjectNotFoundException("Cannot find " + softwareProjectId, e);
}
}
@Override
public SoftwareProjectId identify(ProjectKey projectKey) throws ProjectNotFoundException {
try {
String projectMavenId = projectKey.getMavenId();
List<ProjectSummary> projects = findAllProjects();
for (ProjectSummary project : projects) {
String groupId = project.getGroupId();
String artifactId = project.getArtifactId();
String mavenId = groupId + ":" + artifactId;
if (mavenId.equals(projectMavenId)) {
return new SoftwareProjectId(Integer.toString(project.getId()));
}
}
} catch (Exception e) {
throw new ProjectNotFoundException("Cannot identify " + projectKey, e);
}
throw new ProjectNotFoundException("Cannot identify " + projectKey);
}
private List<ProjectSummary> findAllProjects() throws Exception {
List<ProjectGroupSummary> pgs = client.getAllProjectGroups();
List<ProjectSummary> ps = new ArrayList<ProjectSummary>();
for (ProjectGroupSummary projectGroupSummary : pgs) {
ps.addAll(client.getProjects(projectGroupSummary.getId()));
}
return ps;
}
@Override
public Map<SoftwareProjectId, String> listSoftwareProjectIds() {
Map<SoftwareProjectId, String> projectIds = new HashMap<SoftwareProjectId, String>();
List<ProjectSummary> projects;
try {
projects = findAllProjects();
for (ProjectSummary project : projects) {
SoftwareProjectId projectId = new SoftwareProjectId(Integer.toString(project.getId()));
projectIds.put(projectId, project.getName());
}
} catch (Exception e) {
LOG.warn(e.getMessage(), e);
}
return projectIds;
}
@Override
public boolean isProjectDisabled(SoftwareProjectId softwareProjectId) throws ProjectNotFoundException {
return false;
}
@Override
public List<Commiter> getBuildCommiters(SoftwareProjectId softwareProjectId, String buildId)
throws BuildNotFoundException, ProjectNotFoundException {
Set<Commiter> commiters = new TreeSet<Commiter>();
try {
BuildResult buildResult = getBuildResult(softwareProjectId, buildId);
ScmResult scmResult = buildResult.getScmResult();
List<ChangeSet> changes = scmResult.getChanges();
for (ChangeSet change : changes) {
String author = change.getAuthor();
Commiter commiter = new Commiter(author);
commiter.setName(author);
commiters.add(commiter);
}
} catch (Exception e) {
LOG.warn(e.getMessage());
}
return new ArrayList<Commiter>(commiters);
}
private BuildResult getBuildResult(SoftwareProjectId softwareProjectId, String buildId) throws Exception {
BuildResult buildResult = client.getBuildResult(getId(softwareProjectId), Integer.parseInt(buildId));
return buildResult;
}
@Override
public BuildTime getBuildTime(SoftwareProjectId softwareProjectId, String buildId) throws BuildNotFoundException,
ProjectNotFoundException {
try {
BuildResult buildResult;
buildResult = getBuildResult(softwareProjectId, buildId);
long startTime = buildResult.getStartTime();
long endTime = buildResult.getEndTime();
BuildTime buildTime = new BuildTime();
buildTime.setStartTime(new Date(startTime));
buildTime.setDuration(endTime - startTime);
return buildTime;
} catch (Exception e) {
throw new BuildNotFoundException("Cannot get build time for " + softwareProjectId + " and build id "
+ buildId, e);
}
}
@Override
public List<String> getBuildIds(SoftwareProjectId softwareProjectId) throws ProjectNotFoundException {
List<String> buildIds = new ArrayList<String>();
ProjectSummary project = findProject(softwareProjectId);
Integer latestBuildId = project.getLatestBuildId();
buildIds.add(latestBuildId.toString());
return buildIds;
}
@Override
public BuildState getBuildState(SoftwareProjectId projectId, String buildId) throws ProjectNotFoundException,
BuildNotFoundException {
int id = getId(projectId);
BuildResult buildResult;
try {
buildResult = client.getBuildResult(id, Integer.parseInt(buildId));
return asVisuwallState(buildResult.getState());
} catch (NumberFormatException e) {
throw new BuildNotFoundException(e);
} catch (Exception e) {
throw new BuildNotFoundException(e);
}
}
@Override
public Date getEstimatedFinishTime(SoftwareProjectId projectId, String buildId) throws ProjectNotFoundException,
BuildNotFoundException {
return new Date();
}
@Override
public boolean isBuilding(SoftwareProjectId softwareProjectId, String buildId) throws ProjectNotFoundException,
BuildNotFoundException {
return false;
}
@Override
public String getLastBuildId(SoftwareProjectId softwareProjectId) throws ProjectNotFoundException,
BuildIdNotFoundException {
ProjectSummary project = findProject(softwareProjectId);
return Integer.toString(project.getLatestBuildId());
}
@Override
public List<SoftwareProjectId> findSoftwareProjectIdsByViews(List<String> views) {
List<SoftwareProjectId> softwareProjectIds = new ArrayList<SoftwareProjectId>();
try {
List<ProjectGroupSummary> pgs = client.getAllProjectGroups();
for (String viewName : views) {
for (ProjectGroupSummary projectGroupSummary : pgs) {
if (projectGroupSummary.getName().equals(viewName)) {
List<ProjectSummary> projects = client.getProjects(projectGroupSummary.getId());
for (ProjectSummary project : projects) {
SoftwareProjectId projectId = new SoftwareProjectId(Integer.toString(project.getId()));
softwareProjectIds.add(projectId);
}
}
}
}
} catch (Exception e) {
LOG.warn("Cannot get all projects groups", e);
}
return softwareProjectIds;
}
@Override
public List<String> findViews() {
List<String> views = new ArrayList<String>();
try {
List<ProjectGroupSummary> pgs = client.getAllProjectGroups();
for (ProjectGroupSummary projectGroupSummary : pgs) {
String name = projectGroupSummary.getName();
views.add(name);
}
Collections.sort(views);
} catch (Exception e) {
LOG.warn("Cannot get all projects groups", e);
}
return views;
}
@Override
public List<String> findProjectNamesByView(String viewName) throws ViewNotFoundException {
List<String> projectNames = new ArrayList<String>();
try {
List<ProjectGroupSummary> pgs = client.getAllProjectGroups();
for (ProjectGroupSummary projectGroupSummary : pgs) {
if (projectGroupSummary.getName().equals(viewName)) {
List<ProjectSummary> projects = client.getProjects(projectGroupSummary.getId());
for (ProjectSummary project : projects) {
projectNames.add(project.getName());
}
}
}
} catch (Exception e) {
LOG.warn("Cannot get all projects groups", e);
}
return projectNames;
}
}