Java tutorial
/* * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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.wso2.code.quality.matrices; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.json.JSONArray; import org.json.JSONObject; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * This class is used to find the revierwers of the buggy lines of code */ public class Reviewer { String searchPullReqeustAPIUrl; String pullRequestReviewAPIUrl; Set<String> approvedReviewers = new HashSet<String>(); // to store the reviewed and approved users of the pull requests Set<String> commentedReviewers = new HashSet<String>(); // to store the reviewed and commented users of the pull requests private static final Logger logger = Logger.getLogger(Reviewer.class); //constants for accessing github API private static final String GITHUB_REVIEW_API_STATE_KEY = "state"; private static final String GITHUB_REVIEW_API_APPROVED_KEY = "APPROVED"; private static final String GITHUB_REVIEW_API_COMMENTED_KEY = "COMMENTED"; private static final String GITHUB_REVIEW_API_LOGIN_KEY = "login"; private static final String GITHUB_REVIEW_API_USER_KEY = "user"; private static final String GITHUB_REVIEW_API_ITEMS_KEY = "items"; private static final String GITHUB_REVIEW_API_REPOSITORY_URL_KEY = "repository_url"; private static final String GITHUB_REVIEW_API_NUMBER_KEY = "number"; private static final String GITHUB_REVIEW_API_CLOSED_STATE_KEY = "closed"; public String getSearchPullReqeustAPI() { return searchPullReqeustAPIUrl; } /** * Sets the URL for Github Search API * * @param commitHashToBeSearched commit hash to be searched used for finding the Pull requests */ public void setSearchPullReqeustAPI(String commitHashToBeSearched) { this.searchPullReqeustAPIUrl = "https://api.github.com/search/issues?q=" + commitHashToBeSearched; } public String getPullRequestReviewAPIUrl() { return pullRequestReviewAPIUrl; } public void setPullRequestReviewAPIUrl(String repoLocation, int pullRequestNumber) { this.pullRequestReviewAPIUrl = "https://api.github.com/repos/" + repoLocation + "/pulls/" + pullRequestNumber + "/reviews"; } // map for storing the pull requests numbers against their repository Map<String, Set<Integer>> mapContainingPRNoAgainstRepoName = new HashMap<String, Set<Integer>>(); /** * for finding the reviewers of each commit and storing them in a Set * * @param commitHashObtainedForPRReview commit hash Set for finding the pull requests * @param githubToken github token for accessing github REST API */ public void findReviewers(Set<String> commitHashObtainedForPRReview, String githubToken, RestApiCaller restApiCaller) { commitHashObtainedForPRReview.stream().forEach(commitHashForFindingReviewers -> { setSearchPullReqeustAPI(commitHashForFindingReviewers); // calling the github search API JSONObject rootJsonObject = null; try { rootJsonObject = (JSONObject) restApiCaller.callApi(getSearchPullReqeustAPI(), githubToken, false, true); } catch (CodeQualityMatricesException e) { logger.error(e.getMessage(), e.getCause()); System.exit(1); } // reading thus saved json file if (rootJsonObject != null) { savePrNumberAndRepoName(rootJsonObject); } }); logger.info( "PR numbers which introduce bug lines of code with their relevant repository are saved successfully to mapContainingPRNoAgainstRepoName map"); saveReviewersToList(githubToken, restApiCaller); logger.info( "List of approved reviwers and comment users of the PRs which introduce bug lines to repository are saved in commentedReviewers and approvedReviewers list "); // printing the list of reviewers of pull requests printReviewUsers(); logger.info("Names of approved reviewers and commented reviewers are printed successfully"); } /** * reads the search API output and save the pull request number with the repo name in a map * * @param rootJsonObject JSONObject received from github search API */ public void savePrNumberAndRepoName(JSONObject rootJsonObject) { JSONArray itemsJsonArray = (JSONArray) rootJsonObject.get(GITHUB_REVIEW_API_ITEMS_KEY); Pmt.arrayToStream(itemsJsonArray).map(JSONObject.class::cast) .filter(o -> o.get(GITHUB_REVIEW_API_STATE_KEY).equals(GITHUB_REVIEW_API_CLOSED_STATE_KEY)) .forEach(prJsonObject -> { String repositoryUrl = (String) prJsonObject.get(GITHUB_REVIEW_API_REPOSITORY_URL_KEY); String repositoryLocation = StringUtils.substringAfter(repositoryUrl, "https://api.github.com/repos/"); if (repositoryLocation.contains("wso2/")) { // to filter out only the repositories belongs to wso2 int pullRequetNumber = (int) prJsonObject.get(GITHUB_REVIEW_API_NUMBER_KEY); mapContainingPRNoAgainstRepoName.putIfAbsent(repositoryLocation, new HashSet<Integer>()); // put the repo name key only if it does not exists in the map mapContainingPRNoAgainstRepoName.get(repositoryLocation).add(pullRequetNumber); // since SET is there we do not need to check for availability of the key in the map } }); } /** * Calling the github review API for a selected pull request on its relevant product * * @param githubToken github token for accessing github REST API */ public void saveReviewersToList(String githubToken, RestApiCaller restApiCaller) { for (Map.Entry m : mapContainingPRNoAgainstRepoName.entrySet()) { String productLocation = (String) m.getKey(); Set<Integer> prNumbers = (Set<Integer>) m.getValue(); prNumbers.stream().forEach(prNumber -> { setPullRequestReviewAPIUrl(productLocation, prNumber); JSONArray reviewJsonArray = null; try { reviewJsonArray = (JSONArray) restApiCaller.callApi(getPullRequestReviewAPIUrl(), githubToken, false, true); } catch (CodeQualityMatricesException e) { logger.error(e.getMessage(), e.getCause()); System.exit(1); } // for reading the output JSON from above and adding the reviewers to the Set if (reviewJsonArray != null) { readTheReviewOutJSON(reviewJsonArray, productLocation, prNumber); } }); } } /** * Reading the output received from the review API and saving the relevant reviewers and commented users to relevant Sets * * @param reviewJsonArray JSON response from the github Review API * @param productLocation Product Location for printing the error message when there are no reviewers and a commented users * @param prNumber relevant PR number for finding the reviewers and commenters */ public void readTheReviewOutJSON(JSONArray reviewJsonArray, String productLocation, int prNumber) { if (reviewJsonArray.length() != 0) { Pmt.arrayToStream(reviewJsonArray).map(JSONObject.class::cast).forEach(reviewJsonObject -> { addRelevantUsersToList(reviewJsonObject); }); // for (Object object : reviewJsonArray) { // if (object instanceof JSONObject) { // JSONObject reviewJsonObject = (JSONObject) object; // // // } // } } else { System.out.println("There are no records of reviews for pull request: " + prNumber + " on " + productLocation + " repository"); logger.info("There are no records of reviews for pull request: " + prNumber + " on " + productLocation + " repository"); } } /** * This method is used for saving the relevant reviewers and commented users to relevant Sets * * @param reviewJsonObject jsonObject received from readTheReviewOutJSON method */ public void addRelevantUsersToList(JSONObject reviewJsonObject) { if ((reviewJsonObject.get(GITHUB_REVIEW_API_STATE_KEY)).equals(GITHUB_REVIEW_API_APPROVED_KEY)) { JSONObject userJsonObject = (JSONObject) reviewJsonObject.get(GITHUB_REVIEW_API_USER_KEY); String approvedReviwer = (String) userJsonObject.get(GITHUB_REVIEW_API_LOGIN_KEY); approvedReviewers.add(approvedReviwer); // adding the approved user to the Set } else if ((reviewJsonObject.get(GITHUB_REVIEW_API_STATE_KEY)).equals(GITHUB_REVIEW_API_COMMENTED_KEY)) { JSONObject userJsonObject = (JSONObject) reviewJsonObject.get(GITHUB_REVIEW_API_USER_KEY); String commentedReviwer = (String) userJsonObject.get(GITHUB_REVIEW_API_LOGIN_KEY); commentedReviewers.add(commentedReviwer); // adding the commented user to the Set } } /** * Print the list of reviewers and commented users on the pull requests which introduce bugs to the code base */ public void printReviewUsers() { System.out.println("Reviewed and approved users of the bug lines: " + approvedReviewers); System.out.println("Reviewed and commented users on bug lines: " + commentedReviewers); } }