Wednesday, September 12, 2012

Count Lines of Code

Overview:
Below program displays lines of Java code that your project has. You just need to specify your project home(absolute path), followed by some flags.

NOTE: Java 7 features used

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;

public class CountLinesOfCode {
    public static int counter = 0;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        boolean skipDocComments = readInput(
                "Do you want to skip doc comments? (y/n): ", scanner);

        boolean skipBlankLines = readInput(
                "Do you want to skip blank lines? (y/n): ", scanner);

        boolean skipMultiLineComments = readInput(
                "Do you want to skip multiline comments? (y/n): ", scanner);

        boolean skipSingleLineComments = readInput(
                "Do you want to skip single line comments? (y/n): ", scanner);

        File projectHome = null;

        do {
            System.out.println("Enter Project Home Path: ");
            String projectHomeLocation = scanner.nextLine();
            projectHome = new File(projectHomeLocation);

            if (!projectHome.exists()) {
                System.out.println("Project home specfied doesn't exists!!!");
            }
            if (projectHome.exists() && !projectHome.isDirectory()) {
                System.out.println("Select path to a directory!!!");
            }

        } while (!projectHome.exists() || !projectHome.isDirectory());

        listFilesForFolder(projectHome, skipDocComments, skipBlankLines,
                skipMultiLineComments, skipSingleLineComments);

        System.out.println("\nYour project has " + counter
                + " lines of Java code!!!");
    }

    public static void listFilesForFolder(final File folder,
            final boolean skipDocComments, final boolean skipBlankLines,
            boolean skipMultiLineComments, final boolean skipSingleLineComments) {

        for (final File fileEntry : folder.listFiles()) {

            if (fileEntry.isDirectory()) {
               
                listFilesForFolder(fileEntry, skipDocComments, skipBlankLines,
                        skipMultiLineComments, skipSingleLineComments);
            } else {

                if (fileEntry.getName().contains(".java")) {
                   
                    boolean docCommentStart = false;
                    boolean multiLineCommentsStart = false;
                   
                    System.out.println(fileEntry.getName());
                   
                    try (FileReader fileReader = new FileReader(fileEntry);
                            BufferedReader reader = new BufferedReader(fileReader)) {

                        String line = null;
                       
                        while ((line = reader.readLine()) != null) {
                           
                            if (skipDocComments) {
                                if (line.trim().startsWith("/**")) {
                                    if (line.trim().endsWith("*/")) {
                                        continue;
                                    }
                                    docCommentStart = true;
                                    continue;
                                }
                                if (docCommentStart) {
                                    if (line.trim().endsWith("*/")) {
                                        docCommentStart = false;
                                    }
                                    continue;
                                }
                            }

                            if (skipMultiLineComments) {
                                if (line.trim().startsWith("/*")
                                        && !line.trim().startsWith("/**")) {
                                    if (line.trim().endsWith("*/")) {
                                        continue;
                                    }
                                    multiLineCommentsStart = true;
                                    continue;
                                }
                                if (multiLineCommentsStart) {
                                    if (line.trim().endsWith("*/")) {
                                        multiLineCommentsStart = false;
                                    }
                                    continue;
                                }
                            }

                            if (skipSingleLineComments) {
                                if (line.trim().startsWith("//")) {
                                    continue;
                                }
                            }

                            if (skipBlankLines) {
                                if (line.trim().isEmpty()) {
                                    continue;
                                }
                            }
                           
                            counter++;
                        }
                    } catch (FileNotFoundException e) {
                        System.out.println("Specified file not found!!!");
                    } catch (IOException e) {
                        System.out.println("An exception is thrown while reading/writing a file!!!");
                    }
                }
            }
        }
    }

    public static boolean readInput(String inputMsg, Scanner scanner) {
        String temp = null;
       
        do {
           
            System.out.println(inputMsg);
            temp = scanner.nextLine().trim();
           
            if (temp.matches("[^yYnN]")) {
                System.out.println("Invalid input!!!");
            }
           
        } while (temp.matches("[^yYnN]"));

        return getBoolValue(temp);
    }

    public static boolean getBoolValue(String input) {
        return input.matches("[yY]") ? true : false;
    }
}