View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2018 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.gui;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.nio.charset.StandardCharsets;
25  import java.util.ArrayList;
26  import java.util.List;
27  import java.util.Locale;
28  
29  import com.google.common.collect.ImmutableList;
30  import com.puppycrawl.tools.checkstyle.JavaParser;
31  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
32  import com.puppycrawl.tools.checkstyle.api.DetailAST;
33  import com.puppycrawl.tools.checkstyle.api.FileText;
34  
35  /**
36   * Model for checkstyle frame.
37   * @author Vladislav Lisetskiy
38   */
39  public class MainFrameModel {
40  
41      /**
42       * Parsing modes which available in GUI.
43       */
44      public enum ParseMode {
45  
46          /** Only Java tokens without comments. */
47          PLAIN_JAVA("Plain Java"),
48  
49          /** Java tokens and comment nodes (singleline comments and block comments). */
50          JAVA_WITH_COMMENTS("Java with comments"),
51  
52          /**
53           * Java tokens, comments and Javadoc comments nodes
54           * (which are parsed from block comments).
55           */
56          JAVA_WITH_JAVADOC_AND_COMMENTS("Java with comments and Javadocs");
57  
58          /**
59           * Mode's short description.
60           */
61          private final String description;
62  
63          /**
64           * Provides description.
65           * @param descr description
66           */
67          ParseMode(String descr) {
68              description = descr;
69          }
70  
71          @Override
72          public String toString() {
73              return description;
74          }
75  
76      }
77  
78      /** Parse tree model. */
79      private final ParseTreeTableModel parseTreeTableModel;
80  
81      /** Lines to position map. */
82      private ImmutableList<Integer> linesToPosition = ImmutableList.of();
83  
84      /** Current mode. */
85      private ParseMode parseMode = ParseMode.PLAIN_JAVA;
86  
87      /** The file which is being parsed. */
88      private File currentFile;
89  
90      /** Text for a frame's text area. */
91      private String text;
92  
93      /** Title for the main frame. */
94      private String title = "Checkstyle GUI";
95  
96      /** Whether the reload action is enabled. */
97      private boolean reloadActionEnabled;
98  
99      /** Instantiate the model. */
100     public MainFrameModel() {
101         parseTreeTableModel = new ParseTreeTableModel(null);
102     }
103 
104     /**
105      * Set current parse mode.
106      * @param mode ParseMode enum.
107      */
108     public void setParseMode(ParseMode mode) {
109         parseMode = mode;
110     }
111 
112     /**
113      * Get parse tree table model.
114      * @return parse tree table model.
115      */
116     public ParseTreeTableModel getParseTreeTableModel() {
117         return parseTreeTableModel;
118     }
119 
120     /**
121      * Get text to display in a text area.
122      * @return text to display in a text area.
123      */
124     public String getText() {
125         return text;
126     }
127 
128     /**
129      * Returns title for the main frame.
130      * @return title for the main frame.
131      */
132     public String getTitle() {
133         return title;
134     }
135 
136     /**
137      * Returns true if the reload action is enabled, false otherwise.
138      * @return true if the reload action is enabled.
139      */
140     public boolean isReloadActionEnabled() {
141         return reloadActionEnabled;
142     }
143 
144     /**
145      * Whether a file chooser should accept the file as a source file.
146      * @param file the file to check.
147      * @return true if the file should be accepted.
148      */
149     public static boolean shouldAcceptFile(File file) {
150         return file.isDirectory() || file.getName().endsWith(".java");
151     }
152 
153     /**
154      * Get the directory of the last loaded file.
155      * @return directory of the last loaded file.
156      */
157     public File getLastDirectory() {
158         File lastDirectory = null;
159         if (currentFile != null) {
160             lastDirectory = new File(currentFile.getParent());
161         }
162         return lastDirectory;
163     }
164 
165     /**
166      * Get current file.
167      * @return current file.
168      */
169     public File getCurrentFile() {
170         return currentFile;
171     }
172 
173     /**
174      * Get lines to position map.
175      * It returns unmodifiable collection to
176      * prevent additional overhead of copying
177      * and possible state modifications.
178      * @return lines to position map.
179      * @noinspection ReturnOfCollectionOrArrayField
180      */
181     public ImmutableList<Integer> getLinesToPosition() {
182         return linesToPosition;
183     }
184 
185     /**
186      * Open file and load the file.
187      * @param file the file to open.
188      * @throws CheckstyleException if the file can not be parsed.
189      */
190     public void openFile(File file) throws CheckstyleException {
191         if (file != null) {
192             try {
193                 currentFile = file;
194                 title = "Checkstyle GUI : " + file.getName();
195                 reloadActionEnabled = true;
196                 final DetailAST parseTree;
197 
198                 switch (parseMode) {
199                     case PLAIN_JAVA:
200                         parseTree = JavaParser.parseFile(file, JavaParser.Options.WITHOUT_COMMENTS);
201                         break;
202                     case JAVA_WITH_COMMENTS:
203                     case JAVA_WITH_JAVADOC_AND_COMMENTS:
204                         parseTree = JavaParser.parseFile(file, JavaParser.Options.WITH_COMMENTS);
205                         break;
206                     default:
207                         throw new IllegalArgumentException("Unknown mode: " + parseMode);
208                 }
209 
210                 parseTreeTableModel.setParseTree(parseTree);
211                 parseTreeTableModel.setParseMode(parseMode);
212                 final String[] sourceLines = getFileText(file).toLinesArray();
213 
214                 final List<Integer> linesToPositionTemp = new ArrayList<>();
215                 // starts line counting at 1
216                 linesToPositionTemp.add(0);
217 
218                 final StringBuilder sb = new StringBuilder(1024);
219                 // insert the contents of the file to the text area
220                 for (final String element : sourceLines) {
221                     linesToPositionTemp.add(sb.length());
222                     sb.append(element).append(System.lineSeparator());
223                 }
224                 linesToPosition = ImmutableList.copyOf(linesToPositionTemp);
225                 text = sb.toString();
226             }
227             catch (IOException ex) {
228                 final String exceptionMsg = String.format(Locale.ROOT,
229                     "%s occurred while opening file %s.",
230                     ex.getClass().getSimpleName(), file.getPath());
231                 throw new CheckstyleException(exceptionMsg, ex);
232             }
233         }
234     }
235 
236     /**
237      * Get FileText from a file.
238      * @param file the file to get the FileText from.
239      * @return the FileText.
240      * @throws IOException if the file could not be read.
241      */
242     private static FileText getFileText(File file) throws IOException {
243         return new FileText(file.getAbsoluteFile(),
244                 System.getProperty("file.encoding", StandardCharsets.UTF_8.name()));
245     }
246 
247 }