blob: b18636e5a3c001ff58c222f5714cc9b81d96c668 [file] [log] [blame]
/*******************************************************************************
* 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();
}
}