Accept in_reply_to to thread inline comments
The in_reply_to field supplies the id of another comment, enabling threading. Because id is URL encoded to match a REST API we also encode the in_reply_to field, allowing clients to correctly line up messages by simple string equality. Change-Id: Idc6af51873b9b8a12707c6f4df9d25b627e8b409
This commit is contained in:
		@@ -185,4 +185,8 @@ public final class PatchLineComment {
 | 
			
		||||
  public String getParentUuid() {
 | 
			
		||||
    return parentUuid;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void setParentUuid(String inReplyTo) {
 | 
			
		||||
    parentUuid = inReplyTo;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@ import com.google.gerrit.reviewdb.client.PatchLineComment.Status;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
import com.google.gerrit.server.ChangeUtil;
 | 
			
		||||
import com.google.gerrit.server.change.PutDraft.Input;
 | 
			
		||||
import com.google.gerrit.server.util.Url;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
 | 
			
		||||
@@ -60,7 +61,7 @@ class CreateDraft implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
            ChangeUtil.messageUUID(db.get())),
 | 
			
		||||
        in.line != null ? in.line : 0,
 | 
			
		||||
        rsrc.getAuthorId(),
 | 
			
		||||
        null);
 | 
			
		||||
        Url.decode(in.inReplyTo));
 | 
			
		||||
    c.setStatus(Status.DRAFT);
 | 
			
		||||
    c.setSide(in.side == GetDraft.Side.PARENT ? (short) 0 : (short) 1);
 | 
			
		||||
    c.setMessage(in.message.trim());
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,7 @@ class GetDraft implements RestReadView<DraftResource> {
 | 
			
		||||
    String path;
 | 
			
		||||
    Side side;
 | 
			
		||||
    Integer line;
 | 
			
		||||
    String inReplyTo;
 | 
			
		||||
    String message;
 | 
			
		||||
    Timestamp updated;
 | 
			
		||||
 | 
			
		||||
@@ -53,6 +54,7 @@ class GetDraft implements RestReadView<DraftResource> {
 | 
			
		||||
      if (c.getLine() > 0) {
 | 
			
		||||
        line = c.getLine();
 | 
			
		||||
      }
 | 
			
		||||
      inReplyTo = Url.encode(c.getParentUuid());
 | 
			
		||||
      message = Strings.emptyToNull(c.getMessage());
 | 
			
		||||
      updated = c.getWrittenOn();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,7 @@ import com.google.gerrit.server.ChangeUtil;
 | 
			
		||||
import com.google.gerrit.server.IdentifiedUser;
 | 
			
		||||
import com.google.gerrit.server.change.PostReview.Input;
 | 
			
		||||
import com.google.gerrit.server.project.ChangeControl;
 | 
			
		||||
import com.google.gerrit.server.util.Url;
 | 
			
		||||
import com.google.gwtorm.server.OrmException;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
 | 
			
		||||
@@ -85,6 +86,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
    String id;
 | 
			
		||||
    GetDraft.Side side;
 | 
			
		||||
    int line;
 | 
			
		||||
    String inReplyTo;
 | 
			
		||||
    String message;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -261,6 +263,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
    for (Map.Entry<String, List<Comment>> ent : in.entrySet()) {
 | 
			
		||||
      String path = ent.getKey();
 | 
			
		||||
      for (Comment c : ent.getValue()) {
 | 
			
		||||
        String parent = Url.decode(c.inReplyTo);
 | 
			
		||||
        PatchLineComment e = drafts.remove(c.id);
 | 
			
		||||
        boolean create = e == null;
 | 
			
		||||
        if (create) {
 | 
			
		||||
@@ -270,7 +273,9 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
                  ChangeUtil.messageUUID(db)),
 | 
			
		||||
              c.line,
 | 
			
		||||
              rsrc.getAuthorId(),
 | 
			
		||||
              null);
 | 
			
		||||
              parent);
 | 
			
		||||
        } else if (parent != null) {
 | 
			
		||||
          e.setParentUuid(parent);
 | 
			
		||||
        }
 | 
			
		||||
        e.setStatus(PatchLineComment.Status.PUBLISHED);
 | 
			
		||||
        e.setWrittenOn(timestamp);
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,8 @@ import com.google.gerrit.reviewdb.client.PatchLineComment;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
import com.google.gerrit.server.change.GetDraft.Side;
 | 
			
		||||
import com.google.gerrit.server.change.PutDraft.Input;
 | 
			
		||||
import com.google.gerrit.server.util.Url;
 | 
			
		||||
import com.google.gwtorm.server.OrmException;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
 | 
			
		||||
@@ -37,6 +39,7 @@ class PutDraft implements RestModifyView<DraftResource, Input> {
 | 
			
		||||
    String path;
 | 
			
		||||
    Side side;
 | 
			
		||||
    Integer line;
 | 
			
		||||
    String inReplyTo;
 | 
			
		||||
    Timestamp updated; // Accepted but ignored.
 | 
			
		||||
 | 
			
		||||
    @DefaultInput
 | 
			
		||||
@@ -58,9 +61,9 @@ class PutDraft implements RestModifyView<DraftResource, Input> {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public Object apply(DraftResource rsrc, Input in)
 | 
			
		||||
      throws AuthException, BadRequestException, ResourceConflictException,
 | 
			
		||||
      Exception {
 | 
			
		||||
  public Object apply(DraftResource rsrc, Input in) throws AuthException,
 | 
			
		||||
      BadRequestException, ResourceConflictException, OrmException {
 | 
			
		||||
    PatchLineComment c = rsrc.getComment();
 | 
			
		||||
    if (in == null || in.message == null || in.message.trim().isEmpty()) {
 | 
			
		||||
      return delete.get().apply(rsrc, null);
 | 
			
		||||
    } else if (in.kind != null && !"gerritcodereview#comment".equals(in.kind)) {
 | 
			
		||||
@@ -69,20 +72,19 @@ class PutDraft implements RestModifyView<DraftResource, Input> {
 | 
			
		||||
      throw new BadRequestException("line must be >= 0");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PatchLineComment c = rsrc.getComment();
 | 
			
		||||
    if (in.path != null
 | 
			
		||||
        && !in.path.equals(c.getKey().getParentKey().getFileName())) {
 | 
			
		||||
      // Updating the path alters the primary key, which isn't possible.
 | 
			
		||||
      // Delete then recreate the comment instead of an update.
 | 
			
		||||
      db.get().patchComments().delete(Collections.singleton(c));
 | 
			
		||||
      c = update(new PatchLineComment(
 | 
			
		||||
      c = new PatchLineComment(
 | 
			
		||||
          new PatchLineComment.Key(
 | 
			
		||||
              new Patch.Key(rsrc.getPatchSet().getId(), in.path),
 | 
			
		||||
              c.getKey().get()),
 | 
			
		||||
          c.getLine(),
 | 
			
		||||
          rsrc.getAuthorId(),
 | 
			
		||||
          c.getParentUuid()), in);
 | 
			
		||||
      db.get().patchComments().insert(Collections.singleton(c));
 | 
			
		||||
          c.getParentUuid());
 | 
			
		||||
      db.get().patchComments().insert(Collections.singleton(update(c, in)));
 | 
			
		||||
    } else {
 | 
			
		||||
      db.get().patchComments().update(Collections.singleton(update(c, in)));
 | 
			
		||||
    }
 | 
			
		||||
@@ -96,6 +98,9 @@ class PutDraft implements RestModifyView<DraftResource, Input> {
 | 
			
		||||
    if (in.line != null) {
 | 
			
		||||
      e.setLine(in.line);
 | 
			
		||||
    }
 | 
			
		||||
    if (in.inReplyTo != null) {
 | 
			
		||||
      e.setParentUuid(Url.decode(in.inReplyTo));
 | 
			
		||||
    }
 | 
			
		||||
    e.setMessage(in.message.trim());
 | 
			
		||||
    e.updated();
 | 
			
		||||
    return e;
 | 
			
		||||
 
 | 
			
		||||
@@ -38,21 +38,27 @@ public final class Url {
 | 
			
		||||
   * @return a string with all invalid URL characters escaped.
 | 
			
		||||
   */
 | 
			
		||||
  public static String encode(String component) {
 | 
			
		||||
    if (component != null) {
 | 
			
		||||
      try {
 | 
			
		||||
        return URLEncoder.encode(component, "UTF-8");
 | 
			
		||||
      } catch (UnsupportedEncodingException e) {
 | 
			
		||||
        throw new RuntimeException("JVM must support UTF-8", e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** Decode a URL encoded string, e.g. from {@code "%2F"} to {@code "/"}. */
 | 
			
		||||
  public static String decode(String str) {
 | 
			
		||||
    if (str != null) {
 | 
			
		||||
      try {
 | 
			
		||||
        return URLDecoder.decode(str, "UTF-8");
 | 
			
		||||
      } catch (UnsupportedEncodingException e) {
 | 
			
		||||
        throw new RuntimeException("JVM must support UTF-8", e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private Url() {
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user