package br.uff.ic.dyevc.model; //~--- non-JDK imports -------------------------------------------------------- import br.uff.ic.dyevc.tools.vcs.git.GitCommitTools; import org.codehaus.jackson.annotate.JsonIgnoreProperties; import org.codehaus.jackson.annotate.JsonProperty; import org.codehaus.jackson.annotate.JsonPropertyOrder; //~--- JDK imports ------------------------------------------------------------ import java.io.Serializable; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; /** * Stores information about a singular commit made to VCS. * * @author Cristiano */ @JsonIgnoreProperties( value = { "repositoryId", "inWalk", "parentsCount", "parentsCountLock", "childrenCount", "childrenCountLock", "changeSet", "visited", "author", "flags", "previousFoundIn", "type" }, ignoreUnknown = true ) @JsonPropertyOrder(value = { "_id", "systemName", "commitDate", "committer", "shortMessage", "parents", "foundIn", "lastChanged", "tracked" }) public class CommitInfo implements Comparable<CommitInfo>, Serializable { /** * Number of parents this commit has. If greater than one, this was a merge. * If zero, this was the first commit. */ private int parentsCount = 0; private final Integer parentsCountLock = new Integer(0); /** * Number of children this commit has. If zero, this is a head. If greater * than one, there are branches after this commit. */ private int childrenCount = 0; private final Integer childrenCountLock = new Integer(0); /** * Set of the paths that were affected by this commit */ private Set<CommitChange> changeSet = null; /** * Indicates if this commit was already visited in the process of plotting the graph */ private boolean visited = false; /** * Commit's identification. */ @JsonProperty(value = "_id") protected String hash; /** * System name where this commit is found */ private String systemName; /** * Date the commit was done. */ protected Date commitDate; /** * Commiter (one's that effectively executed the commit action. */ private String committer; /** * Short message written together with the commit. */ private String shortMessage; private Set<String> parents; private Set<String> foundIn; private Set<String> previousFoundIn; private boolean tracked; protected byte type; public byte getType() { return type; } public void setType(byte type) { this.type = type; } public boolean isTracked() { return tracked; } public void setTracked(boolean tracked) { this.tracked = tracked; } public Set<String> getPreviousFoundIn() { return previousFoundIn; } public void setPreviousFoundIn(Set<String> previousFoundIn) { this.previousFoundIn = previousFoundIn; } /** * The id of any repository where this commit was found */ private String repositoryId; /** * Author of commit. */ private String author; /** * Date this commit was last changed in database; */ private Date lastChanged; /** * Constructs a new CommitInfo object. This constructor should not be used by the application. It exists just * and only to be used by JSON framework, when (de)serializing objects to / from JSON notation. */ public CommitInfo() {} /** * Constructs a CommitInfo object with the specified parameters. * @param id The id of this CommitInfo, represented by its hash. * @param repositoryId The id of the repository from where this commit was read. */ public CommitInfo(String id, String repositoryId) { this.hash = id; this.repositoryId = repositoryId; this.parents = new HashSet<String>(); this.foundIn = new HashSet<String>(); } /** * Gets the hash of this CommitInfo. * @return The hash of this CommitInfo. */ public String getHash() { return hash; } /** * Sets the hash of this CommitInfo. * @param hash The new hash. */ public void setHash(String hash) { this.hash = hash; } /** * Gets the system name of this CommitInfo. * @return The system name of this CommitInfo. */ public String getSystemName() { return systemName; } /** * Sets the systemName. * @param systemName The systemName to set. */ public void setSystemName(String systemName) { this.systemName = systemName; } /** * Gets the repositoryId of this CommitInfo. * @return The repositoryId of this CommitInfo. */ public String getRepositoryId() { return repositoryId; } /** * Sets the repositoryId * @param repositoryId The repositoryId to set. */ public void setRepositoryId(String repositoryId) { this.repositoryId = repositoryId; } /** * Gets the commitDate of this CommitInfo. * @return The commitDate of this CommitInfo. */ public Date getCommitDate() { return commitDate; } /** * Sets the commitDate. * @param commitDate The commitDate to set. */ public void setCommitDate(Date commitDate) { this.commitDate = commitDate; } /** * Gets the author of this CommitInfo. * @return The author of this CommitInfo. */ public String getAuthor() { return author; } /** * Sets the author. * @param author The author to set. */ public void setAuthor(String author) { this.author = author; } /** * Gets the committer of this CommitInfo. * @return The committer of this CommitInfo. */ public String getCommitter() { return committer; } /** * Sets the committer. * @param committer The committer to set. */ public void setCommitter(String committer) { this.committer = committer; } /** * Gets the shortMessage of this CommitInfo. * @return The shortMessage of this CommitInfo. */ public String getShortMessage() { return shortMessage; } /** * Sets the shortMessage. * @param shortMessage The shortMessage to set. */ public void setShortMessage(String shortMessage) { this.shortMessage = shortMessage; } /** * Returns a set with the id of each parent for this CommitInfo * @return Set of parent id for this CommitInfo. */ public Set<String> getParents() { // if inWalk, flags must be at least 1 to return parents. if (inWalk && (flags == 0)) { return null; } return parents; } /** * Sets the parents. * @param parents The parents to set. */ public void setParents(Set<String> parents) { this.parents = parents; this.parentsCount = parents.size(); } /** * Gets the set of repository ids where this CommitInfo is known to exist. * @return The set of repository ids where this CommitInfo is known to exist. */ public Set<String> getFoundIn() { return foundIn; } /** * Sets the foundIn. * @param foundIn The foundIn to set. */ public void setFoundIn(Set<String> foundIn) { this.foundIn = foundIn; } /** * Adds a repository id to the set of foundIn repository ids. * @param repId The repository id to be added. */ public void addFoundIn(String repId) { this.foundIn.add(repId); } /** * Adds a collection of repository ids to the set of foundIn repository ids. * @param repIds The collection of repository ids to be added. */ public void addAllToFoundIn(Collection<String> repIds) { this.foundIn.addAll(repIds); } /** * Gets the date this object was last changed in database. * @return the last changed date. */ public Date getLastChanged() { return lastChanged; } /** * Sets the lastChanged * @param lastChanged The lastChanged to set. */ public void setLastChanged(Date lastChanged) { this.lastChanged = lastChanged; } /** * Increment the number of children for this CommitInfo. */ public void incrementChildren() { synchronized (childrenCountLock) { childrenCount++; } } /** * Increment the number of parents for this CommitInfo. */ public void incrementParents() { synchronized (parentsCountLock) { parentsCount++; } } @Override public String toString() { return hash.substring(0, 5); } /** * Gets the number of parents of this CommitInfo. * @return The number of parents of this CommitInfo. */ public int getParentsCount() { synchronized (parentsCountLock) { return parentsCount; } } /** * Gets the number of children of this CommitInfo. * * @return The number of children of this CommitInfo. */ public int getChildrenCount() { synchronized (childrenCountLock) { return childrenCount; } } @Override public int compareTo(CommitInfo o) { int result = 0; if (o == null) { throw new NullPointerException("Cannot compare to a null commit object."); } if ((this.getCommitDate()) != null && (this.getCommitDate().before(o.getCommitDate()))) { result = -1; } if ((this.getCommitDate()) != null && (this.getCommitDate().after(o.getCommitDate()))) { result = 1; } if ((this.getCommitDate()) != null && (this.getCommitDate().equals(o.getCommitDate()))) { result = this.getHash().compareTo(o.getHash()); } return result; } /** * @return the visited */ public boolean isVisited() { return visited; } /** * @param visited the visited to set */ public void setVisited(boolean visited) { this.visited = visited; } /** * @return the changeSet */ public synchronized Set<CommitChange> getChangeSet() { if (changeSet == null) { changeSet = GitCommitTools.getCommitChangeSet(hash, repositoryId); } return changeSet; } /** * @param changeSet the changeSet to set */ public void setChangeSet(Set<CommitChange> changeSet) { this.changeSet = changeSet; } /** * Adds a commit change to this CommitInfo change set. * @param cc The change to added to the change set. */ public void addChangeSet(CommitChange cc) { if (changeSet == null) { changeSet = new TreeSet<CommitChange>(); } this.changeSet.add(cc); } @Override public int hashCode() { int hash = 7; hash = 37 * hash + ((this.hash != null) ? this.hash.hashCode() : 0); return hash; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final CommitInfo other = (CommitInfo)obj; return !((this.hash == null) ? (other.hash != null) : !this.hash.equals(other.hash)); } /** * Indicates that this CommitInfo is being walked and though should use flags to decide * whether parents will be returned or not. If true, parents will be returned only if marked * as {@link br.uff.ic.dyevc.tools.vcs.git.CommonAncestralFinder#PARSED}. */ private boolean inWalk; /** Flags is used to walk through commits. */ private int flags; /** * Gets the flags. * @return The flags. */ public int getFlags() { return flags; } /** * Sets the flags * @param flags The flags to set. */ public void setFlags(int flags) { this.flags = flags; } /** * Marks this CommitInfo as being in a walk. */ public void markInWalk() { inWalk = true; } /** * Resets this CommitInfo and releases it to be walked another time. */ public void resetWalk() { inWalk = false; this.setFlags(0); } }