package de.hub.srcrepo; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.TimeUnit; import com.google.common.base.Preconditions; import de.hub.jstattrack.Statistics; import de.hub.jstattrack.Statistics.UUID; import de.hub.jstattrack.TimeStatistic; import de.hub.jstattrack.TimeStatistic.Timer; import de.hub.jstattrack.services.BatchedPlot; import de.hub.jstattrack.services.Summary; import de.hub.srcrepo.repositorymodel.AbstractFileRef; import de.hub.srcrepo.repositorymodel.DataSet; import de.hub.srcrepo.repositorymodel.Diff; import de.hub.srcrepo.repositorymodel.RepositoryModel; import de.hub.srcrepo.repositorymodel.RepositoryModelFactory; import de.hub.srcrepo.repositorymodel.Rev; public abstract class AbstractRevVisitor implements IRepositoryModelVisitor { public static final UUID revVisitET = Statistics.UUID(AbstractRevVisitor.class, "RevVisitET"); public static final String traverseMetaData = "TraverseMetaData"; private int i = 0; private Map<String, Object> files = new HashMap<String, Object>(); private Map<Rev, Map<String, Object>> branches = new HashMap<Rev, Map<String, Object>>(); public static final TimeStatistic revVisistETStat = new TimeStatistic(TimeUnit.MICROSECONDS).with(Summary.class) .with(BatchedPlot.class).register(revVisitET); private Timer revVisitETStatTimer = null; protected Rev lastVisitedRev = null; protected abstract void clearFiles(); protected abstract void addFile(String name, Object file); protected abstract void removeFile(String name); protected abstract void onRev(Rev rev, Rev traversalParentRev); protected abstract Object getFile(AbstractFileRef fileRef); protected String revInfo(Rev rev) { return rev.getName() + " (" + i++ + "/" + ((RepositoryModel)rev.eContainer()).getAllRevs().size() + ")"; } @Override public void onBranch(Rev commonPreviousRev, Rev newBranchRev) { if (commonPreviousRev == null) { // new root files.clear(); clearFiles(); } else { Map<String, Object> oldFiles = branches.get(commonPreviousRev); if (oldFiles == null) { // first time on a branch, the commonPreviousRev should be the // last visited revison, can keep all files and should save them for // traversal of other branches. Preconditions.checkArgument(commonPreviousRev == lastVisitedRev); branches.put(commonPreviousRev, new HashMap<String, Object>(files)); } else { // real branch, load the files from the last common revision files.clear(); clearFiles(); files.putAll(oldFiles); for (Entry<String, Object> entry : oldFiles.entrySet()) { addFile(entry.getKey(), entry.getValue()); } } } } @Override public void onMerge(Rev commonMergedRev, Rev lastBranchRev) { // nothing to do } @Override public boolean onStartRev(Rev rev, Rev traversalParentRev, int number) { revVisitETStatTimer = revVisistETStat.timer(); return false; } @Override public void onCompleteRev(Rev rev, Rev traversalParentRev) { try { onRev(rev, traversalParentRev); } catch (Exception e) { SrcRepoActivator.INSTANCE.error("Error in visiting rev: " + rev.getName(), e); } lastVisitedRev = rev; revVisitETStatTimer.track(); } @Override public void onCopiedFile(Diff diff) { AbstractFileRef ref = diff.getFile(); if (ref != null) { Object file = getFile(ref); if (file != null) { files.put(diff.getNewPath(), file); addFile(diff.getNewPath(), file); } } } @Override public void onRenamedFile(Diff diff) { AbstractFileRef ref = diff.getFile(); files.remove(diff.getOldPath()); removeFile(diff.getOldPath()); if (ref != null) { Object file = getFile(ref); if (file != null) { files.put(diff.getNewPath(), file); addFile(diff.getNewPath(), file); } } } @Override public void onAddedFile(Diff diff) { AbstractFileRef ref = diff.getFile(); if (ref != null) { Object file = getFile(ref); if (file != null) { files.put(diff.getNewPath(), file); addFile(diff.getNewPath(), file); } } } @Override public void onModifiedFile(Diff diff) { AbstractFileRef ref = diff.getFile(); files.remove(diff.getOldPath()); removeFile(diff.getOldPath()); if (ref != null) { Object file = getFile(ref); if (file != null) { files.put(diff.getNewPath(), file); addFile(diff.getNewPath(), file); } } } @Override public void onDeletedFile(Diff diff) { files.remove(diff.getOldPath()); removeFile(diff.getOldPath()); } @Override public void close(RepositoryModel repositoryModel) { RepositoryModelFactory factory = (RepositoryModelFactory) repositoryModel.eClass().getEPackage() .getEFactoryInstance(); DataSet dataSet = RepositoryModelUtil.getData(repositoryModel, traverseMetaData); if (dataSet == null) { dataSet = factory.createDataSet(); dataSet.setName(traverseMetaData); repositoryModel.getDataSets().add(dataSet); } updateTraverseMetaData(dataSet); } protected void updateTraverseMetaData(DataSet dataSet) { dataSet.setJsonData(Statistics.reportToJSON().toString(1)); } }