LCOV - code coverage report
Current view: top level - server/api/changes - RevisionApiImpl.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 176 226 77.9 %
Date: 2022-11-19 15:00:39 Functions: 49 49 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2013 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.server.api.changes;
      16             : 
      17             : import static com.google.common.base.Preconditions.checkArgument;
      18             : import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
      19             : 
      20             : import com.google.common.collect.ImmutableSet;
      21             : import com.google.common.collect.ListMultimap;
      22             : import com.google.common.collect.MultimapBuilder.ListMultimapBuilder;
      23             : import com.google.gerrit.common.Nullable;
      24             : import com.google.gerrit.entities.PatchSetApproval;
      25             : import com.google.gerrit.extensions.api.changes.ChangeApi;
      26             : import com.google.gerrit.extensions.api.changes.Changes;
      27             : import com.google.gerrit.extensions.api.changes.CherryPickInput;
      28             : import com.google.gerrit.extensions.api.changes.CommentApi;
      29             : import com.google.gerrit.extensions.api.changes.DraftApi;
      30             : import com.google.gerrit.extensions.api.changes.DraftInput;
      31             : import com.google.gerrit.extensions.api.changes.FileApi;
      32             : import com.google.gerrit.extensions.api.changes.GetRelatedOption;
      33             : import com.google.gerrit.extensions.api.changes.RebaseInput;
      34             : import com.google.gerrit.extensions.api.changes.RelatedChangesInfo;
      35             : import com.google.gerrit.extensions.api.changes.ReviewInput;
      36             : import com.google.gerrit.extensions.api.changes.ReviewResult;
      37             : import com.google.gerrit.extensions.api.changes.RevisionApi;
      38             : import com.google.gerrit.extensions.api.changes.RevisionReviewerApi;
      39             : import com.google.gerrit.extensions.api.changes.RobotCommentApi;
      40             : import com.google.gerrit.extensions.api.changes.SubmitInput;
      41             : import com.google.gerrit.extensions.client.ArchiveFormat;
      42             : import com.google.gerrit.extensions.client.SubmitType;
      43             : import com.google.gerrit.extensions.common.ActionInfo;
      44             : import com.google.gerrit.extensions.common.ApplyProvidedFixInput;
      45             : import com.google.gerrit.extensions.common.ApprovalInfo;
      46             : import com.google.gerrit.extensions.common.ChangeInfo;
      47             : import com.google.gerrit.extensions.common.CommentInfo;
      48             : import com.google.gerrit.extensions.common.CommitInfo;
      49             : import com.google.gerrit.extensions.common.DescriptionInput;
      50             : import com.google.gerrit.extensions.common.DiffInfo;
      51             : import com.google.gerrit.extensions.common.EditInfo;
      52             : import com.google.gerrit.extensions.common.FileInfo;
      53             : import com.google.gerrit.extensions.common.Input;
      54             : import com.google.gerrit.extensions.common.MergeableInfo;
      55             : import com.google.gerrit.extensions.common.RobotCommentInfo;
      56             : import com.google.gerrit.extensions.common.TestSubmitRuleInfo;
      57             : import com.google.gerrit.extensions.common.TestSubmitRuleInput;
      58             : import com.google.gerrit.extensions.restapi.BinaryResult;
      59             : import com.google.gerrit.extensions.restapi.IdString;
      60             : import com.google.gerrit.extensions.restapi.RestApiException;
      61             : import com.google.gerrit.extensions.restapi.RestModifyView;
      62             : import com.google.gerrit.server.account.AccountDirectory.FillOptions;
      63             : import com.google.gerrit.server.account.AccountLoader;
      64             : import com.google.gerrit.server.approval.ApprovalsUtil;
      65             : import com.google.gerrit.server.change.FileResource;
      66             : import com.google.gerrit.server.change.RebaseUtil;
      67             : import com.google.gerrit.server.change.RevisionResource;
      68             : import com.google.gerrit.server.git.GitRepositoryManager;
      69             : import com.google.gerrit.server.restapi.change.ApplyProvidedFix;
      70             : import com.google.gerrit.server.restapi.change.ApplyStoredFix;
      71             : import com.google.gerrit.server.restapi.change.CherryPick;
      72             : import com.google.gerrit.server.restapi.change.Comments;
      73             : import com.google.gerrit.server.restapi.change.CreateDraftComment;
      74             : import com.google.gerrit.server.restapi.change.DraftComments;
      75             : import com.google.gerrit.server.restapi.change.Files;
      76             : import com.google.gerrit.server.restapi.change.Fixes;
      77             : import com.google.gerrit.server.restapi.change.GetArchive;
      78             : import com.google.gerrit.server.restapi.change.GetCommit;
      79             : import com.google.gerrit.server.restapi.change.GetDescription;
      80             : import com.google.gerrit.server.restapi.change.GetMergeList;
      81             : import com.google.gerrit.server.restapi.change.GetPatch;
      82             : import com.google.gerrit.server.restapi.change.GetRelated;
      83             : import com.google.gerrit.server.restapi.change.GetRevisionActions;
      84             : import com.google.gerrit.server.restapi.change.ListPortedComments;
      85             : import com.google.gerrit.server.restapi.change.ListPortedDrafts;
      86             : import com.google.gerrit.server.restapi.change.ListRevisionComments;
      87             : import com.google.gerrit.server.restapi.change.ListRevisionDrafts;
      88             : import com.google.gerrit.server.restapi.change.ListRobotComments;
      89             : import com.google.gerrit.server.restapi.change.Mergeable;
      90             : import com.google.gerrit.server.restapi.change.PostReview;
      91             : import com.google.gerrit.server.restapi.change.PreviewFix;
      92             : import com.google.gerrit.server.restapi.change.PutDescription;
      93             : import com.google.gerrit.server.restapi.change.Rebase;
      94             : import com.google.gerrit.server.restapi.change.Reviewed;
      95             : import com.google.gerrit.server.restapi.change.RevisionReviewers;
      96             : import com.google.gerrit.server.restapi.change.RobotComments;
      97             : import com.google.gerrit.server.restapi.change.Submit;
      98             : import com.google.gerrit.server.restapi.change.TestSubmitRule;
      99             : import com.google.gerrit.server.restapi.change.TestSubmitType;
     100             : import com.google.inject.Inject;
     101             : import com.google.inject.Provider;
     102             : import com.google.inject.assistedinject.Assisted;
     103             : import java.util.EnumSet;
     104             : import java.util.List;
     105             : import java.util.Locale;
     106             : import java.util.Map;
     107             : import java.util.Set;
     108             : import org.eclipse.jgit.lib.Repository;
     109             : import org.eclipse.jgit.revwalk.RevWalk;
     110             : 
     111             : class RevisionApiImpl extends RevisionApi.NotImplemented {
     112             :   interface Factory {
     113             :     RevisionApiImpl create(RevisionResource r);
     114             :   }
     115             : 
     116             :   private final GitRepositoryManager repoManager;
     117             :   private final Changes changes;
     118             :   private final RevisionReviewers revisionReviewers;
     119             :   private final RevisionReviewerApiImpl.Factory revisionReviewerApi;
     120             :   private final CherryPick cherryPick;
     121             :   private final Rebase rebase;
     122             :   private final RebaseUtil rebaseUtil;
     123             :   private final Submit submit;
     124             :   private final Reviewed.PutReviewed putReviewed;
     125             :   private final Reviewed.DeleteReviewed deleteReviewed;
     126             :   private final RevisionResource revision;
     127             :   private final Files files;
     128             :   private final Files.ListFiles listFiles;
     129             :   private final GetCommit getCommit;
     130             :   private final GetPatch getPatch;
     131             :   private final PostReview review;
     132             :   private final Mergeable mergeable;
     133             :   private final FileApiImpl.Factory fileApi;
     134             :   private final ListRevisionComments listComments;
     135             :   private final ListRobotComments listRobotComments;
     136             :   private final ListPortedComments listPortedComments;
     137             :   private final ListPortedDrafts listPortedDrafts;
     138             :   private final ApplyStoredFix applyStoredFix;
     139             :   private final PreviewFix.Stored previewStoredFix;
     140             :   private final ApplyProvidedFix applyProvidedFix;
     141             :   private final PreviewFix.Provided previewProvidedFix;
     142             :   private final Fixes fixes;
     143             :   private final ListRevisionDrafts listDrafts;
     144             :   private final CreateDraftComment createDraft;
     145             :   private final DraftComments drafts;
     146             :   private final DraftApiImpl.Factory draftFactory;
     147             :   private final Comments comments;
     148             :   private final CommentApiImpl.Factory commentFactory;
     149             :   private final RobotComments robotComments;
     150             :   private final RobotCommentApiImpl.Factory robotCommentFactory;
     151             :   private final GetRevisionActions revisionActions;
     152             :   private final TestSubmitType testSubmitType;
     153             :   private final TestSubmitType.Get getSubmitType;
     154             :   private final Provider<TestSubmitRule> testSubmitRule;
     155             :   private final Provider<GetMergeList> getMergeList;
     156             :   private final GetRelated getRelated;
     157             :   private final PutDescription putDescription;
     158             :   private final GetDescription getDescription;
     159             :   private final Provider<GetArchive> getArchiveProvider;
     160             :   private final ApprovalsUtil approvalsUtil;
     161             :   private final AccountLoader.Factory accountLoaderFactory;
     162             : 
     163             :   @Inject
     164             :   RevisionApiImpl(
     165             :       GitRepositoryManager repoManager,
     166             :       Changes changes,
     167             :       RevisionReviewers revisionReviewers,
     168             :       RevisionReviewerApiImpl.Factory revisionReviewerApi,
     169             :       CherryPick cherryPick,
     170             :       Rebase rebase,
     171             :       RebaseUtil rebaseUtil,
     172             :       Submit submit,
     173             :       Reviewed.PutReviewed putReviewed,
     174             :       Reviewed.DeleteReviewed deleteReviewed,
     175             :       Files files,
     176             :       Files.ListFiles listFiles,
     177             :       GetCommit getCommit,
     178             :       GetPatch getPatch,
     179             :       PostReview review,
     180             :       Mergeable mergeable,
     181             :       FileApiImpl.Factory fileApi,
     182             :       ListRevisionComments listComments,
     183             :       ListRobotComments listRobotComments,
     184             :       ListPortedComments listPortedComments,
     185             :       ListPortedDrafts listPortedDrafts,
     186             :       ApplyStoredFix applyStoredFix,
     187             :       PreviewFix.Stored previewStoredFix,
     188             :       ApplyProvidedFix applyProvidedFix,
     189             :       PreviewFix.Provided previewProvidedFix,
     190             :       Fixes fixes,
     191             :       ListRevisionDrafts listDrafts,
     192             :       CreateDraftComment createDraft,
     193             :       DraftComments drafts,
     194             :       DraftApiImpl.Factory draftFactory,
     195             :       Comments comments,
     196             :       CommentApiImpl.Factory commentFactory,
     197             :       RobotComments robotComments,
     198             :       RobotCommentApiImpl.Factory robotCommentFactory,
     199             :       GetRevisionActions revisionActions,
     200             :       TestSubmitType testSubmitType,
     201             :       TestSubmitType.Get getSubmitType,
     202             :       Provider<TestSubmitRule> testSubmitRule,
     203             :       Provider<GetMergeList> getMergeList,
     204             :       GetRelated getRelated,
     205             :       PutDescription putDescription,
     206             :       GetDescription getDescription,
     207             :       Provider<GetArchive> getArchiveProvider,
     208             :       ApprovalsUtil approvalsUtil,
     209             :       AccountLoader.Factory accountLoaderFactory,
     210          79 :       @Assisted RevisionResource r) {
     211          79 :     this.repoManager = repoManager;
     212          79 :     this.changes = changes;
     213          79 :     this.revisionReviewers = revisionReviewers;
     214          79 :     this.revisionReviewerApi = revisionReviewerApi;
     215          79 :     this.cherryPick = cherryPick;
     216          79 :     this.rebase = rebase;
     217          79 :     this.rebaseUtil = rebaseUtil;
     218          79 :     this.review = review;
     219          79 :     this.submit = submit;
     220          79 :     this.files = files;
     221          79 :     this.putReviewed = putReviewed;
     222          79 :     this.deleteReviewed = deleteReviewed;
     223          79 :     this.listFiles = listFiles;
     224          79 :     this.getCommit = getCommit;
     225          79 :     this.getPatch = getPatch;
     226          79 :     this.mergeable = mergeable;
     227          79 :     this.fileApi = fileApi;
     228          79 :     this.listComments = listComments;
     229          79 :     this.robotComments = robotComments;
     230          79 :     this.listRobotComments = listRobotComments;
     231          79 :     this.listPortedComments = listPortedComments;
     232          79 :     this.listPortedDrafts = listPortedDrafts;
     233          79 :     this.applyStoredFix = applyStoredFix;
     234          79 :     this.previewStoredFix = previewStoredFix;
     235          79 :     this.applyProvidedFix = applyProvidedFix;
     236          79 :     this.previewProvidedFix = previewProvidedFix;
     237          79 :     this.fixes = fixes;
     238          79 :     this.listDrafts = listDrafts;
     239          79 :     this.createDraft = createDraft;
     240          79 :     this.drafts = drafts;
     241          79 :     this.draftFactory = draftFactory;
     242          79 :     this.comments = comments;
     243          79 :     this.commentFactory = commentFactory;
     244          79 :     this.robotCommentFactory = robotCommentFactory;
     245          79 :     this.revisionActions = revisionActions;
     246          79 :     this.testSubmitType = testSubmitType;
     247          79 :     this.getSubmitType = getSubmitType;
     248          79 :     this.testSubmitRule = testSubmitRule;
     249          79 :     this.getMergeList = getMergeList;
     250          79 :     this.getRelated = getRelated;
     251          79 :     this.putDescription = putDescription;
     252          79 :     this.getDescription = getDescription;
     253          79 :     this.getArchiveProvider = getArchiveProvider;
     254          79 :     this.approvalsUtil = approvalsUtil;
     255          79 :     this.accountLoaderFactory = accountLoaderFactory;
     256          79 :     this.revision = r;
     257          79 :   }
     258             : 
     259             :   @Override
     260             :   public ReviewResult review(ReviewInput in) throws RestApiException {
     261             :     try {
     262          65 :       return review.apply(revision, in).value();
     263           9 :     } catch (Exception e) {
     264           9 :       throw asRestApiException("Cannot post review", e);
     265             :     }
     266             :   }
     267             : 
     268             :   @Override
     269             :   public ChangeInfo submit(SubmitInput in) throws RestApiException {
     270             :     try {
     271          45 :       return submit.apply(revision, in).value();
     272          15 :     } catch (Exception e) {
     273          15 :       throw asRestApiException("Cannot submit change", e);
     274             :     }
     275             :   }
     276             : 
     277             :   @Override
     278             :   public ChangeApi rebase(RebaseInput in) throws RestApiException {
     279             :     try {
     280           9 :       return changes.id(rebaseAsInfo(in)._number);
     281           1 :     } catch (Exception e) {
     282           1 :       throw asRestApiException("Cannot rebase ps", e);
     283             :     }
     284             :   }
     285             : 
     286             :   @Override
     287             :   public ChangeInfo rebaseAsInfo(RebaseInput in) throws RestApiException {
     288             :     try {
     289           9 :       return rebase.apply(revision, in).value();
     290           1 :     } catch (Exception e) {
     291           1 :       throw asRestApiException("Cannot rebase ps", e);
     292             :     }
     293             :   }
     294             : 
     295             :   @Override
     296             :   public boolean canRebase() throws RestApiException {
     297           1 :     try (Repository repo = repoManager.openRepository(revision.getProject());
     298           1 :         RevWalk rw = new RevWalk(repo)) {
     299           1 :       return rebaseUtil.canRebase(revision.getPatchSet(), revision.getChange().getDest(), repo, rw);
     300           0 :     } catch (Exception e) {
     301           0 :       throw asRestApiException("Cannot check if rebase is possible", e);
     302             :     }
     303             :   }
     304             : 
     305             :   @Override
     306             :   public ChangeApi cherryPick(CherryPickInput in) throws RestApiException {
     307             :     try {
     308           6 :       return changes.id(cherryPick.apply(revision, in).value()._number);
     309           2 :     } catch (Exception e) {
     310           2 :       throw asRestApiException("Cannot cherry pick", e);
     311             :     }
     312             :   }
     313             : 
     314             :   @Override
     315             :   public ChangeInfo cherryPickAsInfo(CherryPickInput in) throws RestApiException {
     316             :     try {
     317           1 :       return cherryPick.apply(revision, in).value();
     318           1 :     } catch (Exception e) {
     319           1 :       throw asRestApiException("Cannot cherry pick", e);
     320             :     }
     321             :   }
     322             : 
     323             :   @Override
     324             :   public RevisionReviewerApi reviewer(String id) throws RestApiException {
     325             :     try {
     326           4 :       return revisionReviewerApi.create(
     327           4 :           revisionReviewers.parse(revision, IdString.fromDecoded(id)));
     328           2 :     } catch (Exception e) {
     329           2 :       throw asRestApiException("Cannot parse reviewer", e);
     330             :     }
     331             :   }
     332             : 
     333             :   @Override
     334             :   public void setReviewed(String path, boolean reviewed) throws RestApiException {
     335             :     try {
     336             :       RestModifyView<FileResource, Input> view;
     337           1 :       if (reviewed) {
     338           1 :         view = putReviewed;
     339             :       } else {
     340           1 :         view = deleteReviewed;
     341             :       }
     342           1 :       view.apply(files.parse(revision, IdString.fromDecoded(path)), new Input());
     343           0 :     } catch (Exception e) {
     344           0 :       throw asRestApiException("Cannot update reviewed flag", e);
     345           1 :     }
     346           1 :   }
     347             : 
     348             :   @SuppressWarnings("unchecked")
     349             :   @Override
     350             :   public Set<String> reviewed() throws RestApiException {
     351             :     try {
     352           1 :       return ImmutableSet.copyOf(
     353           1 :           (Iterable<String>) listFiles.setReviewed(true).apply(revision).value());
     354           0 :     } catch (Exception e) {
     355           0 :       throw asRestApiException("Cannot list reviewed files", e);
     356             :     }
     357             :   }
     358             : 
     359             :   @Override
     360             :   public MergeableInfo mergeable() throws RestApiException {
     361             :     try {
     362           1 :       return mergeable.apply(revision).value();
     363           0 :     } catch (Exception e) {
     364           0 :       throw asRestApiException("Cannot check mergeability", e);
     365             :     }
     366             :   }
     367             : 
     368             :   @Override
     369             :   public MergeableInfo mergeableOtherBranches() throws RestApiException {
     370             :     try {
     371           1 :       mergeable.setOtherBranches(true);
     372           1 :       return mergeable.apply(revision).value();
     373           0 :     } catch (Exception e) {
     374           0 :       throw asRestApiException("Cannot check mergeability", e);
     375             :     }
     376             :   }
     377             : 
     378             :   @SuppressWarnings("unchecked")
     379             :   @Override
     380             :   public Map<String, FileInfo> files(@Nullable String base) throws RestApiException {
     381             :     try {
     382           7 :       return (Map<String, FileInfo>) listFiles.setBase(base).apply(revision).value();
     383           1 :     } catch (Exception e) {
     384           1 :       throw asRestApiException("Cannot retrieve files", e);
     385             :     }
     386             :   }
     387             : 
     388             :   @SuppressWarnings("unchecked")
     389             :   @Override
     390             :   public Map<String, FileInfo> files(int parentNum) throws RestApiException {
     391             :     try {
     392           4 :       return (Map<String, FileInfo>) listFiles.setParent(parentNum).apply(revision).value();
     393           1 :     } catch (Exception e) {
     394           1 :       throw asRestApiException("Cannot retrieve files", e);
     395             :     }
     396             :   }
     397             : 
     398             :   @SuppressWarnings("unchecked")
     399             :   @Override
     400             :   public List<String> queryFiles(String query) throws RestApiException {
     401             :     try {
     402           1 :       checkArgument(query != null, "no query provided");
     403           1 :       return (List<String>) listFiles.setQuery(query).apply(revision).value();
     404           0 :     } catch (Exception e) {
     405           0 :       throw asRestApiException("Cannot retrieve files", e);
     406             :     }
     407             :   }
     408             : 
     409             :   @Override
     410             :   public FileApi file(String path) {
     411          14 :     return fileApi.create(files.parse(revision, IdString.fromDecoded(path)));
     412             :   }
     413             : 
     414             :   @Override
     415             :   public CommitInfo commit(boolean addLinks) throws RestApiException {
     416             :     try {
     417          13 :       return getCommit.setAddLinks(addLinks).apply(revision).value();
     418           0 :     } catch (Exception e) {
     419           0 :       throw asRestApiException("Cannot retrieve commit", e);
     420             :     }
     421             :   }
     422             : 
     423             :   @Override
     424             :   public Map<String, List<CommentInfo>> comments() throws RestApiException {
     425             :     try {
     426           7 :       return listComments.apply(revision).value();
     427           0 :     } catch (Exception e) {
     428           0 :       throw asRestApiException("Cannot retrieve comments", e);
     429             :     }
     430             :   }
     431             : 
     432             :   @Override
     433             :   public Map<String, List<RobotCommentInfo>> robotComments() throws RestApiException {
     434             :     try {
     435           2 :       return listRobotComments.apply(revision).value();
     436           0 :     } catch (Exception e) {
     437           0 :       throw asRestApiException("Cannot retrieve robot comments", e);
     438             :     }
     439             :   }
     440             : 
     441             :   @Override
     442             :   public List<CommentInfo> commentsAsList() throws RestApiException {
     443             :     try {
     444           6 :       return listComments.getComments(revision);
     445           0 :     } catch (Exception e) {
     446           0 :       throw asRestApiException("Cannot retrieve comments", e);
     447             :     }
     448             :   }
     449             : 
     450             :   @Override
     451             :   public Map<String, List<CommentInfo>> drafts() throws RestApiException {
     452             :     try {
     453           2 :       return listDrafts.apply(revision).value();
     454           0 :     } catch (Exception e) {
     455           0 :       throw asRestApiException("Cannot retrieve drafts", e);
     456             :     }
     457             :   }
     458             : 
     459             :   @Override
     460             :   public List<RobotCommentInfo> robotCommentsAsList() throws RestApiException {
     461             :     try {
     462           4 :       return listRobotComments.getComments(revision);
     463           0 :     } catch (Exception e) {
     464           0 :       throw asRestApiException("Cannot retrieve robot comments", e);
     465             :     }
     466             :   }
     467             : 
     468             :   @Override
     469             :   public Map<String, List<CommentInfo>> portedComments() throws RestApiException {
     470             :     try {
     471           1 :       return listPortedComments.apply(revision).value();
     472           0 :     } catch (Exception e) {
     473           0 :       throw asRestApiException("Cannot retrieve ported comments", e);
     474             :     }
     475             :   }
     476             : 
     477             :   @Override
     478             :   public Map<String, List<CommentInfo>> portedDrafts() throws RestApiException {
     479             :     try {
     480           1 :       return listPortedDrafts.apply(revision).value();
     481           1 :     } catch (Exception e) {
     482           1 :       throw asRestApiException("Cannot retrieve ported draft comments", e);
     483             :     }
     484             :   }
     485             : 
     486             :   @Override
     487             :   public EditInfo applyFix(String fixId) throws RestApiException {
     488             :     try {
     489           1 :       return applyStoredFix.apply(fixes.parse(revision, IdString.fromDecoded(fixId)), null).value();
     490           1 :     } catch (Exception e) {
     491           1 :       throw asRestApiException("Cannot apply stored fix", e);
     492             :     }
     493             :   }
     494             : 
     495             :   @Override
     496             :   public EditInfo applyFix(ApplyProvidedFixInput applyProvidedFixInput) throws RestApiException {
     497             :     try {
     498           1 :       return applyProvidedFix.apply(revision, applyProvidedFixInput).value();
     499           1 :     } catch (Exception e) {
     500           1 :       throw asRestApiException("Cannot apply fix", e);
     501             :     }
     502             :   }
     503             : 
     504             :   @Override
     505             :   public Map<String, DiffInfo> getFixPreview(String fixId) throws RestApiException {
     506             :     try {
     507           1 :       return previewStoredFix.apply(fixes.parse(revision, IdString.fromDecoded(fixId))).value();
     508           1 :     } catch (Exception e) {
     509           1 :       throw asRestApiException("Cannot preview stored fix", e);
     510             :     }
     511             :   }
     512             : 
     513             :   @Override
     514             :   public Map<String, DiffInfo> getFixPreview(ApplyProvidedFixInput applyProvidedFixInput)
     515             :       throws RestApiException {
     516             :     try {
     517           1 :       return previewProvidedFix.apply(revision, applyProvidedFixInput).value();
     518           1 :     } catch (Exception e) {
     519           1 :       throw asRestApiException("Cannot preview provided fix", e);
     520             :     }
     521             :   }
     522             : 
     523             :   @Override
     524             :   public List<CommentInfo> draftsAsList() throws RestApiException {
     525             :     try {
     526           2 :       return listDrafts.getComments(revision);
     527           0 :     } catch (Exception e) {
     528           0 :       throw asRestApiException("Cannot retrieve drafts", e);
     529             :     }
     530             :   }
     531             : 
     532             :   @Override
     533             :   public DraftApi draft(String id) throws RestApiException {
     534             :     try {
     535          18 :       return draftFactory.create(drafts.parse(revision, IdString.fromDecoded(id)));
     536           0 :     } catch (Exception e) {
     537           0 :       throw asRestApiException("Cannot retrieve draft", e);
     538             :     }
     539             :   }
     540             : 
     541             :   @Override
     542             :   public DraftApi createDraft(DraftInput in) throws RestApiException {
     543             :     try {
     544          18 :       String id = createDraft.apply(revision, in).value().id;
     545             :       // Reread change to pick up new notes refs.
     546          18 :       return changes
     547          18 :           .id(revision.getChange().getId().get())
     548          18 :           .revision(revision.getPatchSet().id().get())
     549          18 :           .draft(id);
     550           1 :     } catch (Exception e) {
     551           1 :       throw asRestApiException("Cannot create draft", e);
     552             :     }
     553             :   }
     554             : 
     555             :   @Override
     556             :   public CommentApi comment(String id) throws RestApiException {
     557             :     try {
     558           3 :       return commentFactory.create(comments.parse(revision, IdString.fromDecoded(id)));
     559           1 :     } catch (Exception e) {
     560           1 :       throw asRestApiException("Cannot retrieve comment", e);
     561             :     }
     562             :   }
     563             : 
     564             :   @Override
     565             :   public RobotCommentApi robotComment(String id) throws RestApiException {
     566             :     try {
     567           1 :       return robotCommentFactory.create(robotComments.parse(revision, IdString.fromDecoded(id)));
     568           0 :     } catch (Exception e) {
     569           0 :       throw asRestApiException("Cannot retrieve robot comment", e);
     570             :     }
     571             :   }
     572             : 
     573             :   @Override
     574             :   public BinaryResult patch() throws RestApiException {
     575             :     try {
     576           3 :       return getPatch.apply(revision).value();
     577           0 :     } catch (Exception e) {
     578           0 :       throw asRestApiException("Cannot get patch", e);
     579             :     }
     580             :   }
     581             : 
     582             :   @Override
     583             :   public BinaryResult patch(String path) throws RestApiException {
     584             :     try {
     585           1 :       return getPatch.setPath(path).apply(revision).value();
     586           1 :     } catch (Exception e) {
     587           1 :       throw asRestApiException("Cannot get patch", e);
     588             :     }
     589             :   }
     590             : 
     591             :   @Override
     592             :   public Map<String, ActionInfo> actions() throws RestApiException {
     593             :     try {
     594           4 :       return revisionActions.apply(revision).value();
     595           0 :     } catch (Exception e) {
     596           0 :       throw asRestApiException("Cannot get actions", e);
     597             :     }
     598             :   }
     599             : 
     600             :   @Override
     601             :   public SubmitType submitType() throws RestApiException {
     602             :     try {
     603           1 :       return getSubmitType.apply(revision).value();
     604           0 :     } catch (Exception e) {
     605           0 :       throw asRestApiException("Cannot get submit type", e);
     606             :     }
     607             :   }
     608             : 
     609             :   @Override
     610             :   public SubmitType testSubmitType(TestSubmitRuleInput in) throws RestApiException {
     611             :     try {
     612           1 :       return testSubmitType.apply(revision, in).value();
     613           0 :     } catch (Exception e) {
     614           0 :       throw asRestApiException("Cannot test submit type", e);
     615             :     }
     616             :   }
     617             : 
     618             :   @Override
     619             :   public TestSubmitRuleInfo testSubmitRule(TestSubmitRuleInput in) throws RestApiException {
     620             :     try {
     621           1 :       return testSubmitRule.get().apply(revision, in).value();
     622           0 :     } catch (Exception e) {
     623           0 :       throw asRestApiException("Cannot test submit rule", e);
     624             :     }
     625             :   }
     626             : 
     627             :   @Override
     628             :   public MergeListRequest getMergeList() throws RestApiException {
     629           1 :     return new MergeListRequest() {
     630             :       @Override
     631             :       public List<CommitInfo> get() throws RestApiException {
     632             :         try {
     633           1 :           GetMergeList gml = getMergeList.get();
     634           1 :           gml.setUninterestingParent(getUninterestingParent());
     635           1 :           gml.setAddLinks(getAddLinks());
     636           1 :           return gml.apply(revision).value();
     637           0 :         } catch (Exception e) {
     638           0 :           throw asRestApiException("Cannot get merge list", e);
     639             :         }
     640             :       }
     641             :     };
     642             :   }
     643             : 
     644             :   @Override
     645             :   public RelatedChangesInfo related() throws RestApiException {
     646           5 :     return related(EnumSet.noneOf(GetRelatedOption.class));
     647             :   }
     648             : 
     649             :   @Override
     650             :   public RelatedChangesInfo related(EnumSet<GetRelatedOption> options) throws RestApiException {
     651             :     try {
     652           5 :       options.forEach(getRelated::addOption);
     653           5 :       return getRelated.apply(revision).value();
     654           0 :     } catch (Exception e) {
     655           0 :       throw asRestApiException("Cannot get related changes", e);
     656             :     }
     657             :   }
     658             : 
     659             :   @Override
     660             :   public ListMultimap<String, ApprovalInfo> votes() throws RestApiException {
     661             :     ListMultimap<String, ApprovalInfo> result =
     662           2 :         ListMultimapBuilder.treeKeys().arrayListValues().build();
     663             :     try {
     664           2 :       Iterable<PatchSetApproval> approvals =
     665           2 :           approvalsUtil.byPatchSet(revision.getNotes(), revision.getPatchSet().id());
     666           2 :       AccountLoader accountLoader =
     667           2 :           accountLoaderFactory.create(
     668           2 :               EnumSet.of(
     669             :                   FillOptions.ID, FillOptions.NAME, FillOptions.EMAIL, FillOptions.USERNAME));
     670           2 :       for (PatchSetApproval approval : approvals) {
     671           2 :         String label = approval.label();
     672           2 :         ApprovalInfo info =
     673             :             new ApprovalInfo(
     674           2 :                 approval.accountId().get(),
     675           2 :                 Integer.valueOf(approval.value()),
     676             :                 null,
     677           2 :                 approval.tag().orElse(null),
     678           2 :                 approval.granted());
     679           2 :         accountLoader.put(info);
     680           2 :         result.get(label).add(info);
     681           2 :       }
     682           2 :       accountLoader.fill();
     683           0 :     } catch (Exception e) {
     684           0 :       throw asRestApiException("Cannot get votes", e);
     685           2 :     }
     686           2 :     return result;
     687             :   }
     688             : 
     689             :   @Override
     690             :   public void description(String description) throws RestApiException {
     691           1 :     DescriptionInput in = new DescriptionInput();
     692           1 :     in.description = description;
     693             :     try {
     694           1 :       putDescription.apply(revision, in);
     695           1 :     } catch (Exception e) {
     696           1 :       throw asRestApiException("Cannot set description", e);
     697           1 :     }
     698           1 :   }
     699             : 
     700             :   @Override
     701             :   public String description() throws RestApiException {
     702             :     try {
     703           2 :       return getDescription.apply(revision).value();
     704           0 :     } catch (Exception e) {
     705           0 :       throw asRestApiException("Cannot get description", e);
     706             :     }
     707             :   }
     708             : 
     709             :   @Override
     710             :   public BinaryResult getArchive(ArchiveFormat format) throws RestApiException {
     711           1 :     GetArchive getArchive = getArchiveProvider.get();
     712           1 :     getArchive.setFormat(format != null ? format.name().toLowerCase(Locale.US) : null);
     713             :     try {
     714           1 :       return getArchive.apply(revision).value();
     715           1 :     } catch (Exception e) {
     716           1 :       throw asRestApiException("Cannot get archive", e);
     717             :     }
     718             :   }
     719             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750