1 /* |
|
2 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 /** |
|
27 * jrunscript JavaScript built-in functions and objects. |
|
28 */ |
|
29 |
|
30 /** |
|
31 * Creates an object that delegates all method calls on |
|
32 * it to the 'invoke' method on the given delegate object.<br> |
|
33 * |
|
34 * Example: |
|
35 * <pre> |
|
36 * <code> |
|
37 * var x = { invoke: function(name, args) { //code...} |
|
38 * var y = new JSInvoker(x); |
|
39 * y.func(3, 3); // calls x.invoke('func', args); where args is array of arguments |
|
40 * </code> |
|
41 * </pre> |
|
42 * @param obj object to be wrapped by JSInvoker |
|
43 * @constructor |
|
44 */ |
|
45 function JSInvoker(obj) { |
|
46 return new JSAdapter({ |
|
47 __get__ : function(name) { |
|
48 return function() { |
|
49 return obj.invoke(name, arguments); |
|
50 } |
|
51 } |
|
52 }); |
|
53 } |
|
54 |
|
55 /** |
|
56 * This variable represents OS environment. Environment |
|
57 * variables can be accessed as fields of this object. For |
|
58 * example, env.PATH will return PATH value configured. |
|
59 */ |
|
60 var env = new JSAdapter({ |
|
61 __get__ : function (name) { |
|
62 return java.lang.System.getenv(name); |
|
63 }, |
|
64 __has__ : function (name) { |
|
65 return java.lang.System.getenv().containsKey(name); |
|
66 }, |
|
67 __getIds__ : function() { |
|
68 return java.lang.System.getenv().keySet().toArray(); |
|
69 }, |
|
70 __delete__ : function(name) { |
|
71 println("can't delete env item"); |
|
72 }, |
|
73 __put__ : function (name, value) { |
|
74 println("can't change env item"); |
|
75 }, |
|
76 toString: function() { |
|
77 return java.lang.System.getenv().toString(); |
|
78 } |
|
79 }); |
|
80 |
|
81 /** |
|
82 * Creates a convenient script object to deal with java.util.Map instances. |
|
83 * The result script object's field names are keys of the Map. For example, |
|
84 * scriptObj.keyName can be used to access value associated with given key.<br> |
|
85 * Example: |
|
86 * <pre> |
|
87 * <code> |
|
88 * var x = java.lang.SystemProperties(); |
|
89 * var y = jmap(x); |
|
90 * println(y['java.class.path']); // prints java.class.path System property |
|
91 * delete y['java.class.path']; // remove java.class.path System property |
|
92 * </code> |
|
93 * </pre> |
|
94 * |
|
95 * @param map java.util.Map instance that will be wrapped |
|
96 * @constructor |
|
97 */ |
|
98 function jmap(map) { |
|
99 return new JSAdapter({ |
|
100 __get__ : function(name) { |
|
101 if (map.containsKey(name)) { |
|
102 return map.get(name); |
|
103 } else { |
|
104 return undefined; |
|
105 } |
|
106 }, |
|
107 __has__ : function(name) { |
|
108 return map.containsKey(name); |
|
109 }, |
|
110 |
|
111 __delete__ : function (name) { |
|
112 return map.remove(name); |
|
113 }, |
|
114 __put__ : function(name, value) { |
|
115 map.put(name, value); |
|
116 }, |
|
117 __getIds__ : function() { |
|
118 return map.keySet().toArray(); |
|
119 }, |
|
120 toString: function() { |
|
121 return map.toString(); |
|
122 } |
|
123 }); |
|
124 } |
|
125 |
|
126 /** |
|
127 * Creates a convenient script object to deal with java.util.List instances. |
|
128 * The result script object behaves like an array. For example, |
|
129 * scriptObj[index] syntax can be used to access values in the List instance. |
|
130 * 'length' field gives size of the List. <br> |
|
131 * |
|
132 * Example: |
|
133 * <pre> |
|
134 * <code> |
|
135 * var x = new java.util.ArrayList(4); |
|
136 * x.add('Java'); |
|
137 * x.add('JavaScript'); |
|
138 * x.add('SQL'); |
|
139 * x.add('XML'); |
|
140 * |
|
141 * var y = jlist(x); |
|
142 * println(y[2]); // prints third element of list |
|
143 * println(y.length); // prints size of the list |
|
144 * |
|
145 * @param map java.util.List instance that will be wrapped |
|
146 * @constructor |
|
147 */ |
|
148 function jlist(list) { |
|
149 function isValid(index) { |
|
150 return typeof(index) == 'number' && |
|
151 index > -1 && index < list.size(); |
|
152 } |
|
153 return new JSAdapter({ |
|
154 __get__ : function(name) { |
|
155 if (isValid(name)) { |
|
156 return list.get(name); |
|
157 } else if (name == 'length') { |
|
158 return list.size(); |
|
159 } else { |
|
160 return undefined; |
|
161 } |
|
162 }, |
|
163 __has__ : function (name) { |
|
164 return isValid(name) || name == 'length'; |
|
165 }, |
|
166 __delete__ : function(name) { |
|
167 if (isValid(name)) { |
|
168 list.remove(name); |
|
169 } |
|
170 }, |
|
171 __put__ : function(name, value) { |
|
172 if (isValid(name)) { |
|
173 list.set(name, value); |
|
174 } |
|
175 }, |
|
176 __getIds__: function() { |
|
177 var res = new Array(list.size()); |
|
178 for (var i = 0; i < res.length; i++) { |
|
179 res[i] = i; |
|
180 } |
|
181 return res; |
|
182 }, |
|
183 toString: function() { |
|
184 return list.toString(); |
|
185 } |
|
186 }); |
|
187 } |
|
188 |
|
189 /** |
|
190 * This is java.lang.System properties wrapped by JSAdapter. |
|
191 * For eg. to access java.class.path property, you can use |
|
192 * the syntax sysProps["java.class.path"] |
|
193 */ |
|
194 var sysProps = new JSAdapter({ |
|
195 __get__ : function (name) { |
|
196 return java.lang.System.getProperty(name); |
|
197 }, |
|
198 __has__ : function (name) { |
|
199 return java.lang.System.getProperty(name) != null; |
|
200 }, |
|
201 __getIds__ : function() { |
|
202 return java.lang.System.getProperties().keySet().toArray(); |
|
203 }, |
|
204 __delete__ : function(name) { |
|
205 java.lang.System.clearProperty(name); |
|
206 return true; |
|
207 }, |
|
208 __put__ : function (name, value) { |
|
209 java.lang.System.setProperty(name, value); |
|
210 }, |
|
211 toString: function() { |
|
212 return "<system properties>"; |
|
213 } |
|
214 }); |
|
215 |
|
216 // stdout, stderr & stdin |
|
217 var out = java.lang.System.out; |
|
218 var err = java.lang.System.err; |
|
219 // can't use 'in' because it is a JavaScript keyword :-( |
|
220 var inp = java.lang.System["in"]; |
|
221 |
|
222 var BufferedInputStream = java.io.BufferedInputStream; |
|
223 var BufferedOutputStream = java.io.BufferedOutputStream; |
|
224 var BufferedReader = java.io.BufferedReader; |
|
225 var DataInputStream = java.io.DataInputStream; |
|
226 var File = java.io.File; |
|
227 var FileInputStream = java.io.FileInputStream; |
|
228 var FileOutputStream = java.io.FileOutputStream; |
|
229 var InputStream = java.io.InputStream; |
|
230 var InputStreamReader = java.io.InputStreamReader; |
|
231 var OutputStream = java.io.OutputStream; |
|
232 var Reader = java.io.Reader; |
|
233 var URL = java.net.URL; |
|
234 |
|
235 /** |
|
236 * Generic any object to input stream mapper |
|
237 * @param str input file name, URL or InputStream |
|
238 * @return InputStream object |
|
239 * @private |
|
240 */ |
|
241 function inStream(str) { |
|
242 if (typeof(str) == "string") { |
|
243 // '-' means standard input |
|
244 if (str == '-') { |
|
245 return java.lang.System["in"]; |
|
246 } |
|
247 // try file first |
|
248 var file = null; |
|
249 try { |
|
250 file = pathToFile(str); |
|
251 } catch (e) { |
|
252 } |
|
253 if (file && file.exists()) { |
|
254 return new FileInputStream(file); |
|
255 } else { |
|
256 try { |
|
257 // treat the string as URL |
|
258 return new URL(str).openStream(); |
|
259 } catch (e) { |
|
260 throw 'file or URL ' + str + ' not found'; |
|
261 } |
|
262 } |
|
263 } else { |
|
264 if (str instanceof InputStream) { |
|
265 return str; |
|
266 } else if (str instanceof URL) { |
|
267 return str.openStream(); |
|
268 } else if (str instanceof File) { |
|
269 return new FileInputStream(str); |
|
270 } |
|
271 } |
|
272 // everything failed, just give input stream |
|
273 return java.lang.System["in"]; |
|
274 } |
|
275 |
|
276 /** |
|
277 * Generic any object to output stream mapper |
|
278 * |
|
279 * @param out output file name or stream |
|
280 * @return OutputStream object |
|
281 * @private |
|
282 */ |
|
283 function outStream(out) { |
|
284 if (typeof(out) == "string") { |
|
285 if (out == '>') { |
|
286 return java.lang.System.out; |
|
287 } else { |
|
288 // treat it as file |
|
289 return new FileOutputStream(pathToFile(out)); |
|
290 } |
|
291 } else { |
|
292 if (out instanceof OutputStream) { |
|
293 return out; |
|
294 } else if (out instanceof File) { |
|
295 return new FileOutputStream(out); |
|
296 } |
|
297 } |
|
298 |
|
299 // everything failed, just return System.out |
|
300 return java.lang.System.out; |
|
301 } |
|
302 |
|
303 /** |
|
304 * stream close takes care not to close stdin, out & err. |
|
305 * @private |
|
306 */ |
|
307 function streamClose(stream) { |
|
308 if (stream) { |
|
309 if (stream != java.lang.System["in"] && |
|
310 stream != java.lang.System.out && |
|
311 stream != java.lang.System.err) { |
|
312 try { |
|
313 stream.close(); |
|
314 } catch (e) { |
|
315 println(e); |
|
316 } |
|
317 } |
|
318 } |
|
319 } |
|
320 |
|
321 /** |
|
322 * Loads and evaluates JavaScript code from a stream or file or URL<br> |
|
323 * |
|
324 * Examples: |
|
325 * <pre> |
|
326 * <code> |
|
327 * load('test.js'); // load script file 'test.js' |
|
328 * load('http://java.sun.com/foo.js'); // load from a URL |
|
329 * </code> |
|
330 * </pre> |
|
331 * |
|
332 * @param str input from which script is loaded and evaluated |
|
333 */ |
|
334 if (typeof(load) == 'undefined') { |
|
335 this.load = function(str) { |
|
336 var stream = inStream(str); |
|
337 var bstream = new BufferedInputStream(stream); |
|
338 var reader = new BufferedReader(new InputStreamReader(bstream)); |
|
339 var oldFilename = engine.get(engine.FILENAME); |
|
340 engine.put(engine.FILENAME, str); |
|
341 try { |
|
342 engine.eval(reader); |
|
343 } finally { |
|
344 engine.put(engine.FILENAME, oldFilename); |
|
345 streamClose(stream); |
|
346 } |
|
347 } |
|
348 } |
|
349 |
|
350 // file system utilities |
|
351 |
|
352 /** |
|
353 * Creates a Java byte[] of given length |
|
354 * @param len size of the array to create |
|
355 * @private |
|
356 */ |
|
357 function javaByteArray(len) { |
|
358 return java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, len); |
|
359 } |
|
360 |
|
361 var curDir = new File('.'); |
|
362 |
|
363 /** |
|
364 * Print present working directory |
|
365 */ |
|
366 function pwd() { |
|
367 println(curDir.getAbsolutePath()); |
|
368 } |
|
369 |
|
370 /** |
|
371 * Changes present working directory to given directory |
|
372 * @param target directory to change to. optional, defaults to user's HOME |
|
373 */ |
|
374 function cd(target) { |
|
375 if (target == undefined) { |
|
376 target = sysProps["user.home"]; |
|
377 } |
|
378 if (!(target instanceof File)) { |
|
379 target = pathToFile(target); |
|
380 } |
|
381 if (target.exists() && target.isDirectory()) { |
|
382 curDir = target; |
|
383 } else { |
|
384 println(target + " is not a directory"); |
|
385 } |
|
386 } |
|
387 |
|
388 /** |
|
389 * Converts path to java.io.File taking care of shell present working dir |
|
390 * |
|
391 * @param pathname file path to be converted |
|
392 * @private |
|
393 */ |
|
394 function pathToFile(pathname) { |
|
395 var tmp = pathname; |
|
396 if (!(tmp instanceof File)) { |
|
397 tmp = new File(tmp); |
|
398 } |
|
399 if (!tmp.isAbsolute()) { |
|
400 return new File(curDir, pathname); |
|
401 } else { |
|
402 return tmp; |
|
403 } |
|
404 } |
|
405 |
|
406 /** |
|
407 * Copies a file or URL or stream to another file or stream |
|
408 * |
|
409 * @param from input file or URL or stream |
|
410 * @param to output stream or file |
|
411 */ |
|
412 function cp(from, to) { |
|
413 if (from == to) { |
|
414 println("file " + from + " cannot be copied onto itself!"); |
|
415 return; |
|
416 } |
|
417 var inp = inStream(from); |
|
418 var out = outStream(to); |
|
419 var binp = new BufferedInputStream(inp); |
|
420 var bout = new BufferedOutputStream(out); |
|
421 var buff = javaByteArray(1024); |
|
422 var len; |
|
423 while ((len = binp.read(buff)) > 0 ) |
|
424 bout.write(buff, 0, len); |
|
425 |
|
426 bout.flush(); |
|
427 streamClose(inp); |
|
428 streamClose(out); |
|
429 } |
|
430 |
|
431 /** |
|
432 * Shows the content of a file or URL or any InputStream<br> |
|
433 * Examples: |
|
434 * <pre> |
|
435 * <code> |
|
436 * cat('test.txt'); // show test.txt file contents |
|
437 * cat('http://java.net'); // show the contents from the URL http://java.net |
|
438 * </code> |
|
439 * </pre> |
|
440 * @param obj input to show |
|
441 * @param pattern optional. show only the lines matching the pattern |
|
442 */ |
|
443 function cat(obj, pattern) { |
|
444 if (obj instanceof File && obj.isDirectory()) { |
|
445 ls(obj); |
|
446 return; |
|
447 } |
|
448 |
|
449 var inp = null; |
|
450 if (!(obj instanceof Reader)) { |
|
451 inp = inStream(obj); |
|
452 obj = new BufferedReader(new InputStreamReader(inp)); |
|
453 } |
|
454 var line; |
|
455 if (pattern) { |
|
456 var count = 1; |
|
457 while ((line=obj.readLine()) != null) { |
|
458 if (line.match(pattern)) { |
|
459 println(count + "\t: " + line); |
|
460 } |
|
461 count++; |
|
462 } |
|
463 } else { |
|
464 while ((line=obj.readLine()) != null) { |
|
465 println(line); |
|
466 } |
|
467 } |
|
468 } |
|
469 |
|
470 /** |
|
471 * Returns directory part of a filename |
|
472 * |
|
473 * @param pathname input path name |
|
474 * @return directory part of the given file name |
|
475 */ |
|
476 function dirname(pathname) { |
|
477 var dirName = "."; |
|
478 // Normalize '/' to local file separator before work. |
|
479 var i = pathname.replace('/', File.separatorChar ).lastIndexOf( |
|
480 File.separator ); |
|
481 if ( i != -1 ) |
|
482 dirName = pathname.substring(0, i); |
|
483 return dirName; |
|
484 } |
|
485 |
|
486 /** |
|
487 * Creates a new dir of given name |
|
488 * |
|
489 * @param dir name of the new directory |
|
490 */ |
|
491 function mkdir(dir) { |
|
492 dir = pathToFile(dir); |
|
493 println(dir.mkdir()? "created" : "can not create dir"); |
|
494 } |
|
495 |
|
496 /** |
|
497 * Creates the directory named by given pathname, including |
|
498 * any necessary but nonexistent parent directories. |
|
499 * |
|
500 * @param dir input path name |
|
501 */ |
|
502 function mkdirs(dir) { |
|
503 dir = pathToFile(dir); |
|
504 println(dir.mkdirs()? "created" : "can not create dirs"); |
|
505 } |
|
506 |
|
507 /** |
|
508 * Removes a given file |
|
509 * |
|
510 * @param pathname name of the file |
|
511 */ |
|
512 function rm(pathname) { |
|
513 var file = pathToFile(pathname); |
|
514 if (!file.exists()) { |
|
515 println("file not found: " + pathname); |
|
516 return false; |
|
517 } |
|
518 // note that delete is a keyword in JavaScript! |
|
519 println(file["delete"]()? "deleted" : "can not delete"); |
|
520 } |
|
521 |
|
522 /** |
|
523 * Removes a given directory |
|
524 * |
|
525 * @param pathname name of the directory |
|
526 */ |
|
527 function rmdir(pathname) { |
|
528 rm(pathname); |
|
529 } |
|
530 |
|
531 /** |
|
532 * Synonym for 'rm' |
|
533 */ |
|
534 function del(pathname) { |
|
535 rm(pathname); |
|
536 } |
|
537 |
|
538 /** |
|
539 * Moves a file to another |
|
540 * |
|
541 * @param from original name of the file |
|
542 * @param to new name for the file |
|
543 */ |
|
544 function mv(from, to) { |
|
545 println(pathToFile(from).renameTo(pathToFile(to))? |
|
546 "moved" : "can not move"); |
|
547 } |
|
548 |
|
549 /** |
|
550 * Synonym for 'mv'. |
|
551 */ |
|
552 function ren(from, to) { |
|
553 mv(from, to); |
|
554 } |
|
555 |
|
556 var months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
|
557 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; |
|
558 |
|
559 /** |
|
560 * Helper function called by ls |
|
561 * @private |
|
562 */ |
|
563 function printFile(f) { |
|
564 var sb = new java.lang.StringBuffer(); |
|
565 sb.append(f.isDirectory()? "d" : "-"); |
|
566 sb.append(f.canRead() ? "r": "-" ); |
|
567 sb.append(f.canWrite() ? "w": "-" ); |
|
568 sb.append(" "); |
|
569 |
|
570 var d = new java.util.Date(f.lastModified()); |
|
571 var c = new java.util.GregorianCalendar(); |
|
572 c.setTime(d); |
|
573 var day = c.get(java.util.Calendar.DAY_OF_MONTH); |
|
574 sb.append(months[c.get(java.util.Calendar.MONTH)] |
|
575 + " " + day ); |
|
576 if (day < 10) { |
|
577 sb.append(" "); |
|
578 } |
|
579 |
|
580 // to get fixed length 'length' field |
|
581 var fieldlen = 8; |
|
582 var len = new java.lang.StringBuffer(); |
|
583 for(var j=0; j<fieldlen; j++) |
|
584 len.append(" "); |
|
585 len.insert(0, java.lang.Long.toString(f.length())); |
|
586 len.setLength(fieldlen); |
|
587 // move the spaces to the front |
|
588 var si = len.toString().indexOf(" "); |
|
589 if ( si != -1 ) { |
|
590 var pad = len.toString().substring(si); |
|
591 len.setLength(si); |
|
592 len.insert(0, pad); |
|
593 } |
|
594 sb.append(len.toString()); |
|
595 sb.append(" "); |
|
596 sb.append(f.getName()); |
|
597 if (f.isDirectory()) { |
|
598 sb.append('/'); |
|
599 } |
|
600 println(sb.toString()); |
|
601 } |
|
602 |
|
603 /** |
|
604 * Lists the files in a directory |
|
605 * |
|
606 * @param dir directory from which to list the files. optional, default to pwd |
|
607 * @param filter pattern to filter the files listed. optional, default is '.'. |
|
608 */ |
|
609 function ls(dir, filter) { |
|
610 if (dir) { |
|
611 dir = pathToFile(dir); |
|
612 } else { |
|
613 dir = curDir; |
|
614 } |
|
615 if (dir.isDirectory()) { |
|
616 var files = dir.listFiles(); |
|
617 for (var i in files) { |
|
618 var f = files[i]; |
|
619 if (filter) { |
|
620 if(!f.getName().match(filter)) { |
|
621 continue; |
|
622 } |
|
623 } |
|
624 printFile(f); |
|
625 } |
|
626 } else { |
|
627 printFile(dir); |
|
628 } |
|
629 } |
|
630 |
|
631 /** |
|
632 * Synonym for 'ls'. |
|
633 */ |
|
634 function dir(d, filter) { |
|
635 ls(d, filter); |
|
636 } |
|
637 |
|
638 /** |
|
639 * Unix-like grep, but accepts JavaScript regex patterns |
|
640 * |
|
641 * @param pattern to search in files |
|
642 * @param files one or more files |
|
643 */ |
|
644 function grep(pattern, files /*, one or more files */) { |
|
645 if (arguments.length < 2) return; |
|
646 for (var i = 1; i < arguments.length; i++) { |
|
647 println(arguments[i] + ":"); |
|
648 cat(arguments[i], pattern); |
|
649 } |
|
650 } |
|
651 |
|
652 /** |
|
653 * Find in files. Calls arbitrary callback function |
|
654 * for each matching file.<br> |
|
655 * |
|
656 * Examples: |
|
657 * <pre> |
|
658 * <code> |
|
659 * find('.') |
|
660 * find('.', '.*\.class', rm); // remove all .class files |
|
661 * find('.', '.*\.java'); // print fullpath of each .java file |
|
662 * find('.', '.*\.java', cat); // print all .java files |
|
663 * </code> |
|
664 * </pre> |
|
665 * |
|
666 * @param dir directory to search files |
|
667 * @param pattern to search in the files |
|
668 * @param callback function to call for matching files |
|
669 */ |
|
670 function find(dir, pattern, callback) { |
|
671 dir = pathToFile(dir); |
|
672 if (!callback) callback = print; |
|
673 var files = dir.listFiles(); |
|
674 for (var f in files) { |
|
675 var file = files[f]; |
|
676 if (file.isDirectory()) { |
|
677 find(file, pattern, callback); |
|
678 } else { |
|
679 if (pattern) { |
|
680 if (file.getName().match(pattern)) { |
|
681 callback(file); |
|
682 } |
|
683 } else { |
|
684 callback(file); |
|
685 } |
|
686 } |
|
687 } |
|
688 } |
|
689 |
|
690 // process utilities |
|
691 |
|
692 /** |
|
693 * Exec's a child process, waits for completion & returns exit code |
|
694 * |
|
695 * @param cmd command to execute in child process |
|
696 */ |
|
697 function exec(cmd) { |
|
698 var process = java.lang.Runtime.getRuntime().exec(cmd); |
|
699 var inp = new DataInputStream(process.getInputStream()); |
|
700 var line = null; |
|
701 while ((line = inp.readLine()) != null) { |
|
702 println(line); |
|
703 } |
|
704 process.waitFor(); |
|
705 $exit = process.exitValue(); |
|
706 } |
|
707 |
|
708 if (typeof(exit) == 'undefined') { |
|
709 /** |
|
710 * Exit the shell program. |
|
711 * |
|
712 * @param exitCode integer code returned to OS shell. |
|
713 * optional, defaults to 0 |
|
714 */ |
|
715 this.exit = function (code) { |
|
716 if (code) { |
|
717 java.lang.System.exit(code + 0); |
|
718 } else { |
|
719 java.lang.System.exit(0); |
|
720 } |
|
721 } |
|
722 } |
|
723 |
|
724 if (typeof(quit) == 'undefined') { |
|
725 /** |
|
726 * synonym for exit |
|
727 */ |
|
728 this.quit = function (code) { |
|
729 exit(code); |
|
730 } |
|
731 } |
|
732 |
|
733 // XML utilities |
|
734 |
|
735 /** |
|
736 * Converts input to DOM Document object |
|
737 * |
|
738 * @param inp file or reader. optional, without this param, |
|
739 * this function returns a new DOM Document. |
|
740 * @return returns a DOM Document object |
|
741 */ |
|
742 function XMLDocument(inp) { |
|
743 var factory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); |
|
744 var builder = factory.newDocumentBuilder(); |
|
745 if (inp) { |
|
746 if (typeof(inp) == "string") { |
|
747 return builder.parse(pathToFile(inp)); |
|
748 } else { |
|
749 return builder.parse(inp); |
|
750 } |
|
751 } else { |
|
752 return builder.newDocument(); |
|
753 } |
|
754 } |
|
755 |
|
756 /** |
|
757 * Converts arbitrary stream, file, URL to XMLSource |
|
758 * |
|
759 * @param inp input stream or file or URL |
|
760 * @return XMLSource object |
|
761 */ |
|
762 function XMLSource(inp) { |
|
763 if (inp instanceof javax.xml.transform.Source) { |
|
764 return inp; |
|
765 } else if (inp instanceof Packages.org.w3c.dom.Document) { |
|
766 return new javax.xml.transform.dom.DOMSource(inp); |
|
767 } else { |
|
768 inp = new BufferedInputStream(inStream(inp)); |
|
769 return new javax.xml.transform.stream.StreamSource(inp); |
|
770 } |
|
771 } |
|
772 |
|
773 /** |
|
774 * Converts arbitrary stream, file to XMLResult |
|
775 * |
|
776 * @param inp output stream or file |
|
777 * @return XMLResult object |
|
778 */ |
|
779 function XMLResult(out) { |
|
780 if (out instanceof javax.xml.transform.Result) { |
|
781 return out; |
|
782 } else if (out instanceof Packages.org.w3c.dom.Document) { |
|
783 return new javax.xml.transform.dom.DOMResult(out); |
|
784 } else { |
|
785 out = new BufferedOutputStream(outStream(out)); |
|
786 return new javax.xml.transform.stream.StreamResult(out); |
|
787 } |
|
788 } |
|
789 |
|
790 /** |
|
791 * Perform XSLT transform |
|
792 * |
|
793 * @param inp Input XML to transform (URL, File or InputStream) |
|
794 * @param style XSL Stylesheet to be used (URL, File or InputStream). optional. |
|
795 * @param out Output XML (File or OutputStream |
|
796 */ |
|
797 function XSLTransform(inp, style, out) { |
|
798 switch (arguments.length) { |
|
799 case 2: |
|
800 inp = arguments[0]; |
|
801 out = arguments[1]; |
|
802 break; |
|
803 case 3: |
|
804 inp = arguments[0]; |
|
805 style = arguments[1]; |
|
806 out = arguments[2]; |
|
807 break; |
|
808 default: |
|
809 println("XSL transform requires 2 or 3 arguments"); |
|
810 return; |
|
811 } |
|
812 |
|
813 var factory = javax.xml.transform.TransformerFactory.newInstance(); |
|
814 var transformer; |
|
815 if (style) { |
|
816 transformer = factory.newTransformer(XMLSource(style)); |
|
817 } else { |
|
818 transformer = factory.newTransformer(); |
|
819 } |
|
820 var source = XMLSource(inp); |
|
821 var result = XMLResult(out); |
|
822 transformer.transform(source, result); |
|
823 if (source.getInputStream) { |
|
824 streamClose(source.getInputStream()); |
|
825 } |
|
826 if (result.getOutputStream) { |
|
827 streamClose(result.getOutputStream()); |
|
828 } |
|
829 } |
|
830 |
|
831 // miscellaneous utilities |
|
832 |
|
833 /** |
|
834 * Prints which command is selected from PATH |
|
835 * |
|
836 * @param cmd name of the command searched from PATH |
|
837 */ |
|
838 function which(cmd) { |
|
839 var st = new java.util.StringTokenizer(env.PATH, File.pathSeparator); |
|
840 while (st.hasMoreTokens()) { |
|
841 var file = new File(st.nextToken(), cmd); |
|
842 if (file.exists()) { |
|
843 println(file.getAbsolutePath()); |
|
844 return; |
|
845 } |
|
846 } |
|
847 } |
|
848 |
|
849 /** |
|
850 * Prints IP addresses of given domain name |
|
851 * |
|
852 * @param name domain name |
|
853 */ |
|
854 function ip(name) { |
|
855 var addrs = InetAddress.getAllByName(name); |
|
856 for (var i in addrs) { |
|
857 println(addrs[i]); |
|
858 } |
|
859 } |
|
860 |
|
861 /** |
|
862 * Prints current date in current locale |
|
863 */ |
|
864 function date() { |
|
865 println(new Date().toLocaleString()); |
|
866 } |
|
867 |
|
868 /** |
|
869 * Echoes the given string arguments |
|
870 */ |
|
871 function echo(x) { |
|
872 for (var i = 0; i < arguments.length; i++) { |
|
873 println(arguments[i]); |
|
874 } |
|
875 } |
|
876 |
|
877 if (typeof(printf) == 'undefined') { |
|
878 /** |
|
879 * This is C-like printf |
|
880 * |
|
881 * @param format string to format the rest of the print items |
|
882 * @param args variadic argument list |
|
883 */ |
|
884 this.printf = function (format, args/*, more args*/) { |
|
885 var array = java.lang.reflect.Array.newInstance(java.lang.Object, |
|
886 arguments.length - 1); |
|
887 for (var i = 0; i < array.length; i++) { |
|
888 array[i] = arguments[i+1]; |
|
889 } |
|
890 java.lang.System.out.printf(format, array); |
|
891 } |
|
892 } |
|
893 |
|
894 /** |
|
895 * Reads one or more lines from stdin after printing prompt |
|
896 * |
|
897 * @param prompt optional, default is '>' |
|
898 * @param multiline to tell whether to read single line or multiple lines |
|
899 */ |
|
900 function read(prompt, multiline) { |
|
901 if (!prompt) { |
|
902 prompt = '>'; |
|
903 } |
|
904 var inp = java.lang.System["in"]; |
|
905 var reader = new BufferedReader(new InputStreamReader(inp)); |
|
906 if (multiline) { |
|
907 var line = ''; |
|
908 while (true) { |
|
909 java.lang.System.err.print(prompt); |
|
910 java.lang.System.err.flush(); |
|
911 var tmp = reader.readLine(); |
|
912 if (tmp == '' || tmp == null) break; |
|
913 line += tmp + '\n'; |
|
914 } |
|
915 return line; |
|
916 } else { |
|
917 java.lang.System.err.print(prompt); |
|
918 java.lang.System.err.flush(); |
|
919 return reader.readLine(); |
|
920 } |
|
921 } |
|
922 |
|
923 if (typeof(println) == 'undefined') { |
|
924 // just synonym to print |
|
925 this.println = print; |
|
926 } |
|
927 |
|