Revision API: Implement comments and drafts

Change-Id: Ic6836a8c301d34c4d32887a1da2d2c24835eaa7a
This commit is contained in:
David Ostrovsky
2014-06-20 02:47:03 +02:00
committed by David Pursehouse
parent d52c47240a
commit 140939e04d
20 changed files with 562 additions and 142 deletions

View File

@@ -28,10 +28,14 @@ import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.CherryPickInput;
import com.google.gerrit.extensions.api.changes.DraftApi;
import com.google.gerrit.extensions.api.changes.DraftInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.ReviewInput.CommentInput;
import com.google.gerrit.extensions.api.changes.SubmitInput;
import com.google.gerrit.extensions.api.projects.BranchInput;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.DiffInfo;
import com.google.gerrit.extensions.common.MergeableInfo;
import com.google.gerrit.extensions.common.SubmitType;
@@ -49,6 +53,10 @@ import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@NoHttpd
public class RevisionIT extends AbstractDaemonTest {
@@ -339,6 +347,96 @@ public class RevisionIT extends AbstractDaemonTest {
assertThat(c.mergeable).isEqualTo(expected);
}
@Test
public void drafts() throws Exception {
PushOneCommit.Result r = createChange();
DraftInput in = new DraftInput();
in.line = 1;
in.message = "nit: trailing whitespace";
in.path = FILE_NAME;
DraftApi draftApi = gApi.changes()
.id(r.getChangeId())
.revision(r.getCommit().name())
.createDraft(in);
assertThat(draftApi
.get()
.message)
.isEqualTo(in.message);
assertThat(gApi.changes()
.id(r.getChangeId())
.revision(r.getCommit().name())
.draft(draftApi.get().id)
.get()
.message)
.isEqualTo(in.message);
assertThat(gApi.changes()
.id(r.getChangeId())
.revision(r.getCommit().name())
.drafts())
.hasSize(1);
in.message = "good catch!";
assertThat(gApi.changes()
.id(r.getChangeId())
.revision(r.getCommit().name())
.draft(draftApi.get().id)
.update(in)
.message)
.isEqualTo(in.message);
assertThat(gApi.changes()
.id(r.getChangeId())
.revision(r.getCommit().name())
.draft(draftApi.get().id)
.get()
.author
.email)
.isEqualTo(admin.email);
draftApi.delete();
assertThat(gApi.changes()
.id(r.getChangeId())
.revision(r.getCommit().name())
.drafts())
.isEmpty();
}
@Test
public void comments() throws Exception {
PushOneCommit.Result r = createChange();
CommentInput in = new CommentInput();
in.line = 1;
in.message = "nit: trailing whitespace";
in.path = FILE_NAME;
ReviewInput reviewInput = new ReviewInput();
Map<String, List<CommentInput>> comments = new HashMap<>();
comments.put(FILE_NAME, Collections.singletonList(in));
reviewInput.comments = comments;
reviewInput.message = "comment test";
gApi.changes()
.id(r.getChangeId())
.current()
.review(reviewInput);
Map<String, List<CommentInfo>> out = gApi.changes()
.id(r.getChangeId())
.revision(r.getCommit().name())
.comments();
assertThat(out).hasSize(1);
CommentInfo comment = Iterables.getOnlyElement(out.get(FILE_NAME));
assertThat(comment.message).isEqualTo(in.message);
assertThat(comment.author.email).isEqualTo(admin.email);
assertThat(gApi.changes()
.id(r.getChangeId())
.revision(r.getCommit().name())
.comment(comment.id)
.get()
.message)
.isEqualTo(in.message);
}
private void merge(PushOneCommit.Result r) throws Exception {
revision(r).review(ReviewInput.approve());
revision(r).submit();

View File

@@ -0,0 +1,22 @@
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.extensions.api.changes;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
public interface CommentApi {
CommentInfo get() throws RestApiException;
}

View File

@@ -0,0 +1,23 @@
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.extensions.api.changes;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
public interface DraftApi extends CommentApi {
CommentInfo update(DraftInput in) throws RestApiException;
void delete() throws RestApiException;
}

View File

@@ -14,11 +14,13 @@
package com.google.gerrit.extensions.api.changes;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.FileInfo;
import com.google.gerrit.extensions.common.MergeableInfo;
import com.google.gerrit.extensions.restapi.NotImplementedException;
import com.google.gerrit.extensions.restapi.RestApiException;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -43,6 +45,14 @@ public interface RevisionApi {
MergeableInfo mergeable() throws RestApiException;
MergeableInfo mergeableOtherBranches() throws RestApiException;
Map<String, List<CommentInfo>> comments() throws RestApiException;
Map<String, List<CommentInfo>> drafts() throws RestApiException;
DraftApi createDraft(DraftInput in) throws RestApiException;
DraftApi draft(String id) throws RestApiException;
CommentApi comment(String id) throws RestApiException;
/**
* A default implementation which allows source compatibility
* when adding new methods to the interface.
@@ -122,5 +132,30 @@ public interface RevisionApi {
public FileApi file(String path) {
throw new NotImplementedException();
}
@Override
public Map<String, List<CommentInfo>> comments() throws RestApiException {
throw new NotImplementedException();
}
@Override
public Map<String, List<CommentInfo>> drafts() throws RestApiException {
throw new NotImplementedException();
}
@Override
public DraftApi createDraft(DraftInput in) throws RestApiException {
throw new NotImplementedException();
}
@Override
public DraftApi draft(String id) throws RestApiException {
throw new NotImplementedException();
}
@Override
public CommentApi comment(String id) throws RestApiException {
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,49 @@
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.api.changes;
import com.google.gerrit.extensions.api.changes.CommentApi;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.change.CommentResource;
import com.google.gerrit.server.change.GetComment;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
class CommentApiImpl implements CommentApi {
interface Factory {
CommentApiImpl create(CommentResource c);
}
private final GetComment getComment;
private final CommentResource comment;
@Inject
CommentApiImpl(GetComment getComment,
@Assisted CommentResource comment) {
this.getComment = getComment;
this.comment = comment;
}
@Override
public CommentInfo get() throws RestApiException {
try {
return getComment.apply(comment);
} catch (OrmException e) {
throw new RestApiException("Cannot retrieve comment", e);
}
}
}

View File

@@ -0,0 +1,78 @@
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.api.changes;
import com.google.gerrit.extensions.api.changes.DraftApi;
import com.google.gerrit.extensions.api.changes.DraftInput;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.change.DeleteDraft;
import com.google.gerrit.server.change.DraftResource;
import com.google.gerrit.server.change.GetDraft;
import com.google.gerrit.server.change.PutDraft;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
class DraftApiImpl implements DraftApi {
interface Factory {
DraftApiImpl create(DraftResource d);
}
private final DeleteDraft deleteDraft;
private final GetDraft getDraft;
private final PutDraft putDraft;
private final DraftResource draft;
@Inject
DraftApiImpl(DeleteDraft deleteDraft,
GetDraft getDraft,
PutDraft putDraft,
@Assisted DraftResource draft) {
this.deleteDraft = deleteDraft;
this.getDraft = getDraft;
this.putDraft = putDraft;
this.draft = draft;
}
@Override
public CommentInfo get() throws RestApiException {
try {
return getDraft.apply(draft);
} catch (OrmException e) {
throw new RestApiException("Cannot retrieve draft", e);
}
}
@Override
public CommentInfo update(DraftInput in) throws RestApiException {
try {
return putDraft.apply(draft, in).value();
} catch (IOException | OrmException e) {
throw new RestApiException("Cannot update draft", e);
}
}
@Override
public void delete() throws RestApiException {
try {
deleteDraft.apply(draft, null);
} catch (IOException | OrmException e) {
throw new RestApiException("Cannot delete draft", e);
}
}
}

View File

@@ -23,6 +23,8 @@ public class Module extends FactoryModule {
bind(Changes.class).to(ChangesImpl.class);
factory(ChangeApiImpl.Factory.class);
factory(CommentApiImpl.Factory.class);
factory(DraftApiImpl.Factory.class);
factory(RevisionApiImpl.Factory.class);
factory(FileApiImpl.Factory.class);
}

View File

@@ -19,19 +19,28 @@ import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.Changes;
import com.google.gerrit.extensions.api.changes.CherryPickInput;
import com.google.gerrit.extensions.api.changes.CommentApi;
import com.google.gerrit.extensions.api.changes.DraftApi;
import com.google.gerrit.extensions.api.changes.DraftInput;
import com.google.gerrit.extensions.api.changes.FileApi;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.RevisionApi;
import com.google.gerrit.extensions.api.changes.SubmitInput;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.FileInfo;
import com.google.gerrit.extensions.common.MergeableInfo;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.server.change.CherryPick;
import com.google.gerrit.server.change.Comments;
import com.google.gerrit.server.change.CreateDraft;
import com.google.gerrit.server.change.DeleteDraftPatchSet;
import com.google.gerrit.server.change.Drafts;
import com.google.gerrit.server.change.FileResource;
import com.google.gerrit.server.change.Files;
import com.google.gerrit.server.change.ListComments;
import com.google.gerrit.server.change.ListDrafts;
import com.google.gerrit.server.change.Mergeable;
import com.google.gerrit.server.change.PostReview;
import com.google.gerrit.server.change.Publish;
@@ -46,6 +55,7 @@ import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -69,6 +79,13 @@ class RevisionApiImpl extends RevisionApi.NotImplemented implements RevisionApi
private final Provider<PostReview> review;
private final Provider<Mergeable> mergeable;
private final FileApiImpl.Factory fileApi;
private final ListComments listComments;
private final ListDrafts listDrafts;
private final CreateDraft createDraft;
private final Drafts drafts;
private final DraftApiImpl.Factory draftFactory;
private final Comments comments;
private final CommentApiImpl.Factory commentFactory;
@Inject
RevisionApiImpl(Changes changes,
@@ -85,6 +102,13 @@ class RevisionApiImpl extends RevisionApi.NotImplemented implements RevisionApi
Provider<PostReview> review,
Provider<Mergeable> mergeable,
FileApiImpl.Factory fileApi,
ListComments listComments,
ListDrafts listDrafts,
CreateDraft createDraft,
Drafts drafts,
DraftApiImpl.Factory draftFactory,
Comments comments,
CommentApiImpl.Factory commentFactory,
@Assisted RevisionResource r) {
this.changes = changes;
this.cherryPick = cherryPick;
@@ -100,6 +124,13 @@ class RevisionApiImpl extends RevisionApi.NotImplemented implements RevisionApi
this.listFiles = listFiles;
this.mergeable = mergeable;
this.fileApi = fileApi;
this.listComments = listComments;
this.listDrafts = listDrafts;
this.createDraft = createDraft;
this.drafts = drafts;
this.draftFactory = draftFactory;
this.comments = comments;
this.commentFactory = commentFactory;
this.revision = r;
}
@@ -244,4 +275,51 @@ class RevisionApiImpl extends RevisionApi.NotImplemented implements RevisionApi
return fileApi.create(files.get().parse(revision,
IdString.fromDecoded(path)));
}
@Override
public Map<String, List<CommentInfo>> comments() throws RestApiException {
try {
return listComments.apply(revision);
} catch (OrmException e) {
throw new RestApiException("Cannot retrieve comments", e);
}
}
@Override
public Map<String, List<CommentInfo>> drafts() throws RestApiException {
try {
return listDrafts.apply(revision);
} catch (OrmException e) {
throw new RestApiException("Cannot retrieve drafts", e);
}
}
@Override
public DraftApi draft(String id) throws RestApiException {
try {
return draftFactory.create(drafts.parse(revision,
IdString.fromDecoded(id)));
} catch (OrmException e) {
throw new RestApiException("Cannot retrieve draft", e);
}
}
@Override
public DraftApi createDraft(DraftInput in) throws RestApiException {
try {
return draft(createDraft.apply(revision, in).value().id);
} catch (IOException | OrmException e) {
throw new RestApiException("Cannot create draft", e);
}
}
@Override
public CommentApi comment(String id) throws RestApiException {
try {
return commentFactory.create(comments.parse(revision,
IdString.fromDecoded(id)));
} catch (OrmException e) {
throw new RestApiException("Cannot retrieve comment", e);
}
}
}

View File

@@ -1,68 +0,0 @@
// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.change;
import com.google.common.base.Strings;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.Comment.Range;
import com.google.gerrit.extensions.common.Side;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.CommentRange;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.server.account.AccountLoader;
import java.sql.Timestamp;
public class CommentInfo {
String id;
String path;
Side side;
Integer line;
String inReplyTo;
String message;
Timestamp updated;
AccountInfo author;
Range range;
CommentInfo(PatchLineComment c, AccountLoader accountLoader) {
id = Url.encode(c.getKey().get());
path = c.getKey().getParentKey().getFileName();
if (c.getSide() == 0) {
side = Side.PARENT;
}
if (c.getLine() > 0) {
line = c.getLine();
}
inReplyTo = Url.encode(c.getParentUuid());
message = Strings.emptyToNull(c.getMessage());
updated = c.getWrittenOn();
range = toRange(c.getRange());
if (accountLoader != null) {
author = accountLoader.get(c.getAuthor());
}
}
public static Range toRange(CommentRange commentRange) {
Range range = null;
if (commentRange != null) {
range = new Range();
range.startLine = commentRange.getStartLine();
range.startCharacter = commentRange.getStartCharacter();
range.endLine = commentRange.getEndLine();
range.endCharacter = commentRange.getEndCharacter();
}
return range;
}
}

View File

@@ -0,0 +1,137 @@
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.change;
import static com.google.common.base.MoreObjects.firstNonNull;
import com.google.common.base.Strings;
import com.google.gerrit.extensions.common.Comment.Range;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.Side;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.CommentRange;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@Singleton
class CommentJson {
private final AccountLoader.Factory accountLoaderFactory;
@Inject
CommentJson(AccountLoader.Factory accountLoaderFactory) {
this.accountLoaderFactory = accountLoaderFactory;
}
CommentInfo format(PatchLineComment c) throws OrmException {
return format(c, true);
}
CommentInfo format(PatchLineComment c, boolean fill) throws OrmException {
AccountLoader loader = null;
if (fill) {
loader = accountLoaderFactory.create(true);
}
CommentInfo commentInfo = toCommentInfo(c, loader);
if (fill) {
loader.fill();
}
return commentInfo;
}
Map<String, List<CommentInfo>> format(Iterable<PatchLineComment> l,
boolean fill) throws OrmException {
Map<String, List<CommentInfo>> out = new TreeMap<>();
AccountLoader accountLoader = fill
? accountLoaderFactory.create(true)
: null;
for (PatchLineComment c : l) {
CommentInfo o = toCommentInfo(c, accountLoader);
List<CommentInfo> list = out.get(o.path);
if (list == null) {
list = new ArrayList<>();
out.put(o.path, list);
}
o.path = null;
list.add(o);
}
for (List<CommentInfo> list : out.values()) {
Collections.sort(list, new Comparator<CommentInfo>() {
@Override
public int compare(CommentInfo a, CommentInfo b) {
int c = firstNonNull(a.side, Side.REVISION).ordinal()
- firstNonNull(b.side, Side.REVISION).ordinal();
if (c == 0) {
c = firstNonNull(a.line, 0) - firstNonNull(b.line, 0);
}
if (c == 0) {
c = a.id.compareTo(b.id);
}
return c;
}
});
}
if (accountLoader != null) {
accountLoader.fill();
}
return out;
}
private CommentInfo toCommentInfo(PatchLineComment c, AccountLoader loader) {
CommentInfo r = new CommentInfo();
r.id = Url.encode(c.getKey().get());
r.path = c.getKey().getParentKey().getFileName();
if (c.getSide() == 0) {
r.side = Side.PARENT;
}
if (c.getLine() > 0) {
r.line = c.getLine();
}
r.inReplyTo = Url.encode(c.getParentUuid());
r.message = Strings.emptyToNull(c.getMessage());
r.updated = c.getWrittenOn();
r.range = toRange(c.getRange());
if (loader != null) {
r.author = loader.get(c.getAuthor());
}
return r;
}
private Range toRange(CommentRange commentRange) {
Range range = null;
if (commentRange != null) {
range = new Range();
range.startLine = commentRange.getStartLine();
range.startCharacter = commentRange.getStartCharacter();
range.endLine = commentRange.getEndLine();
range.endCharacter = commentRange.getEndCharacter();
}
return range;
}
}

View File

@@ -29,7 +29,7 @@ import com.google.inject.Provider;
import com.google.inject.Singleton;
@Singleton
class Comments implements ChildCollection<RevisionResource, CommentResource> {
public class Comments implements ChildCollection<RevisionResource, CommentResource> {
private final DynamicMap<RestView<CommentResource>> views;
private final ListComments list;
private final Provider<ReviewDb> dbProvider;

View File

@@ -19,6 +19,7 @@ import static com.google.gerrit.server.PatchLineCommentsUtil.setCommentRevId;
import com.google.common.base.Strings;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.api.changes.DraftInput;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.Side;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.Response;
@@ -41,19 +42,22 @@ import java.sql.Timestamp;
import java.util.Collections;
@Singleton
class CreateDraft implements RestModifyView<RevisionResource, DraftInput> {
public class CreateDraft implements RestModifyView<RevisionResource, DraftInput> {
private final Provider<ReviewDb> db;
private final ChangeUpdate.Factory updateFactory;
private final CommentJson commentJson;
private final PatchLineCommentsUtil plcUtil;
private final PatchListCache patchListCache;
@Inject
CreateDraft(Provider<ReviewDb> db,
ChangeUpdate.Factory updateFactory,
CommentJson commentJson,
PatchLineCommentsUtil plcUtil,
PatchListCache patchListCache) {
this.db = db;
this.updateFactory = updateFactory;
this.commentJson = commentJson;
this.plcUtil = plcUtil;
this.patchListCache = patchListCache;
}
@@ -89,6 +93,6 @@ class CreateDraft implements RestModifyView<RevisionResource, DraftInput> {
setCommentRevId(c, patchListCache, rsrc.getChange(), rsrc.getPatchSet());
plcUtil.insertComments(db.get(), update, Collections.singleton(c));
update.commit();
return Response.created(new CommentInfo(c, null));
return Response.created(commentJson.format(c, false));
}
}

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.server.change;
import static com.google.gerrit.server.PatchLineCommentsUtil.setCommentRevId;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.reviewdb.client.PatchLineComment;
@@ -33,7 +34,7 @@ import java.io.IOException;
import java.util.Collections;
@Singleton
class DeleteDraft implements RestModifyView<DraftResource, Input> {
public class DeleteDraft implements RestModifyView<DraftResource, Input> {
static class Input {
}

View File

@@ -30,7 +30,7 @@ import com.google.inject.Provider;
import com.google.inject.Singleton;
@Singleton
class Drafts implements ChildCollection<RevisionResource, DraftResource> {
public class Drafts implements ChildCollection<RevisionResource, DraftResource> {
private final DynamicMap<RestView<DraftResource>> views;
private final Provider<CurrentUser> user;
private final ListDrafts list;

View File

@@ -14,27 +14,24 @@
package com.google.gerrit.server.change;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@Singleton
class GetComment implements RestReadView<CommentResource> {
public class GetComment implements RestReadView<CommentResource> {
private final AccountLoader.Factory accountLoaderFactory;
private final CommentJson commentJson;
@Inject
GetComment(AccountLoader.Factory accountLoaderFactory) {
this.accountLoaderFactory = accountLoaderFactory;
GetComment(CommentJson commentJson) {
this.commentJson = commentJson;
}
@Override
public CommentInfo apply(CommentResource rsrc) throws OrmException {
AccountLoader accountLoader = accountLoaderFactory.create(true);
CommentInfo ci = new CommentInfo(rsrc.getComment(), accountLoader);
accountLoader.fill();
return ci;
return commentJson.format(rsrc.getComment());
}
}

View File

@@ -14,27 +14,24 @@
package com.google.gerrit.server.change;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@Singleton
class GetDraft implements RestReadView<DraftResource> {
public class GetDraft implements RestReadView<DraftResource> {
private final AccountLoader.Factory accountLoaderFactory;
private final CommentJson commentJson;
@Inject
GetDraft(AccountLoader.Factory accountLoaderFactory) {
this.accountLoaderFactory = accountLoaderFactory;
GetDraft(CommentJson commentJson) {
this.commentJson = commentJson;
}
@Override
public CommentInfo apply(DraftResource rsrc) throws OrmException {
AccountLoader accountLoader = accountLoaderFactory.create(true);
CommentInfo ci = new CommentInfo(rsrc.getComment(), accountLoader);
accountLoader.fill();
return ci;
return commentJson.format(rsrc.getComment());
}
}

View File

@@ -17,7 +17,6 @@ package com.google.gerrit.server.change;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.PatchLineCommentsUtil;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -25,11 +24,12 @@ import com.google.inject.Provider;
import com.google.inject.Singleton;
@Singleton
class ListComments extends ListDrafts {
public class ListComments extends ListDrafts {
@Inject
ListComments(Provider<ReviewDb> db, AccountLoader.Factory alf,
ListComments(Provider<ReviewDb> db,
CommentJson commentJson,
PatchLineCommentsUtil plcUtil) {
super(db, alf, plcUtil);
super(db, commentJson, plcUtil);
}
@Override

View File

@@ -14,37 +14,31 @@
package com.google.gerrit.server.change;
import static com.google.common.base.MoreObjects.firstNonNull;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gerrit.extensions.common.Side;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.PatchLineCommentsUtil;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
@Singleton
class ListDrafts implements RestReadView<RevisionResource> {
public class ListDrafts implements RestReadView<RevisionResource> {
protected final Provider<ReviewDb> db;
protected CommentJson commentJson;
protected final PatchLineCommentsUtil plcUtil;
private final AccountLoader.Factory accountLoaderFactory;
@Inject
ListDrafts(Provider<ReviewDb> db, AccountLoader.Factory alf,
ListDrafts(Provider<ReviewDb> db,
CommentJson commentJson,
PatchLineCommentsUtil plcUtil) {
this.db = db;
this.accountLoaderFactory = alf;
this.commentJson = commentJson;
this.plcUtil = plcUtil;
}
@@ -61,38 +55,6 @@ class ListDrafts implements RestReadView<RevisionResource> {
@Override
public Map<String, List<CommentInfo>> apply(RevisionResource rsrc)
throws OrmException {
Map<String, List<CommentInfo>> out = Maps.newTreeMap();
AccountLoader accountLoader =
includeAuthorInfo() ? accountLoaderFactory.create(true) : null;
for (PatchLineComment c : listComments(rsrc)) {
CommentInfo o = new CommentInfo(c, accountLoader);
List<CommentInfo> list = out.get(o.path);
if (list == null) {
list = Lists.newArrayList();
out.put(o.path, list);
}
o.path = null;
list.add(o);
}
for (List<CommentInfo> list : out.values()) {
Collections.sort(list, new Comparator<CommentInfo>() {
@Override
public int compare(CommentInfo a, CommentInfo b) {
int c = firstNonNull(a.side, Side.REVISION).ordinal()
- firstNonNull(b.side, Side.REVISION).ordinal();
if (c == 0) {
c = firstNonNull(a.line, 0) - firstNonNull(b.line, 0);
}
if (c == 0) {
c = a.id.compareTo(b.id);
}
return c;
}
});
}
if (accountLoader != null) {
accountLoader.fill();
}
return out;
return commentJson.format(listComments(rsrc), includeAuthorInfo());
}
}

View File

@@ -18,6 +18,7 @@ import static com.google.gerrit.server.PatchLineCommentsUtil.setCommentRevId;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.api.changes.DraftInput;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.Side;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.Response;
@@ -38,12 +39,13 @@ import java.io.IOException;
import java.util.Collections;
@Singleton
class PutDraft implements RestModifyView<DraftResource, DraftInput> {
public class PutDraft implements RestModifyView<DraftResource, DraftInput> {
private final Provider<ReviewDb> db;
private final DeleteDraft delete;
private final PatchLineCommentsUtil plcUtil;
private final ChangeUpdate.Factory updateFactory;
private final CommentJson commentJson;
private final PatchListCache patchListCache;
@Inject
@@ -51,11 +53,13 @@ class PutDraft implements RestModifyView<DraftResource, DraftInput> {
DeleteDraft delete,
PatchLineCommentsUtil plcUtil,
ChangeUpdate.Factory updateFactory,
CommentJson commentJson,
PatchListCache patchListCache) {
this.db = db;
this.delete = delete;
this.plcUtil = plcUtil;
this.updateFactory = updateFactory;
this.commentJson = commentJson;
this.patchListCache = patchListCache;
}
@@ -99,7 +103,7 @@ class PutDraft implements RestModifyView<DraftResource, DraftInput> {
Collections.singleton(update(c, in)));
}
update.commit();
return Response.ok(new CommentInfo(c, null));
return Response.ok(commentJson.format(c, false));
}
private PatchLineComment update(PatchLineComment e, DraftInput in) {

View File

@@ -28,6 +28,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.Side;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.IdString;