package br.uff.ic.dyevc.model; //~--- non-JDK imports -------------------------------------------------------- import org.eclipse.jgit.transport.URIish; //~--- JDK imports ------------------------------------------------------------ import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; /** * Indicates the status of a monitored repository, along with all known branches. * * @author Cristiano */ public class RepositoryStatus { private static final long serialVersionUID = 1735605826498282433L; /** * Repository identification. */ private String repositoryId; /** * Last time this repository was checked for status changes. */ private Date lastCheckedTime; /** * If true, indicates that this is an invalid repository. This status can * be due to access problems. */ private boolean invalid; /** * If repository is invalid, stores the exception message received trying to * access it. */ private String invalidMessage; /** * List of branches that are synchronized. */ private List<BranchStatus> syncedList; /** * List of branches that are not synchronized. */ private List<BranchStatus> nonSyncedList; /** * List of invalid branches */ private List<BranchStatus> invalidList; /** * Number of branches that are ahead */ private int aheadCount = 0; /** * Number of branches that are behind */ private int behindCount = 0; /** * Map ahead commits with the list of repositories where they exist. Gets this list from the pushesTo attribute in * the BranchStatus. */ private Map<String, Set<URIish>> aheadCommitsToRepsMap; /** * Map behind commits with the list of repositories where they do not exist. Gets this list from the pullsFrom * attribute in the BranchStatus. */ private Map<String, Set<URIish>> behindCommitsToRepsMap; /** * Constructs an object of this type * * @param repId */ public RepositoryStatus(String repId) { this.repositoryId = repId; syncedList = new ArrayList<BranchStatus>(); nonSyncedList = new ArrayList<BranchStatus>(); invalidList = new ArrayList<BranchStatus>(); invalid = false; aheadCommitsToRepsMap = new TreeMap<String, Set<URIish>>(); behindCommitsToRepsMap = new TreeMap<String, Set<URIish>>(); if (!"".equals(repId)) { lastCheckedTime = new Date(System.currentTimeMillis()); } } /** * Adds a list of BranchStatus to the list of known branches in this repository. * @param status List to be added */ public void addBranchStatusList(List<BranchStatus> status) { for (Iterator<BranchStatus> it = status.iterator(); it.hasNext(); ) { BranchStatus branchStatus = it.next(); if (branchStatus.getStatus() == BranchStatus.STATUS_OK) { syncedList.add(branchStatus); } else if (branchStatus.getStatus() == BranchStatus.STATUS_INVALID) { invalidList.add(branchStatus); } else { nonSyncedList.add(branchStatus); if (branchStatus.getAhead() > 0) { aheadCount++; updateAheadMap(branchStatus); } if (branchStatus.getBehind() > 0) { behindCount++; updateBehindMap(branchStatus); } } } } /** * Updates the map of behind commits with the behind commits in the specified branch, adding to them the pull list * associated with the branch. * @param branchStatus The branchStatus to get the list of commits and the pull list to be associated to them. */ private void updateBehindMap(BranchStatus branchStatus) { // for behind commits get pull uris, because these commits were pulled from them Set<URIish> behindBranchReps = new HashSet<URIish>(branchStatus.getPullURIs()); for (String hash : branchStatus.getListBehindCommitIds()) { Set<URIish> behindCommitReps = new HashSet<URIish>(behindBranchReps); if (behindCommitsToRepsMap.containsKey(hash)) { behindCommitReps.addAll(behindCommitsToRepsMap.get(hash)); } behindCommitsToRepsMap.put(hash, behindCommitReps); } } /** * Updates the map of ahead commits with the ahead commits in the specified branch, adding to them the push list * associated with the branch. * @param branchStatus The branchStatus to get the list of commits and the push list to be associated to them. */ private void updateAheadMap(BranchStatus branchStatus) { // for ahead commits get push uris, because these commits were not sent to them Set<URIish> aheadBranchReps = new HashSet<URIish>(branchStatus.getPushURIs()); if (aheadBranchReps.isEmpty()) { // if empty, then push uris are the same as pull uris. aheadBranchReps.addAll(branchStatus.getPullURIs()); } for (String hash : branchStatus.getListAheadCommitIds()) { Set<URIish> aheadCommitReps = new HashSet<URIish>(aheadBranchReps); if (aheadCommitsToRepsMap.containsKey(hash)) { aheadCommitReps.addAll(aheadCommitsToRepsMap.get(hash)); } aheadCommitsToRepsMap.put(hash, aheadCommitReps); } } /** * Gets the list of branches that are synchronized with the this repository. * @return the list of synchronized branches. */ public List<BranchStatus> getSyncedRepositoryBranches() { return syncedList; } /** * Gets the list of branches that are invalid. * @return the list of invalid branches. */ public List<BranchStatus> getInvalidRepositoryBranches() { return invalidList; } /** * Gets the list of branches that are not synchronized with this repository. * @return the list of branches that are not synchronized. */ public List<BranchStatus> getNonSyncedRepositoryBranches() { return nonSyncedList; } public String getRepositoryId() { return repositoryId; } public Date getLastCheckedTime() { return lastCheckedTime; } public int getNonSyncedBranchesCount() { return nonSyncedList.size(); } public int getInvalidBranchesCount() { return invalidList.size(); } public int getSyncedBranchesCount() { return syncedList.size(); } public int getTotalBranchesCount() { return nonSyncedList.size() + syncedList.size() + invalidList.size(); } public boolean isInvalid() { return invalid; } /** * @return the aheadCount */ public int getAheadCount() { return aheadCount; } /** * @return the behindCount */ public int getBehindCount() { return behindCount; } /** * @return the invalidMessage */ public String getInvalidMessage() { return invalidMessage; } /** * Sets this repository as invalid. * @param invalidMessage the message that explains why the repository was set as invalid. */ public void setInvalid(String invalidMessage) { this.invalid = true; this.invalidMessage = invalidMessage; } /** * Gets the list of URIs representing repositories that are ahead for the specified commit hash, returning an empty * Set if the hash is not found. * @param hash the hash of the commit to be queried * @return the list of URIs that do not contain the specified commit hash, or null if the hash is not found in the * <code>aheadCommitsToRepsMap</code>. */ public Set<URIish> getAheadRepsForCommit(String hash) { Set<URIish> result = aheadCommitsToRepsMap.get(hash); return (result != null) ? result : new HashSet<URIish>(); } /** * Gets the list of URIs representing repositories that are behind for the specified commit hash, returning an empty * Set if the hash is not found. * @param hash the hash of the commit to be queried * @return the list of URIs that contains the specified commit hash, or null if the hash is not found in the * <code>behindCommitsToRepsMap</code>. */ public Set<URIish> getBehindRepsForCommit(String hash) { Set<URIish> result = behindCommitsToRepsMap.get(hash); return (result != null) ? result : new HashSet<URIish>(); } }