//////////////////////////////////////////////////////////////////////////////// // checkstyle: Checks Java source code for adherence to a set of rules. // Copyright (C) 2001-2017 the original author or authors. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library 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 // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser 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 com.puppycrawl.tools.checkstyle.gui; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; import antlr.ANTLRException; import com.puppycrawl.tools.checkstyle.TreeWalker; import com.puppycrawl.tools.checkstyle.api.CheckstyleException; import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.FileContents; import com.puppycrawl.tools.checkstyle.api.FileText; /** * Model for checkstyle frame. * @author Vladislav Lisetskiy */ public class MainFrameModel { /** * Parsing modes which available in GUI. */ public enum ParseMode { /** Only Java tokens without comments. */ PLAIN_JAVA("Plain Java"), /** Java tokens and comment nodes (singleline comments and block comments). */ JAVA_WITH_COMMENTS("Java with comments"), /** * Java tokens, comments and Javadoc comments nodes * (which are parsed from block comments). */ JAVA_WITH_JAVADOC_AND_COMMENTS("Java with comments and Javadocs"); /** * Mode's short description. */ private final String description; /** * Provides description. * @param descr description */ ParseMode(String descr) { description = descr; } @Override public String toString() { return description; } } /** Lines to position map. */ private final List<Integer> linesToPosition = new ArrayList<>(); /** Parse tree model. */ private final ParseTreeTableModel parseTreeTableModel; /** Current mode. */ private ParseMode parseMode = ParseMode.PLAIN_JAVA; /** The file which is being parsed. */ private File currentFile; /** Text for a frame's text area. */ private String text; /** Title for the main frame. */ private String title = "Checkstyle GUI"; /** Whether the reload action is enabled. */ private boolean reloadActionEnabled; /** Instantiate the model. */ public MainFrameModel() { parseTreeTableModel = new ParseTreeTableModel(null); } /** * Set current parse mode. * @param mode ParseMode enum. */ public void setParseMode(ParseMode mode) { parseMode = mode; } /** * Get parse tree table model. * @return parse tree table model. */ public ParseTreeTableModel getParseTreeTableModel() { return parseTreeTableModel; } /** * Get text to display in a text area. * @return text to display in a text area. */ public String getText() { return text; } /** * @return title for the main frame. */ public String getTitle() { return title; } /** * @return true if the reload action is enabled. */ public boolean isReloadActionEnabled() { return reloadActionEnabled; } /** * Whether a file chooser should accept the file as a source file. * @param file the file to check. * @return true if the file should be accepted. */ public static boolean shouldAcceptFile(File file) { return file.isDirectory() || file.getName().endsWith(".java"); } /** * Get the directory of the last loaded file. * @return directory of the last loaded file. */ public File getLastDirectory() { File lastDirectory = null; if (currentFile != null) { lastDirectory = new File(currentFile.getParent()); } return lastDirectory; } /** * Get current file. * @return current file. */ public File getCurrentFile() { return currentFile; } /** * Get lines to position map. * @return lines to position map. */ public List<Integer> getLinesToPosition() { final List<Integer> copy = new ArrayList<>(linesToPosition); return Collections.unmodifiableList(copy); } /** * Open file and load the file. * @param file the file to open. * @throws CheckstyleException if the file can not be parsed. */ public void openFile(File file) throws CheckstyleException { if (file != null) { try { currentFile = file; title = "Checkstyle GUI : " + file.getName(); reloadActionEnabled = true; final DetailAST parseTree; switch (parseMode) { case PLAIN_JAVA: parseTree = parseFile(file); break; case JAVA_WITH_COMMENTS: case JAVA_WITH_JAVADOC_AND_COMMENTS: parseTree = parseFileWithComments(file); break; default: throw new IllegalArgumentException("Unknown mode: " + parseMode); } parseTreeTableModel.setParseTree(parseTree); parseTreeTableModel.setParseMode(parseMode); final String[] sourceLines = getFileText(file).toLinesArray(); // clear for each new file linesToPosition.clear(); // starts line counting at 1 linesToPosition.add(0); final StringBuilder sb = new StringBuilder(); // insert the contents of the file to the text area for (final String element : sourceLines) { linesToPosition.add(sb.length()); sb.append(element).append(System.lineSeparator()); } text = sb.toString(); } catch (IOException | ANTLRException ex) { final String exceptionMsg = String.format(Locale.ROOT, "%s occurred while opening file %s.", ex.getClass().getSimpleName(), file.getPath()); throw new CheckstyleException(exceptionMsg, ex); } } } /** * Parse a file and return the parse tree. * @param file the file to parse. * @return the root node of the parse tree. * @throws IOException if the file could not be read. * @throws ANTLRException if the file is not a Java source. */ public DetailAST parseFile(File file) throws IOException, ANTLRException { final FileText fileText = getFileText(file); final FileContents contents = new FileContents(fileText); return TreeWalker.parse(contents); } /** * Parse a file and return the parse tree with comment nodes. * @param file the file to parse. * @return the root node of the parse tree. * @throws IOException if the file could not be read. * @throws ANTLRException if the file is not a Java source. */ public DetailAST parseFileWithComments(File file) throws IOException, ANTLRException { final FileText fileText = getFileText(file); final FileContents contents = new FileContents(fileText); return TreeWalker.parseWithComments(contents); } /** * Get FileText from a file. * @param file the file to get the FileText from. * @return the FileText. * @throws IOException if the file could not be read. */ public FileText getFileText(File file) throws IOException { return new FileText(file.getAbsoluteFile(), System.getProperty("file.encoding", "UTF-8")); } }