Refactor GerritHookfilter's issue extraction into separate class

This refactoring brings the functions to the new class as unmodified
as possible. Thereby, we allow easier tracing of changes. Refactoring
of the code is left to follow-up commits.

After some more refactoring, we use this class as single way to
extract issue ids from commit messages.

Change-Id: I2d1dcab2cabc4992c975f649c167d8511cc1f0ab
diff --git a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/util/IssueExtractor.java b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/util/IssueExtractor.java
new file mode 100644
index 0000000..e3b3f08
--- /dev/null
+++ b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/util/IssueExtractor.java
@@ -0,0 +1,66 @@
+package com.googlesource.gerrit.plugins.hooks.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.inject.Inject;
+
+import com.googlesource.gerrit.plugins.hooks.its.ItsName;
+
+import org.eclipse.jgit.lib.Config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IssueExtractor {
+  private static final Logger log = LoggerFactory.getLogger(
+      IssueExtractor.class);
+
+  @Inject @GerritServerConfig
+  private Config gerritConfig;
+
+  @Inject @ItsName
+  private String itsName;
+
+  /**
+   * Gets issue ids from a string.
+   *
+   * @param haystack String to extract issue ids from
+   * @return array of {@link Strings}. Each String being a found issue id.
+   */
+  public String[] getIssueIds(String haystack) {
+    List<Pattern> commentRegexList = getCommentRegexList();
+    if (commentRegexList == null) return new String[] {};
+
+    log.debug("Matching '" + haystack + "' against " + commentRegexList);
+
+    ArrayList<String> issues = new ArrayList<String>();
+    for (Pattern pattern : commentRegexList) {
+      Matcher matcher = pattern.matcher(haystack);
+
+      while (matcher.find()) {
+        int groupCount = matcher.groupCount();
+        for (int i = 1; i <= groupCount; i++) {
+          String group = matcher.group(i);
+          issues.add(group);
+        }
+      }
+    }
+
+    return issues.toArray(new String[issues.size()]);
+  }
+
+  private List<Pattern> getCommentRegexList() {
+    ArrayList<Pattern> regexList = new ArrayList<Pattern>();
+
+    String match = gerritConfig.getString("commentLink", itsName, "match");
+    if (match != null) {
+      regexList.add(Pattern.compile(match));
+    }
+
+    return regexList;
+  }
+}
diff --git a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java
index da27a0c..f5611fa 100644
--- a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java
+++ b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java
@@ -15,12 +15,7 @@
 package com.googlesource.gerrit.plugins.hooks.workflow;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
-import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
@@ -30,7 +25,6 @@
 
 import com.google.gerrit.common.ChangeListener;
 import com.google.gerrit.reviewdb.client.Project.NameKey;
-import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.events.ChangeAbandonedEvent;
 import com.google.gerrit.server.events.ChangeEvent;
 import com.google.gerrit.server.events.ChangeMergedEvent;
@@ -40,17 +34,10 @@
 import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.hooks.its.ItsName;
 
 public class GerritHookFilter implements ChangeListener {
   private static final Logger log = LoggerFactory.getLogger(GerritHookFilter.class);
 
-  @Inject @GerritServerConfig
-  private Config gerritConfig;
-
-  @Inject @ItsName
-  private String itsName;
-
   @Inject
   private GitRepositoryManager repoManager;
 
@@ -69,39 +56,6 @@
     }
   }
 
-  protected String[] getIssueIds(String gitComment) {
-    List<Pattern> commentRegexList = getCommentRegexList();
-    if (commentRegexList == null) return new String[] {};
-
-    log.debug("Matching '" + gitComment + "' against " + commentRegexList);
-
-    ArrayList<String> issues = new ArrayList<String>();
-    for (Pattern pattern : commentRegexList) {
-      Matcher matcher = pattern.matcher(gitComment);
-
-      while (matcher.find()) {
-        int groupCount = matcher.groupCount();
-        for (int i = 1; i <= groupCount; i++) {
-          String group = matcher.group(i);
-          issues.add(group);
-        }
-      }
-    }
-
-    return issues.toArray(new String[issues.size()]);
-  }
-
-  private List<Pattern> getCommentRegexList() {
-    ArrayList<Pattern> regexList = new ArrayList<Pattern>();
-
-    String match = gerritConfig.getString("commentLink", itsName, "match");
-    if (match != null) {
-      regexList.add(Pattern.compile(match));
-    }
-
-    return regexList;
-  }
-
   public void doFilter(PatchSetCreatedEvent hook) throws IOException {
   }
 
diff --git a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddComment.java b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddComment.java
index 69b5ffc..ac19c2e 100644
--- a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddComment.java
+++ b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddComment.java
@@ -31,6 +31,7 @@
 import com.google.gerrit.server.events.CommentAddedEvent;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.hooks.its.ItsFacade;
+import com.googlesource.gerrit.plugins.hooks.util.IssueExtractor;
 
 public class GerritHookFilterAddComment extends GerritHookFilter  {
 
@@ -44,6 +45,9 @@
   @GerritServerConfig
   private Config gerritConfig;
 
+  @Inject
+  private IssueExtractor issueExtractor;
+
   @Override
   public void doFilter(CommentAddedEvent hook) throws IOException {
     if (!(gerritConfig.getBoolean(its.name(), null, "commentOnCommentAdded",
@@ -162,7 +166,7 @@
   private void addComment(ChangeAttribute change, String comment)
       throws IOException {
     String gitComment = change.subject;;
-    String[] issues = getIssueIds(gitComment);
+    String[] issues = issueExtractor.getIssueIds(gitComment);
 
     for (String issue : issues) {
       its.addComment(issue, comment);
diff --git a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToChangeId.java b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToChangeId.java
index 9079808..c3ad727 100644
--- a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToChangeId.java
+++ b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToChangeId.java
@@ -25,6 +25,7 @@
 import com.google.gerrit.server.events.PatchSetCreatedEvent;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.hooks.its.ItsFacade;
+import com.googlesource.gerrit.plugins.hooks.util.IssueExtractor;
 
 public class GerritHookFilterAddRelatedLinkToChangeId extends
     GerritHookFilter  {
@@ -39,6 +40,9 @@
   @GerritServerConfig
   private Config gerritConfig;
 
+  @Inject
+  private IssueExtractor issueExtractor;
+
   @Override
   public void doFilter(PatchSetCreatedEvent patchsetCreated) throws IOException {
     boolean addPatchSetComment = gerritConfig.getBoolean(its.name(), null,
@@ -53,7 +57,7 @@
           getComment(patchsetCreated.change.project,
               patchsetCreated.patchSet.revision);
 
-      String[] issues = getIssueIds(gitComment);
+      String[] issues = issueExtractor.getIssueIds(gitComment);
 
       for (String issue : issues) {
         if (addChangeComment) {
diff --git a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToGitWeb.java b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToGitWeb.java
index 0db89d9..da582f8 100644
--- a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToGitWeb.java
+++ b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToGitWeb.java
@@ -33,6 +33,7 @@
 import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.hooks.its.ItsFacade;
+import com.googlesource.gerrit.plugins.hooks.util.IssueExtractor;
 
 public class GerritHookFilterAddRelatedLinkToGitWeb extends GerritHookFilter {
 
@@ -49,6 +50,8 @@
   @Inject
   private GitWebConfig gitWebConfig;
 
+  @Inject
+  private IssueExtractor issueExtractor;
 
   @Override
   public void doFilter(RefUpdatedEvent hook) throws IOException {
@@ -64,7 +67,7 @@
     if (gitUrl == null) {
       return;
     }
-    String[] issues = getIssueIds(gitComment);
+    String[] issues = issueExtractor.getIssueIds(gitComment);
 
     for (String issue : issues) {
       log.debug("Adding GitWeb URL " + gitUrl + " to issue " + issue);
diff --git a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterChangeState.java b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterChangeState.java
index 959722f..9056357 100644
--- a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterChangeState.java
+++ b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterChangeState.java
@@ -39,6 +39,7 @@
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.hooks.its.InvalidTransitionException;
 import com.googlesource.gerrit.plugins.hooks.its.ItsFacade;
+import com.googlesource.gerrit.plugins.hooks.util.IssueExtractor;
 
 public class GerritHookFilterChangeState extends GerritHookFilter {
   private static final Logger log = LoggerFactory
@@ -51,6 +52,9 @@
   @SitePath
   private File sitePath;
 
+  @Inject
+  private IssueExtractor issueExtractor;
+
   @Override
   public void doFilter(PatchSetCreatedEvent hook) throws IOException {
     performAction(hook.change, new Condition("change", "created"));
@@ -138,7 +142,7 @@
     }
 
     String gitComment = change.subject;
-    String[] issues = getIssueIds(gitComment);
+    String[] issues = issueExtractor.getIssueIds(gitComment);
 
     for (String issue : issues) {
       its.performAction(issue, transition.getAction());