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