package de.hub.srcrepo; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.EObject; import de.hub.srcrepo.ISourceControlSystem.SourceControlException; import de.hub.srcrepo.repositorymodel.Diff; import de.hub.srcrepo.repositorymodel.RepositoryModel; import de.hub.srcrepo.repositorymodel.RepositoryModelFactory; import de.hub.srcrepo.repositorymodel.Rev; /** * This visitor checks out each rev. */ public class RepositoryModelRevisionCheckoutVisitor implements IRepositoryModelVisitor { protected final ISourceControlSystem sourceControlSystem; protected final RepositoryModel repositoryModel; protected final RepositoryModelFactory repositoryFactory; // volatile private Rev currentRev; public RepositoryModelRevisionCheckoutVisitor(ISourceControlSystem sourceControlSystem, RepositoryModel repositoryModel) { this.sourceControlSystem = sourceControlSystem; this.repositoryFactory = (RepositoryModelFactory)repositoryModel.eClass().getEPackage().getEFactoryInstance(); this.repositoryModel = repositoryModel; } @Override public void onMerge(Rev mergeRev, Rev branchRev) { } @Override public void onBranch(Rev commonPreviousRev, Rev newBranchRev) { } private void runJob(WorkspaceJob job) { job.setRule(ResourcesPlugin.getWorkspace().getRoot()); job.schedule(); try { job.join(); } catch (InterruptedException e) { new RuntimeException("Interupt during job execution. Impossible.", e); } IStatus result = job.getResult(); if (result == null) { throw new RuntimeException("Job without result after joined execution. Impossible."); } if (!result.isOK()) { if (result.matches(IStatus.ERROR)) { Throwable e = result.getException(); reportImportError(currentRev, "Unexpected error during job execution [" + job.getName() + "]", e, false); } else { reportImportError(currentRev, "Job with unexpected status [" + job.getName() + "]", null, false); } } } @Override public boolean onStartRev(final Rev rev, Rev traversalParentRev, int number) { SrcRepoActivator.INSTANCE.info("Visit rev " + rev.getName() + " " + "(" + number + "/" + repositoryModel.getAllRevs().size() + ")"); String author = rev.getAuthor(); author = author == null ? "[NO AUTHOR]" : author.trim(); String message = rev.getMessage(); message = message == null ? "[NO MESSAGE]" : message.trim(); SrcRepoActivator.INSTANCE.info("Info for visited ref; " + rev.getTime() +", " + author + ":\n" + message); // move current ref to the new ref currentRev = rev; // checkout the new ref runJob(new CheckoutJob()); return true; } @Override public void onCompleteRev(Rev rev, Rev traversalParentRev) { } @Override public void onCopiedFile(Diff diff) { } @Override public void onRenamedFile(Diff diff) { } @Override public void onAddedFile(Diff diff) { onModifiedFile(diff); } @Override public void onModifiedFile(final Diff diff) { } @Override public void onDeletedFile(Diff diff) { } private class CheckoutJob extends WorkspaceJob { public CheckoutJob() { super(RepositoryModelRevisionCheckoutVisitor.class.getName() + " git checkout."); } @Override public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { // checkout try { sourceControlSystem.checkoutRevision(currentRev.getName()); } catch (SourceControlException e) { reportImportError(currentRev, "Error while checking out.", e, true); } catch (Exception e) { reportImportError(currentRev, "Exception while checking out.", e, true); } return Status.OK_STATUS; } } protected void reportImportError(EObject owner, String message, Throwable e, boolean controlledFail) { if (e != null) { message += ": " + e.getMessage() + "[" + e.getClass().getCanonicalName() + "]."; } if (controlledFail) { SrcRepoActivator.INSTANCE.warning(message, (Exception)e); } else { SrcRepoActivator.INSTANCE.error(message, (Exception)e); } } @Override public void close(RepositoryModel repositoryModel) { } }