]> WPIA git - gigi.git/blob - util-testing/club/wpia/gigi/localisation/TranslationCollector.java
chg: remove csr_name and crt_name columns from certs
[gigi.git] / util-testing / club / wpia / gigi / localisation / TranslationCollector.java
1 package club.wpia.gigi.localisation;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileNotFoundException;
6 import java.io.IOException;
7 import java.io.InputStreamReader;
8 import java.io.PrintWriter;
9 import java.io.UnsupportedEncodingException;
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.LinkedList;
15 import java.util.List;
16 import java.util.Properties;
17 import java.util.TreeSet;
18
19 import org.eclipse.jdt.core.compiler.CategorizedProblem;
20 import org.eclipse.jdt.internal.compiler.ASTVisitor;
21 import org.eclipse.jdt.internal.compiler.CompilationResult;
22 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
23 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
24 import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
25 import org.eclipse.jdt.internal.compiler.batch.FileSystem;
26 import org.eclipse.jdt.internal.compiler.batch.Main;
27 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
28 import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
29 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
30 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
31 import org.eclipse.jdt.internal.compiler.env.ISourceType;
32 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
33 import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
34 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
35 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
36 import org.eclipse.jdt.internal.compiler.parser.Parser;
37 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
38
39 import club.wpia.gigi.database.DatabaseConnection;
40 import club.wpia.gigi.output.template.Template;
41
42 public class TranslationCollector {
43
44     static class TranslationEntry implements Comparable<TranslationEntry> {
45
46         String text;
47
48         String occur1;
49
50         List<String> occur;
51
52         public TranslationEntry(String text, String occur) {
53             this.text = text;
54             occur1 = occur;
55         }
56
57         public List<String> getOccur() {
58             if (occur == null) {
59                 return Arrays.asList(occur1);
60             }
61             return occur;
62         }
63
64         public void add(String t) {
65             if (occur == null) {
66                 occur = new ArrayList<>(Arrays.asList(occur1));
67             }
68             occur.add(t);
69         }
70
71         @Override
72         public int compareTo(TranslationEntry o) {
73             int i = occur1.compareTo(o.occur1);
74             if (i != 0) {
75                 return i;
76             }
77
78             return text.compareTo(o.text);
79         }
80     }
81
82     private HashMap<String, TranslationEntry> translations = new HashMap<>();
83
84     public final File base;
85
86     private boolean hadErrors = false;
87
88     private int statements = 0;
89
90     public TranslationCollector(File base, File conf) {
91         this.base = base;
92         taint = new LinkedList<>();
93         for (String s : new FileIterable(conf)) {
94             taint.add(TaintSource.parseTaint(s));
95         }
96     }
97
98     interface ASTVisitorFactory {
99
100         public ASTVisitor createVisitor(CompilationUnitDeclaration parsedUnit);
101     }
102
103     public void run(File out) throws IOException {
104         scanTemplates();
105         scanCode(new ASTVisitorFactory() {
106
107             @Override
108             public ASTVisitor createVisitor(CompilationUnitDeclaration parsedUnit) {
109                 return new TranslationCollectingVisitor(parsedUnit, taint.toArray(new TaintSource[taint.size()]), TranslationCollector.this);
110             }
111         });
112
113         System.err.println("Total Translatable Strings: " + translations.size());
114         TreeSet<TranslationEntry> trs = new TreeSet<>(translations.values());
115         writePOFile(out, trs);
116     }
117
118     public void runSQLValidation() throws IOException {
119         scanCode(new ASTVisitorFactory() {
120
121             @Override
122             public ASTVisitor createVisitor(CompilationUnitDeclaration parsedUnit) {
123                 return new SQLTestingVisitor(parsedUnit, TranslationCollector.this);
124             }
125         });
126         System.out.println("Validated: " + statements + " SQL statements.");
127     }
128
129     public void add(String text, String line) {
130         if (text.contains("\r") || text.contains("\n")) {
131             throw new Error("Malformed translation in " + line);
132         }
133         TranslationEntry i = translations.get(text);
134         if (i == null) {
135             translations.put(text, new TranslationEntry(text, line));
136             return;
137         }
138         i.add(line);
139     }
140
141     private void scanCode(ASTVisitorFactory visitor) throws Error {
142         PrintWriter out = new PrintWriter(System.err);
143         Main m = new Main(out, out, false, null, null);
144         File[] fs = recurse(new File(new File(new File(base, "src"), "club"), "wpia"), new LinkedList<File>(), ".java").toArray(new File[0]);
145         String[] t = new String[fs.length + 3];
146         t[0] = "-cp";
147         t[1] = new File(base, "bin").getAbsolutePath();
148         t[2] = "-7";
149         for (int i = 0; i < fs.length; i++) {
150             t[i + 3] = fs[i].getAbsolutePath();
151         }
152         m.configure(t);
153         FileSystem environment = m.getLibraryAccess();
154         CompilerOptions compilerOptions = new CompilerOptions(m.options);
155         compilerOptions.performMethodsFullRecovery = false;
156         compilerOptions.performStatementsRecovery = false;
157         // check
158         compilerOptions.sourceLevel = ClassFileConstants.JDK1_7;
159         compilerOptions.complianceLevel = ClassFileConstants.JDK1_7;
160         compilerOptions.originalComplianceLevel = ClassFileConstants.JDK1_7;
161
162         ProblemReporter pr = new ProblemReporter(m.getHandlingPolicy(), compilerOptions, m.getProblemFactory());
163         ITypeRequestor tr = new ITypeRequestor() {
164
165             @Override
166             public void accept(ISourceType[] sourceType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
167                 throw new IllegalStateException("source type not implemented");
168             }
169
170             @Override
171             public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
172                 le.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
173             }
174
175             @Override
176             public void accept(ICompilationUnit unit, AccessRestriction accessRestriction) {
177                 throw new IllegalStateException("compilation unit not implemented");
178             }
179         };
180         le = new LookupEnvironment(tr, compilerOptions, pr, environment);
181         Parser parser = new Parser(pr, compilerOptions.parseLiteralExpressionsAsConstants);
182         CompilationUnit[] sourceUnits = m.getCompilationUnits();
183         CompilationUnitDeclaration[] parsedUnits = new CompilationUnitDeclaration[sourceUnits.length];
184         for (int i = 0; i < parsedUnits.length; i++) {
185
186             CompilationResult unitResult = new CompilationResult(sourceUnits[i], i, parsedUnits.length, compilerOptions.maxProblemsPerUnit);
187             CompilationUnitDeclaration parsedUnit = parser.parse(sourceUnits[i], unitResult);
188             le.buildTypeBindings(parsedUnit, null /* no access restriction */);
189             parsedUnits[i] = parsedUnit;
190         }
191         le.completeTypeBindings();
192         for (int i = 0; i < parsedUnits.length; i++) {
193             CompilationUnitDeclaration parsedUnit = parsedUnits[i];
194
195             parser.getMethodBodies(parsedUnit);
196             parsedUnit.scope.faultInTypes();
197             parsedUnit.scope.verifyMethods(le.methodVerifier());
198             parsedUnit.resolve();
199         }
200         for (int i = 0; i < parsedUnits.length; i++) {
201             CompilationUnitDeclaration parsedUnit = parsedUnits[i];
202             if (parsedUnit.compilationResult.problems != null) {
203                 int err = 0;
204                 for (int c = 0; c < parsedUnit.compilationResult.problemCount; c++) {
205                     CategorizedProblem problem = parsedUnit.compilationResult.problems[c];
206                     if (problem.isError()) {
207                         err++;
208                     }
209                     if (OUTPUT_WARNINGS || problem.isError()) {
210                         System.err.println(problem);
211                         StringBuilder prob = new StringBuilder();
212                         prob.append(parsedUnit.compilationResult.fileName);
213                         prob.append(":");
214                         prob.append(problem.getSourceLineNumber());
215                         System.err.println(prob.toString());
216                     }
217                 }
218                 if (err > 0) {
219                     throw new Error();
220                 }
221             }
222             // Skip Database connection as some statements need to be run on older DB scheme version.
223             if(new String(parsedUnit.getFileName()).endsWith("/src/club/wpia/gigi/database/DatabaseConnection.java")) {
224                 continue;
225             }
226             if (parsedUnit.types == null) {
227                 System.err.println("No types");
228
229             } else {
230                 ASTVisitor v = visitor.createVisitor(parsedUnit);
231                 for (TypeDeclaration td : parsedUnit.types) {
232                     td.traverse(v, td.scope);
233                 }
234             }
235             parsedUnits[i] = parsedUnit;
236         }
237     }
238
239     private void scanTemplates() throws UnsupportedEncodingException, FileNotFoundException {
240         File[] ts = recurse(new File(new File(new File(base, "src"), "club"), "wpia"), new LinkedList<File>(), ".templ").toArray(new File[0]);
241         for (File file : ts) {
242             Template t = new Template(new InputStreamReader(new FileInputStream(file), "UTF-8"));
243             LinkedList<String> i = new LinkedList<String>();
244             t.addTranslations(i);
245             for (String string : i) {
246                 add(string, file.getAbsolutePath().substring(base.getAbsolutePath().length() + 1) + ":1");
247             }
248         }
249     }
250
251     static LookupEnvironment le;
252
253     private static final boolean OUTPUT_WARNINGS = false;
254
255     private LinkedList<TaintSource> taint;
256
257     public static void main(String[] args) throws IOException {
258         Properties pp = new Properties();
259         pp.load(new InputStreamReader(new FileInputStream("config/test.properties"), "UTF-8"));
260         DatabaseConnection.init(pp);
261         TranslationCollector tc = new TranslationCollector(new File(args[1]), new File(args[0]));
262         if (args[2].equals("SQLValidation")) {
263             tc.runSQLValidation();
264         } else {
265             tc.run(new File(args[2]));
266         }
267         if (tc.hadErrors) {
268             System.exit(1);
269         } else {
270             System.exit(0);
271         }
272     }
273
274     public static void writePOFile(File target, Collection<TranslationEntry> strings) throws IOException {
275         PrintWriter out = new PrintWriter(target);
276         for (TranslationEntry s : strings) {
277             out.print("#:");
278             for (String st : s.getOccur()) {
279                 out.print(" " + st);
280             }
281             out.println();
282             out.println("msgid \"" + s.text.replace("\\", "\\\\").replace("\"", "\\\"") + "\"");
283             out.println("msgstr \"\"");
284             out.println();
285         }
286         out.close();
287     }
288
289     private static List<File> recurse(File file, List<File> toAdd, String pt) {
290         if (file.isDirectory()) {
291             for (File f : file.listFiles()) {
292                 recurse(f, toAdd, pt);
293             }
294         } else {
295             if (file.getName().endsWith(pt)) {
296                 toAdd.add(file);
297             }
298         }
299         return toAdd;
300     }
301
302     public void hadError() {
303         hadErrors = true;
304     }
305
306     public void countStatement() {
307         statements++;
308     }
309 }