/* license-start * * Copyright (C) 2008 - 2013 Crispico, <http://www.crispico.com/>. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details, at <http://www.gnu.org/licenses/>. * * Contributors: * Crispico - Initial API and implementation * * license-end */ package org.flowerplatform.web.git.history.remote; import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang3.StringEscapeUtils; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryCache; import org.eclipse.jgit.lib.RepositoryCache.FileKey; import org.eclipse.jgit.lib.RepositoryState; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.RevWalkUtils; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.PathFilterGroup; import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.jgit.util.FS; import org.flowerplatform.common.CommonPlugin; import org.flowerplatform.communication.CommunicationPlugin; import org.flowerplatform.communication.channel.CommunicationChannel; import org.flowerplatform.communication.channel.ICommunicationChannelLifecycleListener; import org.flowerplatform.communication.command.DisplaySimpleMessageClientCommand; import org.flowerplatform.communication.stateful_service.IStatefulClientLocalState; import org.flowerplatform.communication.stateful_service.IStatefulServiceMXBean; import org.flowerplatform.communication.stateful_service.RegularStatefulService; import org.flowerplatform.communication.stateful_service.RemoteInvocation; import org.flowerplatform.communication.stateful_service.StatefulServiceInvocationContext; import org.flowerplatform.communication.tree.NodeInfo; import org.flowerplatform.communication.tree.remote.GenericTreeStatefulService; import org.flowerplatform.communication.tree.remote.PathFragment; import org.flowerplatform.web.git.GitNodeType; import org.flowerplatform.web.git.GitPlugin; import org.flowerplatform.web.git.GitService; import org.flowerplatform.web.git.GitUtils; import org.flowerplatform.web.git.explorer.entity.RefNode; import org.flowerplatform.web.git.history.internal.FileDiff; import org.flowerplatform.web.git.history.internal.WebCommit; import org.flowerplatform.web.git.history.internal.WebCommitList; import org.flowerplatform.web.git.history.internal.WebCommitPlotRenderer; import org.flowerplatform.web.git.history.internal.WebWalk; import org.flowerplatform.web.git.history.remote.dto.HistoryEntryDto; import org.flowerplatform.web.git.history.remote.dto.HistoryFileDiffEntryDto; import org.flowerplatform.web.git.history.remote.dto.HistoryViewInfoDto; import org.flowerplatform.web.git.remote.dto.CommitDto; /** * @author Cristina Constantinescu */ @SuppressWarnings({ "restriction", "rawtypes", "unchecked" }) public class GitHistoryStatefulService extends RegularStatefulService<CommunicationChannel, HistoryViewInfoDto> implements IStatefulServiceMXBean, ICommunicationChannelLifecycleListener { public static final String SERVICE_ID = "GitHistoryStatefulService"; private static final String STATEFUL_CLIENT_ID = "Git History"; public GitHistoryStatefulService() { super(); clients = new HashMap<CommunicationChannel, HistoryViewInfoDto>(); } /////////////////////////////////////////////////////////////// // JMX Methods /////////////////////////////////////////////////////////////// public Collection<String> getStatefulClientIdsForCommunicationChannel(CommunicationChannel communicationChannel) { return Collections.singleton(STATEFUL_CLIENT_ID); } /////////////////////////////////////////////////////////////// // Normal methods /////////////////////////////////////////////////////////////// @Override protected String getStatefulServiceId() { return SERVICE_ID; } public static GitHistoryStatefulService getInstance() { return (GitHistoryStatefulService) CommunicationPlugin.getInstance().getServiceRegistry().getService(SERVICE_ID); } @Override protected HistoryViewInfoDto getDataFromStatefulClientLocalState(StatefulServiceInvocationContext context, IStatefulClientLocalState statefulClientLocalState) { // channel destroyed if (statefulClientLocalState == null) { return null; } return ((GitHistoryStatefulClientLocalState) statefulClientLocalState).getInfo(); } @Override public void communicationChannelCreated(CommunicationChannel webCommunicationChannel) { // do nothing } @Override public void communicationChannelDestroyed(CommunicationChannel webCommunicationChannel) { unsubscribe(new StatefulServiceInvocationContext(webCommunicationChannel, null, null), null); } private WebWalk getWebWalk(CommunicationChannel channel, HistoryViewInfoDto info) throws IOException { configObjectInfo(channel, info); // if (!info.getIsResource()) { String path = null; if (info.getFile() != null) { IPath workdirPath = new Path(info.getRepository().getWorkTree().getPath()); int segmentCount = workdirPath.segmentCount(); IPath filePath = null; if (info.getFilter() == HistoryViewInfoDto.SHOWALLFOLDER) { filePath = new Path(info.getFile().getParentFile().getPath()); } else /* if (showAllFilter == ShowFilter.SHOWALLRESOURCE) */{ filePath = new Path(info.getFile().getPath()); } if (filePath != null) { path = filePath.removeFirstSegments(segmentCount).setDevice(null).toString(); } } WebWalk walk = new WebWalk(info.getRepository()); setupWalk(walk, info.getRepository(), path); info.setPath(path); return walk; // } else { // RepositoryMapping mapping = RepositoryMapping.getMapping(info.getResource()); // // String path = null; // if (info.getFilter() == HistoryViewInfoDto.SHOWALLFOLDER) { // // if the resource's parent is the workspace root, we will // // get nonsense from map.getRepoRelativePath(), so we // // check here and use the project instead // if (info.getResource().getParent() instanceof IWorkspaceRoot) { // path = mapping.getRepoRelativePath(info.getResource().getProject()); // } else { // path = mapping.getRepoRelativePath(info.getResource().getParent()); // } // } else if (info.getFilter() == HistoryViewInfoDto.SHOWALLPROJECT) { // path = mapping.getRepoRelativePath(info.getResource().getProject()); // } else if (info.getFilter() == HistoryViewInfoDto.SHOWALLREPO) { // // nothing // } else /* if (showAllFilter == ShowFilter.SHOWALLRESOURCE) */{ // path = mapping.getRepoRelativePath(info.getResource()); // } // // WebWalk walk = new WebWalk(info.getRepository()); // setupWalk(walk, info.getRepository(), path); // // info.setPath(path); // // return walk; // } } private void setupWalk(WebWalk walk, Repository repo, String path) throws IOException { walk.addAdditionalRefs(repo.getRefDatabase().getAdditionalRefs()); walk.addAdditionalRefs(repo.getRefDatabase().getRefs(Constants.R_NOTES).values()); walk.sort(RevSort.COMMIT_TIME_DESC, true); walk.sort(RevSort.BOUNDARY, true); walk.setRetainBody(false); setWalkStartPoints(walk, repo, walk.parseCommit(repo.resolve(Constants.HEAD))); createFileWalker(walk, repo, path); } private TreeWalk createFileWalker(RevWalk walk, Repository db, String path) { TreeWalk fileWalker = new TreeWalk(db); fileWalker.setRecursive(true); fileWalker.setFilter(TreeFilter.ANY_DIFF); if (path == null || path.isEmpty()) { walk.setTreeFilter(TreeFilter.ALL); } else { List<String> stringPaths = new ArrayList<String>(1); stringPaths.add(path); walk.setTreeFilter(AndTreeFilter.create(PathFilterGroup .createFromStrings(stringPaths), TreeFilter.ANY_DIFF)); } return fileWalker; } private String getCommitMessage(Repository repo, HistoryEntryDto entry, RevCommit commit) throws IOException { DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); int maxBranches = 20; StringBuilder d = new StringBuilder(); d.append("<p>"); d.append(GitPlugin.getInstance().getMessage("git.history.commitMessage.commit")); d.append(" "); d.append(commit.getId().name()); d.append("<br>"); PersonIdent author = commit.getAuthorIdent(); if (author != null) { d.append(GitPlugin.getInstance().getMessage("git.history.commitMessage.author")); d.append(": "); d.append(author.getName()); d.append(" <"); d.append(author.getEmailAddress()); d.append("> "); d.append(fmt.format(author.getWhen())); d.append("<br>"); } PersonIdent committer = commit.getCommitterIdent(); if (committer != null) { d.append(GitPlugin.getInstance().getMessage("git.history.commitMessage.committer")); d.append(": "); d.append(committer.getName()); d.append(" <"); d.append(committer.getEmailAddress()); d.append("> "); d.append(fmt.format(committer.getWhen())); d.append("<br>"); } for (CommitDto parent : entry.getCommitMessage().getParents()) { d.append(GitPlugin.getInstance().getMessage("git.history.commitMessage.parent")); d.append(": "); d.append(String.format("<u><a href=''>%s</a></u>", parent.getId())); d.append(" ("); d.append(parent.getLabel()); d.append(")"); d.append("<br>"); } for (CommitDto child : entry.getCommitMessage().getChildren()) { d.append(GitPlugin.getInstance().getMessage("git.history.commitMessage.child")); d.append(": "); d.append(String.format("<u><a href=''>%s</a></u>", child.getId())); d.append(" ("); d.append(child.getLabel()); d.append(")"); d.append("<br>"); } List<Ref> branches = getBranches(commit, getBranches(repo), repo); if (!branches.isEmpty()) { d.append(GitPlugin.getInstance().getMessage("git.history.commitMessage.branches")); d.append(": "); int count = 0; for (Iterator<Ref> i = branches.iterator(); i.hasNext();) { Ref head = i.next(); d.append(formatHeadRef(head)); if (i.hasNext()) { if (count++ <= maxBranches) { d.append(", "); } else { d.append(GitPlugin.getInstance().getMessage( "git.history.commitMessage.author", new Object[] {Integer.valueOf(branches.size() - maxBranches)})); break; } } } d.append("<br>"); } String tagsString = getTagsString(repo, commit); if (tagsString.length() > 0) { d.append(GitPlugin.getInstance().getMessage("git.history.commitMessage.tags")); d.append(": "); d.append(tagsString); d.append("<br>"); } d.append("<br>"); d.append(String.format("<b>%s</b>", StringEscapeUtils.escapeHtml3(commit.getFullMessage()).replaceAll("\n", "<br>"))); d.append("</p>"); return d.toString(); } // private List<RefNode> getRefNodes(RevCommit commit, Repository repo, String refPrefix) { // List<Ref> availableBranches = new ArrayList<Ref>(); // List<RefNode> nodes = new ArrayList<RefNode>(); // try { // Map<String, Ref> branches = repo.getRefDatabase().getRefs(refPrefix); // for (Ref branch : branches.values()) { // if (branch.getLeaf().getObjectId().equals(commit.getId())) // availableBranches.add(branch); // } // RepositoryNode repoNode = new RepositoryNode(null, repo); // for (Ref ref : availableBranches) // nodes.add(new RefNode(repoNode, repo, ref)); // // } catch (IOException e) { // // ignore here // } // return nodes; // } private List<Ref> getBranches(RevCommit commit, Collection<Ref> allRefs, Repository db) throws MissingObjectException, IncorrectObjectTypeException, IOException { RevWalk revWalk = new RevWalk(db); try { revWalk.setRetainBody(false); return RevWalkUtils.findBranchesReachableFrom(commit, revWalk, allRefs); } finally { revWalk.dispose(); } } private List<Ref> getBranches(Repository repo) throws IOException { List<Ref> ref = new ArrayList<Ref>(); ref.addAll(repo.getRefDatabase().getRefs(Constants.R_HEADS).values()); ref.addAll(repo.getRefDatabase().getRefs(Constants.R_REMOTES).values()); return ref; } private String formatHeadRef(Ref ref) { String name = ref.getName(); if (name.startsWith(Constants.R_HEADS)) { return name.substring(Constants.R_HEADS.length()); } else if (name.startsWith(Constants.R_REMOTES)) { return name.substring(Constants.R_REMOTES.length()); } return name; } private String getTagsString(Repository repo, RevCommit commit) { StringBuilder sb = new StringBuilder(); Map<String, Ref> tagsMap = repo.getTags(); for (Entry<String, Ref> tagEntry : tagsMap.entrySet()) { ObjectId target = tagEntry.getValue().getPeeledObjectId(); if (target == null) { target = tagEntry.getValue().getObjectId(); } if (target != null && target.equals(commit)) { if (sb.length() > 0) { sb.append(", "); } sb.append(tagEntry.getKey()); } } return sb.toString(); } private String getInfo(HistoryViewInfoDto objectInfo) { String repositoryName = GitPlugin.getInstance().getUtils().getRepositoryName(objectInfo.getRepository()); if (objectInfo.getResource() == null && objectInfo.getFile() == null) { return GitPlugin.getInstance().getMessage("git.history.repo.pattern", new Object[] {repositoryName}); } else if (objectInfo.getResource() != null) { String type; switch (objectInfo.getResource().getType()) { case IResource.PROJECT: type = GitPlugin.getInstance().getMessage("git.history.projectType"); break; case IResource.FILE: type = GitPlugin.getInstance().getMessage("git.history.fileType"); break; default: type = GitPlugin.getInstance().getMessage("git.history.folderType"); break; } String path = objectInfo.getResource().getFullPath().makeRelative().toString(); if (objectInfo.getResource().getType() == IResource.FOLDER) { path = path + '/'; } return GitPlugin.getInstance().getMessage("git.history.file.pattern", new Object[] {type, path, repositoryName}); } else { // single file from Repository String path; String type; if (objectInfo.getFile().isDirectory()) { type = GitPlugin.getInstance().getMessage("git.history.folderType"); path = objectInfo.getFile().getPath() ; } else { type = GitPlugin.getInstance().getMessage("git.history.fileType"); path = objectInfo.getFile().getPath(); } String repoPath = objectInfo.getRepository().getDirectory().getPath(); path = path.substring(path.indexOf(repoPath) + repoPath.length()); return GitPlugin.getInstance().getMessage("git.history.file.pattern", new Object[] {type, path, repositoryName}); } } private void setWalkStartPoints(RevWalk walk, Repository repo, AnyObjectId headId) throws IOException { markStartAllRefs(repo, walk, Constants.R_HEADS); markStartAllRefs(repo, walk, Constants.R_REMOTES); markStartAllRefs(repo, walk, Constants.R_TAGS); markStartAdditionalRefs(repo, walk); markUninteresting(repo, walk, Constants.R_NOTES); walk.markStart(walk.parseCommit(headId)); } private void markStartAllRefs(Repository repo, RevWalk walk, String prefix) throws IOException, MissingObjectException, IncorrectObjectTypeException { for (Entry<String, Ref> refEntry : repo .getRefDatabase().getRefs(prefix).entrySet()) { Ref ref = refEntry.getValue(); if (ref.isSymbolic()) continue; markStartRef(repo, walk, ref); } } private void markStartAdditionalRefs(Repository repo, RevWalk walk) throws IOException { List<Ref> additionalRefs = repo.getRefDatabase() .getAdditionalRefs(); for (Ref ref : additionalRefs) markStartRef(repo, walk, ref); } private void markStartRef(Repository repo, RevWalk walk, Ref ref) throws IOException, IncorrectObjectTypeException { try { Object refTarget = walk.parseAny(ref.getLeaf().getObjectId()); if (refTarget instanceof RevCommit) walk.markStart((RevCommit) refTarget); } catch (MissingObjectException e) { // If there is a ref which points to Nirvana then we should simply // ignore this ref. We should not let a corrupt ref cause that the // history view is not filled at all } } private void markUninteresting(Repository repo, RevWalk walk, String prefix) throws IOException, MissingObjectException, IncorrectObjectTypeException { for (Entry<String, Ref> refEntry : repo .getRefDatabase().getRefs(prefix).entrySet()) { Ref ref = refEntry.getValue(); if (ref.isSymbolic()) continue; Object refTarget = walk.parseAny(ref.getLeaf().getObjectId()); if (refTarget instanceof RevCommit) walk.markUninteresting((RevCommit) refTarget); } } private void configObjectInfo(CommunicationChannel channel, HistoryViewInfoDto info) throws IOException { if (info.getIsResource()) { // IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember((String) info.getSelectedObject()); // RepositoryMapping mapping = RepositoryMapping.getMapping(resource); // // if (mapping == null) { // throw new IOException(); // } // info.setResource1(resource); // info.setRepository1(GitPlugin.getInstance().getGitUtils().getRepository(mapping)); } else { Object node = GenericTreeStatefulService.getNodeByPathFor((List<PathFragment>) info.getSelectedObject(), null); GenericTreeStatefulService service = GenericTreeStatefulService.getServiceFromPathWithRoot((List<PathFragment>) info.getSelectedObject()); NodeInfo nodeInfo = service.getVisibleNodes().get(node); Repository repository = GitService.getInstance().getRepository(nodeInfo); if (GitNodeType.NODE_TYPE_FILE.equals(nodeInfo.getPathFragment().getType()) || GitNodeType.NODE_TYPE_WDIR.equals(nodeInfo.getPathFragment().getType())) { repository = GitPlugin.getInstance().getUtils().getRepository((File) node); } else if (node instanceof RefNode) { // create working directory for local branch File mainRepoFile = repository.getDirectory().getParentFile(); String branchName = ((RefNode) node).getRef().getName().substring(Constants.R_HEADS.length()); File wdirFile = new File(mainRepoFile.getParentFile(), GitUtils.WORKING_DIRECTORY_PREFIX + branchName); repository = GitPlugin.getInstance().getUtils().getRepository(wdirFile); } else { throw new IOException(); } if (repository == null) { throw new IOException(); } info.setFile1(null); info.setRepository1(repository); } } private String mergeStatus(Repository repository) { String message = null; try { Ref head = repository.getRef(Constants.HEAD); if (head == null || !head.isSymbolic()) { message = GitPlugin.getInstance().getMessage("git.merge.headIsNoBranch"); } else if (!repository.getRepositoryState().equals(RepositoryState.SAFE)) message = GitPlugin.getInstance().getMessage("git.merge.wrongRepositoryState", repository.getRepositoryState()); } catch (IOException e) { message = e.getMessage(); } return message; } /////////////////////////////////////////////////////////////// // @RemoteInvocation methods /////////////////////////////////////////////////////////////// @RemoteInvocation public void subscribe(StatefulServiceInvocationContext context, IStatefulClientLocalState statefulClientLocalState) { super.subscribe(context, statefulClientLocalState); //invokeClientMethod(context.getCommunicationChannel(), context.getStatefulClientId(), "refresh", new Object[] {((GitHistoryStatefulClientLocalState) statefulClientLocalState).getInfo()}); } @RemoteInvocation public HistoryViewInfoDto getObjectInfo(StatefulServiceInvocationContext context, HistoryViewInfoDto info) { try { configObjectInfo(context.getCommunicationChannel(), info); info.setRepositoryLocation(info.getRepository().getDirectory().getAbsolutePath()); info.setInfo(getInfo(info)); return info; } catch (IOException e) { return null; } } @RemoteInvocation public List<Object> getLogEntries(StatefulServiceInvocationContext context, HistoryViewInfoDto info) { try { WebWalk walk = getWebWalk(context.getCommunicationChannel(), info); WebCommitList loadedCommits = new WebCommitList(); loadedCommits.source(walk); loadedCommits.fillTo(10000); WebCommit[] commitsAsArray = new WebCommit[loadedCommits.size()]; loadedCommits.toArray(commitsAsArray); List<HistoryEntryDto> result = new ArrayList<HistoryEntryDto>(); for (WebCommit commit : commitsAsArray) { commit.parseBody(); HistoryEntryDto entry = new HistoryEntryDto(); entry.setId(commit.getId().name()); entry.setShortId(commit.getId().abbreviate(7).name()); entry.setMessage(commit.getShortMessage()); PersonIdent person = commit.getAuthorIdent(); entry.setAuthor(person.getName()); entry.setAuthorEmail(person.getEmailAddress()); entry.setAuthoredDate(person.getWhen()); person = commit.getCommitterIdent(); entry.setCommitter(person.getName()); entry.setCommitterEmail(person.getEmailAddress()); entry.setCommitteredDate(person.getWhen()); WebCommitPlotRenderer renderer = new WebCommitPlotRenderer(commit); renderer.paint(); entry.setSpecialMessage(renderer.getSpecialMessage()); entry.setDrawings(renderer.getDrawings()); for (int i = 0; i < commit.getParentCount(); i++) { WebCommit p = (WebCommit)commit.getParent(i); p.parseBody(); CommitDto parent = new CommitDto(); parent.setId(p.getId().name()); parent.setLabel(p.getShortMessage()); entry.getCommitMessage().getParents().add(parent); } for (int i = 0; i < commit.getChildCount(); i++) { WebCommit p = (WebCommit)commit.getChild(i); p.parseBody(); CommitDto child = new CommitDto(); child.setId(p.getId().name()); child.setLabel(p.getShortMessage()); entry.getCommitMessage().getChildren().add(child); } result.add(entry); } walk.dispose(); return Arrays.asList(new Object[] {result, info}); } catch (IOException e) { return null; } } @RemoteInvocation public List<HistoryFileDiffEntryDto> getCommitFileDiffs(StatefulServiceInvocationContext context, HistoryEntryDto entry, HistoryViewInfoDto info) { List<HistoryFileDiffEntryDto> entries =new ArrayList<HistoryFileDiffEntryDto>(); try { Repository repo = RepositoryCache.open(FileKey.exact(new File(info.getRepositoryLocation()), FS.DETECTED)); RevWalk walk = new RevWalk(repo); RevCommit commit = walk.parseCommit(repo.resolve(entry.getId())); for (RevCommit parent : commit.getParents()) { walk.parseBody(parent); } FileDiff[] fileDiffs = FileDiff.compute(createFileWalker(new WebWalk(repo), repo, info.getPath()), commit, TreeFilter.ALL); for (FileDiff fd : fileDiffs) { HistoryFileDiffEntryDto fileEntry = new HistoryFileDiffEntryDto(); fileEntry.setFile(fd.getLabel(fd)); //fileEntry.setImage(GitPlugin.getInstance().getGitUtils().getImageURL(fd.getImageDescriptor(fd))); entries.add(fileEntry); } walk.dispose(); } catch (Exception e) { context.getCommunicationChannel().sendCommandWithPush( new DisplaySimpleMessageClientCommand( CommonPlugin.getInstance().getMessage("error"), e.getMessage(), DisplaySimpleMessageClientCommand.ICON_ERROR)); return null; } return entries; } @RemoteInvocation public String getCommitMessage(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation) { try { Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED));; RevCommit commit = new RevWalk(repo).parseCommit(repo.resolve(entry.getId())); return getCommitMessage(repo, entry, commit); } catch (Exception e) { context.getCommunicationChannel().sendCommandWithPush( new DisplaySimpleMessageClientCommand( CommonPlugin.getInstance().getMessage("error"), e.getMessage(), DisplaySimpleMessageClientCommand.ICON_ERROR)); return null; } } // @RemoteInvocation // public boolean checkout(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation) { // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED));; // RevCommit commit = new RevWalk(repo).parseCommit(repo.resolve(entry.getId())); // // List<RefNode> nodes = getRefNodes(commit, repo, Constants.R_HEADS); // // String target; // if (nodes.isEmpty()) // target = commit.name(); // else { // target = nodes.get(0).getObject().getName(); // } // // return new CheckoutOperation(repo, target, context.getCommunicationChannel()).execute(); // // } catch (Exception e) { // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // e.getMessage(), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } // } // // @RemoteInvocation // public boolean cherryPick(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation) { // WebProgressMonitor monitor = ProgressMonitorStatefulService.getInstance(). // createProgressMonitor(GitPlugin.getInstance().getMessage("git.cherryPick.monitor.title", new Object[] {entry.getShortId()})); // // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED));; // RevCommit commit = new RevWalk(repo).parseCommit(repo.resolve(entry.getId())); // // CherryPickCommand command = new Git(repo).cherryPick().include(commit.getId()); // CherryPickResult result = (CherryPickResult) GitPlugin.getInstance().getGitUtils().runGitCommandInUserRepoConfig(repo, command); // // ProjectUtil.refreshValidProjects( // ProjectUtil.getValidOpenProjects(repo), // new SubProgressMonitor(monitor, 1)); // // RevCommit newHead = result.getNewHead(); // if (newHead != null && result.getCherryPickedRefs().isEmpty()) { // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // GitPlugin.getInstance().getMessage("git.cherryPick.noCherryPickPerformed.title"), // GitPlugin.getInstance().getMessage("git.cherryPick.noCherryPickPerformed.message"), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } // if (newHead == null) { // CherryPickStatus status = result.getStatus(); // switch (status) { // case CONFLICTING: // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // GitPlugin.getInstance().getMessage("git.cherryPick.cherryPickConflicts.title"), // GitPlugin.getInstance().getMessage("git.cherryPick.cherryPickConflicts.message"), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // case FAILED: // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // GitPlugin.getInstance().getMessage("git.cherryPick.cherryPickFailed.message"), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // case OK: // break; // } // } // return true; // } catch (Exception e) { // logger.debug(CommonPlugin.getInstance().getMessage("error"), e); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // e.getMessage(), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } finally { // monitor.done(); // } // } // // @RemoteInvocation // public boolean revert(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation) { // WebProgressMonitor monitor = ProgressMonitorStatefulService.getInstance(). // createProgressMonitor(GitPlugin.getInstance().getMessage("git.revert.monitor.title", new Object[] {entry.getShortId()})); // // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED));; // RevCommit commit = new RevWalk(repo).parseCommit(repo.resolve(entry.getId())); // // RevertCommand command = new Git(repo).revert().include(commit); // RevCommit newHead = (RevCommit) GitPlugin.getInstance().getGitUtils().runGitCommandInUserRepoConfig(repo, command); // // ProjectUtil.refreshValidProjects( // ProjectUtil.getValidOpenProjects(repo), // new SubProgressMonitor(monitor, 1)); // // List<Ref> revertedRefs = command.getRevertedRefs(); // if (newHead != null && revertedRefs.isEmpty()) { // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // GitPlugin.getInstance().getMessage("git.revert.noRevert.title"), // GitPlugin.getInstance().getMessage("git.revert.alreadyReverted.message"), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } // if (newHead == null) { // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // GitPlugin.getInstance().getMessage("git.revert.failed"), // command.getFailingResult().toString(), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } // return true; // } catch (Exception e) { // logger.debug(CommonPlugin.getInstance().getMessage("error"), e); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // e.getMessage(), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } finally { // monitor.done(); // } // } // // @RemoteInvocation // public CreateBranchPageDto populate_createBranchPage(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation) { // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED));; // RevCommit commit = new RevWalk(repo).parseCommit(repo.resolve(entry.getId())); // // if (repo.isBare()) { // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // GitPlugin.getInstance().getMessage("git.repo.bare"), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return null; // } // // CreateBranchPageDto result = new CreateBranchPageDto(); // result.setPrefixName(Constants.R_HEADS); // result.getRefs().add(new GitRef(commit.getId().getName(), entry.getShortId())); // // return result; // } catch (IOException e) { // logger.debug(CommonPlugin.getInstance().getMessage("error"), e); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // GitPlugin.getInstance().getMessage("git.page.populate.error"), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return null; // } // } // // @RemoteInvocation // public boolean createBranch(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation, String name, GitRef baseOn, boolean checkout) { // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED));; // // Git git = new Git(repo); // // Ref newBranch = git.branchCreate(). // setName(name). // setStartPoint(baseOn.getName()). // setUpstreamMode(SetupUpstreamMode.TRACK). // call(); // // // notify clients about changes // RepositoryTreeNode parent = new LocalNode(new BranchesNode(new RepositoryNode(null, repo), repo), repo); // RepositoryTreeNode newNode = new RefNode(parent, repo, newBranch); // if (checkout) { // return new CheckoutOperation(repo, ((Ref)newNode.getObject()).getName(), context.getCommunicationChannel()).execute(); // } else { // GitRepositoriesTreeStatefulService.getInstance().dispatchContentUpdate(parent); // } // // return true; // } catch (Exception e) { // logger.debug(CommonPlugin.getInstance().getMessage("error"), e); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // e.getMessage(), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } // } // // @RemoteInvocation // public ConfigTagPageDto populate_createTagPage(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation) { // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED));; // RevCommit revCommit = new RevWalk(repo).parseCommit(repo.resolve(entry.getId())); // // List<RevCommit> revCommits = new ArrayList<RevCommit>(); // revCommits.add(revCommit); // // List<CommitDto> commits = new ArrayList<CommitDto>(); // for (RevCommit commit : revCommits) { // CommitDto commitDto = new CommitDto(); // commitDto.setId(commit.name()); // commitDto.setShortId(commit.abbreviate(7).name()); // commitDto.setLabel(commit.abbreviate(7).name() + ": " + commit.getShortMessage()); // commits.add(commitDto); // } // // ConfigTagPageDto result = new ConfigTagPageDto(); // result.setCommits(commits); // result.setAddEmptyLine(false); // result.setInitialSelectedIndex(0); // // return result; // } catch (IOException e) { // logger.debug(CommonPlugin.getInstance().getMessage("error"), e); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // GitPlugin.getInstance().getMessage("git.page.populate.error"), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return null; // } // } // // @RemoteInvocation // public boolean createTag(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation, String name, String message, CommitDto commit) { // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED));; // Git git = new Git(repo); // // TagCommand tag = git.tag().setName(name).setMessage(message); // if (commit != null) { // ObjectId objectId = repo.resolve(commit.getId()); // RevCommit revCommit = new RevWalk(repo).lookupCommit(objectId); // // tag.setObjectId(revCommit); // } // tag.call(); // // RepositoryTreeNode parent = new TagsNode(new RepositoryNode(null, repo), repo); // GitRepositoriesTreeStatefulService.getInstance().dispatchContentUpdate(parent); // // return true; // } catch (GitAPIException e) { // logger.debug(CommonPlugin.getInstance().getMessage("error"), e); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // e.getMessage(), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } catch (IOException e1) { // logger.debug(CommonPlugin.getInstance().getMessage("error"), e1); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // GitPlugin.getInstance().getMessage("git.createTagPage.error"), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } // } // // @RemoteInvocation // public boolean reset(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation, int resetType) { // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED));; // RevCommit revCommit = new RevWalk(repo).parseCommit(repo.resolve(entry.getId())); // // ResetType type; // switch (resetType) { // case 0: // type = ResetType.SOFT; // break; // case 1: // type = ResetType.MIXED; // break; // default: // type = ResetType.HARD; // } // // new ResetOperation(repo, revCommit.getName(), type).execute(); // // return true; // } catch (Exception e) { // logger.debug(CommonPlugin.getInstance().getMessage("error"), e); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // e.getMessage(), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } // } // // @RemoteInvocation // public ConfigFetchPushPageDto populate_pushCommitPage(StatefulServiceInvocationContext context, String repositoryLocation) { // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED));; // // return GitPlugin.getInstance().getGitUtils().getConfigFetchPushPageDto(repo, false); // } catch (Exception e) { // logger.debug(CommonPlugin.getInstance().getMessage("error"), e); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // e.getMessage(), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return null; // } // } // // @RemoteInvocation // public boolean pushCommit(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation, RemoteConfig pushConfig, String target, boolean isForceUpdate) { // GitService.tlCommand.set((InvokeServiceMethodServerCommand) context.getCommand()); // // WebProgressMonitor monitor = ProgressMonitorStatefulService.getInstance(). // createProgressMonitor(GitPlugin.getInstance().getMessage("git.push.monitor.title")); // // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED));; // RevCommit revCommit = new RevWalk(repo).parseCommit(repo.resolve(entry.getId())); // // // RefSpec refSpec = new RefSpec(). // setSourceDestination(revCommit.name(), target). // setForceUpdate(isForceUpdate); // // org.eclipse.jgit.transport.RemoteConfig remoteConfig = null; // List<org.eclipse.jgit.transport.RemoteConfig> remotes = org.eclipse.jgit.transport.RemoteConfig.getAllRemoteConfigs(repo.getConfig()); // for (org.eclipse.jgit.transport.RemoteConfig remote : remotes) { // if (remote.getName().equals(pushConfig.getRemoteName())) { // remoteConfig = remote; // break; // } // } // List<RefSpec> fetchSpecs = remoteConfig != null ? remoteConfig.getFetchRefSpecs() : null; // // Collection<RemoteRefUpdate> remoteRefUpdates = Transport // .findRemoteRefUpdatesFor(repo, // Collections.singleton(refSpec), fetchSpecs); // // EclipseGitProgressTransformer gitMonitor = new EclipseGitProgressTransformer(monitor); // Transport transport = Transport.open(repo, new URIish(pushConfig.getPushUri()).toPrivateString()); // transport.setCredentialsProvider(new GitUsernamePasswordCredentialsProvider()); // PushResult result = transport.push(gitMonitor, remoteRefUpdates); // // context.getCommunicationChannel().sendObject(new OpenOperationResultWindowClientCommand( // GitPlugin.getInstance().getMessage("git.push.result"), // GitPlugin.getInstance().getGitUtils().handlePushResult(result))); // // return true; // } catch (Exception e) { // if (GitPlugin.getInstance().getGitUtils().isAuthentificationException(e)) { // GitService.getInstance().openLoginWindow(); // return true; // } // logger.debug(CommonPlugin.getInstance().getMessage("error"), e); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // e.getMessage(), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } finally { // monitor.done(); // } // } // // @RemoteInvocation // public boolean merge(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation) { // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED)); // RevCommit commit = new RevWalk(repo).parseCommit(repo.resolve(entry.getId())); // // String status = mergeStatus(repo); // if (status != null) { // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // status, // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } // // List<RefNode> nodes = getRefNodes(commit, repo, Constants.R_HEADS); // // String target; // if (nodes.isEmpty()) // target = commit.name(); // else { // target = nodes.get(0).getObject().getName(); // } // // MergeOperation op = new MergeOperation(repo, target, false, context.getCommunicationChannel()); // // return op.execute(); // } catch (Exception e) { // logger.debug(CommonPlugin.getInstance().getMessage("error"), e); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // e.getMessage(), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } // } // // @RemoteInvocation // public boolean rebase(StatefulServiceInvocationContext context, HistoryEntryDto entry, String repositoryLocation) { // try { // Repository repo = RepositoryCache.open(FileKey.exact(new File(repositoryLocation), FS.DETECTED)); // // if (!repo.getFullBranch().startsWith(Constants.R_HEADS)) { // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // GitPlugin.getInstance().getMessage("git.rebase.noLocalBranch"), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } // // String currentBranch = repo.getBranch(); // RevCommit commit = new RevWalk(repo).parseCommit(repo.resolve(entry.getId())); // // Ref ref; // List<RefNode> nodes = getRefNodes(commit, repo, Constants.R_HEADS); // if (nodes.size() == 0) // ref = new ObjectIdRef.Unpeeled(Storage.LOOSE, commit.getName(), commit); // else if (nodes.size() == 1) // ref = nodes.get(0).getObject(); // else { // BranchConfig branchConfig = new BranchConfig(repo.getConfig(), currentBranch); // String trackingBranch = branchConfig.getTrackingBranch(); // Ref remoteRef = null; // // for (int i = 0; i < nodes.size(); i++) { // Ref obj = nodes.get(i).getObject(); // if (trackingBranch != null && trackingBranch.equals(obj.getName())) { // ref = obj; // break; // } // if (obj.getName().startsWith(Constants.R_REMOTES)) { // remoteRef = obj; // } // } // // if (remoteRef != null) { // ref = remoteRef; // } else { // // We tried to pick a nice ref, just pick the first then // ref = nodes.get(0).getObject(); // } // } // // RebaseOperation op = new RebaseOperation(repo, ref.getName()); // op.execute(); // // context.getCommunicationChannel().sendObject(new OpenOperationResultWindowClientCommand( // GitPlugin.getInstance().getMessage("git.rebase.result"), // op.handleRebaseResult())); // // return true; // } catch (Exception e) { // logger.debug(CommonPlugin.getInstance().getMessage("error"), e); // context.getCommunicationChannel().sendObject( // new DisplaySimpleMessageClientCommand( // CommonPlugin.getInstance().getMessage("error"), // e.getMessage(), // DisplaySimpleMessageClientCommand.ICON_ERROR)); // return false; // } // } }