1 | import javax.imageio.*; |
2 | import java.awt.image.*; |
3 | import java.awt.event.*; |
4 | import java.awt.*; |
5 | import java.security.spec.*; |
6 | import java.security.*; |
7 | import java.lang.management.*; |
8 | import java.lang.ref.*; |
9 | import java.lang.reflect.*; |
10 | import java.net.*; |
11 | import java.io.*; |
12 | import javax.swing.table.*; |
13 | import javax.swing.text.*; |
14 | import javax.swing.event.*; |
15 | import javax.swing.*; |
16 | import java.util.concurrent.atomic.*; |
17 | import java.util.concurrent.*; |
18 | import java.util.regex.*; |
19 | import java.util.List; |
20 | import java.util.zip.*; |
21 | import java.util.*; |
22 | |
23 | |
24 | public class main { |
25 | public static void main(String[] args) throws Exception { |
26 | addToMultiPortSilent("Get Selected Table Line Helper Bot."); |
27 | } |
28 | |
29 | static String answer(String s) { |
30 | if (match3("get selected table line", s)) { |
31 | Component focus = getFocusOwner(); |
32 | if (!(focus instanceof JTable)) return "no table"; |
33 | JTable tbl = (JTable) ( focus); |
34 | return structure(getSelectedLine(tbl)); |
35 | } |
36 | |
37 | if (match3("get selected table line as map", s)) { |
38 | Component focus = getFocusOwner(); |
39 | if (!(focus instanceof JTable)) return "no table"; |
40 | JTable tbl = (JTable) ( focus); |
41 | return structure(getSelectedLineAsMap(tbl)); |
42 | } |
43 | |
44 | return null; |
45 | } |
46 | |
47 | static Map<String, String> getSelectedLineAsMap(JTable tbl) { |
48 | int row = tbl.getSelectedRow(); |
49 | if (row >= 0 && row < tbl.getModel().getRowCount()) { |
50 | Map<String, String> map = new TreeMap<String, String>(); |
51 | for (int i = 0; i < tbl.getModel().getColumnCount(); i++) |
52 | map.put(tbl.getModel().getColumnName(i), |
53 | String.valueOf(tbl.getModel().getValueAt(row, i))); |
54 | return map; |
55 | } |
56 | return null; |
57 | } |
58 | |
59 | static List<String> getSelectedLine(JTable tbl) { |
60 | int row = tbl.getSelectedRow(); |
61 | if (row >= 0 && row < tbl.getModel().getRowCount()) { |
62 | List<String> l = new ArrayList<String>(); |
63 | for (int i = 0; i < tbl.getModel().getColumnCount(); i++) |
64 | l.add(String.valueOf(tbl.getModel().getValueAt(row, i))); |
65 | return l; |
66 | } |
67 | return null; |
68 | } |
69 | |
70 | static Component getFocusOwner() { |
71 | return KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); |
72 | } |
73 | |
74 | static long addToMultiPortSilent(String botName) { |
75 | return addToMultiPort(botName); |
76 | } |
77 | static class Matches { |
78 | String[] m; |
79 | String get(int i) { return m[i]; } |
80 | String unq(int i) { return unquote(m[i]); } |
81 | String fsi(int i) { return formatSnippetID(unq(i)); } |
82 | boolean bool(int i) { return "true".equals(unq(i)); } |
83 | String rest() { return m[m.length-1]; } // for matchStart |
84 | } |
85 | // class Matches |
86 | |
87 | static boolean match3(String pat, String s) { |
88 | return match3(pat, s, null); |
89 | } |
90 | |
91 | static boolean match3(String pat, String s, Matches matches) { |
92 | if (s == null) return false; |
93 | List<String> tokpat = parse3(pat), toks = parse3(s); |
94 | String[] m = match2(tokpat, toks); |
95 | //print(structure(tokpat) + " on " + structure(toks) + " => " + structure(m)); |
96 | if (m == null) |
97 | return false; |
98 | else { |
99 | if (matches != null) matches.m = m; |
100 | return true; |
101 | } |
102 | } |
103 | |
104 | static String structure(Object o) { |
105 | return structure(o, 0); |
106 | } |
107 | |
108 | // leave to false, unless unstructure() breaks |
109 | static boolean structure_allowShortening = false; |
110 | |
111 | static String structure(Object o, int stringSizeLimit) { |
112 | if (o == null) return "null"; |
113 | String name = o.getClass().getName(); |
114 | |
115 | StringBuilder buf = new StringBuilder(); |
116 | |
117 | if (o instanceof Collection) { // TODO: store the type (e.g. HashSet/TreeSet) |
118 | for (Object x : (Collection) o) { |
119 | if (buf.length() != 0) buf.append(", "); |
120 | buf.append(structure(x, stringSizeLimit)); |
121 | } |
122 | return "[" + buf + "]"; |
123 | } |
124 | |
125 | if (o instanceof Map) { |
126 | for (Object e : ((Map) o).entrySet()) { |
127 | if (buf.length() != 0) buf.append(", "); |
128 | buf.append(structure(((Map.Entry) e).getKey(), stringSizeLimit)); |
129 | buf.append("="); |
130 | buf.append(structure(((Map.Entry) e).getValue(), stringSizeLimit)); |
131 | } |
132 | return "{" + buf + "}"; |
133 | } |
134 | |
135 | if (o.getClass().isArray()) { |
136 | int n = Array.getLength(o); |
137 | for (int i = 0; i < n; i++) { |
138 | if (buf.length() != 0) buf.append(", "); |
139 | buf.append(structure(Array.get(o, i), stringSizeLimit)); |
140 | } |
141 | return "array{" + buf + "}"; |
142 | } |
143 | |
144 | if (o instanceof String) |
145 | return quote(stringSizeLimit != 0 ? shorten((String) o, stringSizeLimit) : (String) o); |
146 | |
147 | if (o instanceof Class) |
148 | return "class(" + quote(((Class) o).getName()) + ")"; |
149 | |
150 | if (o instanceof Throwable) |
151 | return "exception(" + quote(((Throwable) o).getMessage()) + ")"; |
152 | |
153 | // Need more cases? This should cover all library classes... |
154 | if (name.startsWith("java.") || name.startsWith("javax.")) |
155 | return String.valueOf(o); |
156 | |
157 | String shortName = o.getClass().getName().replaceAll("^main\\$", ""); |
158 | |
159 | int numFields = 0; |
160 | String fieldName = ""; |
161 | if (shortName.equals("DynamicObject")) { |
162 | shortName = (String) get(o, "className"); |
163 | Map<String, Object> fieldValues = (Map) get(o, "fieldValues"); |
164 | |
165 | for (String _fieldName : fieldValues.keySet()) { |
166 | fieldName = _fieldName; |
167 | Object value = fieldValues.get(fieldName); |
168 | if (value != null) { |
169 | if (buf.length() != 0) buf.append(", "); |
170 | buf.append(fieldName + "=" + structure(value, stringSizeLimit)); |
171 | } |
172 | ++numFields; |
173 | } |
174 | } else { |
175 | // regular class |
176 | // TODO: go to superclasses too |
177 | Field[] fields = o.getClass().getDeclaredFields(); |
178 | for (Field field : fields) { |
179 | if ((field.getModifiers() & Modifier.STATIC) != 0) |
180 | continue; |
181 | Object value; |
182 | try { |
183 | field.setAccessible(true); |
184 | value = field.get(o); |
185 | } catch (Exception e) { |
186 | value = "?"; |
187 | } |
188 | |
189 | fieldName = field.getName(); |
190 | |
191 | // put special cases here... |
192 | |
193 | if (value != null) { |
194 | if (buf.length() != 0) buf.append(", "); |
195 | buf.append(fieldName + "=" + structure(value, stringSizeLimit)); |
196 | } |
197 | ++numFields; |
198 | } |
199 | } |
200 | |
201 | String b = buf.toString(); |
202 | |
203 | if (numFields == 1 && structure_allowShortening) |
204 | b = b.replaceAll("^" + fieldName + "=", ""); // drop field name if only one |
205 | String s = shortName; |
206 | if (buf.length() != 0) |
207 | s += "(" + b + ")"; |
208 | return s; |
209 | } |
210 | |
211 | static Object addToMultiPort_responder; |
212 | |
213 | static long addToMultiPort(final String botName) { |
214 | return addToMultiPort(botName, new Object() { |
215 | public String answer(String s, List<String> history) { |
216 | String answer = (String) ( callOpt(getMainClass(), "answer", s, history)); |
217 | if (answer != null) return answer; |
218 | answer = (String) callOpt(getMainClass(), "answer", s); |
219 | if (answer != null) return answer; |
220 | if (match3("get injection id", s)) |
221 | return getInjectionID(); |
222 | return null; |
223 | } |
224 | }); |
225 | } |
226 | |
227 | static long addToMultiPort(final String botName, final Object responder) { |
228 | print(botName); |
229 | addToMultiPort_responder = responder; |
230 | startMultiPort(); |
231 | List ports = getMultiPorts(); |
232 | if (ports.isEmpty()) |
233 | fail("No multiports!"); |
234 | if (ports.size() > 1) |
235 | print("Multiple multi-ports. Using last one."); |
236 | Object port = last(ports); |
237 | return (Long) call(port, "addResponder", botName, new Object() { |
238 | public String answer(String s, List<String> history) { |
239 | if (match3("get injection id", s)) |
240 | return getInjectionID(); |
241 | if (match3("your name", s)) |
242 | return botName; |
243 | return (String) call(responder, "answer", s, history); |
244 | } |
245 | }); |
246 | } |
247 | |
248 | |
249 | static Class include(String progID) { |
250 | Class c = hotwire(progID); |
251 | setOpt(c, "programID", getProgramID()); |
252 | return c; |
253 | } |
254 | |
255 | |
256 | static int l(Object[] array) { |
257 | return array == null ? 0 : array.length; |
258 | } |
259 | |
260 | static int l(List list) { |
261 | return list == null ? 0 : list.size(); |
262 | } |
263 | |
264 | static int l(String s) { |
265 | return s == null ? 0 : s.length(); |
266 | } |
267 | |
268 | static String quote(String s) { |
269 | if (s == null) return "null"; |
270 | return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\r", "\\r").replace("\n", "\\n") + "\""; |
271 | } |
272 | |
273 | static String quote(long l) { |
274 | return quote("" + l); |
275 | } |
276 | |
277 | |
278 | static List<String> parse3(String s) { |
279 | return dropPunctuation(javaTokPlusPeriod(s)); |
280 | } |
281 | |
282 | // match2 matches multiple "*" (matches a single token) wildcards and zero or one "..." wildcards (matches multiple tokens) |
283 | |
284 | static String[] match2(List<String> pat, List<String> tok) { |
285 | // standard case (no ...) |
286 | int i = pat.indexOf("..."); |
287 | if (i < 0) return match2_match(pat, tok); |
288 | |
289 | pat = new ArrayList<String>(pat); // We're modifying it, so copy first |
290 | pat.set(i, "*"); |
291 | while (pat.size() < tok.size()) { |
292 | pat.add(i, "*"); |
293 | pat.add(i+1, ""); // doesn't matter |
294 | } |
295 | |
296 | return match2_match(pat, tok); |
297 | } |
298 | |
299 | static String[] match2_match(List<String> pat, List<String> tok) { |
300 | List<String> result = new ArrayList<String>(); |
301 | if (pat.size() != tok.size()) { |
302 | /*if (debug) |
303 | print("Size mismatch: " + structure(pat) + " vs " + structure(tok));*/ |
304 | return null; |
305 | } |
306 | for (int i = 1; i < pat.size(); i += 2) { |
307 | String p = pat.get(i), t = tok.get(i); |
308 | /*if (debug) |
309 | print("Checking " + p + " against " + t);*/ |
310 | if ("*".equals(p)) |
311 | result.add(t); |
312 | else if (!p.equalsIgnoreCase(t)) |
313 | return null; |
314 | } |
315 | return result.toArray(new String[result.size()]); |
316 | } |
317 | |
318 | |
319 | static Object get(Object o, String field) { |
320 | if (o instanceof Class) return get((Class) o, field); |
321 | |
322 | if (o.getClass().getName().equals("main$DynamicObject")) |
323 | return call(get_raw(o, "fieldValues"), "get", field); |
324 | |
325 | return get_raw(o, field); |
326 | } |
327 | |
328 | static Object get_raw(Object o, String field) { |
329 | try { |
330 | Field f = get_findField(o.getClass(), field); |
331 | f.setAccessible(true); |
332 | return f.get(o); |
333 | } catch (Exception e) { |
334 | throw new RuntimeException(e); |
335 | } |
336 | } |
337 | |
338 | static Object get(Class c, String field) { |
339 | try { |
340 | Field f = get_findStaticField(c, field); |
341 | f.setAccessible(true); |
342 | return f.get(null); |
343 | } catch (Exception e) { |
344 | throw new RuntimeException(e); |
345 | } |
346 | } |
347 | |
348 | static Field get_findStaticField(Class<?> c, String field) { |
349 | for (Field f : c.getDeclaredFields()) |
350 | if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0) |
351 | return f; |
352 | throw new RuntimeException("Static field '" + field + "' not found in " + c.getName()); |
353 | } |
354 | |
355 | static Field get_findField(Class<?> c, String field) { |
356 | for (Field f : c.getDeclaredFields()) |
357 | if (f.getName().equals(field)) |
358 | return f; |
359 | throw new RuntimeException("Field '" + field + "' not found in " + c.getName()); |
360 | } |
361 | |
362 | static String shorten(String s, int max) { |
363 | return s.length() <= max ? s : s.substring(0, Math.min(s.length(), max)) + "..."; |
364 | } |
365 | |
366 | static String getInjectionID() { |
367 | return (String) call(getJavaX(), "getInjectionID", getMainClass()); |
368 | } |
369 | |
370 | // start multi-port if none exists in current VM. |
371 | static void startMultiPort() { |
372 | // TODO: might start multiple if run concurrently... |
373 | if (getMultiPorts().isEmpty()) |
374 | callMain(hotwire("#1001672")); |
375 | } |
376 | |
377 | static List<Object> getMultiPorts() { |
378 | return (List) call(getJavaX(), "getMultiPorts"); |
379 | } |
380 | |
381 | static int max(int a, int b) { |
382 | return Math.max(a, b); |
383 | } |
384 | |
385 | static Object callOpt(Object o, String method, Object... args) { |
386 | try { |
387 | if (o == null) return null; |
388 | if (o instanceof Class) { |
389 | Method m = callOpt_findStaticMethod((Class) o, method, args, false); |
390 | if (m == null) return null; |
391 | m.setAccessible(true); |
392 | return m.invoke(null, args); |
393 | } else { |
394 | Method m = callOpt_findMethod(o, method, args, false); |
395 | if (m == null) return null; |
396 | m.setAccessible(true); |
397 | return m.invoke(o, args); |
398 | } |
399 | } catch (Exception e) { |
400 | throw new RuntimeException(e); |
401 | } |
402 | } |
403 | |
404 | static Method callOpt_findStaticMethod(Class c, String method, Object[] args, boolean debug) { |
405 | Class _c = c; |
406 | while (c != null) { |
407 | for (Method m : c.getDeclaredMethods()) { |
408 | if (debug) |
409 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
410 | if (!m.getName().equals(method)) { |
411 | if (debug) System.out.println("Method name mismatch: " + method); |
412 | continue; |
413 | } |
414 | |
415 | if ((m.getModifiers() & Modifier.STATIC) == 0 || !callOpt_checkArgs(m, args, debug)) |
416 | continue; |
417 | |
418 | return m; |
419 | } |
420 | c = c.getSuperclass(); |
421 | } |
422 | return null; |
423 | } |
424 | |
425 | static Method callOpt_findMethod(Object o, String method, Object[] args, boolean debug) { |
426 | Class c = o.getClass(); |
427 | while (c != null) { |
428 | for (Method m : c.getDeclaredMethods()) { |
429 | if (debug) |
430 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
431 | if (m.getName().equals(method) && callOpt_checkArgs(m, args, debug)) |
432 | return m; |
433 | } |
434 | c = c.getSuperclass(); |
435 | } |
436 | return null; |
437 | } |
438 | |
439 | private static boolean callOpt_checkArgs(Method m, Object[] args, boolean debug) { |
440 | Class<?>[] types = m.getParameterTypes(); |
441 | if (types.length != args.length) { |
442 | if (debug) |
443 | System.out.println("Bad parameter length: " + args.length + " vs " + types.length); |
444 | return false; |
445 | } |
446 | for (int i = 0; i < types.length; i++) |
447 | if (!(args[i] == null || isInstanceX(types[i], args[i]))) { |
448 | if (debug) |
449 | System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); |
450 | return false; |
451 | } |
452 | return true; |
453 | } |
454 | |
455 | |
456 | |
457 | static Class getMainClass() { try { |
458 | |
459 | return Class.forName("main"); |
460 | |
461 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
462 | |
463 | |
464 | static String programID; |
465 | |
466 | static String getProgramID() { |
467 | return programID; |
468 | } |
469 | |
470 | static <A> A last(List<A> l) { |
471 | return l.isEmpty() ? null : l.get(l.size()-1); |
472 | } |
473 | |
474 | static void setOpt(Object o, String field, Object value) { |
475 | if (o instanceof Class) setOpt((Class) o, field, value); |
476 | else try { |
477 | Field f = setOpt_findField(o.getClass(), field); |
478 | if (f == null) return; |
479 | f.setAccessible(true); |
480 | f.set(o, value); |
481 | } catch (Exception e) { |
482 | throw new RuntimeException(e); |
483 | } |
484 | } |
485 | |
486 | static void setOpt(Class c, String field, Object value) { |
487 | try { |
488 | Field f = setOpt_findStaticField(c, field); |
489 | if (f == null) return; |
490 | f.setAccessible(true); |
491 | f.set(null, value); |
492 | } catch (Exception e) { |
493 | throw new RuntimeException(e); |
494 | } |
495 | } |
496 | |
497 | static Field setOpt_findField(Class<?> c, String field) { |
498 | for (Field f : c.getDeclaredFields()) |
499 | if (f.getName().equals(field)) |
500 | return f; |
501 | return null; |
502 | } |
503 | |
504 | static Field setOpt_findStaticField(Class<?> c, String field) { |
505 | for (Field f : c.getDeclaredFields()) |
506 | if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0) |
507 | return f; |
508 | return null; |
509 | } |
510 | |
511 | static List<String> dropPunctuation(List<String> tok) { |
512 | tok = new ArrayList<String>(tok); |
513 | for (int i = 1; i < tok.size(); i += 2) { |
514 | String t = tok.get(i); |
515 | if (t.length() == 1 && !Character.isLetter(t.charAt(0)) && !Character.isDigit(t.charAt(0)) && !t.equals("*")) { |
516 | tok.set(i-1, tok.get(i-1) + tok.get(i+1)); |
517 | tok.remove(i); |
518 | tok.remove(i); |
519 | i -= 2; |
520 | } |
521 | } |
522 | return tok; |
523 | } |
524 | |
525 | // This is made for NL parsing. |
526 | // It's javaTok extended with "..." token, "$n" and "#n" |
527 | |
528 | static List<String> javaTokPlusPeriod(String s) { |
529 | List<String> tok = new ArrayList<String>(); |
530 | int l = s.length(); |
531 | |
532 | int i = 0; |
533 | while (i < l) { |
534 | int j = i; |
535 | char c; String cc; |
536 | |
537 | // scan for whitespace |
538 | while (j < l) { |
539 | c = s.charAt(j); |
540 | cc = s.substring(j, Math.min(j+2, l)); |
541 | if (c == ' ' || c == '\t' || c == '\r' || c == '\n') |
542 | ++j; |
543 | else if (cc.equals("/*")) { |
544 | do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/")); |
545 | j = Math.min(j+2, l); |
546 | } else if (cc.equals("//")) { |
547 | do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); |
548 | } else |
549 | break; |
550 | } |
551 | |
552 | tok.add(s.substring(i, j)); |
553 | i = j; |
554 | if (i >= l) break; |
555 | c = s.charAt(i); |
556 | cc = s.substring(i, Math.min(i+2, l)); |
557 | |
558 | // scan for non-whitespace |
559 | if (c == '\'' || c == '"') { |
560 | char opener = c; |
561 | ++j; |
562 | while (j < l) { |
563 | if (s.charAt(j) == opener) { |
564 | ++j; |
565 | break; |
566 | } else if (s.charAt(j) == '\\' && j+1 < l) |
567 | j += 2; |
568 | else |
569 | ++j; |
570 | } |
571 | } else if (Character.isJavaIdentifierStart(c)) |
572 | do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || s.charAt(j) == '\'')); // for things like "this one's" |
573 | else if (Character.isDigit(c)) |
574 | do ++j; while (j < l && Character.isDigit(s.charAt(j))); |
575 | else if (cc.equals("[[")) { |
576 | do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]")); |
577 | j = Math.min(j+2, l); |
578 | } else if (s.substring(j, Math.min(j+3, l)).equals("...")) |
579 | j += 3; |
580 | else if (c == '$' || c == '#') |
581 | do ++j; while (j < l && Character.isDigit(s.charAt(j))); |
582 | else |
583 | ++j; |
584 | |
585 | tok.add(s.substring(i, j)); |
586 | i = j; |
587 | } |
588 | |
589 | if ((tok.size() % 2) == 0) tok.add(""); |
590 | return tok; |
591 | } |
592 | |
593 | |
594 | static StringBuffer print_log; |
595 | |
596 | static void print() { |
597 | print(""); |
598 | } |
599 | |
600 | static void print(Object o) { |
601 | String s = String.valueOf(o) + "\n"; |
602 | synchronized(StringBuffer.class) { |
603 | if (print_log == null) print_log = new StringBuffer(); |
604 | } |
605 | print_log.append(s); |
606 | System.out.print(s); |
607 | } |
608 | |
609 | static void print(long l) { |
610 | print(String.valueOf(l)); |
611 | } |
612 | |
613 | static Object call(Object o, String method, Object... args) { |
614 | try { |
615 | if (o instanceof Class) { |
616 | Method m = call_findStaticMethod((Class) o, method, args, false); |
617 | m.setAccessible(true); |
618 | return m.invoke(null, args); |
619 | } else { |
620 | Method m = call_findMethod(o, method, args, false); |
621 | m.setAccessible(true); |
622 | return m.invoke(o, args); |
623 | } |
624 | } catch (Exception e) { |
625 | throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e); |
626 | } |
627 | } |
628 | |
629 | static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) { |
630 | Class _c = c; |
631 | while (c != null) { |
632 | for (Method m : c.getDeclaredMethods()) { |
633 | if (debug) |
634 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
635 | if (!m.getName().equals(method)) { |
636 | if (debug) System.out.println("Method name mismatch: " + method); |
637 | continue; |
638 | } |
639 | |
640 | if ((m.getModifiers() & Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug)) |
641 | continue; |
642 | |
643 | return m; |
644 | } |
645 | c = c.getSuperclass(); |
646 | } |
647 | throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName()); |
648 | } |
649 | |
650 | static Method call_findMethod(Object o, String method, Object[] args, boolean debug) { |
651 | Class c = o.getClass(); |
652 | while (c != null) { |
653 | for (Method m : c.getDeclaredMethods()) { |
654 | if (debug) |
655 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
656 | if (m.getName().equals(method) && call_checkArgs(m, args, debug)) |
657 | return m; |
658 | } |
659 | c = c.getSuperclass(); |
660 | } |
661 | throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName()); |
662 | } |
663 | |
664 | private static boolean call_checkArgs(Method m, Object[] args, boolean debug) { |
665 | Class<?>[] types = m.getParameterTypes(); |
666 | if (types.length != args.length) { |
667 | if (debug) |
668 | System.out.println("Bad parameter length: " + args.length + " vs " + types.length); |
669 | return false; |
670 | } |
671 | for (int i = 0; i < types.length; i++) |
672 | if (!(args[i] == null || isInstanceX(types[i], args[i]))) { |
673 | if (debug) |
674 | System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); |
675 | return false; |
676 | } |
677 | return true; |
678 | } |
679 | |
680 | |
681 | // compile JavaX source, load classes & return main class |
682 | // src can be a snippet ID or actual source code |
683 | // TODO: record injection? |
684 | |
685 | static Class<?> hotwire(String src) { |
686 | try { |
687 | Class j = getJavaX(); |
688 | |
689 | synchronized(j) { // hopefully this goes well... |
690 | List<File> libraries = new ArrayList<File>(); |
691 | File srcDir = (File) call(j, "transpileMain", src, libraries); |
692 | if (srcDir == null) |
693 | fail("transpileMain returned null (src=" + quote(src) + ")"); |
694 | |
695 | Object androidContext = get(j, "androidContext"); |
696 | if (androidContext != null) |
697 | return (Class) call(j, "loadx2android", srcDir, src); |
698 | |
699 | File classesDir = (File) call(j, "TempDirMaker_make"); |
700 | String javacOutput = (String) call(j, "compileJava", srcDir, libraries, classesDir); |
701 | System.out.println(javacOutput); |
702 | |
703 | URL[] urls = new URL[libraries.size()+1]; |
704 | urls[0] = classesDir.toURI().toURL(); |
705 | for (int i = 0; i < libraries.size(); i++) |
706 | urls[i+1] = libraries.get(i).toURI().toURL(); |
707 | |
708 | // make class loader |
709 | URLClassLoader classLoader = new URLClassLoader(urls); |
710 | |
711 | // load & return main class |
712 | Class<?> theClass = classLoader.loadClass("main"); |
713 | |
714 | call(j, "setVars", theClass, isSnippetID(src) ? src: null); |
715 | |
716 | if (isSnippetID(src)) |
717 | callOpt(j, "addInstance", src, theClass); |
718 | |
719 | return theClass; |
720 | } |
721 | } catch (Exception e) { |
722 | throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e); |
723 | } |
724 | } |
725 | |
726 | static RuntimeException fail() { |
727 | throw new RuntimeException("fail"); |
728 | } |
729 | |
730 | static RuntimeException fail(Object msg) { |
731 | throw new RuntimeException(String.valueOf(msg)); |
732 | } |
733 | |
734 | static String programID() { |
735 | return getProgramID(); |
736 | } |
737 | |
738 | // extended over Class.isInstance() to handle primitive types |
739 | static boolean isInstanceX(Class type, Object arg) { |
740 | if (type == boolean.class) return arg instanceof Boolean; |
741 | if (type == int.class) return arg instanceof Integer; |
742 | if (type == long.class) return arg instanceof Long; |
743 | if (type == float.class) return arg instanceof Float; |
744 | if (type == short.class) return arg instanceof Short; |
745 | if (type == char.class) return arg instanceof Character; |
746 | if (type == byte.class) return arg instanceof Byte; |
747 | return type.isInstance(arg); |
748 | } |
749 | |
750 | static Class __javax; |
751 | |
752 | static Class getJavaX() { |
753 | return __javax; |
754 | } |
755 | |
756 | static void callMain(Object c, String... args) { |
757 | callOpt(c, "main", new Object[] {args}); |
758 | } |
759 | |
760 | public static boolean isSnippetID(String s) { |
761 | try { |
762 | parseSnippetID(s); |
763 | return true; |
764 | } catch (RuntimeException e) { |
765 | return false; |
766 | } |
767 | } |
768 | |
769 | public static long parseSnippetID(String snippetID) { |
770 | long id = Long.parseLong(shortenSnippetID(snippetID)); |
771 | if (id == 0) fail("0 is not a snippet ID"); |
772 | return id; |
773 | } |
774 | |
775 | static String shortenSnippetID(String snippetID) { |
776 | if (snippetID.startsWith("#")) |
777 | snippetID = snippetID.substring(1); |
778 | String httpBlaBla = "http://tinybrain.de/"; |
779 | if (snippetID.startsWith(httpBlaBla)) |
780 | snippetID = snippetID.substring(httpBlaBla.length()); |
781 | return snippetID; |
782 | } |
783 | } |
Snippet is not live.
Travelled to 12 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #2000584 |
Snippet name: | Test input for function finding |
Eternal ID of this version: | #2000584/1 |
Text MD5: | 591b04a03fb90fa5c3d9f0d4803702ce |
Author: | stefan |
Category: | javax |
Type: | New Tinybrain snippet |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2015-11-21 18:31:22 |
Source code size: | 23886 bytes / 783 lines |
Pitched / IR pitched: | No / Yes |
Views / Downloads: | 487 / 350 |
Referenced in: | [show references] |