Link to home
Start Free TrialLog in
Avatar of Rohit Bajaj
Rohit BajajFlag for India

asked on

Java file getting too big

HI,
In my java spring application... There are soem files of around 800 lines...
Does that indicate a bad code design.. What are the factors i should consider to shorten the files and split them into two ?
Whats the ideal maximum file length ?

Thanks
ASKER CERTIFIED SOLUTION
Avatar of gurpsbassi
gurpsbassi
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Rohit Bajaj

ASKER

HI,
I was asking about the java file .. Here is the file :
@Component
public class SlashCommand {
    private final String gitApiUrl = "https://api.github.com/";
    private final String gitBaseUrl = "https://github.com/";
    private static final Logger logger = LoggerFactory.getLogger(SlashCommand.class);

    @Autowired
    private UserDao userDao;
    @Autowired
    private GraphQL graphQL;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private Oauth2Service oauth2Service;

    public ModelAndView process(String slashCommand, String userId, String conversationId, String conversationName,
                                String page, String repoTobeUsed, String talkValidationToken)
            throws URISyntaxException {
        ModelAndView modelAndView = null;
        String[] slashCommandSplitArray = slashCommand.split(" ");
        String githubCommand = slashCommandSplitArray[0];
        UserInfo userInfo = userDao.getUserInfo(userId);

        logger.info("Slash Command : " + slashCommand + " received for user : " + userId);

        //Take user to authentication if user is yet not authenticated
        if (!userInfo.isAuthenticated()) {
            modelAndView = new ModelAndView("unauthenticated");
            String authUrl = oauth2Service.getAuthUrl(userId, talkValidationToken);
            modelAndView.addObject("OAuthURL", authUrl);
            return modelAndView;
        }

        Boolean isGithubCommandValid = isGithubCommandValid(slashCommandSplitArray, githubCommand);
        if (!isGithubCommandValid || githubCommand.equals("help")) {
            modelAndView = handleHelpScreen(userInfo);
            return modelAndView;
        }
        // fetch the repository to be used... by default its the repo in slashCommand or talkEvent but
        // in case repo is specified as a separate query parameter that is to be used.
        String repoWithOwnerToBeUsed = fetchRepoToBeUsed(repoTobeUsed, conversationId, slashCommandSplitArray, userInfo);
        //If repository is not specified and default is not set, ask to set default repository
        if ((repoWithOwnerToBeUsed == null || repoWithOwnerToBeUsed.length() == 0)) {
            modelAndView = handleChooseRepository(userInfo, page);
            return modelAndView;
        }
        Boolean isValid = ValidateRepo(repoWithOwnerToBeUsed, userInfo);
        if (!isValid) {
            modelAndView = handleInvalidRepo(repoWithOwnerToBeUsed, page, userInfo, githubCommand);
            return modelAndView;
        }
        modelAndView = handleCommand(githubCommand, slashCommandSplitArray, userInfo, conversationId, conversationName, repoWithOwnerToBeUsed, page, talkValidationToken, modelAndView);
        modelAndView.addObject("repository", repoWithOwnerToBeUsed);
        modelAndView.addObject("conversationId", conversationId);
        return modelAndView;
    }

    private ModelAndView handlePullRequests(UserInfo userInfo, String repository, String page) {
        PullRequestPage pullRequestPage = fetchPullRequests(repository, userInfo, page);
        if (page == null) {
            pullRequestPage.setFirstPage(true);
        }
        ModelAndView mav = new ModelAndView("pull");
        mav.addObject("pullRequestPage", pullRequestPage);
        mav.addObject("repoUrl", gitBaseUrl + repository);
        mav.addObject("pullsUrl", gitBaseUrl + repository + "/pulls");
        return mav;
    }

    private ModelAndView handleBranches(UserInfo userInfo, String repository, String page) {
        RepoBranches repoBranches = fetchBranchesForRepo(repository, userInfo, page);
        if (page == null) {
            repoBranches.setFirstPage(true);
        }
        ModelAndView mav = new ModelAndView("repo-branches");
        mav.addObject("repoBranches", repoBranches);
        mav.addObject("repoUrl", gitBaseUrl + repository);
        mav.addObject("repo", getRepoName(repository));
        mav.addObject("owner", getOwner(repository, userInfo));
        mav.addObject("userId", userInfo.getUserId());
        return mav;
    }

    private PullRequestPage fetchPullRequests(String repo, UserInfo userInfo, String page) {
        String repoName = getRepoName(repo);
        String owner = getOwner(repo, userInfo);
        String query;
        if (page == null) {
            query = graphQL.queryForPullRequests(owner, repoName);
        } else {
            query = graphQL.queryForAfterPullRequests(owner, repoName, page);
        }
        JsonNode result = graphQL.execute(query, userInfo.getAccessToken());
        List<PullRequest> pullRequestList = parsePullRequestJson(result, repo);
        Boolean hasNextPage = result.findValue("hasNextPage").asBoolean();
        String endCursor = result.findValue("endCursor").asText();
        int total = result.findValue("totalCount").asInt();
        PullRequestPage pullRequestPage = new PullRequestPage(total, repo, pullRequestList, endCursor, hasNextPage);
        return pullRequestPage;
    }

    private List<PullRequest> parsePullRequestJson(JsonNode jsonNode, String repo) {
        JsonNode edges = jsonNode.findValue("edges");
        int edgesSize = edges.size();
        List<PullRequest> pullRequestList = new ArrayList<>();
        for (int i = 0; i < edgesSize; i++) {
            JsonNode node = edges.get(i);
            String number = node.findValue("number").asText();
            String title = node.findValue("title").asText();
            Date createdAt = Utility.parseDate(node.findValue("createdAt").asText());
            String login = node.findValue("login").asText();
            PullRequest pullRequest = new PullRequest.Builder(number, title, createdAt, repo).login(login).build();
            pullRequestList.add(pullRequest);
        }
        return pullRequestList;
    }

    private RepoBranches fetchBranchesForRepo(String repo, UserInfo userInfo, String page) {
        String repoName = getRepoName(repo);
        String owner = getOwner(repo, userInfo);
        String query = null;
        if (page == null) {
            query = graphQL.queryForRepoBranchesInfo(owner, repoName);
        } else {
            query = graphQL.queryForAfterRepoBranchesInfo(owner, repoName, page);
        }

        JsonNode result = graphQL.execute(query, userInfo.getAccessToken());
        RepoBranches repoBranches = parseRepoBranchesJson(result, repo);
        repoBranches.setRepo(repo);
        if (repoBranches.getTotalCount() <= 100) {
            List<Branch> branchList = repoBranches.getBranchList();
            Collections.sort(branchList, new Comparator<Branch>() {
                @Override
                public int compare(Branch o1, Branch o2) {
                    if (o1.getDate().compareTo(o2.getDate()) >= 0) {
                        return -1;
                    }
                    return 1;
                }
            });
        }
        return repoBranches;
    }

    private RepoBranches parseRepoBranchesJson(JsonNode jsonNode, String repo) {
        JsonNode edges = jsonNode.findValue("edges");
        int edgesSize = edges.size();
        String repoPullUrl = gitBaseUrl + repo + "/pulls";
        List<Branch> branchList = new ArrayList<>();
        for (int i = 0; i < edgesSize; i++) {
            JsonNode node = edges.get(i);
            String branchName = node.findValue("name").asText();
            int associatedPullRequests = node.findValue("associatedPullRequests").findValue("totalCount").asInt();
            JsonNode author = node.findValue("author");
            Date date = Utility.parseDate(author.findValue("date").asText());
            JsonNode loginNode = author.findValue("login");
            String login = loginNode == null ? "" : loginNode.asText();
            Branch branch = new Branch(branchName, date, login, repo, associatedPullRequests, repoPullUrl);
            branchList.add(branch);
        }
        int totalCount = jsonNode.findValue("totalCount").asInt();
        String endCursor = jsonNode.findValue("endCursor").asText();
        Boolean hasNextPage = jsonNode.findValue("hasNextPage").asBoolean();
        return new RepoBranches(totalCount, endCursor, hasNextPage, branchList);
    }

    private ModelAndView handleShow(UserInfo userInfo, String objectId, String repoWithOwner) throws URISyntaxException {
        ModelAndView mav = null;
        GitObject gitObject = findObjectType(objectId, repoWithOwner, userInfo);
        if (gitObject == GitObject.TAG) {
            Tag tag = fetchTagDetails(objectId, repoWithOwner, userInfo);
            if (tag == null) {
                return invalidPage(objectId);
            }
            mav = new ModelAndView("show-tag");
            mav.addObject("tag", tag);
            mav.addObject("repoUrl", gitBaseUrl + repoWithOwner);
        } else if (gitObject == GitObject.BRANCH) {
            mav = handleBranchCommand(repoWithOwner, userInfo, objectId);
        } else if (gitObject == GitObject.COMMIT) {
            mav = handleSingleCommit(objectId, repoWithOwner, userInfo);
        } else if (gitObject == GitObject.ISSUE_OR_PULL) {
            String issueOrPullNumber = objectId.substring(1);
            JsonNode jsonNode = fetchIssueNumberDetails(issueOrPullNumber, repoWithOwner, userInfo);
            if (jsonNode.has("errors")) {
                String pullNumber = issueOrPullNumber;
                mav = handlePullCommand(pullNumber, repoWithOwner, userInfo, objectId);
            } else {
                String issueNumber = issueOrPullNumber;
                mav = handleIssueCommand(jsonNode, issueNumber, repoWithOwner);
            }
        }
        mav.addObject("repoWithOwner", repoWithOwner);
        return mav;
    }

    private ModelAndView invalidPage(String objectId) {
        ModelAndView mav = new ModelAndView("invalid-id");
        mav.addObject("id", objectId);
        return mav;
    }

    private JsonNode fetchIssueNumberDetails(String issueNumber, String repo, UserInfo userInfo) {
        String repoName = getRepoName(repo);
        String owner = getOwner(repo, userInfo);
        String query = graphQL.queryForIssueNumber(owner, repoName, issueNumber);
        JsonNode result = graphQL.execute(query, userInfo.getAccessToken());
        return result;
    }

    private JsonNode fetchPullRequestNumberDetails(String issueNumber, String repo, UserInfo userInfo) {
        String repoName = getRepoName(repo);
        String owner = getOwner(repo, userInfo);
        String query = graphQL.queryForPullRequestNumber(owner, repoName, issueNumber);
        JsonNode result = graphQL.execute(query, userInfo.getAccessToken());
        return result;
    }

    private ModelAndView handleRepo(UserInfo userInfo, String repository) {
        //TODO: Fetch repository readme
        //TODO: Fetch commit counts
        ModelAndView mav = new ModelAndView("show-repo");
        JsonNode repositoryDetails = fetchRepoDetails(repository, userInfo);
        String numOfPullRequests = repositoryDetails.findValue("pullRequests").findValue("totalCount").asText();
        String numOfIssues = repositoryDetails.findValue("issues").findValue("totalCount").asText();
        String numOfBranches = repositoryDetails.findValue("refs").findValue("totalCount").asText();
        JsonNode descriptionNode = repositoryDetails.findValue("description");
        String description = descriptionNode == NullNode.instance ? null : descriptionNode.asText();
        mav.addObject("numOfPullRequests", numOfPullRequests);
        mav.addObject("numOfBranches", numOfBranches);
        mav.addObject("numOfIssues", numOfIssues);
        mav.addObject("repoName", repository);
        mav.addObject("repoText", description);
        mav.addObject("repoUrl", gitBaseUrl + repository);
        mav.addObject("repoBranchUrl", gitBaseUrl + repository + "/branches");
        mav.addObject("repoIssueUrl", gitBaseUrl + repository + "/issues");
        return mav;
    }

    private ModelAndView handleDefault(UserInfo userInfo, String conversationId, String conversationName, String repository, String page) throws URISyntaxException {
        ModelAndView mav;
        if (!repository.equals(userInfo.getDefaultRepoName(conversationId))) {
            setDefaultRepository(userInfo, conversationId, repository);
            mav = new ModelAndView("set-default");
            mav.addObject("repo", repository);
            mav.addObject("repoUrl", gitBaseUrl + repository);
            mav.addObject("chatName", conversationName);
            return mav;
        } else {
            RepoPage repoPage = fetchAllReposAccessibleToUser(userInfo, page);
            mav = new ModelAndView("repo");
            mav.addObject("repo", repository);
            mav.addObject("repoPage", repoPage);
            mav.addObject("userId", userInfo.getUserId());
            mav.addObject("isValid", true);
            mav.addObject("default", true);
            return mav;
        }
    }

    private void setDefaultRepository(UserInfo userInfo, String conversationId, String repository) {
        Map<String, String> userDefaultRepoMaps = userInfo.getDefaultRepoMap();
        userDefaultRepoMaps.put(conversationId, repository);
        userDao.updateUserDefaultRepo(userInfo.getUserId(), new Gson().toJson(userDefaultRepoMaps));
    }

    private Boolean ValidateRepo(String repository, UserInfo userInfo) {
        String repoName = getRepoName(repository);
        String owner = getOwner(repository, userInfo);
        String query = graphQL.queryForValidatingRepo(owner, repoName);
        JsonNode jsonNode = graphQL.execute(query, userInfo.getAccessToken());
        return jsonNode.findValue("id") != null;
    }

    private ModelAndView handleChooseRepository(UserInfo userInfo, String page) throws URISyntaxException {
        RepoPage repoPage = fetchAllReposAccessibleToUser(userInfo, page);
        ModelAndView mav = new ModelAndView("repo");
        mav.addObject("repoPage", repoPage);
        mav.addObject("userId", userInfo.getUserId());
        mav.addObject("chooseRepo", true);
        mav.addObject("default", true);
        return mav;
    }

    private RepoPage fetchAllReposAccessibleToUser(UserInfo userInfo, String page) throws URISyntaxException {
        String accessToken = userInfo.getAccessToken();
        String repoUrl = null;
        repoUrl = new URIBuilder(gitApiUrl + "user/repos").addParameter("access_token", accessToken).addParameter("page", page).addParameter("per_page", "10").build().toString();
        ResponseEntity<Repo[]> responseEntity = restTemplate.getForEntity(repoUrl, Repo[].class);
        Repo[] repos = responseEntity.getBody();
        PageLinks pageLinks = new PageLinks(responseEntity);
        RepoPage repoPage = new RepoPage(repos, pageLinks);
        return repoPage;
    }

    private ModelAndView handleHelpScreen(UserInfo userInfo) {
        ModelAndView modelAndView = new ModelAndView("github-help");
        modelAndView.addObject("userId", userInfo.getUserId());
        return modelAndView;
    }

    private ModelAndView handleIssues(UserInfo userInfo, String repository, String page) {
        IssuePage issuePage = fetchIssuesForRepo(repository, userInfo, page);
        if (page == null) {
            issuePage.setFirstPage(true);
        }
        ModelAndView modelAndView = new ModelAndView("repo-issues");
        modelAndView.addObject("issuePage", issuePage);
        modelAndView.addObject("repoUrl", gitBaseUrl + repository);
        modelAndView.addObject("issuesUrl", gitBaseUrl + repository + "/issues");

        return modelAndView;
    }

    private IssuePage fetchIssuesForRepo(String repo, UserInfo userInfo, String page) {
        String repoName = getRepoName(repo);
        String owner = getOwner(repo, userInfo);
        String query;
        if (page == null) {
            query = graphQL.queryForIssuesInfo(owner, repoName);
        } else {
            query = graphQL.queryForAfterIssuesInfo(owner, repoName, page);
        }
        JsonNode result = graphQL.execute(query, userInfo.getAccessToken());
        IssuePage issuePage = parseIssuesJson(result, repo);
        issuePage.setRepo(repo);
        return issuePage;
    }

    private IssuePage parseIssuesJson(JsonNode jsonNode, String repo) {
        JsonNode edges = jsonNode.findValue("edges");
        int edgesSize = edges.size();
        List<Issue> issueList = new ArrayList<>();
        for (int i = 0; i < edgesSize; i++) {
            JsonNode node = edges.get(i);
            String issueNumber = node.findValue("number").asText();
            String title = node.findValue("title").asText();
            JsonNode author = node.findValue("author");
            Date date = Utility.parseDate(node.findValue("createdAt").asText());
            JsonNode loginNode = author.findValue("login");
            String login = loginNode == null ? "" : loginNode.asText();
            Issue issue = new Issue(issueNumber, title, date, login, repo);
            issueList.add(issue);
        }
        int totalCount = jsonNode.findValue("totalCount").asInt();
        String endCursor = jsonNode.findValue("endCursor").asText();
        Boolean hasNextPage = jsonNode.findValue("hasNextPage").asBoolean();
        return new IssuePage(totalCount, endCursor, hasNextPage, issueList);
    }

    private Commit fetchCommitDetails(String objectId, String repo, UserInfo userInfo) throws URISyntaxException {
        String repoName = getRepoName(repo);
        String owner = getOwner(repo, userInfo);
        String urlPrefix = gitApiUrl + "repos/" + owner + "/" + repoName;
        String commitUrl = new URIBuilder(urlPrefix + "/commits/" + objectId).addParameter("access_token", userInfo.getAccessToken()).build().toString();
        Commit commit;
        try {
            commit = restTemplate.getForObject(commitUrl, Commit.class);
        } catch (Exception e) {
            return null;
        }
        return commit;
    }

    private String compareBranch(String branch, String repo, UserInfo userInfo) throws URISyntaxException {
        String repoName = getRepoName(repo);
        String owner = getOwner(repo, userInfo);
        String accessToken = userInfo.getAccessToken();
        String urlPrefix = gitApiUrl + "repos/" + owner + "/" + repoName;
        String compareUrl = new URIBuilder(urlPrefix + "/compare/master..." + branch).addParameter("access_token", accessToken).build().toString();
        JsonNode jsonNode = restTemplate.getForObject(compareUrl, JsonNode.class);
        String aheadBy = jsonNode.findValue("ahead_by").asText();
        return aheadBy;
    }

    private JsonNode fetchBranchDetails(String branch, String repo, UserInfo userInfo) {
        String repoName = getRepoName(repo);
        String owner = getOwner(repo, userInfo);
        String query = graphQL.queryForBranchInfo(owner, repoName, branch);
        JsonNode result = graphQL.execute(query, userInfo.getAccessToken());
        return result;
    }

    private GitObject findObjectType(String objectId, String repository, UserInfo userInfo) throws URISyntaxException {
        String gitAncestryRegex = "((\\^|~)[\\^~0-9]*){0,1}";
        if (objectId.matches("(HEAD|@)" + gitAncestryRegex)) {
            return GitObject.COMMIT;
        }
        if (objectId.startsWith("#")) {
            return GitObject.ISSUE_OR_PULL;
        }
        if (objectId.contains(".")) {
            return GitObject.TAG;
        }
        String shaAncestryRegex = "[0-9a-f]{6,40}" + gitAncestryRegex;
        if (!objectId.matches(shaAncestryRegex)) {
            return GitObject.BRANCH;
        }
        String repoName = getRepoName(repository);
        String owner = getOwner(repository, userInfo);
        String accessToken = userInfo.getAccessToken();
        String urlPrefix = gitApiUrl + "repos/" + owner + "/" + repoName;
        String commitUrl = new URIBuilder(urlPrefix + "/commits/" + objectId).addParameter("access_token", accessToken).build().toString();
        JsonNode jsonNode = restTemplate.getForObject(commitUrl, JsonNode.class);
        if (jsonNode.findValue("sha").asText() != null) {
            return GitObject.COMMIT;
        }
        return GitObject.BRANCH;
    }

    private Tag fetchTagDetails(String tagName, String repo, UserInfo userInfo) {
        String repoName = getRepoName(repo);
        String owner = getOwner(repo, userInfo);
        String accessToken = userInfo.getAccessToken();
        String urlPrefix = gitApiUrl + "repos/" + owner + "/" + repoName;
        String releaseTagApiUrl = urlPrefix + "/releases/tags/" + tagName;
        String tagApiUrl = urlPrefix + "/git/refs/tags/" + tagName;
        try {
            releaseTagApiUrl = new URIBuilder(releaseTagApiUrl).addParameter("access_token", accessToken).build().toString();
            tagApiUrl = new URIBuilder(tagApiUrl).addParameter("access_token", accessToken).build().toString();
        } catch (URISyntaxException e) {
            return null;
        }
        String gitPrefix = "https://github.com/" + owner + "/" + repoName;
        String tagHtmlUrl = gitPrefix + "/releases/tag/" + tagName;
        Tag tag = null;
        String sha;
        String commitUrl;
        try {
            tag = restTemplate.getForObject(releaseTagApiUrl, Tag.class);
            JsonNode jsonNode = restTemplate.getForObject(tagApiUrl, JsonNode.class);
            sha = jsonNode.findValue("sha").asText();
            commitUrl = gitPrefix + "/commit/" + sha;
            tag.setTargetCommit(sha);
            tag.setUrl(commitUrl);
        } catch (Exception e) {
            JsonNode jsonNode = restTemplate.getForObject(tagApiUrl, JsonNode.class);
            sha = jsonNode.findValue("sha").asText();
            commitUrl = gitPrefix + "/commit/" + sha;
            String url = jsonNode.findValue("object").findValue("url").asText() + "?access_token=" + accessToken;
            jsonNode = restTemplate.getForObject(url, JsonNode.class);
            String message = jsonNode.findValue("message").asText();
            tag = new Tag();
            tag.setName(tagName);
            tag.setBody(message);
            tag.setUrl(commitUrl);
            tag.setHtmlUrl(tagHtmlUrl);
            tag.setTargetCommit(sha);
            String gitUrl = gitPrefix + "/archive/" + tagName;
            tag.setTarballUrl(gitUrl + ".tar.gz");
            tag.setZipballUrl(gitUrl + ".zip");
        }
        return tag;
    }

    private JsonNode fetchRepoDetails(String repo, UserInfo userInfo) {
        String repoName = getRepoName(repo);
        String owner = getOwner(repo, userInfo);
        String query = graphQL.queryForRepoInfo(owner, repoName);
        JsonNode result = graphQL.execute(query, userInfo.getAccessToken());
        return result;
    }

    private String getRepoName(String repoWithOwner) {
        String[] repoWithOwnerSplit = repoWithOwner.split("/");
        String repoName;
        if (repoWithOwnerSplit.length > 1) {
            repoName = repoWithOwnerSplit[1];
        } else {
            repoName = repoWithOwnerSplit[0];
        }
        return repoName;
    }

    private String getOwner(String repoWithOwner, UserInfo userInfo) {
        String[] repoWithOwnerSplit = repoWithOwner.split("/");
        String owner;
        if (repoWithOwnerSplit.length > 1) {
            owner = repoWithOwnerSplit[0];
        } else {
            owner = userInfo.getDisplayName();
        }
        return owner;
    }

    private String fetchRepositoryFromCommand(String[] slashCommandSplitArray) {
        if (slashCommandSplitArray.length < 2) {
            return null;
        }

        String command = slashCommandSplitArray[0];

        if (command.equals("show")) {
            if (slashCommandSplitArray.length > 2) {
                return slashCommandSplitArray[2];
            }
            return null;
        } else {
            return slashCommandSplitArray[1];
        }
    }

    private Boolean isGithubCommandValid(String[] slashCommandSplitArray, String githubCommand) {
        Set validGithubCommands = new HashSet<>();
        validGithubCommands.addAll(Arrays.asList("repos", "pull", "branch", "issue", "log", "default", "repo", "show", "branches", "pulls", "issues"));
        if (slashCommandSplitArray.length > 3 || (slashCommandSplitArray.length == 3 && !slashCommandSplitArray[0].equals("show"))) {
            return false;
        } else if (githubCommand.length() == 0) {
            return false;
        } else if (!validGithubCommands.contains(githubCommand)) {
            return false;
        }
        return true;
    }

    private ModelAndView handleCommand(String gitCommand, String[] slashCommandSplitArray, UserInfo userInfo, String conversationId, String conversationName, String repoWithOwnerToBeUsed, String page, String talkValidationToken, ModelAndView mav) throws URISyntaxException {
        switch (gitCommand) {
            case "pull":
                mav = handlePullCommand(slashCommandSplitArray[1].substring(1), repoWithOwnerToBeUsed, userInfo, slashCommandSplitArray[1]);
            case "branch":
                mav = handleBranchCommand(repoWithOwnerToBeUsed, userInfo, slashCommandSplitArray[1]);
            case "issue":
                mav = handleIssueCommand(null, slashCommandSplitArray[1].substring(1), repoWithOwnerToBeUsed);
            case "log":
                Boolean isSingleCommit = isSingleCommit(slashCommandSplitArray, userInfo);
                if (isSingleCommit) {
                    mav = handleSingleCommit(slashCommandSplitArray[1], repoWithOwnerToBeUsed, userInfo);
                } else {
                    mav = handleAllCommits(repoWithOwnerToBeUsed, userInfo, talkValidationToken);
                }
                break;
            case "default":
                mav = handleDefault(userInfo, conversationId, conversationName, repoWithOwnerToBeUsed, page);
                break;
            case "repo":
                mav = handleRepo(userInfo, repoWithOwnerToBeUsed);
                break;
            case "repos":
                mav = handleReposCommand(userInfo);
                break;
            case "show":
                if (slashCommandSplitArray.length > 1) {
                    mav = handleShow(userInfo, slashCommandSplitArray[1], repoWithOwnerToBeUsed);
                } else {
                    mav = handleHelpScreen(userInfo);
                }
                break;

            case "branches":
                mav = handleBranches(userInfo, repoWithOwnerToBeUsed, page);
                break;

            case "pulls":
                mav = handlePullRequests(userInfo, repoWithOwnerToBeUsed, page);
                break;

            case "issues":
                mav = handleIssues(userInfo, repoWithOwnerToBeUsed, page);
                break;

            default:
                mav = handleHelpScreen(userInfo);
                break;
        }
        return mav;
    }

    private ModelAndView handleReposCommand(UserInfo userInfo) throws URISyntaxException {
        String query = graphQL.queryForRepos();
        JsonNode reposJsonNode = graphQL.execute(query, userInfo.getAccessToken());
        List<Repo> repoList = parseRepoJson(reposJsonNode);
        Boolean hasNextPage = reposJsonNode.findValue("hasNextPage").asBoolean();
        String endCursor = reposJsonNode.findValue("endCursor").asText();
        ModelAndView modelAndView = new ModelAndView("repo");
        modelAndView.addObject("repoList", repoList);
        modelAndView.addObject("hasNextPage", hasNextPage);
        modelAndView.addObject("endCursor", endCursor);
        return modelAndView;
    }

    private List<Repo> parseRepoJson(JsonNode reposJsonNode) {
        JsonNode edges = reposJsonNode.findValue("edges");
        int edgesSize = edges.size();
        List<Repo> repoList = new ArrayList<>();
        for (int i = 0; i < edgesSize; i++) {
            JsonNode node = edges.get(i);
            String name = node.findValue("name").asText();
            String login = node.findValue("login").asText();
            String pushedAt = node.findValue("pushedAt").asText();
            String description = node.findValue("description").asText();
            String url = node.findValue("url").asText();
            Repo repo = new Repo(login + "/" + name, url, pushedAt, description);
            repoList.add(repo);
        }
        return repoList;
    }


    private String fetchRepoToBeUsed(String repoTobeUsed, String conversationId, String[] slashCommandSplitArray, UserInfo userInfo) {
        String repository;
        if (repoTobeUsed != null) {
            repository = repoTobeUsed;
        } else {
            repository = userInfo.getDefaultRepoName(conversationId);
            String repoFromSlashCommand = fetchRepositoryFromCommand(slashCommandSplitArray);
            if (repoFromSlashCommand != null) {
                repository = repoFromSlashCommand;
            }
        }
        return repository;
    }

    private ModelAndView handleInvalidRepo(String repository, String page, UserInfo userInfo, String githubCommand) throws URISyntaxException {
        ModelAndView modelAndView = new ModelAndView("repo");
        RepoPage repoPage = fetchAllReposAccessibleToUser(userInfo, page);
        modelAndView.addObject("repo", repository);
        modelAndView.addObject("repoPage", repoPage);
        modelAndView.addObject("userId", userInfo.getUserId());
        modelAndView.addObject("isValid", false);
        if (githubCommand.equals("default")) {
            modelAndView.addObject("default", true);
        }
        return modelAndView;
    }

    private ModelAndView handlePullCommand(String pullNumber, String repository, UserInfo userInfo, String objectId) {
        JsonNode jsonNode = fetchPullRequestNumberDetails(pullNumber, repository, userInfo);
        if (jsonNode.has("errors")) {
            return invalidPage(objectId);
        }
        String title = jsonNode.findValue("title").asText();
        String createdAt = jsonNode.findValue("createdAt").asText();
        Date date = Utility.parseDate(createdAt);
        String url = jsonNode.findValue("url").asText();
        String login = jsonNode.findValue("login").asText();
        PullRequest pullRequest = new PullRequest.Builder(pullNumber, title, date, repository).url(url).login(login).build();
        ModelAndView mav = new ModelAndView("show-pull");
        mav.addObject("pull", pullRequest);
        mav.addObject("repo", repository);
        mav.addObject("repoUrl", gitBaseUrl + repository);
        return mav;

    }

    private ModelAndView handleBranchCommand(String repoWithOwner, UserInfo userInfo, String objectId) throws URISyntaxException {
        JsonNode jsonNode = fetchBranchDetails(objectId, repoWithOwner, userInfo);
        if (jsonNode.findValue("associatedPullRequests") == null) {
            return invalidPage(objectId);
        }
        String numPullRequest = jsonNode.findValue("associatedPullRequests").findValue("totalCount").asText();
        String aheadBy = compareBranch(objectId, repoWithOwner, userInfo);
        ModelAndView mav = new ModelAndView("show-branch");
        mav.addObject("branch", objectId);
        mav.addObject("aheadBy", aheadBy);
        mav.addObject("owner", getOwner(repoWithOwner, userInfo));
        mav.addObject("repo", getRepoName(repoWithOwner));
        mav.addObject("numPullRequest", numPullRequest);
        mav.addObject("repoUrl", gitBaseUrl + repoWithOwner);
        mav.addObject("repoPullUrl", gitBaseUrl + repoWithOwner + "/pulls");
        mav.addObject("branchUrl", gitBaseUrl + repoWithOwner + "/tree/" + objectId);
        return mav;
    }

    private ModelAndView handleIssueCommand(JsonNode issueDetailNode, String issueNumber, String repository) {
        String title = issueDetailNode.findValue("title").asText();
        String createdAt = issueDetailNode.findValue("createdAt").asText();
        Date date = Utility.parseDate(createdAt);
        String url = issueDetailNode.findValue("url").asText();
        String login = issueDetailNode.findValue("login").asText();
        Issue issue = new Issue(issueNumber, title, date, repository, url, login);
        ModelAndView mav = new ModelAndView("show-issue");
        mav.addObject("issue", issue);
        mav.addObject("repo", repository);
        mav.addObject("repoUrl", gitBaseUrl + repository);
        return mav;
    }

    private ModelAndView handleSingleCommit(String objectId, String repoWithOwner, UserInfo userInfo) throws URISyntaxException {
        Commit commit = fetchCommitDetails(objectId, repoWithOwner, userInfo);
        if (commit == null) {
            return invalidPage(objectId);
        }
        String shortsha = commit.getSha().substring(0, 8);
        String sha = commit.getSha();
        String htmlUrl = commit.getHtmlUrl();
        String message = commit.getCommit_().getMessage();
        String authorName = commit.getCommit_().getAuthor().getName();
        String date = commit.getCommit_().getAuthor().getCommitDate();
        date = date.split("T")[0];
        ModelAndView mav = new ModelAndView("show-commit");
        mav.addObject("shortsha", shortsha);
        mav.addObject("sha", sha);
        mav.addObject("htmlUrl", htmlUrl);
        mav.addObject("message", message);
        mav.addObject("authorName", authorName);
        mav.addObject("date", date);
        mav.addObject("repo", repoWithOwner);
        mav.addObject("repoUrl", gitBaseUrl + repoWithOwner);
        mav.addObject("treeUrl", GitObject.COMMIT + repoWithOwner + "/tree/" + objectId);
        return mav;
    }

    private Boolean isSingleCommit(String[] slashCommandSplitArray, UserInfo userInfo) {
        if (slashCommandSplitArray.length == 3)
            return true;
        else if (slashCommandSplitArray.length == 1)
            return false;
        else if (slashCommandSplitArray.length == 2) {
            Boolean isRepoWithOwner = ValidateRepo(slashCommandSplitArray[1], userInfo);
            if (isRepoWithOwner) {
                return false;
            }
            return true;
        }
        return false;
    }

    private List<GroupedCommits> fetchAllCommitDetails(String repoNameWithOwner, UserInfo userInfo) throws URISyntaxException {
        String repoName = getRepoName(repoNameWithOwner);
        String owner = getOwner(repoNameWithOwner, userInfo);
        String urlPrefix = gitApiUrl + "repos/" + owner + "/" + repoName;
        String commitUrl = new URIBuilder(urlPrefix + "/commits").addParameter("access_token", userInfo.getAccessToken()).addParameter("per_page", "100").build().toString();
        ArrayNode commitsJsonNode;
        try {
            commitsJsonNode = (ArrayNode) restTemplate.getForObject(commitUrl, JsonNode.class);
        } catch (Exception e) {
            return null;
        }
        if (commitsJsonNode == null)
            return null;
        List<GroupedCommits> commitsGroupedByDateList = new ArrayList<>();
        String prevDate = "";
        GroupedCommits groupedCommits = new GroupedCommits();
        for (int i = 0; i < commitsJsonNode.size(); i++) {
            Map commitDetailsMap = new HashMap<>();
            JsonNode jsonNode = commitsJsonNode.get(i);
            String commitSha = jsonNode.get("sha").asText();
            String date = jsonNode.get("commit").get("author").get("date").asText().split("T")[0];
            date = Utility.getDate(date);
            String message = jsonNode.get("commit").get("message").asText();
            String htmlUrl = jsonNode.get("html_url").asText();
            message = Utility.fetchFirstThreeLines(message);
            String login = "";
            JsonNode authorJsonNode = jsonNode.get("author");
            if (authorJsonNode.getNodeType() == JsonNodeType.NULL) {
                JsonNode nameJsonNode = jsonNode.get("commit").get("author").get("name");
                if (nameJsonNode.getNodeType() != JsonNodeType.NULL) {
                    login = nameJsonNode.asText();
                }
            } else {
                login = authorJsonNode.get("login").asText();
            }
            commitDetailsMap.put("sha", commitSha);
            commitDetailsMap.put("date", date);
            commitDetailsMap.put("login", login);
            commitDetailsMap.put("message", message);
            commitDetailsMap.put("html_url", htmlUrl);
            if (i == 0) {
                groupedCommits.getCommits().add(commitDetailsMap);
            } else if (date.equals(prevDate)) {
                groupedCommits.getCommits().add(commitDetailsMap);
            } else {
                groupedCommits.setDate(prevDate);
                commitsGroupedByDateList.add(groupedCommits);
                groupedCommits = new GroupedCommits();
                groupedCommits.getCommits().add(commitDetailsMap);
            }
            prevDate = date;
        }
        return commitsGroupedByDateList;
    }

    private ModelAndView handleAllCommits(String repoWithOwner, UserInfo userInfo, String talkValidationToken) throws URISyntaxException {
        List<GroupedCommits> commitsGroupedByDateList = fetchAllCommitDetails(repoWithOwner, userInfo);
        if (commitsGroupedByDateList == null) {
            return invalidPage(repoWithOwner);
        }
        String owner = repoWithOwner.split("/")[0];
        String repo = repoWithOwner.split("/")[1];
        ModelAndView modelAndView = new ModelAndView("all-commits");
        modelAndView.addObject("talkValidationToken", talkValidationToken);
        modelAndView.addObject("userId", userInfo.getUserId());
        modelAndView.addObject("owner", owner);
        modelAndView.addObject("repo", repo);
        modelAndView.addObject("lastDate", fetchLastCommit(commitsGroupedByDateList).get("date"));
        modelAndView.addObject("lastSha", fetchLastCommit(commitsGroupedByDateList).get("sha"));
        modelAndView.addObject("repoUrl", gitBaseUrl + owner + "/" + repo);
        modelAndView.addObject("commitsGroupedByDateList", commitsGroupedByDateList);
        return modelAndView;
    }

    private Map fetchLastCommit(List<GroupedCommits> commitsGroupedByDateList) {
        GroupedCommits lastGroupedCommits = commitsGroupedByDateList.get(commitsGroupedByDateList.size() - 1);
        List<Map> commits = lastGroupedCommits.getCommits();
        Map lastCommit = commits.get(commits.size() - 1);
        return lastCommit;
    }

    private enum GitObject {
        COMMIT, BRANCH, ISSUE_OR_PULL, TAG
    }

    private class GroupedCommits {
        private String date;
        private List<Map> commits = new ArrayList<>();

        public String getDate() {
            return date;
        }

        public void setDate(String date) {
            this.date = date;
        }

        public List<Map> getCommits() {
            return commits;
        }

        public void setCommits(List<Map> commits) {
            this.commits = commits;
        }
    }
}

Open in new window


The main function here is the public function process which inturn forwards the call to handleCommand
For a start I would not have my rest controller so tightly bound to the github endpoint.
I would move all the GitHub integration into a facade which talks to GitHub using oAuth and graphql.
The facade can then be injected into your rest controller and the facade can also be mocked.
Hi
I didnt understand that..
Can you give me a pseudocode example of how you will modify the above code...

Also the process function is the only public function used by thr controller.

I was thinking of defining multiple classes
One for each command.. As in the above code the main job is done by the function
Handlecommand which uses lot of switch statements...
Instead i could have a handler like pullhandler, repoHandler....these classes
And forward the processing to them..
This way i can have the code for each of them separately...in various classes.

Please suggest n guide

Thanks
your project is an integration project.
Your rest controller should talk to a facade class.

The facade glass will then talk to GitHub using graphql. Its just introducing another layer thats all.