Import accounts using GitHub+Git user info.

Often GitHub user information is not complete,
as the full profile (login/name/email) is not mandatory.

When e-mail is empty, take the information from the
commit author, assuming that pull request GitUser
and commit author are the same.

Change-Id: I97f072733c3e84b07497c195ad44527c51ee4d38
diff --git a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitHubUser.java b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitHubUser.java
new file mode 100644
index 0000000..0cfdd5a
--- /dev/null
+++ b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/GitHubUser.java
@@ -0,0 +1,66 @@
+// 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.googlesource.gerrit.plugins.github.git;
+
+import java.io.IOException;
+
+import org.kohsuke.github.GHUser;
+import org.kohsuke.github.GitUser;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+
+import lombok.Getter;
+
+public class GitHubUser {
+  @Getter
+  private final String login;
+  @Getter
+  private final String name;
+  @Getter
+  private final String email;
+
+  private GitHubUser(GHUser gitHubUser, GitUser author) throws IOException {
+    this.login = initLogin(gitHubUser).or(generateLogin(author.getName()));
+    this.name = initFullName(gitHubUser).or(author.getName());
+    this.email = initEmail(gitHubUser).or(author.getEmail());
+  }
+
+  private static String generateLogin(String fullName) {
+    return fullName.toLowerCase().replaceAll("^[a-z0-9]", "_");
+  }
+
+  private static Optional<String> initLogin(GHUser gitHubUser) {
+    return Optional.fromNullable(gitHubUser != null ? gitHubUser.getLogin()
+        : null);
+  }
+
+  private static Optional<String> initEmail(GHUser gitHubUser)
+      throws IOException {
+    return Optional.fromNullable(gitHubUser != null ? Strings
+        .emptyToNull(gitHubUser.getEmail()) : null);
+  }
+
+  private static Optional<String> initFullName(GHUser gitHubUser)
+      throws IOException {
+    return Optional.fromNullable(gitHubUser != null ? Strings
+        .emptyToNull(gitHubUser.getName()) : null);
+  }
+
+  public static GitHubUser from(GHUser gitHubUser, GitUser author)
+      throws IOException {
+    return new GitHubUser(gitHubUser, author);
+  }
+}
diff --git a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/PullRequestImportJob.java b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/PullRequestImportJob.java
index f9c9399..0e941af 100644
--- a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/PullRequestImportJob.java
+++ b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/git/PullRequestImportJob.java
@@ -16,6 +16,7 @@
 import java.io.IOException;
 import java.util.List;
 
+import org.apache.commons.lang.StringUtils;
 import org.eclipse.jgit.api.FetchCommand;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.api.errors.GitAPIException;
@@ -47,6 +48,7 @@
 import com.google.gerrit.reviewdb.client.Project.NameKey;
 import com.google.gerrit.reviewdb.server.AccountExternalIdAccess;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.StringUtil;
 import com.google.gerrit.server.account.AccountImporter;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.project.ProjectCache;
@@ -188,16 +190,11 @@
       RevCommit revCommit =
           walk.parseCommit(ObjectId.fromString(ghCommitDetail.getSha()));
 
-      Account.Id pullRequestOwner;
-      // It may happen that the user that created the Pull Request has been
-      // removed from GitHub: we assume that the commit author was that user
-      // as there are no other choices.
-      if (pr.getUser() == null) {
-        pullRequestOwner = getOrRegisterAccount(db, ghCommitDetail.getCommit().getAuthor());
-      } else {
-        pullRequestOwner = getOrRegisterAccount(db, pr.getUser());
-      }
+      GHUser prUser = pr.getUser();
+      GitUser commitAuthor = ghCommitDetail.getCommit().getAuthor();
+      GitHubUser gitHubUser = GitHubUser.from(prUser, commitAuthor);
 
+      Account.Id pullRequestOwner = getOrRegisterAccount(db, gitHubUser);
       Id changeId =
           createChange.addCommitToChange(db, project, gitRepo,
               destinationBranch, pullRequestOwner, revCommit,
@@ -212,21 +209,14 @@
   }
 
   private com.google.gerrit.reviewdb.client.Account.Id getOrRegisterAccount(
-      ReviewDb db, GitUser author) throws BadRequestException,
+      ReviewDb db, GitHubUser author) throws BadRequestException,
       ResourceConflictException, UnprocessableEntityException, OrmException,
       IOException {
-    return getOrRegisterAccount(db, author.getName(), author.getName(),
+    return getOrRegisterAccount(db, author.getLogin(), author.getName(),
         author.getEmail());
   }
 
   private com.google.gerrit.reviewdb.client.Account.Id getOrRegisterAccount(
-      ReviewDb db, GHUser user) throws OrmException, BadRequestException,
-      ResourceConflictException, UnprocessableEntityException, IOException {
-    return getOrRegisterAccount(db, user.getLogin(), user.getName(),
-        user.getEmail());
-  }
-
-  private com.google.gerrit.reviewdb.client.Account.Id getOrRegisterAccount(
       ReviewDb db, String login, String name, String email)
       throws OrmException, BadRequestException, ResourceConflictException,
       UnprocessableEntityException, IOException {