Java tutorial
/******************************************************************************* * Copyright (C) 2011, Chris Aniszczyk <caniszczyk@gmail.com> * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Chris Aniszczyk - initial API and implementation *******************************************************************************/ package org.eclipse.egit.internal.relengtools; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExecutableExtension; import org.eclipse.egit.core.project.RepositoryMapping; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.LogCommand; import org.eclipse.jgit.api.errors.NoHeadException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.internal.util.Util; public class ShowInfoHandler extends AbstractHandler implements IExecutableExtension { static final String OLD_TAG = "v20100723-1115"; static final String NEW_TAG = "v20101018-1500"; private boolean runTest = false; /* * (non-Javadoc) * * @see * org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands. * ExecutionEvent) */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { if (runTest) { try { runTest(); } catch (final Exception e) { throw new ExecutionException(e.getMessage(), e); } return null; } // show info on an existing project final ISelection s = HandlerUtil.getCurrentSelection(event); if (s instanceof IStructuredSelection) { final Object obj = ((IStructuredSelection) s).getFirstElement(); final IProject proj = (IProject) Util.getAdapter(obj, IProject.class); if (proj != null) { try { showInfo(proj); } catch (final Exception e) { throw new ExecutionException(e.getMessage(), e); } } } return null; } private void runTest() throws Exception { // first test project deeplinkTest(); // second test project handlerTest(); } private void deeplinkTest() throws Exception { final IProject deeplink = ResourcesPlugin.getWorkspace().getRoot() .getProject("org.eclipse.e4.core.deeplink"); System.out.println("\nTest for project: " + deeplink); final RepositoryMapping rm = RepositoryMapping.getMapping(deeplink); final Repository repo = rm.getRepository(); final RevCommit expectedLastCommit = getCommit(repo, "d660f0a07c8ff16c9b46b3d69bc1c271b2cf4aba"); final RevCommit latestCommit = getLatestCommitFor(rm, repo, deeplink); System.out.println(expectedLastCommit.equals(latestCommit) + " Latest commit: expected: " + expectedLastCommit + "\n\tgot: " + latestCommit); final Map<String, Ref> tags = repo.getTags(); final Set<Ref> expectedTags = new HashSet<Ref>(Arrays.asList(tags.get(NEW_TAG))); final Set<Ref> twoTags = getTagsForCommit(repo, expectedLastCommit); System.out.println( expectedTags.equals(twoTags) + " Found tags: expected: " + expectedTags + "\n\tgot: " + twoTags); final Set<Ref> tagsContainingCommit = getTagsContainingCommit(repo, expectedLastCommit); System.out.println(expectedTags.equals(tagsContainingCommit) + " Found tags containing commit " + expectedLastCommit + ":\n\texpected: " + expectedTags + "\n\tgot: " + tagsContainingCommit); } private void handlerTest() throws Exception { final IProject handler = ResourcesPlugin.getWorkspace().getRoot() .getProject("org.eclipse.e4.core.deeplink.handler"); System.out.println("\nTest for project: " + handler); final RepositoryMapping rm = RepositoryMapping.getMapping(handler); final Repository repo = rm.getRepository(); final RevCommit expectedLastCommit = getCommit(repo, "b42ad39c90fc57b679154ca33dfb306004dc08a3"); final RevCommit latestCommit = getLatestCommitFor(rm, repo, handler); System.out.println(expectedLastCommit.equals(latestCommit) + " Latest commit: expected: " + expectedLastCommit + "\n\tgot: " + latestCommit); final Set<Ref> expectedTags = Collections.EMPTY_SET; final Set<Ref> noTags = getTagsForCommit(repo, expectedLastCommit); System.out.println( expectedTags.equals(noTags) + " Found tags: expected: " + expectedTags + "\n\tgot: " + noTags); final Map<String, Ref> tags = repo.getTags(); final Set<Ref> expectedContainingTags = new HashSet<Ref>(Arrays.asList(tags.get("R0_10"), tags.get("v20100722-1700"), tags.get("v20100723-1115"), tags.get("v20101018-1500"))); final Set<Ref> tagsContainingCommit = getTagsContainingCommit(repo, expectedLastCommit); System.out.println(expectedContainingTags.equals(tagsContainingCommit) + " Found tags containing commit " + expectedLastCommit + ":\n\texpected: " + expectedContainingTags + "\n\tgot: " + tagsContainingCommit); } /** * @param proj * @throws Exception */ private void showInfo(IProject proj) throws Exception { final RepositoryMapping rm = RepositoryMapping.getMapping(proj); final Repository repo = rm.getRepository(); // final RevCommit latestCommit = getLatestCommitFor(rm, repo, proj); final RevCommit latestCommit = getLatestCommitFor(rm, repo, proj); System.out.println(latestCommit + ": " + latestCommit.getShortMessage()); final RevCommit oldCommit = getCommitForTag(repo, OLD_TAG); final RevCommit newCommit = getCommitForTag(repo, NEW_TAG); System.out.println(getTagsForCommit(repo, newCommit)); System.out.println(getTagsForCommit(repo, newCommit)); System.out.println(getTagsForCommit(repo, getCommit(repo, "b42ad39c90fc57b679154ca33dfb306004dc08a3"))); showLogBetween(repo, oldCommit, newCommit); } public static void showLogBetween(final Repository repo, final RevCommit oldCommit, final RevCommit newCommit) throws MissingObjectException, IncorrectObjectTypeException, NoHeadException, Exception { final Git git = new Git(repo); final LogCommand command = git.log(); command.addRange(oldCommit, newCommit); System.out.println("\nCommits:"); for (final RevCommit rc : command.call()) { System.out.println(rc); System.out.print("Tags: "); System.out.println(getTagsForCommit(repo, rc)); System.out.println(rc.getShortMessage()); } } public static RevCommit getLatestCommitFor(RepositoryMapping mapping, Repository repo, IProject project) throws Exception { final RevWalk walk = new RevWalk(repo); walk.reset(); walk.sort(RevSort.TOPO, true); walk.sort(RevSort.COMMIT_TIME_DESC, true); walk.setTreeFilter( AndTreeFilter.create(TreeFilter.ANY_DIFF, PathFilter.create(mapping.getRepoRelativePath(project)))); final ObjectId start = repo.resolve(Constants.HEAD); walk.markStart(walk.parseCommit(start)); // I should only be able to see commits that contain files // where project is a path prefix final RevCommit commit = walk.next(); return commit; } public static RevCommit getCommitForTag(Repository repo, String name) throws Exception { final Ref ref = repo.getTags().get(name); final RevWalk walk = new RevWalk(repo); final RevObject obj = walk.parseAny(ref.getObjectId()); final RevCommit tagCommit; if (obj instanceof RevCommit) { tagCommit = (RevCommit) obj; } else { tagCommit = walk.parseCommit(((RevTag) obj).getObject()); } return tagCommit; } public static Set<Ref> getTagsForCommit(Repository repo, RevCommit c) throws Exception { initializeTagMap(repo); Set<Ref> s = commitToTagRef.get(c); if (s == null) { s = Collections.EMPTY_SET; } return s; } private static HashMap<RevCommit, Set<Ref>> commitToTagRef = null; private static void initializeTagMap(Repository repo) throws Exception { if (commitToTagRef == null) { final RevWalk walk = new RevWalk(repo); commitToTagRef = new HashMap<RevCommit, Set<Ref>>(); for (final Ref ref : repo.getTags().values()) { final RevObject obj = walk.parseAny(ref.getObjectId()); RevCommit commit = null; if (obj instanceof RevCommit) { commit = (RevCommit) obj; } else if (obj instanceof RevTag) { commit = walk.parseCommit(((RevTag) obj).getObject()); } Set<Ref> tags = commitToTagRef.get(commit); if (tags == null) { tags = new HashSet<Ref>(); commitToTagRef.put(commit, tags); } tags.add(ref); } } } // mimic git tag --contains <commit> private static Set<Ref> getTagsContainingCommit(Repository repo, RevCommit commit) throws Exception { final Set<Ref> tags = new HashSet<Ref>(); final RevWalk walk = new RevWalk(repo); commit = walk.parseCommit(commit); for (final Ref ref : repo.getTags().values()) { final RevCommit tagCommit; try { tagCommit = walk.parseCommit(ref.getObjectId()); } catch (final IncorrectObjectTypeException notCommit) { continue; } if (walk.isMergedInto(commit, tagCommit)) { tags.add(ref); } } return tags; } public static RevCommit getCommit(Repository repo, String name) throws Exception { final RevWalk walk = new RevWalk(repo); final ObjectId id = repo.resolve(name); return walk.parseCommit(id); } @Override public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { if ("test".equals(data)) { runTest = true; } } }