1ddc5943053db65efa25bc7fe8ca10a1153a13be
[javainspect.git] / src / main / java / eu / svjatoslav / inspector / java / methods / JavaFile.java
1 /*
2  * JavaInspect - Utility to visualize java software
3  * Copyright (C) 2013-2018, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of version 3 of the GNU Lesser General Public License
7  * or later as published by the Free Software Foundation.
8  */
9
10 package eu.svjatoslav.inspector.java.methods;
11
12 import eu.svjatoslav.commons.string.tokenizer.InvalidSyntaxException;
13 import eu.svjatoslav.commons.string.tokenizer.Tokenizer;
14 import eu.svjatoslav.commons.string.tokenizer.TokenizerMatch;
15
16 import java.io.*;
17 import java.util.ArrayList;
18 import java.util.List;
19
20 import static eu.svjatoslav.commons.string.tokenizer.Terminator.TerminationStrategy.DROP;
21 import static eu.svjatoslav.commons.string.tokenizer.Terminator.TerminationStrategy.PRESERVE;
22
23 public class JavaFile {
24
25     public static final String UTF_8 = "UTF-8";
26     public final List<Clazz> classes = new ArrayList<>();
27     final StringBuffer contents = new StringBuffer();
28     private final List<Import> imports = new ArrayList<>();
29     private final File file;
30     private String packageName;
31
32     public JavaFile(final File file) throws IOException, InvalidSyntaxException {
33         this.file = file;
34         parse();
35     }
36
37     public void parse() throws IOException, InvalidSyntaxException {
38         System.out.println("java file: " + file);
39
40         readFile();
41
42         final Tokenizer tokenizer = new Tokenizer(contents.toString());
43
44         // empty space
45         tokenizer.addTerminator(" ", DROP);
46         tokenizer.addTerminator("\t", DROP);
47         tokenizer.addTerminator("\n", DROP);
48
49         tokenizer.addTerminator(";", PRESERVE);
50         tokenizer.addTerminator("{", PRESERVE);
51         tokenizer.addTerminator("}", PRESERVE);
52         tokenizer.addTerminator("(", PRESERVE);
53         tokenizer.addTerminator(")", PRESERVE);
54         tokenizer.addTerminator("[", PRESERVE);
55         tokenizer.addTerminator("]", PRESERVE);
56         tokenizer.addTerminator("<", PRESERVE);
57         tokenizer.addTerminator(">", PRESERVE);
58         tokenizer.addTerminator(",", PRESERVE);
59         tokenizer.addTerminator("@", PRESERVE);
60
61         // comments
62         tokenizer.addTerminator("//", "\n", DROP);
63         tokenizer.addTerminator("/*", "*/", DROP);
64
65         final Modifiers modifiers = new Modifiers();
66
67         while (true) {
68             final TokenizerMatch match = tokenizer.getNextToken();
69             if (match == null)
70                 break;
71
72             if (match.token.equals("package")) {
73                 parsePackage(tokenizer);
74                 continue;
75             }
76
77             if (match.token.equals("import")) {
78                 parseImport(tokenizer);
79                 continue;
80             }
81
82             final boolean wasModifier = modifiers.parseModifier(match.token);
83             if (wasModifier)
84                 continue;
85
86             if ("class".equals(match.token)) {
87                 parseClass(tokenizer);
88                 continue;
89             }
90
91             if ("interface".equals(match.token)) {
92                 parseInterface(tokenizer);
93                 continue;
94             }
95
96             if ("@".equals(match.token)) {
97                 new Annotation(tokenizer);
98                 continue;
99             }
100
101             System.out.println("    " + modifiers.toString() + " "
102                     + match.token);
103             modifiers.reset();
104             skipUntilSemicolon(tokenizer);
105         }
106
107     }
108
109     private void parseClass(final Tokenizer tokenizer)
110             throws InvalidSyntaxException {
111
112         final TokenizerMatch match = tokenizer.getNextToken();
113         final Clazz clazz = new Clazz(packageName, match.token, tokenizer,
114                 false);
115         // System.out.println(clazz.toString());
116         classes.add(clazz);
117
118     }
119
120     private void parseImport(final Tokenizer tokenizer)
121             throws InvalidSyntaxException {
122
123         final Import imp = new Import();
124
125         final TokenizerMatch match = tokenizer.getNextToken();
126
127         if (match.token.equals("static")) {
128             imp.isStatic = true;
129             imp.path = tokenizer.getNextToken().token;
130         } else
131             imp.path = match.token;
132
133         imports.add(imp);
134
135         tokenizer.expectAndConsumeNextToken(";");
136     }
137
138     private void parseInterface(final Tokenizer tokenizer)
139             throws InvalidSyntaxException {
140
141         final TokenizerMatch match = tokenizer.getNextToken();
142         final Clazz clazz = new Clazz(packageName, match.token, tokenizer, true);
143         // System.out.println(clazz.toString());
144         classes.add(clazz);
145     }
146
147     private void parsePackage(final Tokenizer tokenizer)
148             throws InvalidSyntaxException {
149
150         final TokenizerMatch match = tokenizer.getNextToken();
151
152         packageName = match.token;
153
154         tokenizer.expectAndConsumeNextToken(";");
155     }
156
157     private void readFile() throws IOException {
158         InputStreamReader inputStream = new InputStreamReader(new FileInputStream(file), UTF_8);
159
160         final BufferedReader bufferedReader = new BufferedReader(inputStream);
161
162         while (true) {
163             final String line = bufferedReader.readLine();
164
165             if (line == null)
166                 break;
167
168             contents.append(line);
169             contents.append("\n");
170         }
171
172         bufferedReader.close();
173         inputStream.close();
174     }
175
176     public void skipUntilSemicolon(final Tokenizer tokenizer) throws InvalidSyntaxException {
177         while (true) {
178             final TokenizerMatch token = tokenizer.getNextToken();
179
180             if (token == null)
181                 return;
182
183             if (token.token.equals(";"))
184                 return;
185         }
186     }
187
188 }