Changes API: Add methods to suggest reviewers
Change-Id: I8bdc52eeaa8336558fff2e3a0682f861bc9008b8
This commit is contained in:
		
				
					committed by
					
						
						David Pursehouse
					
				
			
			
				
	
			
			
			
						parent
						
							b32ae744de
						
					
				
				
					commit
					64a436d152
				
			@@ -26,10 +26,10 @@ import com.google.gerrit.common.data.AccessSection;
 | 
			
		||||
import com.google.gerrit.common.data.GlobalCapability;
 | 
			
		||||
import com.google.gerrit.common.data.Permission;
 | 
			
		||||
import com.google.gerrit.common.data.PermissionRule;
 | 
			
		||||
import com.google.gerrit.extensions.common.SuggestedReviewerInfo;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroup;
 | 
			
		||||
import com.google.gerrit.server.account.CreateGroupArgs;
 | 
			
		||||
import com.google.gerrit.server.account.PerformCreateGroup;
 | 
			
		||||
import com.google.gerrit.server.change.SuggestReviewers.SuggestedReviewerInfo;
 | 
			
		||||
import com.google.gerrit.server.git.MetaDataUpdate;
 | 
			
		||||
import com.google.gerrit.server.git.ProjectConfig;
 | 
			
		||||
import com.google.gson.reflect.TypeToken;
 | 
			
		||||
 
 | 
			
		||||
@@ -16,10 +16,12 @@ package com.google.gerrit.extensions.api.changes;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.extensions.common.ChangeInfo;
 | 
			
		||||
import com.google.gerrit.extensions.common.ListChangesOption;
 | 
			
		||||
import com.google.gerrit.extensions.common.SuggestedReviewerInfo;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.NotImplementedException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.RestApiException;
 | 
			
		||||
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public interface ChangeApi {
 | 
			
		||||
@@ -79,6 +81,9 @@ public interface ChangeApi {
 | 
			
		||||
  void addReviewer(AddReviewerInput in) throws RestApiException;
 | 
			
		||||
  void addReviewer(String in) throws RestApiException;
 | 
			
		||||
 | 
			
		||||
  SuggestedReviewersRequest suggestReviewers() throws RestApiException;
 | 
			
		||||
  SuggestedReviewersRequest suggestReviewers(String query) throws RestApiException;
 | 
			
		||||
 | 
			
		||||
  ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException;
 | 
			
		||||
 | 
			
		||||
  /** {@code get} with {@link ListChangesOption} set to all except CHECK. */
 | 
			
		||||
@@ -101,6 +106,31 @@ public interface ChangeApi {
 | 
			
		||||
  ChangeInfo check() throws RestApiException;
 | 
			
		||||
  ChangeInfo check(FixInput fix) throws RestApiException;
 | 
			
		||||
 | 
			
		||||
  public abstract class SuggestedReviewersRequest {
 | 
			
		||||
    private String query;
 | 
			
		||||
    private int limit;
 | 
			
		||||
 | 
			
		||||
    public abstract List<SuggestedReviewerInfo> get() throws RestApiException;
 | 
			
		||||
 | 
			
		||||
    public SuggestedReviewersRequest withQuery(String query) {
 | 
			
		||||
      this.query = query;
 | 
			
		||||
      return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SuggestedReviewersRequest withLimit(int limit) {
 | 
			
		||||
      this.limit = limit;
 | 
			
		||||
      return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getQuery() {
 | 
			
		||||
      return query;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getLimit() {
 | 
			
		||||
      return limit;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * A default implementation which allows source compatibility
 | 
			
		||||
   * when adding new methods to the interface.
 | 
			
		||||
@@ -176,6 +206,16 @@ public interface ChangeApi {
 | 
			
		||||
      throw new NotImplementedException();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public SuggestedReviewersRequest suggestReviewers() throws RestApiException {
 | 
			
		||||
      throw new NotImplementedException();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public SuggestedReviewersRequest suggestReviewers(String query) throws RestApiException {
 | 
			
		||||
      throw new NotImplementedException();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException {
 | 
			
		||||
      throw new NotImplementedException();
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,20 @@
 | 
			
		||||
// Copyright (C) 2014 The Android Open Source Project
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package com.google.gerrit.extensions.common;
 | 
			
		||||
 | 
			
		||||
public class GroupBaseInfo {
 | 
			
		||||
  public String id;
 | 
			
		||||
  public String name;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,20 @@
 | 
			
		||||
// Copyright (C) 2014 The Android Open Source Project
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package com.google.gerrit.extensions.common;
 | 
			
		||||
 | 
			
		||||
public class SuggestedReviewerInfo {
 | 
			
		||||
  public AccountInfo account;
 | 
			
		||||
  public GroupBaseInfo group;
 | 
			
		||||
}
 | 
			
		||||
@@ -26,6 +26,7 @@ import com.google.gerrit.extensions.api.changes.RevertInput;
 | 
			
		||||
import com.google.gerrit.extensions.api.changes.RevisionApi;
 | 
			
		||||
import com.google.gerrit.extensions.common.ChangeInfo;
 | 
			
		||||
import com.google.gerrit.extensions.common.ListChangesOption;
 | 
			
		||||
import com.google.gerrit.extensions.common.SuggestedReviewerInfo;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.IdString;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.RestApiException;
 | 
			
		||||
import com.google.gerrit.server.change.Abandon;
 | 
			
		||||
@@ -40,6 +41,7 @@ import com.google.gerrit.server.change.PutTopic;
 | 
			
		||||
import com.google.gerrit.server.change.Restore;
 | 
			
		||||
import com.google.gerrit.server.change.Revert;
 | 
			
		||||
import com.google.gerrit.server.change.Revisions;
 | 
			
		||||
import com.google.gerrit.server.change.SuggestReviewers;
 | 
			
		||||
import com.google.gwtorm.server.OrmException;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
@@ -47,6 +49,7 @@ import com.google.inject.assistedinject.Assisted;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
 | 
			
		||||
@@ -57,6 +60,7 @@ class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
 | 
			
		||||
  private final Changes changeApi;
 | 
			
		||||
  private final Revisions revisions;
 | 
			
		||||
  private final RevisionApiImpl.Factory revisionApi;
 | 
			
		||||
  private final Provider<SuggestReviewers> suggestReviewers;
 | 
			
		||||
  private final ChangeResource change;
 | 
			
		||||
  private final Abandon abandon;
 | 
			
		||||
  private final Revert revert;
 | 
			
		||||
@@ -73,6 +77,7 @@ class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
 | 
			
		||||
  ChangeApiImpl(Changes changeApi,
 | 
			
		||||
      Revisions revisions,
 | 
			
		||||
      RevisionApiImpl.Factory revisionApi,
 | 
			
		||||
      Provider<SuggestReviewers> suggestReviewers,
 | 
			
		||||
      Abandon abandon,
 | 
			
		||||
      Revert revert,
 | 
			
		||||
      Restore restore,
 | 
			
		||||
@@ -88,6 +93,7 @@ class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
 | 
			
		||||
    this.revert = revert;
 | 
			
		||||
    this.revisions = revisions;
 | 
			
		||||
    this.revisionApi = revisionApi;
 | 
			
		||||
    this.suggestReviewers = suggestReviewers;
 | 
			
		||||
    this.abandon = abandon;
 | 
			
		||||
    this.restore = restore;
 | 
			
		||||
    this.getTopic = getTopic;
 | 
			
		||||
@@ -199,6 +205,34 @@ class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public SuggestedReviewersRequest suggestReviewers() throws RestApiException {
 | 
			
		||||
    return new SuggestedReviewersRequest() {
 | 
			
		||||
      @Override
 | 
			
		||||
      public List<SuggestedReviewerInfo> get() throws RestApiException {
 | 
			
		||||
        return ChangeApiImpl.this.suggestReviewers(this);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public SuggestedReviewersRequest suggestReviewers(String query)
 | 
			
		||||
      throws RestApiException {
 | 
			
		||||
    return suggestReviewers().withQuery(query);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private List<SuggestedReviewerInfo> suggestReviewers(SuggestedReviewersRequest r)
 | 
			
		||||
      throws RestApiException {
 | 
			
		||||
    try {
 | 
			
		||||
      SuggestReviewers mySuggestReviewers = suggestReviewers.get();
 | 
			
		||||
      mySuggestReviewers.setQuery(r.getQuery());
 | 
			
		||||
      mySuggestReviewers.setLimit(r.getLimit());
 | 
			
		||||
      return mySuggestReviewers.apply(change);
 | 
			
		||||
    } catch (OrmException | IOException e) {
 | 
			
		||||
      throw new RestApiException("Cannot retrieve suggested reviewers", e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public ChangeInfo get(EnumSet<ListChangesOption> s)
 | 
			
		||||
      throws RestApiException {
 | 
			
		||||
 
 | 
			
		||||
@@ -14,12 +14,17 @@
 | 
			
		||||
 | 
			
		||||
package com.google.gerrit.server.change;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Function;
 | 
			
		||||
import com.google.common.base.MoreObjects;
 | 
			
		||||
import com.google.common.base.Strings;
 | 
			
		||||
import com.google.common.collect.Iterables;
 | 
			
		||||
import com.google.common.collect.Lists;
 | 
			
		||||
import com.google.common.collect.Ordering;
 | 
			
		||||
import com.google.gerrit.common.Nullable;
 | 
			
		||||
import com.google.gerrit.common.data.GroupReference;
 | 
			
		||||
import com.google.gerrit.common.errors.NoSuchGroupException;
 | 
			
		||||
import com.google.gerrit.extensions.common.GroupBaseInfo;
 | 
			
		||||
import com.google.gerrit.extensions.common.SuggestedReviewerInfo;
 | 
			
		||||
import com.google.gerrit.extensions.common.AccountInfo;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.BadRequestException;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.RestReadView;
 | 
			
		||||
@@ -37,7 +42,6 @@ import com.google.gerrit.server.account.AccountVisibility;
 | 
			
		||||
import com.google.gerrit.server.account.GroupBackend;
 | 
			
		||||
import com.google.gerrit.server.account.GroupMembers;
 | 
			
		||||
import com.google.gerrit.server.config.GerritServerConfig;
 | 
			
		||||
import com.google.gerrit.server.group.GroupJson.GroupBaseInfo;
 | 
			
		||||
import com.google.gerrit.server.project.NoSuchProjectException;
 | 
			
		||||
import com.google.gerrit.server.project.ProjectControl;
 | 
			
		||||
import com.google.gwtorm.server.OrmException;
 | 
			
		||||
@@ -60,6 +64,20 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
 | 
			
		||||
  private static final String MAX_SUFFIX = "\u9fa5";
 | 
			
		||||
  private static final int DEFAULT_MAX_SUGGESTED = 10;
 | 
			
		||||
  private static final int DEFAULT_MAX_MATCHES = 100;
 | 
			
		||||
  private static final Ordering<SuggestedReviewerInfo> ORDERING =
 | 
			
		||||
      Ordering.natural().onResultOf(new Function<SuggestedReviewerInfo, String>() {
 | 
			
		||||
        @Nullable
 | 
			
		||||
        @Override
 | 
			
		||||
        public String apply(@Nullable SuggestedReviewerInfo suggestedReviewerInfo) {
 | 
			
		||||
          if (suggestedReviewerInfo == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
          }
 | 
			
		||||
          return suggestedReviewerInfo.account != null
 | 
			
		||||
              ? MoreObjects.firstNonNull(suggestedReviewerInfo.account.email,
 | 
			
		||||
              Strings.nullToEmpty(suggestedReviewerInfo.account.name))
 | 
			
		||||
              : Strings.nullToEmpty(suggestedReviewerInfo.group.name);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
  private final AccountLoader accountLoader;
 | 
			
		||||
  private final AccountControl accountControl;
 | 
			
		||||
@@ -159,7 +177,9 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
 | 
			
		||||
 | 
			
		||||
    List<SuggestedReviewerInfo> reviewer = Lists.newArrayList();
 | 
			
		||||
    for (AccountInfo a : suggestedAccounts) {
 | 
			
		||||
      reviewer.add(new SuggestedReviewerInfo(a));
 | 
			
		||||
      SuggestedReviewerInfo info = new SuggestedReviewerInfo();
 | 
			
		||||
      info.account = a;
 | 
			
		||||
      reviewer.add(info);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Project p = rsrc.getControl().getProject();
 | 
			
		||||
@@ -169,11 +189,13 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
 | 
			
		||||
        GroupBaseInfo info = new GroupBaseInfo();
 | 
			
		||||
        info.id = Url.encode(g.getUUID().get());
 | 
			
		||||
        info.name = g.getName();
 | 
			
		||||
        reviewer.add(new SuggestedReviewerInfo(info));
 | 
			
		||||
        SuggestedReviewerInfo suggestedReviewerInfo = new SuggestedReviewerInfo();
 | 
			
		||||
        suggestedReviewerInfo.group = info;
 | 
			
		||||
        reviewer.add(suggestedReviewerInfo);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Collections.sort(reviewer);
 | 
			
		||||
    reviewer = ORDERING.immutableSortedCopy(reviewer);
 | 
			
		||||
    if (reviewer.size() <= limit) {
 | 
			
		||||
      return reviewer;
 | 
			
		||||
    } else {
 | 
			
		||||
@@ -342,29 +364,4 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static class SuggestedReviewerInfo implements Comparable<SuggestedReviewerInfo> {
 | 
			
		||||
    public AccountInfo account;
 | 
			
		||||
    public GroupBaseInfo group;
 | 
			
		||||
 | 
			
		||||
    SuggestedReviewerInfo(AccountInfo a) {
 | 
			
		||||
      this.account = a;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SuggestedReviewerInfo(GroupBaseInfo g) {
 | 
			
		||||
      this.group = g;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int compareTo(SuggestedReviewerInfo o) {
 | 
			
		||||
      return getSortValue().compareTo(o.getSortValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getSortValue() {
 | 
			
		||||
      return account != null
 | 
			
		||||
          ? MoreObjects.firstNonNull(account.email,
 | 
			
		||||
              Strings.nullToEmpty(account.name))
 | 
			
		||||
          : Strings.nullToEmpty(group.name);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user