Port "mark reviewed" to new JSON API
Defines /changes/*/revisions/*/files/* as the JSON endpoint for file resources, escaping / as %2F as in /projects. Add an endpoint /reviewed under this to mark/unmark files as reviewed with PUT/DELETE. Change-Id: I1de9934b709bdad8014d1d30a25703d7fd55be88
This commit is contained in:
		@@ -15,23 +15,25 @@
 | 
			
		||||
package com.google.gerrit.client.patches;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.client.Gerrit;
 | 
			
		||||
import com.google.gerrit.client.VoidResult;
 | 
			
		||||
import com.google.gerrit.client.changes.PatchTable;
 | 
			
		||||
import com.google.gerrit.client.changes.PatchTable.PatchValidator;
 | 
			
		||||
import com.google.gerrit.client.changes.Util;
 | 
			
		||||
import com.google.gerrit.client.rpc.RestApi;
 | 
			
		||||
import com.google.gerrit.client.ui.ChangeLink;
 | 
			
		||||
import com.google.gerrit.client.ui.InlineHyperlink;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Patch;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.PatchSet;
 | 
			
		||||
import com.google.gwt.event.dom.client.ClickEvent;
 | 
			
		||||
import com.google.gwt.event.dom.client.ClickHandler;
 | 
			
		||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
 | 
			
		||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
 | 
			
		||||
import com.google.gwt.user.client.rpc.AsyncCallback;
 | 
			
		||||
import com.google.gwt.user.client.ui.Anchor;
 | 
			
		||||
import com.google.gwt.user.client.ui.CheckBox;
 | 
			
		||||
import com.google.gwt.user.client.ui.FlowPanel;
 | 
			
		||||
import com.google.gwtexpui.safehtml.client.SafeHtml;
 | 
			
		||||
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
 | 
			
		||||
import com.google.gwtjsonrpc.common.AsyncCallback;
 | 
			
		||||
import com.google.gwtjsonrpc.common.VoidResult;
 | 
			
		||||
 | 
			
		||||
public class ReviewedPanels {
 | 
			
		||||
 | 
			
		||||
@@ -98,8 +100,13 @@ public class ReviewedPanels {
 | 
			
		||||
      fileList.updateReviewedStatus(patchKey, reviewed);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PatchUtil.DETAIL_SVC.setReviewedByCurrentUser(patchKey, reviewed,
 | 
			
		||||
        new AsyncCallback<VoidResult>() {
 | 
			
		||||
    PatchSet.Id ps = patchKey.getParentKey();
 | 
			
		||||
    RestApi api = new RestApi("/changes/").id(ps.getParentKey().get())
 | 
			
		||||
        .view("revisions").id(ps.get())
 | 
			
		||||
        .view("files").id(patchKey.getFileName())
 | 
			
		||||
        .view("reviewed");
 | 
			
		||||
 | 
			
		||||
    AsyncCallback<VoidResult> cb = new AsyncCallback<VoidResult>() {
 | 
			
		||||
      @Override
 | 
			
		||||
      public void onFailure(Throwable arg0) {
 | 
			
		||||
        // nop
 | 
			
		||||
@@ -109,7 +116,12 @@ public class ReviewedPanels {
 | 
			
		||||
      public void onSuccess(VoidResult result) {
 | 
			
		||||
        // nop
 | 
			
		||||
      }
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
    if (reviewed) {
 | 
			
		||||
      api.put(cb);
 | 
			
		||||
    } else {
 | 
			
		||||
      api.delete(cb);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void go() {
 | 
			
		||||
 
 | 
			
		||||
@@ -210,6 +210,10 @@ public class RestApi {
 | 
			
		||||
    return idRaw(URL.encodeQueryString(id));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public RestApi id(int id) {
 | 
			
		||||
    return idRaw(Integer.toString(id));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public RestApi idRaw(String name) {
 | 
			
		||||
    if (hasQueryParams) {
 | 
			
		||||
      throw new IllegalStateException();
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ class CreateDraft implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
            new Patch.Key(rsrc.getPatchSet().getId(), in.path),
 | 
			
		||||
            ChangeUtil.messageUUID(db.get())),
 | 
			
		||||
        in.line != null ? in.line : 0,
 | 
			
		||||
        rsrc.getAuthorId(),
 | 
			
		||||
        rsrc.getAccountId(),
 | 
			
		||||
        Url.decode(in.inReplyTo));
 | 
			
		||||
    c.setStatus(Status.DRAFT);
 | 
			
		||||
    c.setSide(in.side == GetDraft.Side.PARENT ? (short) 0 : (short) 1);
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,7 @@ class Drafts implements ChildCollection<RevisionResource, DraftResource> {
 | 
			
		||||
    for (PatchLineComment c : dbProvider.get().patchComments()
 | 
			
		||||
        .draftByPatchSetAuthor(
 | 
			
		||||
            rev.getPatchSet().getId(),
 | 
			
		||||
            rev.getAuthorId())) {
 | 
			
		||||
            rev.getAccountId())) {
 | 
			
		||||
      if (uuid.equals(c.getKey().get())) {
 | 
			
		||||
        return new DraftResource(rev, c);
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@ class ListDrafts implements RestReadView<RevisionResource> {
 | 
			
		||||
    for (PatchLineComment c : db.get().patchComments()
 | 
			
		||||
        .draftByPatchSetAuthor(
 | 
			
		||||
            rsrc.getPatchSet().getId(),
 | 
			
		||||
            rsrc.getAuthorId())) {
 | 
			
		||||
            rsrc.getAccountId())) {
 | 
			
		||||
      Comment o = new Comment(c);
 | 
			
		||||
      List<Comment> list = out.get(o.path);
 | 
			
		||||
      if (list == null) {
 | 
			
		||||
 
 | 
			
		||||
@@ -16,11 +16,14 @@ package com.google.gerrit.server.change;
 | 
			
		||||
 | 
			
		||||
import static com.google.gerrit.server.change.ChangeResource.CHANGE_KIND;
 | 
			
		||||
import static com.google.gerrit.server.change.DraftResource.DRAFT_KIND;
 | 
			
		||||
import static com.google.gerrit.server.change.PatchResource.PATCH_KIND;
 | 
			
		||||
import static com.google.gerrit.server.change.ReviewerResource.REVIEWER_KIND;
 | 
			
		||||
import static com.google.gerrit.server.change.RevisionResource.REVISION_KIND;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.extensions.registration.DynamicMap;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.RestApiModule;
 | 
			
		||||
import com.google.gerrit.server.change.Reviewed.DeleteReviewed;
 | 
			
		||||
import com.google.gerrit.server.change.Reviewed.PutReviewed;
 | 
			
		||||
import com.google.gerrit.server.config.FactoryModule;
 | 
			
		||||
 | 
			
		||||
public class Module extends RestApiModule {
 | 
			
		||||
@@ -29,9 +32,11 @@ public class Module extends RestApiModule {
 | 
			
		||||
    bind(Revisions.class);
 | 
			
		||||
    bind(Reviewers.class);
 | 
			
		||||
    bind(Drafts.class);
 | 
			
		||||
    bind(Patches.class);
 | 
			
		||||
 | 
			
		||||
    DynamicMap.mapOf(binder(), CHANGE_KIND);
 | 
			
		||||
    DynamicMap.mapOf(binder(), DRAFT_KIND);
 | 
			
		||||
    DynamicMap.mapOf(binder(), PATCH_KIND);
 | 
			
		||||
    DynamicMap.mapOf(binder(), REVIEWER_KIND);
 | 
			
		||||
    DynamicMap.mapOf(binder(), REVISION_KIND);
 | 
			
		||||
 | 
			
		||||
@@ -58,6 +63,10 @@ public class Module extends RestApiModule {
 | 
			
		||||
    put(DRAFT_KIND).to(PutDraft.class);
 | 
			
		||||
    delete(DRAFT_KIND).to(DeleteDraft.class);
 | 
			
		||||
 | 
			
		||||
    child(REVISION_KIND, "files").to(Patches.class);
 | 
			
		||||
    put(PATCH_KIND, "reviewed").to(PutReviewed.class);
 | 
			
		||||
    delete(PATCH_KIND, "reviewed").to(DeleteReviewed.class);
 | 
			
		||||
 | 
			
		||||
    install(new FactoryModule() {
 | 
			
		||||
      @Override
 | 
			
		||||
      protected void configure() {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,42 @@
 | 
			
		||||
// 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.gerrit.extensions.restapi.RestResource;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.RestView;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Account;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Patch;
 | 
			
		||||
import com.google.inject.TypeLiteral;
 | 
			
		||||
 | 
			
		||||
public class PatchResource implements RestResource {
 | 
			
		||||
  public static final TypeLiteral<RestView<PatchResource>> PATCH_KIND =
 | 
			
		||||
      new TypeLiteral<RestView<PatchResource>>() {};
 | 
			
		||||
 | 
			
		||||
  private final RevisionResource rev;
 | 
			
		||||
  private final Patch.Key key;
 | 
			
		||||
 | 
			
		||||
  PatchResource(RevisionResource rev, String name) {
 | 
			
		||||
    this.rev = rev;
 | 
			
		||||
    this.key = new Patch.Key(rev.getPatchSet().getId(), name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public Patch.Key getPatchKey() {
 | 
			
		||||
    return key;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Account.Id getAccountId() {
 | 
			
		||||
    return rev.getAccountId();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
// 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.gerrit.extensions.registration.DynamicMap;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.AuthException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.ChildCollection;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.IdString;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.RestView;
 | 
			
		||||
import com.google.gwtorm.server.OrmException;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
 | 
			
		||||
class Patches implements ChildCollection<RevisionResource, PatchResource> {
 | 
			
		||||
  private final DynamicMap<RestView<PatchResource>> views;
 | 
			
		||||
 | 
			
		||||
  @Inject
 | 
			
		||||
  Patches(DynamicMap<RestView<PatchResource>> views) {
 | 
			
		||||
    this.views = views;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public DynamicMap<RestView<PatchResource>> views() {
 | 
			
		||||
    return views;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public RestView<RevisionResource> list() throws AuthException {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public PatchResource parse(RevisionResource rev, IdString id)
 | 
			
		||||
      throws ResourceNotFoundException, OrmException, AuthException {
 | 
			
		||||
    return new PatchResource(rev, id.get());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -161,7 +161,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
          input.notify,
 | 
			
		||||
          change,
 | 
			
		||||
          revision.getPatchSet(),
 | 
			
		||||
          revision.getAuthorId(),
 | 
			
		||||
          revision.getAccountId(),
 | 
			
		||||
          message,
 | 
			
		||||
          comments).sendAsync();
 | 
			
		||||
      fireCommentAddedHook(revision);
 | 
			
		||||
@@ -285,7 +285,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
                  new Patch.Key(rsrc.getPatchSet().getId(), path),
 | 
			
		||||
                  ChangeUtil.messageUUID(db)),
 | 
			
		||||
              c.line,
 | 
			
		||||
              rsrc.getAuthorId(),
 | 
			
		||||
              rsrc.getAccountId(),
 | 
			
		||||
              parent);
 | 
			
		||||
        } else if (parent != null) {
 | 
			
		||||
          e.setParentUuid(parent);
 | 
			
		||||
@@ -326,7 +326,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
    Map<String, PatchLineComment> drafts = Maps.newHashMap();
 | 
			
		||||
    for (PatchLineComment c : db.patchComments().draftByPatchSetAuthor(
 | 
			
		||||
          rsrc.getPatchSet().getId(),
 | 
			
		||||
          rsrc.getAuthorId())) {
 | 
			
		||||
          rsrc.getAccountId())) {
 | 
			
		||||
      drafts.put(c.getKey().get(), c);
 | 
			
		||||
    }
 | 
			
		||||
    return drafts;
 | 
			
		||||
@@ -375,7 +375,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
      } else if (c == null) {
 | 
			
		||||
        c = new PatchSetApproval(new PatchSetApproval.Key(
 | 
			
		||||
                rsrc.getPatchSet().getId(),
 | 
			
		||||
                rsrc.getAuthorId(),
 | 
			
		||||
                rsrc.getAccountId(),
 | 
			
		||||
                at.getCategory().getId()),
 | 
			
		||||
            ent.getValue());
 | 
			
		||||
        c.setGranted(timestamp);
 | 
			
		||||
@@ -405,7 +405,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
        // as a reviewer by picking the first server-wide ApprovalType.
 | 
			
		||||
        PatchSetApproval c = new PatchSetApproval(new PatchSetApproval.Key(
 | 
			
		||||
            rsrc.getPatchSet().getId(),
 | 
			
		||||
            rsrc.getAuthorId(),
 | 
			
		||||
            rsrc.getAccountId(),
 | 
			
		||||
            approvalTypes.getApprovalTypes().get(0).getCategory().getId()),
 | 
			
		||||
            (short) 0);
 | 
			
		||||
        c.setGranted(timestamp);
 | 
			
		||||
@@ -428,7 +428,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
      List<PatchSetApproval> del) throws OrmException {
 | 
			
		||||
    Map<String, PatchSetApproval> current = Maps.newHashMap();
 | 
			
		||||
    for (PatchSetApproval a : db.patchSetApprovals().byPatchSetUser(
 | 
			
		||||
          rsrc.getPatchSet().getId(), rsrc.getAuthorId())) {
 | 
			
		||||
          rsrc.getPatchSet().getId(), rsrc.getAccountId())) {
 | 
			
		||||
      if (ApprovalCategory.SUBMIT.equals(a.getCategoryId())) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
@@ -475,7 +475,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
 | 
			
		||||
 | 
			
		||||
    message = new ChangeMessage(
 | 
			
		||||
        new ChangeMessage.Key(change.getId(), ChangeUtil.messageUUID(db)),
 | 
			
		||||
        rsrc.getAuthorId(),
 | 
			
		||||
        rsrc.getAccountId(),
 | 
			
		||||
        timestamp,
 | 
			
		||||
        rsrc.getPatchSet().getId());
 | 
			
		||||
    message.setMessage(String.format(
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,84 @@
 | 
			
		||||
// 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.gerrit.extensions.restapi.Response;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.RestModifyView;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountPatchReview;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
import com.google.gwtorm.server.OrmException;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
 | 
			
		||||
class Reviewed {
 | 
			
		||||
  static class Input {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static class PutReviewed implements RestModifyView<PatchResource, Input> {
 | 
			
		||||
    private final Provider<ReviewDb> dbProvider;
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    PutReviewed(Provider<ReviewDb> dbProvider) {
 | 
			
		||||
      this.dbProvider = dbProvider;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Object apply(PatchResource resource, Input input)
 | 
			
		||||
        throws OrmException {
 | 
			
		||||
      ReviewDb db = dbProvider.get();
 | 
			
		||||
      AccountPatchReview apr = getExisting(db, resource);
 | 
			
		||||
      if (apr == null) {
 | 
			
		||||
        db.accountPatchReviews().insert(
 | 
			
		||||
            Collections.singleton(new AccountPatchReview(resource.getPatchKey(),
 | 
			
		||||
                resource.getAccountId())));
 | 
			
		||||
        return Response.created("");
 | 
			
		||||
      } else {
 | 
			
		||||
        return Response.ok("");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static class DeleteReviewed implements RestModifyView<PatchResource, Input> {
 | 
			
		||||
    private final Provider<ReviewDb> dbProvider;
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    DeleteReviewed(Provider<ReviewDb> dbProvider) {
 | 
			
		||||
      this.dbProvider = dbProvider;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Object apply(PatchResource resource, Input input)
 | 
			
		||||
        throws OrmException {
 | 
			
		||||
      ReviewDb db = dbProvider.get();
 | 
			
		||||
      AccountPatchReview apr = getExisting(db, resource);
 | 
			
		||||
      if (apr != null) {
 | 
			
		||||
        db.accountPatchReviews().delete(Collections.singleton(apr));
 | 
			
		||||
      }
 | 
			
		||||
      return Response.none();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static AccountPatchReview getExisting(ReviewDb db,
 | 
			
		||||
      PatchResource resource) throws OrmException {
 | 
			
		||||
    AccountPatchReview.Key key = new AccountPatchReview.Key(
 | 
			
		||||
        resource.getPatchKey(), resource.getAccountId());
 | 
			
		||||
    return db.accountPatchReviews().get(key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private Reviewed() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -47,7 +47,7 @@ public class RevisionResource implements RestResource {
 | 
			
		||||
    return ps;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Account.Id getAuthorId() {
 | 
			
		||||
  Account.Id getAccountId() {
 | 
			
		||||
    return ((IdentifiedUser) getControl().getCurrentUser()).getAccountId();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user