package hudson.plugins.synergy;
import hudson.model.AbstractBuild;
import hudson.model.User;
import hudson.scm.ChangeLogSet;
import hudson.scm.EditType;
import java.io.IOException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
public final class SynergyChangeLogSet extends ChangeLogSet<SynergyChangeLogSet.LogEntry> {
private final List<LogEntry> logs;
/**
* @GuardedBy this
*/
private Map<String, Long> revisionMap;
public SynergyChangeLogSet(AbstractBuild build, List<LogEntry> logs) {
super(build);
// we want recent changes first
// TODO
/*
Collections.sort(logs, new Comparator<LogEntry>() {
public int compare(LogEntry a, LogEntry b) {
return b.getTaskId().compareTo(a.get)
}
});
*/
this.logs = Collections.unmodifiableList(logs);
for (LogEntry log : logs)
log.setParent(this);
}
public boolean isEmptySet() {
return logs.isEmpty();
}
public List<LogEntry> getLogs() {
return logs;
}
public Iterator<LogEntry> iterator() {
return logs.iterator();
}
public synchronized Map<String, Long> getRevisionMap() throws IOException {
if (revisionMap == null)
revisionMap = SynergySCM.parseRevisionFile(build);
return revisionMap;
}
@Exported
public List<RevisionInfo> getRevisions() throws IOException {
List<RevisionInfo> r = new ArrayList<RevisionInfo>();
for (Map.Entry<String, Long> e : getRevisionMap().entrySet())
r.add(new RevisionInfo(e.getKey(), e.getValue()));
return r;
}
@ExportedBean(defaultVisibility = 999)
public static final class RevisionInfo {
@Exported
public final String module;
@Exported
public final long revision;
public RevisionInfo(String module, long revision) {
this.module = module;
this.revision = revision;
}
}
/**
* One commit.
* <p>
* Setter methods are public only so that the objects can be constructed
* from Digester. So please consider this object read-only.
*/
public static class LogEntry extends ChangeLogSet.Entry {
private String taskId;
private int version;
private User author;
private String date;
private String msg;
private List<Path> paths = new ArrayList<Path>();
/**
* Gets the {@link SynergyChangeLogSet} to which this change set
* belongs.
*/
public SynergyChangeLogSet getParent() {
return (SynergyChangeLogSet) super.getParent();
}
/**
* Gets the id of the task.
*/
@Exported
public String getTaskId() {
return taskId;
}
@Exported
public void setTaskId(String id) {
this.taskId = id;
}
@Override
public User getAuthor() {
if (author == null)
return User.getUnknown();
return author;
}
@Override
public Collection<String> getAffectedPaths() {
return new AbstractList<String>() {
public String get(int index) {
return paths.get(index).value;
}
public int size() {
return paths.size();
}
};
}
public void setUser(String author) {
this.author = User.get(author);
}
@Exported
public String getUser() {
return author==null ? null : author.getDisplayName();
}
@Exported
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
@Override
@Exported
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void addPath(Path p) {
p.entry = this;
paths.add(p);
}
/**
* Gets the files that are changed in this commit.
*
* @return can be empty but never null.
*/
@Exported
public List<Path> getPaths() {
return paths;
}
public void setParent(SynergyChangeLogSet parent) {
super.setParent(parent);
}
@Exported
public int getVersion() {
return version;
}
@Exported
public void setVersion(int version) {
this.version = version;
}
}
/**
* A file in a commit.
* <p>
* Setter methods are public only so that the objects can be constructed
* from Digester. So please consider this object read-only.
*/
@ExportedBean(defaultVisibility = 999)
public static class Path {
private LogEntry entry;
private char action;
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
private String value;
/**
* Gets the {@link LogEntry} of which this path is a member.
*/
public LogEntry getLogEntry() {
return entry;
}
/**
* Sets the {@link LogEntry} of which this path is a member.
*/
public void setLogEntry(LogEntry entry) {
this.entry = entry;
}
public void setAction(String action) {
this.action = action.charAt(0);
}
/**
* Path in the repository. Such as <tt>/test/trunk/foo.c</tt>
*/
@Exported(name = "file")
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Exported
public EditType getEditType() {
if (action == 'A')
return EditType.ADD;
if (action == 'D')
return EditType.DELETE;
return EditType.EDIT;
}
}
}