public PullRequestData addPullRequestData(GHPullRequest pullRequest, AbstractProject project)
      throws IOException {

    ConcurrentHashMap<String, PullRequestData> pullRequestDataMap =
        projectPullRequestDataLookup.get(project);

    if (pullRequestDataMap == null) {
      projectPullRequestDataLookup.putIfAbsent(
          project, new ConcurrentHashMap<String, PullRequestData>());
      pullRequestDataMap = projectPullRequestDataLookup.get(project);
    }

    PullRequestData data = pullRequestDataMap.get(pullRequest.getHtmlUrl().toString());
    if (data == null) {

      String pullRequestUrl = pullRequest.getHtmlUrl().toString();

      PullRequestData newPullRequestData =
          new PullRequestData(pullRequest, ProjectData.getInstance(project, true));

      pullRequestDataMap.putIfAbsent(pullRequestUrl, newPullRequestData);

      data = pullRequestDataMap.get(pullRequestUrl);

      if (data == newPullRequestData) {
        data.save();
      }
    }

    return data;
  }
 public static String getPullRequestAsString(GHPullRequest pullRequest) throws IOException {
   return pullRequest.getHtmlUrl()
       + " ["
       + pullRequest.getState()
       + "] Updated: "
       + pullRequest.getUpdatedAt();
 }
  /** Posts a note to set the expectation. */
  protected void greet(GHPullRequest pr) throws IOException {
    if (hasGreetingComment(pr)) return; // no need to do anything

    System.out.println("Greeting " + pr.getRepository().getName() + "\t" + pr.getTitle());

    pr.comment(
        String.format(
            "Thank you for a pull request! Please check [this document](%s) for how the Jenkins project handles pull requests",
            LINK));
  }
  private void build(GHPullRequest pr, GHUser buildRequester, TriggerCause cause)
      throws IOException {
    ArrayList<ParameterValue> parameters = getDefaultBuildParameters();
    parameters.add(new StringParameterValue(PR_COMMIT, pr.getHead().getSha()));
    parameters.add(new StringParameterValue(PR_BRANCH, pr.getHead().getRef()));
    if (buildRequester != null) {
      parameters.add(new StringParameterValue(BUILD_REQUESTER, buildRequester.getLogin()));
      if (buildRequester.getEmail() != null) {
        parameters.add(new StringParameterValue(BUILD_REQUEST_EMAIL, buildRequester.getEmail()));
      }
    }
    parameters.add(new StringParameterValue(PR_NUMBER, String.valueOf(pr.getNumber())));
    parameters.add(new StringParameterValue(PR_MERGE_BRANCH, pr.getBase().getRef()));
    parameters.add(new StringParameterValue(PR_OWNER, pr.getUser().getLogin()));
    if (pr.getUser().getEmail() != null) {
      parameters.add(new StringParameterValue(PR_OWNER_EMAIL, pr.getUser().getEmail()));
    }
    final StringParameterValue prUrlParam =
        new StringParameterValue(PR_URL, pr.getHtmlUrl().toString());
    parameters.add(prUrlParam);

    project.scheduleBuild2(
        project.getQuietPeriod(),
        cause,
        new ParametersAction(parameters),
        getBuildData(prUrlParam),
        new RevisionParameterAction(pr.getHead().getSha()));
  }
  private void check(GHPullRequest pr) throws IOException {
    ConcurrentMap<Integer, GhprbPullRequest> pulls = helper.getTrigger().getPulls();

    final Integer id = pr.getNumber();
    GhprbPullRequest pull;
    if (pulls.containsKey(id)) {
      pull = pulls.get(id);
    } else {
      pulls.putIfAbsent(id, new GhprbPullRequest(pr, helper, this));
      pull = pulls.get(id);
    }
    pull.check(pr);
  }
  private void deleteInstances(GHPullRequest pullRequest) throws IOException {
    PullRequestManager pullRequestManager = PullRequestManager.getInstance();
    List<PullRequestData> pullRequestDataList = new ArrayList<PullRequestData>();
    Authentication old = SecurityContextHolder.getContext().getAuthentication();
    SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM);
    try {
      for (AbstractProject<?, ?> project :
          Jenkins.getInstance().getAllItems(AbstractProject.class)) {

        PullRequestData data =
            pullRequestManager.removePullRequestData(pullRequest.getHtmlUrl().toString(), project);

        if (data != null) {
          pullRequestDataList.add(data);
        }
      }
    } finally {
      SecurityContextHolder.getContext().setAuthentication(old);
    }
    PullRequestCleanup.deleteInstances(pullRequestDataList, pullRequest);
  }
  public void check() {
    if (!initGhRepository()) {
      return;
    }

    if (helper.isProjectDisabled()) {
      logger.log(Level.FINE, "Project is disabled, not checking github state");
      return;
    }

    List<GHPullRequest> openPulls;
    try {
      openPulls = ghRepository.getPullRequests(GHIssueState.OPEN);
    } catch (IOException ex) {
      logger.log(Level.SEVERE, "Could not retrieve open pull requests.", ex);
      return;
    }

    ConcurrentMap<Integer, GhprbPullRequest> pulls = helper.getTrigger().getPulls();

    Set<Integer> closedPulls = new HashSet<Integer>(pulls.keySet());

    for (GHPullRequest pr : openPulls) {
      if (pr.getHead() == null) {
        try {
          pr = ghRepository.getPullRequest(pr.getNumber());
        } catch (IOException ex) {
          logger.log(Level.SEVERE, "Could not retrieve pr " + pr.getNumber(), ex);
          return;
        }
      }
      try {
        check(pr);
      } catch (IOException ex) {
        logger.log(Level.SEVERE, "Could not retrieve pr " + pr.getNumber(), ex);
        return;
      }
      closedPulls.remove(pr.getNumber());
    }

    // remove closed pulls so we don't check them again
    for (Integer id : closedPulls) {
      pulls.remove(id);
    }
  }
 /** Checks if this pull request already has a greeting */
 protected boolean hasGreetingComment(GHPullRequest pr) throws IOException {
   for (GHIssueComment c : pr.listComments()) {
     if (c.getBody().contains(LINK)) return true;
   }
   return false;
 }
  void handle(GHEventPayload.IssueComment issueComment, GitHub gitHub) throws IOException {
    // check the trigger phrase
    PullRequestBuildTrigger trigger = project.getTrigger(PullRequestBuildTrigger.class);
    if (StringUtils.isBlank(trigger.getTriggerPhrase())) {
      if (LOGGER.isLoggable(Level.FINE)) {
        LOGGER.fine("No trigger phrase configured for project: " + project.getDisplayName());
      }
      return;
    }

    String issueUrl = issueComment.getIssue().getHtmlUrl().toString();
    if (!issueUrl.startsWith(gitHubRepositoryUrl)) {
      LOGGER.finest(
          MessageFormat.format(
              "GitHub issue {0} is not related to project {1}. "
                  + "GitHub project URL configured for project {1}: {2}",
              issueUrl, project.getFullName(), gitHubRepositoryUrl));

      return;
    }

    String commentBody = issueComment.getComment().getBody();
    if (!triggerPhrasePattern.matcher(commentBody).find()) {
      if (LOGGER.isLoggable(Level.FINE)) {
        LOGGER.fine("No trigger phrase matching on comment: " + commentBody);
      }
      return;
    }

    GHUser buildRequester = issueComment.getComment().getUser();
    if (!isWhitelisted(buildRequester, gitHub)) {
      LOGGER.info(
          MessageFormat.format(
              "GitHub user {0} is not in the whitelist of project {1}",
              buildRequester.getLogin(), project.getFullName()));

      return;
    }

    final int prNumber = issueComment.getIssue().getNumber();

    GHPullRequest pullRequest = issueComment.getRepository().getPullRequest(prNumber);
    // Updating PR to force the cache (if present) to refresh:
    pullRequest.setTitle(pullRequest.getTitle());

    pullRequest = issueComment.getRepository().getPullRequest(prNumber);

    if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine("ghPullRequest = " + getPullRequestAsString(pullRequest));
    }

    if (pullRequest.getState() == GHIssueState.OPEN) {
      PullRequestData pullRequestData =
          PullRequestManager.getInstance().addPullRequestData(pullRequest, project);

      cancelBuilds(pullRequestData);
      build(pullRequest, buildRequester, new TriggerCause(pullRequest, buildRequester));
    } else if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine(
          MessageFormat.format(
              "Pull request {0} is not opened, no build is triggered",
              pullRequest.getHtmlUrl().toString()));
    }
  }
  void handle(GHEventPayload.PullRequest prEventPayload, GitHub gitHub) throws IOException {
    GHPullRequest pullRequest = prEventPayload.getPullRequest();
    String pullRequestUrl = pullRequest.getHtmlUrl().toString();
    if (!pullRequestUrl.startsWith(gitHubRepositoryUrl)) {
      LOGGER.config(
          MessageFormat.format(
              "Pull request {0} is not related to project {1}. "
                  + "GitHub project URL configured for project {1}: {2}",
              pullRequestUrl, project.getFullName(), gitHubRepositoryUrl));
      return;
    }

    LOGGER.info(
        MessageFormat.format(
            "Handling event ''{0}'' of pull request {1} for project {2}",
            prEventPayload.getAction(), pullRequestUrl, project.getFullName()));

    PullRequestManager pullRequestManager = PullRequestManager.getInstance();
    PullRequestData pullRequestData =
        pullRequestManager.getPullRequestData(pullRequestUrl, project);

    if (PullRequestManager.PullRequestAction.CLOSED.equals(prEventPayload.getAction())) {
      if (pullRequestData != null) {
        cancelBuilds(pullRequestData);
        deleteInstances(pullRequest);
      } else {
        LOGGER.warning(
            "No previous data available for received Pull Request 'close' event: "
                + pullRequestUrl);
      }
      return;
    }

    if (!isWhitelisted(pullRequest.getUser(), gitHub)) {
      LOGGER.info(
          MessageFormat.format(
              "GitHub user {0} is not in the whitelist of project {1}",
              pullRequest.getUser().getLogin(), project.getFullName()));

      return;
    }

    boolean startBuild = false;

    if (pullRequestData == null) {
      if (PullRequestManager.PullRequestAction.SYNCHRONIZE.equals(prEventPayload.getAction())) {
        LOGGER.info(
            MessageFormat.format(
                "Updated pull request {0} was not built previously", pullRequestUrl));
      }
      pullRequestData = pullRequestManager.addPullRequestData(pullRequest, project);
      startBuild = pullRequestData.getLastUpdated().equals(pullRequest.getUpdatedAt());

    } else if (pullRequestData.update(pullRequest)) {
      pullRequestData.save();
      startBuild = true;
    }

    if (LOGGER.isLoggable(Level.FINEST)) {
      LOGGER.finest("Received event payload: " + prEventPayload);
    }

    if (startBuild) {
      if (LOGGER.isLoggable(Level.FINE)) {
        LOGGER.fine(
            "Cancelling previous running builds and starting new build for Pull request: "
                + pullRequestData);
      }
      cancelBuilds(pullRequestData);
      build(pullRequest, null, new TriggerCause(prEventPayload));

    } else if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine("No new build has been triggered for Pull request: " + pullRequestData);
    }
  }