Fix owner: search operator substring regression

In prior releases the owner: and reviewer: operators performed
substring searching to locate user accounts that match the argument,
and find all changes relevant to those accounts.  Fix the operators
to perform that multiple-account searching again.

Bug: issue 646
Change-Id: Ie0d67ad15ddffa7d2d774466c42f84dc1a760f25
Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2010-08-04 15:04:09 -07:00
parent 6cbee9cb64
commit f76fb4f82c
4 changed files with 146 additions and 45 deletions

View File

@@ -15,12 +15,14 @@
package com.google.gerrit.server.account;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.AccountExternalId;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.client.ResultSet;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
@@ -52,28 +54,37 @@ public class AccountResolver {
* there are multiple candidates.
*/
public Account find(final String nameOrEmail) throws OrmException {
Set<Account.Id> r = findAll(nameOrEmail);
return r.size() == 1 ? byId.get(r.iterator().next()).getAccount() : null;
}
/**
* Locate exactly one account matching the name or name/email string.
*
* @param nameOrEmail a string of the format
* "Full Name &lt;email@example&gt;", just the email address
* ("email@example"), a full name ("Full Name"), an account id
* ("18419") or an user name ("username").
* @return the accounts that match, empty collection if none. Never null.
*/
public Set<Account.Id> findAll(String nameOrEmail) throws OrmException {
Matcher m = Pattern.compile("^.* \\(([1-9][0-9]*)\\)$").matcher(nameOrEmail);
if (m.matches()) {
return byId.get(Account.Id.parse(m.group(1))).getAccount();
return Collections.singleton(Account.Id.parse(m.group(1)));
}
if (nameOrEmail.matches("^[1-9][0-9]*$")) {
return byId.get(Account.Id.parse(nameOrEmail)).getAccount();
return Collections.singleton(Account.Id.parse(nameOrEmail));
}
if (nameOrEmail.matches(Account.USER_NAME_PATTERN)) {
Account who = findByUserName(nameOrEmail);
AccountState who = byId.getByUsername(nameOrEmail);
if (who != null) {
return who;
return Collections.singleton(who.getAccount().getId());
}
}
Account account = findByNameOrEmail(nameOrEmail);
if (account != null) {
return account;
}
return null;
return findAllByNameOrEmail(nameOrEmail);
}
/**
@@ -87,39 +98,61 @@ public class AccountResolver {
*/
public Account findByNameOrEmail(final String nameOrEmail)
throws OrmException {
Set<Account.Id> r = findAllByNameOrEmail(nameOrEmail);
return r.size() == 1 ? byId.get(r.iterator().next()).getAccount() : null;
}
/**
* Locate exactly one account matching the name or name/email string.
*
* @param nameOrEmail a string of the format
* "Full Name &lt;email@example&gt;", just the email address
* ("email@example"), a full name ("Full Name").
* @return the accounts that match, empty collection if none. Never null.
*/
public Set<Account.Id> findAllByNameOrEmail(final String nameOrEmail)
throws OrmException {
final int lt = nameOrEmail.indexOf('<');
final int gt = nameOrEmail.indexOf('>');
if (lt >= 0 && gt > lt && nameOrEmail.contains("@")) {
return findByEmail(nameOrEmail.substring(lt + 1, gt));
return byEmail.get(nameOrEmail.substring(lt + 1, gt));
}
if (nameOrEmail.contains("@")) {
return findByEmail(nameOrEmail);
return byEmail.get(nameOrEmail);
}
final Account.Id id = realm.lookup(nameOrEmail);
if (id != null) {
return byId.get(id).getAccount();
return Collections.singleton(id);
}
return oneAccount(schema.get().accounts().byFullName(nameOrEmail));
}
private Account findByEmail(final String email) {
final Set<Account.Id> candidates = byEmail.get(email);
if (1 == candidates.size()) {
return byId.get(candidates.iterator().next()).getAccount();
List<Account> m = schema.get().accounts().byFullName(nameOrEmail).toList();
if (m.size() == 1) {
return Collections.singleton(m.get(0).getId());
}
return null;
}
private static Account oneAccount(final ResultSet<Account> rs) {
final List<Account> r = rs.toList();
return r.size() == 1 ? r.get(0) : null;
}
private Account findByUserName(final String userName) {
AccountState as = byId.getByUsername(userName);
return as != null ? as.getAccount() : null;
// At this point we have no clue. Just perform a whole bunch of suggestions
// and pray we come up with a reasonable result list.
//
Set<Account.Id> result = new HashSet<Account.Id>();
String a = nameOrEmail;
String b = nameOrEmail + "\u9fa5";
for (Account act : schema.get().accounts().suggestByFullName(a, b, 10)) {
result.add(act.getId());
}
for (AccountExternalId extId : schema
.get()
.accountExternalIds()
.suggestByKey(
new AccountExternalId.Key(AccountExternalId.SCHEME_USERNAME, a),
new AccountExternalId.Key(AccountExternalId.SCHEME_USERNAME, b), 10)) {
result.add(extId.getAccountId());
}
for (AccountExternalId extId : schema.get().accountExternalIds()
.suggestByEmailAddress(a, b, 10)) {
result.add(extId.getAccountId());
}
return result;
}
}