001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2016 the original author or authors. 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018//////////////////////////////////////////////////////////////////////////////// 019 020package com.puppycrawl.tools.checkstyle.gui; 021 022import java.io.File; 023import java.io.IOException; 024import java.util.ArrayList; 025import java.util.List; 026import java.util.Locale; 027 028import antlr.ANTLRException; 029 030import com.google.common.collect.ImmutableList; 031import com.puppycrawl.tools.checkstyle.TreeWalker; 032import com.puppycrawl.tools.checkstyle.api.CheckstyleException; 033import com.puppycrawl.tools.checkstyle.api.DetailAST; 034import com.puppycrawl.tools.checkstyle.api.FileContents; 035import com.puppycrawl.tools.checkstyle.api.FileText; 036 037/** 038 * Model for checkstyle frame. 039 * @author Vladislav Lisetskiy 040 */ 041public class MainFrameModel { 042 043 /** Lines to position map. */ 044 private final List<Integer> linesToPosition = new ArrayList<>(); 045 046 /** Parse tree model. */ 047 private final ParseTreeTableModel parseTreeTableModel; 048 049 /** The file which is being parsed. */ 050 private File currentFile; 051 052 /** Text for a frame's text area. */ 053 private String text; 054 055 /** Title for the main frame. */ 056 private String title = "Checkstyle GUI"; 057 058 /** Whether the reload action is enabled. */ 059 private boolean reloadActionEnabled; 060 061 /** Instantiate the model. */ 062 public MainFrameModel() { 063 parseTreeTableModel = new ParseTreeTableModel(null); 064 } 065 066 /** 067 * Get parse tree table model. 068 * @return parse tree table model. 069 */ 070 public ParseTreeTableModel getParseTreeTableModel() { 071 return parseTreeTableModel; 072 } 073 074 /** 075 * Get text to display in a text area. 076 * @return text to display in a text area. 077 */ 078 public String getText() { 079 return text; 080 } 081 082 /** 083 * @return title for the main frame. 084 */ 085 public String getTitle() { 086 return title; 087 } 088 089 /** 090 * @return true if the reload action is enabled. 091 */ 092 public boolean isReloadActionEnabled() { 093 return reloadActionEnabled; 094 } 095 096 /** 097 * Whether a file chooser should accept the file as a source file. 098 * @param file the file to check. 099 * @return true if the file should be accepted. 100 */ 101 public static boolean shouldAcceptFile(File file) { 102 return file.isDirectory() || file.getName().endsWith(".java"); 103 } 104 105 /** 106 * Get the directory of the last loaded file. 107 * @return directory of the last loaded file. 108 */ 109 public File getLastDirectory() { 110 File lastDirectory = null; 111 if (currentFile != null) { 112 lastDirectory = new File(currentFile.getParent()); 113 } 114 return lastDirectory; 115 } 116 117 /** 118 * Get current file. 119 * @return current file. 120 */ 121 public File getCurrentFile() { 122 return currentFile; 123 } 124 125 /** 126 * Get lines to position map. 127 * @return lines to position map. 128 */ 129 public List<Integer> getLinesToPosition() { 130 return ImmutableList.copyOf(linesToPosition); 131 } 132 133 /** 134 * Open file and load the file. 135 * @param file the file to open. 136 * @throws CheckstyleException if the file can not be parsed. 137 */ 138 public void openFile(File file) throws CheckstyleException { 139 if (file != null) { 140 try { 141 currentFile = file; 142 title = "Checkstyle GUI : " + file.getName(); 143 reloadActionEnabled = true; 144 final DetailAST parseTree = parseFile(file); 145 parseTreeTableModel.setParseTree(parseTree); 146 final String[] sourceLines = getFileText(file).toLinesArray(); 147 148 // clear for each new file 149 linesToPosition.clear(); 150 // starts line counting at 1 151 linesToPosition.add(0); 152 153 final StringBuilder sb = new StringBuilder(); 154 // insert the contents of the file to the text area 155 for (final String element : sourceLines) { 156 linesToPosition.add(sb.length()); 157 sb.append(element).append(System.lineSeparator()); 158 } 159 text = sb.toString(); 160 } 161 catch (IOException | ANTLRException ex) { 162 final String exceptionMsg = String.format(Locale.ROOT, 163 "%s occurred while opening file %s.", 164 ex.getClass().getSimpleName(), file.getPath()); 165 throw new CheckstyleException(exceptionMsg, ex); 166 } 167 } 168 } 169 170 /** 171 * Parse a file and return the parse tree. 172 * @param file the file to parse. 173 * @return the root node of the parse tree. 174 * @throws IOException if the file could not be read. 175 * @throws ANTLRException if the file is not a Java source. 176 */ 177 public DetailAST parseFile(File file) throws IOException, ANTLRException { 178 final FileText fileText = getFileText(file); 179 final FileContents contents = new FileContents(fileText); 180 return TreeWalker.parse(contents); 181 } 182 183 /** 184 * Get FileText from a file. 185 * @param file the file to get the FileText from. 186 * @return the FileText. 187 * @throws IOException if the file could not be read. 188 */ 189 public FileText getFileText(File file) throws IOException { 190 return new FileText(file.getAbsoluteFile(), 191 System.getProperty("file.encoding", "UTF-8")); 192 } 193}