|  |  | @@ -18,13 +18,13 @@ import com.google.common.collect.ImmutableList; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.common.collect.ImmutableMap; |  |  |  | import com.google.common.collect.ImmutableMap; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.common.collect.Lists; |  |  |  | import com.google.common.collect.Lists; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.common.collect.Maps; |  |  |  | import com.google.common.collect.Maps; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.common.util.concurrent.CheckedFuture; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.common.ChangeHooks; |  |  |  | import com.google.gerrit.common.ChangeHooks; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import com.google.gerrit.common.TimeUtil; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.common.data.GroupDescription; |  |  |  | import com.google.gerrit.common.data.GroupDescription; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.common.errors.NoSuchGroupException; |  |  |  | import com.google.gerrit.common.errors.NoSuchGroupException; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.extensions.api.changes.AddReviewerInput; |  |  |  | import com.google.gerrit.extensions.api.changes.AddReviewerInput; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.extensions.restapi.AuthException; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.extensions.restapi.BadRequestException; |  |  |  | import com.google.gerrit.extensions.restapi.BadRequestException; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import com.google.gerrit.extensions.restapi.RestApiException; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.extensions.restapi.RestModifyView; |  |  |  | import com.google.gerrit.extensions.restapi.RestModifyView; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.extensions.restapi.UnprocessableEntityException; |  |  |  | import com.google.gerrit.extensions.restapi.UnprocessableEntityException; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.reviewdb.client.Account; |  |  |  | import com.google.gerrit.reviewdb.client.Account; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -34,7 +34,6 @@ import com.google.gerrit.reviewdb.client.PatchSet; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.reviewdb.client.PatchSetApproval; |  |  |  | import com.google.gerrit.reviewdb.client.PatchSetApproval; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.reviewdb.server.ReviewDb; |  |  |  | import com.google.gerrit.reviewdb.server.ReviewDb; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.ApprovalsUtil; |  |  |  | import com.google.gerrit.server.ApprovalsUtil; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.ChangeUtil; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.IdentifiedUser; |  |  |  | import com.google.gerrit.server.IdentifiedUser; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.PatchSetUtil; |  |  |  | import com.google.gerrit.server.PatchSetUtil; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.account.AccountCache; |  |  |  | import com.google.gerrit.server.account.AccountCache; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -44,11 +43,11 @@ import com.google.gerrit.server.account.GroupMembers; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.change.ReviewerJson.PostResult; |  |  |  | import com.google.gerrit.server.change.ReviewerJson.PostResult; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.change.ReviewerJson.ReviewerInfo; |  |  |  | import com.google.gerrit.server.change.ReviewerJson.ReviewerInfo; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.config.GerritServerConfig; |  |  |  | import com.google.gerrit.server.config.GerritServerConfig; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import com.google.gerrit.server.git.BatchUpdate; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import com.google.gerrit.server.git.UpdateException; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.group.GroupsCollection; |  |  |  | import com.google.gerrit.server.group.GroupsCollection; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.group.SystemGroupBackend; |  |  |  | import com.google.gerrit.server.group.SystemGroupBackend; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.index.ChangeIndexer; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.mail.AddReviewerSender; |  |  |  | import com.google.gerrit.server.mail.AddReviewerSender; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.notedb.ChangeUpdate; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.project.ChangeControl; |  |  |  | import com.google.gerrit.server.project.ChangeControl; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gerrit.server.project.NoSuchProjectException; |  |  |  | import com.google.gerrit.server.project.NoSuchProjectException; | 
			
		
	
		
		
			
				
					
					|  |  |  | import com.google.gwtorm.server.OrmException; |  |  |  | import com.google.gwtorm.server.OrmException; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -83,14 +82,13 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final GroupMembers.Factory groupMembersFactory; |  |  |  |   private final GroupMembers.Factory groupMembersFactory; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final AccountLoader.Factory accountLoaderFactory; |  |  |  |   private final AccountLoader.Factory accountLoaderFactory; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final Provider<ReviewDb> dbProvider; |  |  |  |   private final Provider<ReviewDb> dbProvider; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final ChangeUpdate.Factory updateFactory; |  |  |  |   private final BatchUpdate.Factory batchUpdateFactory; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   private final Provider<IdentifiedUser> user; |  |  |  |   private final Provider<IdentifiedUser> user; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final IdentifiedUser.GenericFactory identifiedUserFactory; |  |  |  |   private final IdentifiedUser.GenericFactory identifiedUserFactory; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final Config cfg; |  |  |  |   private final Config cfg; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final ChangeHooks hooks; |  |  |  |   private final ChangeHooks hooks; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final AccountCache accountCache; |  |  |  |   private final AccountCache accountCache; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final ReviewerJson json; |  |  |  |   private final ReviewerJson json; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final ChangeIndexer indexer; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   @Inject |  |  |  |   @Inject | 
			
		
	
		
		
			
				
					
					|  |  |  |   PostReviewers(AccountsCollection accounts, |  |  |  |   PostReviewers(AccountsCollection accounts, | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -102,14 +100,13 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer | 
			
		
	
		
		
			
				
					
					|  |  |  |       GroupMembers.Factory groupMembersFactory, |  |  |  |       GroupMembers.Factory groupMembersFactory, | 
			
		
	
		
		
			
				
					
					|  |  |  |       AccountLoader.Factory accountLoaderFactory, |  |  |  |       AccountLoader.Factory accountLoaderFactory, | 
			
		
	
		
		
			
				
					
					|  |  |  |       Provider<ReviewDb> db, |  |  |  |       Provider<ReviewDb> db, | 
			
		
	
		
		
			
				
					
					|  |  |  |       ChangeUpdate.Factory updateFactory, |  |  |  |       BatchUpdate.Factory batchUpdateFactory, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       Provider<IdentifiedUser> user, |  |  |  |       Provider<IdentifiedUser> user, | 
			
		
	
		
		
			
				
					
					|  |  |  |       IdentifiedUser.GenericFactory identifiedUserFactory, |  |  |  |       IdentifiedUser.GenericFactory identifiedUserFactory, | 
			
		
	
		
		
			
				
					
					|  |  |  |       @GerritServerConfig Config cfg, |  |  |  |       @GerritServerConfig Config cfg, | 
			
		
	
		
		
			
				
					
					|  |  |  |       ChangeHooks hooks, |  |  |  |       ChangeHooks hooks, | 
			
		
	
		
		
			
				
					
					|  |  |  |       AccountCache accountCache, |  |  |  |       AccountCache accountCache, | 
			
		
	
		
		
			
				
					
					|  |  |  |       ReviewerJson json, |  |  |  |       ReviewerJson json) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       ChangeIndexer indexer) { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     this.accounts = accounts; |  |  |  |     this.accounts = accounts; | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.reviewerFactory = reviewerFactory; |  |  |  |     this.reviewerFactory = reviewerFactory; | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.approvalsUtil = approvalsUtil; |  |  |  |     this.approvalsUtil = approvalsUtil; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -119,20 +116,18 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.groupMembersFactory = groupMembersFactory; |  |  |  |     this.groupMembersFactory = groupMembersFactory; | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.accountLoaderFactory = accountLoaderFactory; |  |  |  |     this.accountLoaderFactory = accountLoaderFactory; | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.dbProvider = db; |  |  |  |     this.dbProvider = db; | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.updateFactory = updateFactory; |  |  |  |     this.batchUpdateFactory = batchUpdateFactory; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     this.user = user; |  |  |  |     this.user = user; | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.identifiedUserFactory = identifiedUserFactory; |  |  |  |     this.identifiedUserFactory = identifiedUserFactory; | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.cfg = cfg; |  |  |  |     this.cfg = cfg; | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.hooks = hooks; |  |  |  |     this.hooks = hooks; | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.accountCache = accountCache; |  |  |  |     this.accountCache = accountCache; | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.json = json; |  |  |  |     this.json = json; | 
			
		
	
		
		
			
				
					
					|  |  |  |     this.indexer = indexer; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   @Override |  |  |  |   @Override | 
			
		
	
		
		
			
				
					
					|  |  |  |   public PostResult apply(ChangeResource rsrc, AddReviewerInput input) |  |  |  |   public PostResult apply(ChangeResource rsrc, AddReviewerInput input) | 
			
		
	
		
		
			
				
					
					|  |  |  |       throws AuthException, BadRequestException, UnprocessableEntityException, |  |  |  |       throws UpdateException, OrmException, RestApiException, IOException { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       OrmException, IOException { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     if (input.reviewer == null) { |  |  |  |     if (input.reviewer == null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       throw new BadRequestException("missing reviewer field"); |  |  |  |       throw new BadRequestException("missing reviewer field"); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -151,8 +146,8 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   private PostResult putAccount(ReviewerResource rsrc) throws OrmException, |  |  |  |   private PostResult putAccount(ReviewerResource rsrc) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       IOException { |  |  |  |       throws OrmException, UpdateException, RestApiException { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     Account member = rsrc.getReviewerUser().getAccount(); |  |  |  |     Account member = rsrc.getReviewerUser().getAccount(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     ChangeControl control = rsrc.getReviewerControl(); |  |  |  |     ChangeControl control = rsrc.getReviewerControl(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     PostResult result = new PostResult(); |  |  |  |     PostResult result = new PostResult(); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -164,8 +159,7 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   private PostResult putGroup(ChangeResource rsrc, AddReviewerInput input) |  |  |  |   private PostResult putGroup(ChangeResource rsrc, AddReviewerInput input) | 
			
		
	
		
		
			
				
					
					|  |  |  |       throws BadRequestException, |  |  |  |       throws UpdateException, RestApiException, OrmException, IOException { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       UnprocessableEntityException, OrmException, IOException { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     GroupDescription.Basic group = groupsCollection.parseInternal(input.reviewer); |  |  |  |     GroupDescription.Basic group = groupsCollection.parseInternal(input.reviewer); | 
			
		
	
		
		
			
				
					
					|  |  |  |     PostResult result = new PostResult(); |  |  |  |     PostResult result = new PostResult(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (!isLegalReviewerGroup(group.getGroupUUID())) { |  |  |  |     if (!isLegalReviewerGroup(group.getGroupUUID())) { | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -179,7 +173,7 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer | 
			
		
	
		
		
			
				
					
					|  |  |  |     Set<Account> members; |  |  |  |     Set<Account> members; | 
			
		
	
		
		
			
				
					
					|  |  |  |     try { |  |  |  |     try { | 
			
		
	
		
		
			
				
					
					|  |  |  |       members = groupMembersFactory.create(control.getUser()).listAccounts( |  |  |  |       members = groupMembersFactory.create(control.getUser()).listAccounts( | 
			
		
	
		
		
			
				
					
					|  |  |  |               group.getGroupUUID(), control.getProject().getNameKey()); |  |  |  |           group.getGroupUUID(), control.getProject().getNameKey()); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } catch (NoSuchGroupException e) { |  |  |  |     } catch (NoSuchGroupException e) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       throw new UnprocessableEntityException(e.getMessage()); |  |  |  |       throw new UnprocessableEntityException(e.getMessage()); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } catch (NoSuchProjectException e) { |  |  |  |     } catch (NoSuchProjectException e) { | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -229,42 +223,72 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer | 
			
		
	
		
		
			
				
					
					|  |  |  |     return false; |  |  |  |     return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   private void addReviewers(ChangeResource rsrc, PostResult result, |  |  |  |  | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       Map<Account.Id, ChangeControl> reviewers) |  |  |  |   private void addReviewers( | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       throws OrmException, IOException { |  |  |  |       ChangeResource rsrc, PostResult result, Map<Account.Id, ChangeControl> reviewers) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     ReviewDb db = dbProvider.get(); |  |  |  |       throws OrmException, RestApiException, UpdateException { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     ChangeUpdate update = updateFactory.create(rsrc.getControl()); |  |  |  |     try (BatchUpdate bu = batchUpdateFactory.create( | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     List<PatchSetApproval> added; |  |  |  |             dbProvider.get(), rsrc.getProject(), rsrc.getUser(), TimeUtil.nowTs())) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     db.changes().beginTransaction(rsrc.getId()); |  |  |  |       Op op = new Op(rsrc, reviewers); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     try { |  |  |  |       Change.Id id = rsrc.getChange().getId(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       ChangeUtil.bumpRowVersionNotLastUpdatedOn(rsrc.getId(), db); |  |  |  |       bu.addOp(id, op); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       added = approvalsUtil.addReviewers(db, rsrc.getNotes(), update, |  |  |  |       bu.execute(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |           rsrc.getControl().getLabelTypes(), rsrc.getChange(), |  |  |  |  | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |           reviewers.keySet()); |  |  |  |       result.reviewers = Lists.newArrayListWithCapacity(op.added.size()); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       db.commit(); |  |  |  |       for (PatchSetApproval psa : op.added) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     } finally { |  |  |  |         // New reviewers have value 0, don't bother normalizing. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       db.rollback(); |  |  |  |         result.reviewers.add( | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           json.format(new ReviewerInfo( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               psa.getAccountId()), reviewers.get(psa.getAccountId()), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               ImmutableList.of(psa))); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       // We don't do this inside Op, since the accounts are in a different | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       // table. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       accountLoaderFactory.create(true).fill(result.reviewers); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   private class Op extends BatchUpdate.Op { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     private final ChangeResource rsrc; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     private final Map<Account.Id, ChangeControl> reviewers; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     private List<PatchSetApproval> added; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     private PatchSet patchSet; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Op(ChangeResource rsrc, Map<Account.Id, ChangeControl> reviewers) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       this.rsrc = rsrc; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       this.reviewers = reviewers; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     update.commit(); |  |  |  |     @Override | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     CheckedFuture<?, IOException> indexFuture = |  |  |  |     public boolean updateChange(BatchUpdate.ChangeContext ctx) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         indexer.indexAsync(rsrc.getProject(), rsrc.getId()); |  |  |  |         throws RestApiException, OrmException, IOException { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     result.reviewers = Lists.newArrayListWithCapacity(added.size()); |  |  |  |       added = | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     for (PatchSetApproval psa : added) { |  |  |  |           approvalsUtil.addReviewers( | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       // New reviewers have value 0, don't bother normalizing. |  |  |  |               ctx.getDb(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       result.reviewers.add(json.format( |  |  |  |               ctx.getNotes(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |           new ReviewerInfo(psa.getAccountId()), |  |  |  |               ctx.getUpdate(ctx.getChange().currentPatchSetId()), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |           reviewers.get(psa.getAccountId()), |  |  |  |               rsrc.getControl().getLabelTypes(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |           ImmutableList.of(psa))); |  |  |  |               rsrc.getChange(), | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |               reviewers.keySet()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       if (!added.isEmpty()) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         patchSet = psUtil.current(dbProvider.get(), rsrc.getNotes()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       return !added.isEmpty(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     accountLoaderFactory.create(true).fill(result.reviewers); |  |  |  |  | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     indexFuture.checkedGet(); |  |  |  |     @Override | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     emailReviewers(rsrc.getChange(), added); |  |  |  |     public void postUpdate(BatchUpdate.Context ctx) throws Exception { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     if (!added.isEmpty()) { |  |  |  |       emailReviewers(rsrc.getChange(), added); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       PatchSet patchSet = psUtil.current(dbProvider.get(), rsrc.getNotes()); |  |  |  |  | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       for (PatchSetApproval psa : added) { |  |  |  |       if (!added.isEmpty()) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         Account account = accountCache.get(psa.getAccountId()).getAccount(); |  |  |  |         for (PatchSetApproval psa : added) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         hooks.doReviewerAddedHook(rsrc.getChange(), account, patchSet, dbProvider.get()); |  |  |  |           Account account = accountCache.get(psa.getAccountId()).getAccount(); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           hooks.doReviewerAddedHook( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                   rsrc.getChange(), account, patchSet, dbProvider.get()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
	
		
		
			
				
					
					|  |  |   |