| /******************************************************************************* |
| * Copyright (c) 2013 Ericsson and others. |
| * 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: |
| * Miles Parker, Tasktop Technologies - initial API and implementation |
| * Steffen Pingel, Tasktop Technologies - original GerritUtil implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.internal.gerrit.core.remote; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.mylyn.internal.gerrit.core.GerritUtil; |
| import org.eclipse.mylyn.internal.gerrit.core.ReviewItemCache; |
| import org.eclipse.mylyn.internal.gerrit.core.client.PatchSetContent; |
| import org.eclipse.mylyn.reviews.core.model.IComment; |
| import org.eclipse.mylyn.reviews.core.model.IFileItem; |
| import org.eclipse.mylyn.reviews.core.model.IFileVersion; |
| import org.eclipse.mylyn.reviews.core.model.ILineLocation; |
| import org.eclipse.mylyn.reviews.core.model.ILineRange; |
| import org.eclipse.mylyn.reviews.core.model.IReviewItemSet; |
| import org.eclipse.mylyn.reviews.core.model.IReviewsFactory; |
| import org.eclipse.mylyn.reviews.core.model.IUser; |
| import org.eclipse.mylyn.reviews.core.spi.remote.review.ReviewItemSetContentRemoteFactory; |
| import org.eclipse.osgi.util.NLS; |
| |
| import com.google.gerrit.common.data.AccountInfoCache; |
| import com.google.gerrit.common.data.CommentDetail; |
| import com.google.gerrit.common.data.PatchScript; |
| import com.google.gerrit.prettify.common.SparseFileContent; |
| import com.google.gerrit.reviewdb.Patch; |
| import com.google.gerrit.reviewdb.PatchLineComment; |
| |
| /** |
| * Manages retrieval of patch set contents, including file versions and associated comments, from Gerrit API. |
| * |
| * @author Miles Parker |
| * @author Steffen Pingel |
| */ |
| public abstract class PatchSetContentRemoteFactory<RemoteKeyType> extends |
| ReviewItemSetContentRemoteFactory<PatchSetContent, RemoteKeyType> { |
| |
| private final ReviewItemCache cache; |
| |
| private final GerritRemoteFactoryProvider gerritFactoryProvider; |
| |
| public PatchSetContentRemoteFactory(GerritRemoteFactoryProvider gerritRemoteFactoryProvider) { |
| super(gerritRemoteFactoryProvider); |
| this.gerritFactoryProvider = gerritRemoteFactoryProvider; |
| cache = new ReviewItemCache(); |
| } |
| |
| public PatchSetContent pull(IReviewItemSet parentObject, PatchSetContent content, IProgressMonitor monitor) |
| throws CoreException { |
| gerritFactoryProvider.getClient().loadPatchSetContent(content, monitor); |
| for (Patch patch : content.getTargetDetail().getPatches()) { |
| PatchScript patchScript = content.getPatchScript(patch.getKey()); |
| CommentDetail commentDetail = patchScript.getCommentDetail(); |
| List<PatchLineComment> comments = new ArrayList<PatchLineComment>(); |
| comments.addAll(commentDetail.getCommentsA()); |
| comments.addAll(commentDetail.getCommentsB()); |
| for (PatchLineComment comment : comments) { |
| gerritFactoryProvider.pullUser(gerritFactoryProvider.getRoot(), patchScript.getCommentDetail() |
| .getAccounts(), comment.getAuthor(), monitor); |
| } |
| } |
| return content; |
| } |
| |
| @Override |
| public void push(PatchSetContent remoteObject, IProgressMonitor monitor) throws CoreException { |
| //noop, push not supported in Gerrit |
| } |
| |
| boolean addComments(IReviewItemSet set, IFileVersion version, List<PatchLineComment> comments, |
| AccountInfoCache accountInfoCache) { |
| version.getComments().clear(); |
| if (version == null || comments == null || comments.isEmpty()) { |
| return false; |
| } |
| boolean changed = comments.size() != version.getComments().size(); |
| int oldDraftCount = version.getDrafts().size(); |
| int draftCount = 0; |
| for (PatchLineComment gerritComment : comments) { |
| ILineRange line = IReviewsFactory.INSTANCE.createLineRange(); |
| line.setStart(gerritComment.getLine()); |
| line.setEnd(gerritComment.getLine()); |
| ILineLocation location = IReviewsFactory.INSTANCE.createLineLocation(); |
| location.getRanges().add(line); |
| |
| IComment comment = IReviewsFactory.INSTANCE.createComment(); |
| IUser author = getGerritProvider().createUser(getGerritProvider().getRoot(), accountInfoCache, |
| gerritComment.getAuthor()); |
| |
| comment.setId(gerritComment.getKey().get()); |
| comment.setCreationDate(gerritComment.getWrittenOn()); |
| comment.setTitle(GerritUtil.shortenText(gerritComment.getMessage(), 10, 20)); |
| comment.setDescription(gerritComment.getMessage()); |
| comment.setDraft(PatchLineComment.Status.DRAFT == gerritComment.getStatus()); |
| if (comment.isDraft()) { |
| draftCount++; |
| } |
| comment.setAuthor(author); |
| comment.getLocations().add(location); |
| version.getComments().add(comment); |
| } |
| changed |= draftCount != oldDraftCount; |
| return changed; |
| } |
| |
| @Override |
| public boolean isPullNeeded(IReviewItemSet parent, List<IFileItem> items, PatchSetContent remote) { |
| return true; |
| } |
| |
| @Override |
| public List<IFileItem> createModel(IReviewItemSet set, PatchSetContent content) { |
| List<IFileItem> items = set.getItems(); |
| if (!items.isEmpty()) { |
| return items; |
| } |
| for (Patch patch : content.getTargetDetail().getPatches()) { |
| String targetId = patch.getKey().toString(); |
| String sourceFileName = (patch.getSourceFileName() != null) |
| ? patch.getSourceFileName() |
| : patch.getFileName(); |
| String baseId = (content.getBase() != null) |
| ? new Patch.Key(content.getBase().getId(), sourceFileName).toString() |
| : "base-" + targetId; |
| String id = baseId + ":" + targetId; //$NON-NLS-1$ |
| IFileItem item = (IFileItem) getCache().getItem(id); |
| if (item == null) { |
| item = IReviewsFactory.INSTANCE.createFileItem(); |
| item.setId(id); |
| item.setName(patch.getFileName()); |
| item.setAddedBy(set.getAddedBy()); |
| item.setCommittedBy(set.getCommittedBy()); |
| item.setReference(patch.getKey().getParentKey() + "," + patch.getFileName()); |
| getCache().put(item); |
| } |
| items.add(item); |
| |
| PatchScript patchScript = content.getPatchScript(patch.getKey()); |
| if (patchScript != null) { |
| IFileVersion baseVersion = (IFileVersion) getCache().getItem(baseId); |
| if (baseVersion == null) { |
| baseVersion = IReviewsFactory.INSTANCE.createFileVersion(); |
| baseVersion.setId(baseId); |
| baseVersion.setContent(patchScript.getA().asString()); |
| baseVersion.setPath(patchScript.getA().getPath()); |
| baseVersion.setDescription((content.getBase() != null) ? NLS.bind("Patch Set {0}", |
| content.getBase().getPatchSetId()) : "Base"); |
| baseVersion.setFile(item); |
| baseVersion.setName(item.getName()); |
| getCache().put(baseVersion); |
| } |
| item.setBase(baseVersion); |
| |
| IFileVersion targetVersion = (IFileVersion) getCache().getItem(targetId); |
| if (targetVersion == null) { |
| targetVersion = IReviewsFactory.INSTANCE.createFileVersion(); |
| targetVersion.setId(targetId); |
| SparseFileContent target = patchScript.getB().apply(patchScript.getA(), patchScript.getEdits()); |
| targetVersion.setContent(target.asString()); |
| targetVersion.setPath(patchScript.getB().getPath()); |
| targetVersion.setDescription(NLS.bind("Patch Set {0}", content.getTargetDetail() |
| .getPatchSet() |
| .getPatchSetId())); |
| targetVersion.setFile(item); |
| targetVersion.setAddedBy(item.getAddedBy()); |
| targetVersion.setCommittedBy(item.getCommittedBy()); |
| targetVersion.setName(item.getName()); |
| getCache().put(targetVersion); |
| } |
| item.setTarget(targetVersion); |
| } |
| } |
| return items; |
| } |
| |
| @Override |
| public boolean isCreateModelNeeded(IReviewItemSet set, List<IFileItem> items) { |
| return super.isCreateModelNeeded(set, items) || items == null || items.isEmpty(); |
| } |
| |
| @Override |
| public boolean updateModel(IReviewItemSet set, List<IFileItem> items, PatchSetContent content) { |
| boolean changed = false; |
| for (IFileItem item : items) { |
| IFileItem fileItem = item; |
| PatchScript patchScript = content.getPatchScript(Patch.Key.parse(item.getReference())); |
| if (patchScript != null) { |
| CommentDetail commentDetail = patchScript.getCommentDetail(); |
| changed |= addComments(set, fileItem.getBase(), commentDetail.getCommentsA(), |
| commentDetail.getAccounts()); |
| changed |= addComments(set, fileItem.getTarget(), commentDetail.getCommentsB(), |
| commentDetail.getAccounts()); |
| } |
| } |
| if (changed && set.getReview() != null) { |
| getGerritProvider().save(set.getReview()); |
| } |
| return changed; |
| } |
| |
| public GerritRemoteFactoryProvider getGerritProvider() { |
| return gerritFactoryProvider; |
| } |
| |
| @Override |
| protected List<IFileItem> open(IReviewItemSet parentObject, String localKey) { |
| return parentObject.getItems(); |
| } |
| |
| @Override |
| public String getLocalKey(IReviewItemSet parentObject, List<IFileItem> modelObject) { |
| return parentObject.getId(); |
| } |
| |
| public ReviewItemCache getCache() { |
| return cache; |
| } |
| |
| @Override |
| public String getModelDescription(IReviewItemSet set, List<IFileItem> items, String localKey) { |
| if (set.getReview() != null) { |
| return "Review " + set.getReview().getId() + ", Patch Set " + set.getId(); |
| } |
| return set.getName(); |
| } |
| } |