| 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 | } |