1 | // |
2 | // (c) Copyright, Moebius Solutions, 2002 |
3 | // |
4 | // All Rights Reserved |
5 | // |
6 | // This material may be reproduced by or for the U. S. Government |
7 | // pursuant to the copyright license under the clause at |
8 | // DFARS 252.227-7013 (OCT 1988). |
9 | // |
10 | /* |
11 | * $Id: Generator.java,v 1.2 2004/12/06 22:36:08 hastings Exp $ |
12 | */ |
13 | package com.moesol.generator; |
14 | |
15 | import java.lang.reflect.*; |
16 | import com.moesol.generator.core.*; |
17 | import com.moesol.generator.visitor.*; |
18 | |
19 | public class Generator { |
20 | // singleton |
21 | private static Generator instance = new Generator(); |
22 | private Generator() { |
23 | } |
24 | public static Generator getInstance() { |
25 | return instance; |
26 | } |
27 | |
28 | static void usage() { |
29 | System.out.println("usage: "+ Generator.class.getName() +" [options] -m <map_path> class ..."); |
30 | System.out.println(" -m <map_math> Sets the translation map."); |
31 | System.out.println(" -d <dest_dir> Sets the directory for C++ proxy header files."); |
32 | System.out.println(" -j <jni_dir> Sets the directory for jni output files."); |
33 | System.out.println(" -jh <h_dir> Sets the directory for jni header output files."); |
34 | System.out.println(" -t <test_dir> Sets the directory for test output files."); |
35 | System.out.println(" -k Keep going after an error."); |
36 | System.out.println(" -q Quieter output."); |
37 | System.out.println(" -tf <name> Trace finds for name."); |
38 | System.out.println(" -skip Skip missing translations."); |
39 | System.out.println(" -prefix <pre> Overrides the default search prefix.h"); |
40 | System.out.println(" -suffix <suf> Overrides the default file output name suffix."); |
41 | System.out.println(" -list List methods in properties style."); |
42 | System.out.println(" -public Show public fields and methods (default)."); |
43 | System.out.println(" -protected Also include protected fields and methods."); |
44 | System.out.println(" -package Also include package private fields and methods."); |
45 | System.out.println(" -private Also include private fields and methods."); |
46 | System.out.println(" -no-native Suppress native methods."); |
47 | System.out.println(" -no-values Suppress field.value property."); |
48 | System.out.println(" -no-sync Suppress the synchronized modifier."); |
49 | System.exit(2); |
50 | } |
51 | public static void main(String args[]) { |
52 | Generator g = Generator.getInstance(); |
53 | |
54 | if (0 == args.length) { |
55 | usage(); |
56 | } |
57 | for (int i = 0; i < args.length; i++) { |
58 | if (args[i].equals("-m")) { |
59 | i++; |
60 | g.setTranslationContext(getArgOrFail(args, i)); |
61 | } else if (args[i].equals("-d")) { |
62 | i++; |
63 | g.setOutputDir(getArgOrFail(args, i)); |
64 | } else if (args[i].equals("-j")) { |
65 | i++; |
66 | g.setJniDir(getArgOrFail(args, i)); |
67 | } else if (args[i].equals("-jh")) { |
68 | i++; |
69 | g.setJniHeaderDir(getArgOrFail(args, i)); |
70 | } else if (args[i].equals("-t")) { |
71 | i++; |
72 | g.setTestDir(getArgOrFail(args, i)); |
73 | } else if (args[i].equals("-k")) { |
74 | keep_going = true; |
75 | } else if (args[i].equals("-q")) { |
76 | quiet = true; |
77 | } else if (args[i].equals("-list")) { |
78 | print_list = true; |
79 | } else if (args[i].equals("-tf")) { |
80 | i++; |
81 | g.setTraceFinds(getArgOrFail(args, i)); |
82 | } else if (args[i].equals("-skip")) { |
83 | g.setSkipOnMissingTranslation(true); |
84 | } else if (args[i].equals("-prefix")) { |
85 | i++; |
86 | g.setPrefixOverride(getArgOrFail(args, i)); |
87 | } else if (args[i].equals("-suffix")) { |
88 | i++; |
89 | g.setSuffixOverride(getArgOrFail(args, i)); |
90 | } else if (args[i].equals("-public")) { |
91 | // nothing to do |
92 | } else if (args[i].equals("-protected")) { |
93 | g.setGenProtected(true); |
94 | } else if (args[i].equals("-package")) { |
95 | g.setGenPackage(true); |
96 | } else if (args[i].equals("-private")) { |
97 | g.setGenPrivate(true); |
98 | } else if (args[i].equals("-no-native")) { |
99 | g.setNoNative(true); |
100 | } else if (args[i].equals("-no-values")) { |
101 | g.setNoValues(true); |
102 | } else if (args[i].equals("-no-sync")) { |
103 | g.setNoSync(true); |
104 | } else { |
105 | if (g.m_trans_ctx == null && !print_list) { |
106 | usage(); |
107 | } |
108 | g.processClass(args[i]); |
109 | } |
110 | } |
111 | // Jmv has a UI thread that prevents exit |
112 | System.exit(0); |
113 | } |
114 | private static String getArgOrFail(String args[], int i) { |
115 | if (i >= args.length) { |
116 | usage(); |
117 | } |
118 | return args[i]; |
119 | } |
120 | void setTranslationContext(String file) { |
121 | try { |
122 | m_trans_ctx = new TranslationContext(file); |
123 | } catch (Exception e) { |
124 | System.err.println(e.getMessage()); |
125 | System.exit(1); |
126 | } |
127 | } |
128 | void setOutputDir(String dir) { |
129 | m_dir = dir; |
130 | } |
131 | void setJniDir(String dir) { |
132 | m_jni = dir; |
133 | } |
134 | void setJniHeaderDir(String dir) { |
135 | m_jni_h = dir; |
136 | } |
137 | void setTestDir(String dir) { |
138 | m_test = dir; |
139 | } |
140 | void setTraceFinds(String name) { |
141 | m_trace_finds = name; |
142 | } |
143 | void setSkipOnMissingTranslation(boolean skip) { |
144 | m_skip_on_missing_translation = skip; |
145 | } |
146 | void setPrefixOverride(String prefix_override) { |
147 | m_prefix_override = prefix_override; |
148 | } |
149 | void setSuffixOverride(String suffix_override) { |
150 | m_suffix_override = suffix_override; |
151 | } |
152 | public void setGenProtected(boolean v) { |
153 | m_gen_protected = v; |
154 | } |
155 | public void setGenPackage(boolean v) { |
156 | m_gen_package = v; |
157 | } |
158 | public void setGenPrivate(boolean v) { |
159 | m_gen_private = v; |
160 | } |
161 | public void setNoNative(boolean v) { |
162 | m_no_native = v; |
163 | } |
164 | public void setNoValues(boolean v) { |
165 | m_no_values = v; |
166 | } |
167 | private void setNoSync(boolean v) { |
168 | m_no_sync = v; |
169 | } |
170 | void processClass(String className) { |
171 | try { |
172 | Class c = Class.forName(className, false, this.getClass().getClassLoader()); |
173 | processClass(c); |
174 | } catch (ApplyException e) { |
175 | printApplyException(e); |
176 | if (!keep_going) { |
177 | System.exit(1); |
178 | } |
179 | } catch (Throwable t) { |
180 | System.err.println("<" + className + ">" + t.getMessage()); |
181 | t.printStackTrace(); |
182 | if (!keep_going) { |
183 | System.exit(1); |
184 | } |
185 | } |
186 | } |
187 | void processClass(Class c) throws ApplyException { |
188 | if (print_list) { |
189 | printList(c); |
190 | return; |
191 | } |
192 | |
193 | // TODO make context and generate the same class, see tlb2java. |
194 | m_trans_ctx.setTraceFinds(m_trace_finds); |
195 | m_trans_ctx.setSkipOnMissingTranslation(m_skip_on_missing_translation); |
196 | m_trans_ctx.setPrefix(m_prefix_override); |
197 | m_trans_ctx.setSuffix(m_suffix_override); |
198 | m_trans_ctx.setGenProtected(m_gen_protected); |
199 | m_trans_ctx.setGenPackage(m_gen_package); |
200 | m_trans_ctx.setGenPrivate(m_gen_private); |
201 | m_trans_ctx.setNoNative(m_no_native); |
202 | m_trans_ctx.setNoValues(m_no_values); |
203 | m_trans_ctx.setNoSync(m_no_sync); |
204 | if (m_dir != null) { |
205 | new JavaClassGenerator(c, quiet, m_trans_ctx).generate(m_dir); |
206 | } |
207 | if (m_jni != null) { |
208 | new JniClassGenerator(c, quiet, m_trans_ctx).generate(m_jni); |
209 | } |
210 | if (m_jni_h != null) { |
211 | new JniHeaderClassGenerator(c, quiet, m_trans_ctx).generate(m_jni_h); |
212 | } |
213 | if (m_test != null) { |
214 | new TestClassGenerator(c, quiet, m_trans_ctx).generate(m_test); |
215 | } |
216 | } |
217 | /** |
218 | * Called when -list is specified. |
219 | */ |
220 | private void printList(Class c) throws ApplyException { |
221 | if (!Modifier.isPublic(c.getModifiers())) { |
222 | if (!quiet) { |
223 | System.out.println("skipping non-public: " + c.getName()); |
224 | } |
225 | return; |
226 | } |
227 | |
228 | ReflectVisitor v = new ReflectVisitor() { |
229 | public void visitField(Class c, Field f) { } |
230 | public void visitMethod(Class c, Method m) { |
231 | if (c.isInterface()) { |
232 | return; |
233 | } |
234 | if (Modifier.isPublic(m.getModifiers())) { |
235 | System.out.print("jni.translation."); |
236 | System.out.print(ClassGenerator.stripPackageName(c.getName())); |
237 | System.out.print('.'); |
238 | System.out.print(m.getName()); |
239 | System.out.print("("); |
240 | Class p[] = m.getParameterTypes(); |
241 | if (p.length > 0) { |
242 | System.out.print(p[0].getName()); |
243 | } |
244 | for (int i = 1; i < p.length; i++) { |
245 | System.out.print(","); |
246 | System.out.print(p[i].getName()); |
247 | } |
248 | System.out.print("): // returns "); |
249 | System.out.print(m.getReturnType().getName()); |
250 | System.out.println(); |
251 | } |
252 | } |
253 | public void visitConstructor(Class c, Constructor ctor) { } |
254 | }; |
255 | VisitClass.visitReflect(c, v); |
256 | } |
257 | private void printApplyException(ApplyException e) { |
258 | System.err.println(e.getMessage()); |
259 | System.err.println(); |
260 | e.printStackTrace(); |
261 | if (e.getRootCause() != null) { |
262 | System.err.print("root: "); |
263 | System.err.println(e.getRootCause().getMessage()); |
264 | e.getRootCause().printStackTrace(); |
265 | } |
266 | } |
267 | |
268 | private TranslationContext m_trans_ctx = null; // TODO use a bean context to share with sub components? |
269 | private String m_dir = null; |
270 | private String m_jni = null; |
271 | private String m_jni_h = null; |
272 | private String m_test = null; |
273 | private String m_trace_finds = null; |
274 | private boolean m_skip_on_missing_translation = false; |
275 | private String m_prefix_override = null; |
276 | private String m_suffix_override = null; |
277 | private boolean m_gen_protected = false; |
278 | private boolean m_gen_package = false; |
279 | private boolean m_gen_private = false; |
280 | private boolean m_no_native = false; // Generate native methods by default |
281 | private boolean m_no_values = false; // Generate values by default |
282 | private boolean m_no_sync; // Suppress synchronized in modifiers |
283 | private static boolean keep_going = false; |
284 | private static boolean quiet = false; |
285 | private static boolean print_list = false; |
286 | } |