📄 linecounter.java
字号:
/* * LineCounter.java - a line counter program * Copyright (C) 2003-2004 Rob Spoor * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */package nl.icemanx.util;import java.io.*;import java.util.*;import nl.icemanx.io.FileFilter;import nl.icemanx.io.FileUtils;import org.jdom.*;import org.jdom.input.SAXBuilder;/** * A line counter program. * <br> * It reads its configuration from an XML file that must adhere to the * following DTD:<pre> * <!ELEMENT linecounter (class*)> * <!ELEMENT class (extensions, comments)> * <!ATTLIST class name NMTOKEN #REQUIRED> * * <!ELEMENT extensions (extension+)> * * <!ELEMENT extension EMPTY> * <!ATTLIST extension value NMTOKEN #REQUIRED> * <!ATTLIST extension description CDATA #REQUIRED> * * <!ELEMENT comments ((single | multi)+)> * * <!ELEMENT single EMPTY> * <!ATTLIST single start CDATA #REQUIRED> * * <!ELEMENT multi EMPTY> * <!ATTLIST multi start CDATA #REQUIRED> * <!ATTLIST multi end CDATA #REQUIRED></pre> *<br> * It must always provide a <tt>--class</tt> parameter with a name from the * configuration file. * * @author Rob Spoor * @version 0.5, 2004-01-17 * @see FileFilter */public final class LineCounter{ /** * Encapsulation of begin and end of multi-line comments. * * @author Rob Spoor * @version 0.1, 2003-09-05 */ private static class Comment { /** * The begin of the multi-line comment. */ private String begin; /** * The end of the multi-line comment. */ private String end; /** * Creates a multi-line comment begin-end pair. * * @param begin The begin of the multi-line comment. * @param end The end of the multi-line comment. */ public Comment(String begin, String end) { this.begin = begin; this.end = end; } /** * @return The begin of the multi-line comment. */ public String getBegin() { return begin; } /** * @return The end of the multi-line comment. */ public String getEnd() { return end; } } /** * The version number; */ public static String version = "0.5"; /** * The file filter to use. */ private FileFilter filter; /** * An array with the starting strings of single line comment. */ private String[] singleLineComments; /** * An array with multi-line comment begin-end string pairs. */ private Comment[] multiLineComments; /** * The number of files read. */ private long files; /** * The number of lines in total. */ private long lines; /** * The number of lines of code. */ private long linesOfCode; /** * The number of lines of comment. */ private long linesOfComment; /** * The number of blank lines. */ private long blankLines; /** * Creates a line counter * * @param classElement The root element of the class to read. * @throws IllegalArgumentException If <tt>classElement</tt> is * <tt>null</tt>. */ public LineCounter(Element classElement) { super(); if (classElement == null) { throw new IllegalArgumentException("Non-existent class given"); } // The description is not important filter = new FileFilter(getExtensions(classElement), ""); singleLineComments = getSingleLineComments(classElement); multiLineComments = getMultiLineComments(classElement); files = 0; lines = 0; linesOfCode = 0; linesOfComment = 0; blankLines = 0; } /** * @return The number of files in total. */ public long numberOfFiles() { return files; } /** * @return The number of lines in total. */ public long lines() { return lines; } /** * @return The number of lines of code. */ public long linesOfCode() { return linesOfCode; } /** * @return The number of lines of comment. */ public long linesOfComment() { return linesOfComment; } /** * @return The number of blank lines. */ public long blankLines() { return blankLines; } /** * @return The file filter of the line counter. */ public FileFilter getFileFilter() { return filter; } /** * Checkes whether a line is blank. * * @param line The line to check. * @return <tt>true</tt> iff <tt>line</tt> is blank. */ private boolean isBlank(String line) { return line.equals(""); } /** * Checkes whether a line is a single line comment. * * @param line The line to check. * @return <tt>true</tt> iff <tt>line</tt> starts with a single line * comment. */ private boolean isSingleLineComment(String line) { for (int i = 0; i < singleLineComments.length; i++) { if (line.regionMatches( 0, singleLineComments[i], 0, singleLineComments[i].length() )) { return true; } } return false; } /** * Checkes whether a line contains the start of multi-line comment. * * @param line The line to check. * @return The matching end string if the line contains the start of * multi-line comment, <tt>null</tt> otherwise. */ private String isMultiLineCommentStart(String line) { for (int i = 0; i < multiLineComments.length; i++) { String begin = multiLineComments[i].getBegin(); if (line.regionMatches(0, begin, 0, begin.length())) { return multiLineComments[i].getEnd(); } } return null; } /** * Checkes whether a line contains the end of multi-line comment. * * @param line The line to check. * @param commentEnd The comment end string to check on. * @return <tt>true</tt> iff <tt>line</tt> contains * <tt>commentEnd<tt>. */ private boolean containsCommentEnd(String line, String commentEnd) { return (line.indexOf(commentEnd) != -1); } /** * Counts the lines from a file. * * @param filename The name of the file. * @throws IOException If there is no such file, or an error occurs during * the reading of the file. */ public void countLines(String filename) throws IOException { BufferedReader in = new BufferedReader(new FileReader(filename)); String line; String commentEnd; while ((line = in.readLine()) != null) { line = line.trim(); if (isBlank(line)) { blankLines++; } else if (isSingleLineComment(line)) { linesOfComment++; } else if ((commentEnd = isMultiLineCommentStart(line)) != null) { // keep reading comment lines until commentEnd is found linesOfComment++; while ((line != null) && (!containsCommentEnd(line, commentEnd))) { linesOfComment++; lines++; line = in.readLine(); } } else { linesOfCode++; } lines++; } files++; } /** * Runs the line counter. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -