PageRenderTime 77ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 2ms

/text/src/test/resources/examples/java/jruby.in.java

https://github.com/rimolive/core
Java | 13963 lines | 12550 code | 421 blank | 992 comment | 360 complexity | 177e0295a7887cd9ab9c9ef722d9455d MD5 | raw file
Possible License(s): EPL-1.0, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  1. package org.jruby;
  2. public enum CompatVersion {
  3. RUBY1_8, RUBY1_9, BOTH;
  4. public static CompatVersion getVersionFromString(String compatString) {
  5. if (compatString.equalsIgnoreCase("RUBY1_8")) {
  6. return CompatVersion.RUBY1_8;
  7. } else if (compatString.equalsIgnoreCase("RUBY1_9")) {
  8. return CompatVersion.RUBY1_9;
  9. } else {
  10. return null;
  11. }
  12. }
  13. }
  14. /***** BEGIN LICENSE BLOCK *****
  15. * Version: CPL 1.0/GPL 2.0/LGPL 2.1
  16. *
  17. * The contents of this file are subject to the Common Public
  18. * License Version 1.0 (the "License"); you may not use this file
  19. * except in compliance with the License. You may obtain a copy of
  20. * the License at http://www.eclipse.org/legal/cpl-v10.html
  21. *
  22. * Software distributed under the License is distributed on an "AS
  23. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  24. * implied. See the License for the specific language governing
  25. * rights and limitations under the License.
  26. *
  27. * Copyright (C) 2007 Damian Steer <pldms@mac.com>
  28. *
  29. * Alternatively, the contents of this file may be used under the terms of
  30. * either of the GNU General Public License Version 2 or later (the "GPL"),
  31. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  32. * in which case the provisions of the GPL or the LGPL are applicable instead
  33. * of those above. If you wish to allow use of your version of this file only
  34. * under the terms of either the GPL or the LGPL, and not to allow others to
  35. * use your version of this file under the terms of the CPL, indicate your
  36. * decision by deleting the provisions above and replace them with the notice
  37. * and other provisions required by the GPL or the LGPL. If you do not delete
  38. * the provisions above, a recipient may use your version of this file under
  39. * the terms of any one of the CPL, the GPL or the LGPL.
  40. ***** END LICENSE BLOCK *****/
  41. package org.jruby;
  42. /**
  43. * An almost entirely useless interface for those objects that we _really_ want
  44. * to finalise.
  45. *
  46. * @author pldms
  47. *
  48. */
  49. public interface Finalizable {
  50. public void finalize();
  51. }
  52. /***** BEGIN LICENSE BLOCK *****
  53. * Version: CPL 1.0/GPL 2.0/LGPL 2.1
  54. *
  55. * The contents of this file are subject to the Common Public
  56. * License Version 1.0 (the "License"); you may not use this file
  57. * except in compliance with the License. You may obtain a copy of
  58. * the License at http://www.eclipse.org/legal/cpl-v10.html
  59. *
  60. * Software distributed under the License is distributed on an "AS
  61. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  62. * implied. See the License for the specific language governing
  63. * rights and limitations under the License.
  64. *
  65. * Copyright (C) 2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
  66. * Copyright (C) 2002 Jan Arne Petersen <jpetersen@uni-bonn.de>
  67. *
  68. * Alternatively, the contents of this file may be used under the terms of
  69. * either of the GNU General Public License Version 2 or later (the "GPL"),
  70. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  71. * in which case the provisions of the GPL or the LGPL are applicable instead
  72. * of those above. If you wish to allow use of your version of this file only
  73. * under the terms of either the GPL or the LGPL, and not to allow others to
  74. * use your version of this file under the terms of the CPL, indicate your
  75. * decision by deleting the provisions above and replace them with the notice
  76. * and other provisions required by the GPL or the LGPL. If you do not delete
  77. * the provisions above, a recipient may use your version of this file under
  78. * the terms of any one of the CPL, the GPL or the LGPL.
  79. ***** END LICENSE BLOCK *****/
  80. package org.jruby;
  81. /**
  82. * Error numbers.
  83. * @fixme
  84. * this interface is a big hack defining a bunch of arbitrary valor as system call error numbers
  85. * this is actually because I need them but will probably need to be changed to something smarter
  86. * sooner or later.
  87. * The purpose of this class it to help implement the Errno module which in turn in needed by rubicon.
  88. * @author Benoit Cerrina
  89. **/
  90. public interface IErrno
  91. {
  92. int EPERM = 1;
  93. int ENOENT = 2;
  94. int ESRCH = 3;
  95. int EINTR = 4;
  96. int EIO = 5;
  97. int ENXIO = 6;
  98. int E2BIG = 7;
  99. int ENOEXEC = 8;
  100. int EBADF = 9;
  101. int ECHILD = 10;
  102. int EDEADLK = 11;
  103. int ENOMEM = 12;
  104. int EACCES = 13;
  105. int EFAULT = 14;
  106. int ENOTBLK = 15;
  107. int EBUSY = 16;
  108. int EEXIST = 17;
  109. int EXDEV = 18;
  110. int ENODEV = 19;
  111. int ENOTDIR = 20;
  112. int EISDIR = 21;
  113. int EINVAL = 22;
  114. int ENFILE = 23;
  115. int EMFILE = 24;
  116. int ENOTTY = 25;
  117. int ETXTBSY = 26;
  118. int EFBIG = 27;
  119. int ENOSPC = 28;
  120. int ESPIPE = 29;
  121. int EROFS = 30;
  122. int EMLINK = 31;
  123. int EPIPE = 32;
  124. int EDOM = 33;
  125. int ERANGE = 34;
  126. int EWOULDBLOCK = 35;
  127. int EAGAIN = 35;
  128. int EINPROGRESS = 36;
  129. int EALREADY = 37;
  130. int ENOTSOCK = 38;
  131. int EDESTADDRREQ = 39;
  132. int EMSGSIZE = 40;
  133. int EPROTOTYPE = 41;
  134. int ENOPROTOOPT = 42;
  135. int EPROTONOSUPPORT = 43;
  136. int ESOCKTNOSUPPORT = 44;
  137. int EOPNOTSUPP = 45;
  138. int EPFNOSUPPORT = 46;
  139. int EAFNOSUPPORT = 47;
  140. int EADDRINUSE = 48;
  141. int EADDRNOTAVAIL = 49;
  142. int ENETDOWN = 50;
  143. int ENETUNREACH = 51;
  144. int ENETRESET = 52;
  145. int ECONNABORTED = 53;
  146. int ECONNRESET = 54;
  147. int ENOBUFS = 55;
  148. int EISCONN = 56;
  149. int ENOTCONN = 57;
  150. int ESHUTDOWN = 58;
  151. int ETOOMANYREFS = 59;
  152. int ETIMEDOUT = 60;
  153. int ECONNREFUSED = 61;
  154. int ELOOP = 62;
  155. int ENAMETOOLONG = 63;
  156. int EHOSTDOWN = 64;
  157. int EHOSTUNREACH = 65;
  158. int ENOTEMPTY = 66;
  159. int EUSERS = 68;
  160. int EDQUOT = 69;
  161. int ESTALE = 70;
  162. int EREMOTE = 71;
  163. int ENOLCK = 77;
  164. int ENOSYS = 78;
  165. int EOVERFLOW = 84;
  166. int EIDRM = 90;
  167. int ENOMSG = 91;
  168. int EILSEQ = 92;
  169. int EBADMSG = 94;
  170. int EMULTIHOP = 95;
  171. int ENODATA = 96;
  172. int ENOLINK = 97;
  173. int ENOSR = 98;
  174. int ENOSTR = 99;
  175. int EPROTO = 100;
  176. int ETIME = 101;
  177. int EOPNOTSUPP_DARWIN = 102;
  178. }
  179. /*
  180. ***** BEGIN LICENSE BLOCK *****
  181. * Version: CPL 1.0/GPL 2.0/LGPL 2.1
  182. *
  183. * The contents of this file are subject to the Common Public
  184. * License Version 1.0 (the "License"); you may not use this file
  185. * except in compliance with the License. You may obtain a copy of
  186. * the License at http://www.eclipse.org/legal/cpl-v10.html
  187. *
  188. * Software distributed under the License is distributed on an "AS
  189. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  190. * implied. See the License for the specific language governing
  191. * rights and limitations under the License.
  192. *
  193. * Copyright (C) 2002-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
  194. * Copyright (C) 2004-2006 Thomas E Enebo <enebo@acm.org>
  195. * Copyright (C) 2005 Charles O Nutter <headius@headius.com>
  196. * Copyright (C) 2006 Miguel Covarrubias <mlcovarrubias@gmail.com>
  197. * Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
  198. *
  199. * Alternatively, the contents of this file may be used under the terms of
  200. * either of the GNU General Public License Version 2 or later (the "GPL"),
  201. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  202. * in which case the provisions of the GPL or the LGPL are applicable instead
  203. * of those above. If you wish to allow use of your version of this file only
  204. * under the terms of either the GPL or the LGPL, and not to allow others to
  205. * use your version of this file under the terms of the CPL, indicate your
  206. * decision by deleting the provisions above and replace them with the notice
  207. * and other provisions required by the GPL or the LGPL. If you do not delete
  208. * the provisions above, a recipient may use your version of this file under
  209. * the terms of any one of the CPL, the GPL or the LGPL.
  210. ***** END LICENSE BLOCK *****/
  211. package org.jruby;
  212. import java.util.List;
  213. import java.util.Map;
  214. import org.jruby.internal.runtime.methods.DynamicMethod;
  215. import org.jruby.runtime.builtin.IRubyObject;
  216. import org.jruby.runtime.builtin.Variable;
  217. /**
  218. * This class is used to provide an intermediate superclass for modules and classes that include
  219. * other modules. It inserts itself as the immediate superClass of the includer, but defers all
  220. * module methods to the actual superclass. Multiple of these intermediate superclasses can be
  221. * added for multiple included modules.
  222. *
  223. * This allows the normal superclass-based searches (searchMethod, getConstant, etc) to traverse
  224. * the superclass ancestors as normal while the included modules do not actually show up in
  225. * direct inheritance traversal.
  226. *
  227. * @see org.jruby.RubyModule
  228. */
  229. public final class IncludedModuleWrapper extends RubyClass {
  230. private final RubyModule delegate;
  231. public IncludedModuleWrapper(Ruby runtime, RubyClass superClass, RubyModule delegate) {
  232. super(runtime, superClass, false);
  233. this.delegate = delegate;
  234. this.metaClass = delegate.metaClass;
  235. }
  236. /**
  237. * Overridden newIncludeClass implementation to allow attaching future includes to the correct module
  238. * (i.e. the one to which this is attached)
  239. *
  240. * @see org.jruby.RubyModule#newIncludeClass(RubyClass)
  241. */
  242. @Override
  243. public IncludedModuleWrapper newIncludeClass(RubyClass superClass) {
  244. IncludedModuleWrapper includedModule = new IncludedModuleWrapper(getRuntime(), superClass, getNonIncludedClass());
  245. // include its parent (and in turn that module's parents)
  246. if (getSuperClass() != null) {
  247. includedModule.includeModule(getSuperClass());
  248. }
  249. return includedModule;
  250. }
  251. @Override
  252. public boolean isModule() {
  253. return false;
  254. }
  255. @Override
  256. public boolean isClass() {
  257. return false;
  258. }
  259. @Override
  260. public boolean isIncluded() {
  261. return true;
  262. }
  263. @Override
  264. public boolean isImmediate() {
  265. return true;
  266. }
  267. @Override
  268. public void setMetaClass(RubyClass newRubyClass) {
  269. throw new UnsupportedOperationException("An included class is only a wrapper for a module");
  270. }
  271. @Override
  272. public Map<String, DynamicMethod> getMethods() {
  273. return delegate.getMethods();
  274. }
  275. @Override
  276. public void addMethod(String name, DynamicMethod method) {
  277. throw new UnsupportedOperationException("An included class is only a wrapper for a module");
  278. }
  279. public void setMethods(Map newMethods) {
  280. throw new UnsupportedOperationException("An included class is only a wrapper for a module");
  281. }
  282. @Override
  283. public String getName() {
  284. return delegate.getName();
  285. }
  286. @Override
  287. public RubyModule getNonIncludedClass() {
  288. return delegate;
  289. }
  290. @Override
  291. public RubyClass getRealClass() {
  292. return getSuperClass().getRealClass();
  293. }
  294. @Override
  295. protected boolean isSame(RubyModule module) {
  296. return delegate.isSame(module);
  297. }
  298. /**
  299. * We don't want to reveal ourselves to Ruby code, so delegate this
  300. * operation.
  301. */
  302. @Override
  303. public IRubyObject id() {
  304. return delegate.id();
  305. }
  306. //
  307. // VARIABLE TABLE METHODS - pass to delegate
  308. //
  309. @Override
  310. protected boolean variableTableContains(String name) {
  311. return delegate.variableTableContains(name);
  312. }
  313. @Override
  314. protected boolean variableTableFastContains(String internedName) {
  315. return delegate.variableTableFastContains(internedName);
  316. }
  317. @Override
  318. protected IRubyObject variableTableFetch(String name) {
  319. return delegate.variableTableFetch(name);
  320. }
  321. @Override
  322. protected IRubyObject variableTableFastFetch(String internedName) {
  323. return delegate.variableTableFastFetch(internedName);
  324. }
  325. @Override
  326. protected IRubyObject variableTableStore(String name, IRubyObject value) {
  327. return delegate.variableTableStore(name, value);
  328. }
  329. @Override
  330. protected IRubyObject variableTableFastStore(String internedName, IRubyObject value) {
  331. return delegate.variableTableFastStore(internedName, value);
  332. }
  333. @Override
  334. protected IRubyObject variableTableRemove(String name) {
  335. return delegate.variableTableRemove(name);
  336. }
  337. @Override
  338. protected VariableTableEntry[] variableTableGetTable() {
  339. return delegate.variableTableGetTable();
  340. }
  341. @Override
  342. protected int variableTableGetSize() {
  343. return delegate.variableTableGetSize();
  344. }
  345. @Override
  346. protected void variableTableSync(List<Variable<IRubyObject>> vars) {
  347. delegate.variableTableSync(vars);
  348. }
  349. @Override
  350. protected IRubyObject variableTableReadLocked(VariableTableEntry entry) {
  351. return delegate.variableTableReadLocked(entry);
  352. }
  353. /**
  354. * Method to help ease transition to new variables implementation.
  355. * Will likely be deprecated in the near future.
  356. */
  357. @SuppressWarnings("unchecked")
  358. @Override
  359. @Deprecated // born deprecated
  360. protected Map variableTableGetMap() {
  361. return delegate.variableTableGetMap();
  362. }
  363. /**
  364. * Method to help ease transition to new variables implementation.
  365. * Will likely be deprecated in the near future.
  366. */
  367. @SuppressWarnings("unchecked")
  368. @Override
  369. @Deprecated // born deprecated
  370. protected Map variableTableGetMap(Map map) {
  371. return delegate.variableTableGetMap(map);
  372. }
  373. //
  374. // CONSTANT TABLE METHODS - pass to delegate
  375. //
  376. @Override
  377. protected boolean constantTableContains(String name) {
  378. return delegate.constantTableContains(name);
  379. }
  380. @Override
  381. protected boolean constantTableFastContains(String internedName) {
  382. return delegate.constantTableFastContains(internedName);
  383. }
  384. @Override
  385. protected IRubyObject constantTableFetch(String name) {
  386. return delegate.constantTableFetch(name);
  387. }
  388. @Override
  389. protected IRubyObject constantTableFastFetch(String internedName) {
  390. return delegate.constantTableFastFetch(internedName);
  391. }
  392. @Override
  393. protected IRubyObject constantTableStore(String name, IRubyObject value) {
  394. // FIXME: legal here? may want UnsupportedOperationException
  395. return delegate.constantTableStore(name, value);
  396. }
  397. @Override
  398. protected IRubyObject constantTableFastStore(String internedName, IRubyObject value) {
  399. // FIXME: legal here? may want UnsupportedOperationException
  400. return delegate.constantTableFastStore(internedName, value);
  401. }
  402. @Override
  403. protected IRubyObject constantTableRemove(String name) {
  404. // this _is_ legal (when removing an undef)
  405. return delegate.constantTableRemove(name);
  406. }
  407. @Override
  408. protected ConstantTableEntry[] constantTableGetTable() {
  409. return delegate.constantTableGetTable();
  410. }
  411. @Override
  412. protected int constantTableGetSize() {
  413. return delegate.constantTableGetSize();
  414. }
  415. @Override
  416. protected void constantTableSync(List<Variable<IRubyObject>> vars) {
  417. // FIXME: legal here? may want UnsupportedOperationException
  418. delegate.constantTableSync(vars);
  419. }
  420. /**
  421. * Method to help ease transition to new variables implementation.
  422. * Will likely be deprecated in the near future.
  423. */
  424. @SuppressWarnings("unchecked")
  425. @Override
  426. @Deprecated // born deprecated
  427. protected Map constantTableGetMap() {
  428. return delegate.constantTableGetMap();
  429. }
  430. /**
  431. * Method to help ease transition to new variables implementation.
  432. * Will likely be deprecated in the near future.
  433. */
  434. @SuppressWarnings("unchecked")
  435. @Override
  436. @Deprecated // born deprecated
  437. protected Map constantTableGetMap(Map map) {
  438. return delegate.constantTableGetMap(map);
  439. }
  440. }
  441. /***** BEGIN LICENSE BLOCK *****
  442. * Version: CPL 1.0/GPL 2.0/LGPL 2.1
  443. *
  444. * The contents of this file are subject to the Common Public
  445. * License Version 1.0 (the "License"); you may not use this file
  446. * except in compliance with the License. You may obtain a copy of
  447. * the License at http://www.eclipse.org/legal/cpl-v10.html
  448. *
  449. * Software distributed under the License is distributed on an "AS
  450. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  451. * implied. See the License for the specific language governing
  452. * rights and limitations under the License.
  453. *
  454. * Copyright (C) 2007 Charles Nutter <charles.o.nutter@sun.com>
  455. * Copyright (C) 2008 MenTaLguY <mental@rydia.net>
  456. *
  457. * Alternatively, the contents of this file may be used under the terms of
  458. * either of the GNU General Public License Version 2 or later (the "GPL"),
  459. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  460. * in which case the provisions of the GPL or the LGPL are applicable instead
  461. * of those above. If you wish to allow use of your version of this file only
  462. * under the terms of either the GPL or the LGPL, and not to allow others to
  463. * use your version of this file under the terms of the CPL, indicate your
  464. * decision by deleting the provisions above and replace them with the notice
  465. * and other provisions required by the GPL or the LGPL. If you do not delete
  466. * the provisions above, a recipient may use your version of this file under
  467. * the terms of any one of the CPL, the GPL or the LGPL.
  468. ***** END LICENSE BLOCK *****/
  469. package org.jruby;
  470. import java.applet.Applet;
  471. import java.awt.BorderLayout;
  472. import java.awt.Color;
  473. import java.awt.Container;
  474. import java.awt.EventQueue;
  475. import java.awt.Font;
  476. import java.awt.Insets;
  477. import java.awt.Graphics;
  478. import java.awt.GraphicsConfiguration;
  479. import java.awt.GraphicsEnvironment;
  480. import java.awt.image.VolatileImage;
  481. import java.io.IOException;
  482. import java.io.InputStream;
  483. import java.io.PrintStream;
  484. import java.net.URL;
  485. import java.util.Arrays;
  486. import java.lang.reflect.InvocationTargetException;
  487. import org.jruby.anno.JRubyMethod;
  488. import org.jruby.demo.TextAreaReadline;
  489. import org.jruby.javasupport.JavaUtil;
  490. import org.jruby.runtime.Block;
  491. import org.jruby.runtime.ThreadContext;
  492. import org.jruby.runtime.builtin.IRubyObject;
  493. import javax.swing.JScrollPane;
  494. import javax.swing.JTextPane;
  495. /**
  496. * @author <a href="mailto:mental@rydia.net">MenTaLguY</a>
  497. *
  498. * The JRubyApplet class provides a simple way to write Java applets using
  499. * JRuby without needing to create a custom Java applet class. At applet
  500. * initialization time, JRubyApplet starts up a JRuby runtime, then evaluates
  501. * the scriptlet given as the "eval" applet parameter.
  502. *
  503. * The Java applet instance is available to the Ruby script as
  504. * JRUBY_APPLET; the script can define callbacks for applet start, stop,
  505. * and destroy by passing blocks to JRUBY_APPLET.on_start,
  506. * JRUBY_APPLET.on_stop, and JRUBY_APPLET.on_destroy, respectively.
  507. *
  508. * Ruby code can install a custom paint callback using JRUBY_APPLET.on_paint
  509. * (the Graphics2D object is passed as an argument to the callback). By
  510. * default, JRubyApplet painting is double-buffered, but you can select
  511. * single-buffered painting via JRUBY_APPLET.double_buffered = false.
  512. *
  513. * The applet's background color can be set via JRUBY_APPLET.background_color=.
  514. * You may want to set it to nil if you're not using double-buffering, so that
  515. * no background color will be drawn (your own paint code is then responsible
  516. * for filling the area).
  517. *
  518. * Beyond these things, you should be able to use JRuby's Java integration
  519. * to do whatever you would do in Java with the applet instance.
  520. *
  521. */
  522. public class JRubyApplet extends Applet {
  523. private Ruby runtime;
  524. private boolean doubleBuffered = true;
  525. private Color backgroundColor = Color.WHITE;
  526. private RubyProc startProc;
  527. private RubyProc stopProc;
  528. private RubyProc destroyProc;
  529. private RubyProc paintProc;
  530. private Graphics priorGraphics;
  531. private IRubyObject wrappedGraphics;
  532. private VolatileImage backBuffer;
  533. private Graphics backBufferGraphics;
  534. private Facade facade;
  535. private interface Facade {
  536. public InputStream getInputStream();
  537. public PrintStream getOutputStream();
  538. public PrintStream getErrorStream();
  539. public void attach(Ruby runtime, Applet applet);
  540. public void destroy();
  541. }
  542. private static RubyProc blockToProc(Ruby runtime, Block block) {
  543. if (block.isGiven()) {
  544. RubyProc proc = block.getProcObject();
  545. if (proc == null) {
  546. proc = RubyProc.newProc(runtime, block, block.type);
  547. }
  548. return proc;
  549. } else {
  550. return null;
  551. }
  552. }
  553. private boolean getBooleanParameter(String name, boolean defaultValue) {
  554. String value = getParameter(name);
  555. if ( value != null ) {
  556. return value.equals("true");
  557. } else {
  558. return defaultValue;
  559. }
  560. }
  561. private InputStream getCodeResourceAsStream(String name) {
  562. if (name == null) {
  563. return null;
  564. }
  565. try {
  566. final URL directURL = new URL(getCodeBase(), name);
  567. return directURL.openStream();
  568. } catch (IOException e) {
  569. }
  570. return JRubyApplet.class.getClassLoader().getResourceAsStream(name);
  571. }
  572. private static void safeInvokeAndWait(Runnable runnable) throws InvocationTargetException, InterruptedException {
  573. if (EventQueue.isDispatchThread()) {
  574. try {
  575. runnable.run();
  576. } catch (Exception e) {
  577. throw new InvocationTargetException(e);
  578. }
  579. } else {
  580. EventQueue.invokeAndWait(runnable);
  581. }
  582. }
  583. public static class RubyMethods {
  584. @JRubyMethod
  585. public static IRubyObject on_start(IRubyObject recv, Block block) {
  586. JRubyApplet applet = (JRubyApplet)recv.dataGetStruct();
  587. synchronized (applet) {
  588. applet.startProc = blockToProc(applet.runtime, block);
  589. }
  590. return recv;
  591. }
  592. @JRubyMethod
  593. public static IRubyObject on_stop(IRubyObject recv, Block block) {
  594. JRubyApplet applet = (JRubyApplet)recv.dataGetStruct();
  595. synchronized (applet) {
  596. applet.stopProc = blockToProc(applet.runtime, block);
  597. }
  598. return recv;
  599. }
  600. @JRubyMethod
  601. public static IRubyObject on_destroy(IRubyObject recv, Block block) {
  602. JRubyApplet applet = (JRubyApplet)recv.dataGetStruct();
  603. synchronized (applet) {
  604. applet.destroyProc = blockToProc(applet.runtime, block);
  605. }
  606. return recv;
  607. }
  608. @JRubyMethod
  609. public static IRubyObject on_paint(IRubyObject recv, Block block) {
  610. JRubyApplet applet = (JRubyApplet)recv.dataGetStruct();
  611. synchronized (applet) {
  612. applet.paintProc = blockToProc(applet.runtime, block);
  613. applet.repaint();
  614. }
  615. return recv;
  616. }
  617. }
  618. @Override
  619. public void init() {
  620. super.init();
  621. if (getBooleanParameter("jruby.console", false)) {
  622. facade = new ConsoleFacade(getParameter("jruby.banner"));
  623. } else {
  624. facade = new TrivialFacade();
  625. }
  626. synchronized (this) {
  627. if (runtime != null) {
  628. return;
  629. }
  630. final RubyInstanceConfig config = new RubyInstanceConfig() {{
  631. setInput(facade.getInputStream());
  632. setOutput(facade.getOutputStream());
  633. setError(facade.getErrorStream());
  634. setObjectSpaceEnabled(getBooleanParameter("jruby.objectspace", false));
  635. }};
  636. Ruby.setSecurityRestricted(true);
  637. runtime = Ruby.newInstance(config);
  638. }
  639. final String scriptName = getParameter("jruby.script");
  640. final InputStream scriptStream = getCodeResourceAsStream(scriptName);
  641. final String evalString = getParameter("jruby.eval");
  642. try {
  643. final JRubyApplet applet = this;
  644. safeInvokeAndWait(new Runnable() {
  645. public void run() {
  646. applet.setLayout(new BorderLayout());
  647. applet.facade.attach(applet.runtime, applet);
  648. if (scriptStream != null) {
  649. applet.runtime.runFromMain(scriptStream, scriptName);
  650. }
  651. if (evalString != null) {
  652. applet.runtime.evalScriptlet(evalString);
  653. }
  654. }
  655. });
  656. } catch (InterruptedException e) {
  657. } catch (InvocationTargetException e) {
  658. throw new RuntimeException("Error running script", e.getCause());
  659. }
  660. }
  661. private void invokeCallback(final RubyProc proc, final IRubyObject[] args) {
  662. if (proc == null) {
  663. return;
  664. }
  665. final Ruby runtime = this.runtime;
  666. try {
  667. safeInvokeAndWait(new Runnable() {
  668. public void run() {
  669. ThreadContext context = runtime.getCurrentContext();
  670. proc.call(context, args);
  671. }
  672. });
  673. } catch (InterruptedException e) {
  674. } catch (InvocationTargetException e) {
  675. throw new RuntimeException("Ruby callback failed", e.getCause());
  676. }
  677. }
  678. public synchronized void setBackgroundColor(Color color) {
  679. backgroundColor = color;
  680. repaint();
  681. }
  682. public synchronized Color getBackgroundColor() {
  683. return backgroundColor;
  684. }
  685. public synchronized boolean isDoubleBuffered() {
  686. return doubleBuffered;
  687. }
  688. public synchronized void setDoubleBuffered(boolean shouldBuffer) {
  689. doubleBuffered = shouldBuffer;
  690. repaint();
  691. }
  692. @Override
  693. public synchronized void start() {
  694. super.start();
  695. invokeCallback(startProc, new IRubyObject[] {});
  696. }
  697. @Override
  698. public synchronized void stop() {
  699. invokeCallback(stopProc, new IRubyObject[] {});
  700. super.stop();
  701. }
  702. @Override
  703. public synchronized void destroy() {
  704. try {
  705. invokeCallback(destroyProc, new IRubyObject[] {});
  706. } finally {
  707. facade.destroy();
  708. final Ruby runtime = this.runtime;
  709. this.runtime = null;
  710. startProc = null;
  711. stopProc = null;
  712. destroyProc = null;
  713. paintProc = null;
  714. priorGraphics = null;
  715. wrappedGraphics = null;
  716. runtime.tearDown();
  717. super.destroy();
  718. }
  719. }
  720. @Override
  721. public void update(Graphics g) {
  722. paint(g);
  723. }
  724. @Override
  725. public synchronized void paint(Graphics g) {
  726. if (doubleBuffered) {
  727. paintBuffered(g);
  728. } else {
  729. paintUnbuffered(g);
  730. }
  731. }
  732. private synchronized void paintBuffered(Graphics g) {
  733. do {
  734. GraphicsConfiguration config = getGraphicsConfiguration();
  735. int width = getWidth();
  736. int height = getHeight();
  737. if (backBuffer == null || width != backBuffer.getWidth() || height != backBuffer.getHeight() || backBuffer.validate(config) == VolatileImage.IMAGE_INCOMPATIBLE) {
  738. if (backBuffer != null) {
  739. backBufferGraphics.dispose();
  740. backBufferGraphics = null;
  741. backBuffer.flush();
  742. backBuffer = null;
  743. }
  744. backBuffer = config.createCompatibleVolatileImage(width, height);
  745. backBufferGraphics = backBuffer.createGraphics();
  746. }
  747. backBufferGraphics.setClip(g.getClip());
  748. paintUnbuffered(backBufferGraphics);
  749. g.drawImage(backBuffer, 0, 0, this);
  750. } while (backBuffer.contentsLost());
  751. }
  752. private synchronized void paintUnbuffered(Graphics g) {
  753. if (backgroundColor != null) {
  754. g.setColor(backgroundColor);
  755. g.fillRect(0, 0, getWidth(), getHeight());
  756. }
  757. if (paintProc != null) {
  758. if (priorGraphics != g) {
  759. wrappedGraphics = JavaUtil.convertJavaToUsableRubyObject(runtime, g);
  760. priorGraphics = g;
  761. }
  762. ThreadContext context = runtime.getCurrentContext();
  763. paintProc.call(context, new IRubyObject[] {wrappedGraphics});
  764. }
  765. super.paint(g);
  766. }
  767. private static class TrivialFacade implements Facade {
  768. public TrivialFacade() {}
  769. public InputStream getInputStream() { return System.in; }
  770. public PrintStream getOutputStream() { return System.out; }
  771. public PrintStream getErrorStream() { return System.err; }
  772. public void attach(Ruby runtime, Applet applet) {
  773. final IRubyObject wrappedApplet = JavaUtil.convertJavaToUsableRubyObject(runtime, applet);
  774. wrappedApplet.dataWrapStruct(applet);
  775. runtime.defineGlobalConstant("JRUBY_APPLET", wrappedApplet);
  776. wrappedApplet.getMetaClass().defineAnnotatedMethods(RubyMethods.class);
  777. }
  778. public void destroy() {}
  779. }
  780. private static class ConsoleFacade implements Facade {
  781. private JTextPane textPane;
  782. private JScrollPane scrollPane;
  783. private TextAreaReadline adaptor;
  784. private InputStream inputStream;
  785. private PrintStream outputStream;
  786. private PrintStream errorStream;
  787. public ConsoleFacade(String bannerText) {
  788. textPane = new JTextPane();
  789. textPane.setMargin(new Insets(4, 4, 0, 4));
  790. textPane.setCaretColor(new Color(0xa4, 0x00, 0x00));
  791. textPane.setBackground(new Color(0xf2, 0xf2, 0xf2));
  792. textPane.setForeground(new Color(0xa4, 0x00, 0x00));
  793. Font font = findFont("Monospaced", Font.PLAIN, 14,
  794. new String[] {"Monaco", "Andale Mono"});
  795. textPane.setFont(font);
  796. scrollPane = new JScrollPane(textPane);
  797. scrollPane.setDoubleBuffered(true);
  798. if ( bannerText != null ) {
  799. bannerText = " " + bannerText + " \n\n";
  800. }
  801. adaptor = new TextAreaReadline(textPane, bannerText);
  802. inputStream = adaptor.getInputStream();
  803. outputStream = new PrintStream(adaptor.getOutputStream());
  804. errorStream = new PrintStream(adaptor.getOutputStream());
  805. }
  806. public InputStream getInputStream() { return inputStream; }
  807. public PrintStream getOutputStream() { return outputStream; }
  808. public PrintStream getErrorStream() { return errorStream; }
  809. public void attach(Ruby runtime, Applet applet) {
  810. adaptor.hookIntoRuntime(runtime);
  811. applet.add(scrollPane);
  812. applet.validate();
  813. }
  814. public void destroy() {
  815. Container parent = scrollPane.getParent();
  816. adaptor.shutdown();
  817. if (parent != null) {
  818. parent.remove(scrollPane);
  819. }
  820. }
  821. private Font findFont(String otherwise, int style, int size, String[] families) {
  822. String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
  823. Arrays.sort(fonts);
  824. for (int i = 0; i < families.length; i++) {
  825. if (Arrays.binarySearch(fonts, families[i]) >= 0) {
  826. return new Font(families[i], style, size);
  827. }
  828. }
  829. return new Font(otherwise, style, size);
  830. }
  831. }
  832. }
  833. /***** BEGIN LICENSE BLOCK *****
  834. * Version: CPL 1.0/GPL 2.0/LGPL 2.1
  835. *
  836. * The contents of this file are subject to the Common Public
  837. * License Version 1.0 (the "License"); you may not use this file
  838. * except in compliance with the License. You may obtain a copy of
  839. * the License at http://www.eclipse.org/legal/cpl-v10.html
  840. *
  841. * Software distributed under the License is distributed on an "AS
  842. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  843. * implied. See the License for the specific language governing
  844. * rights and limitations under the License.
  845. *
  846. * Copyright (C) 2007 Ola Bini <ola@ologix.com>
  847. *
  848. * Alternatively, the contents of this file may be used under the terms of
  849. * either of the GNU General Public License Version 2 or later (the "GPL"),
  850. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  851. * in which case the provisions of the GPL or the LGPL are applicable instead
  852. * of those above. If you wish to allow use of your version of this file only
  853. * under the terms of either the GPL or the LGPL, and not to allow others to
  854. * use your version of this file under the terms of the CPL, indicate your
  855. * decision by deleting the provisions above and replace them with the notice
  856. * and other provisions required by the GPL or the LGPL. If you do not delete
  857. * the provisions above, a recipient may use your version of this file under
  858. * the terms of any one of the CPL, the GPL or the LGPL.
  859. ***** END LICENSE BLOCK *****/
  860. package org.jruby;
  861. import java.io.BufferedWriter;
  862. import java.io.OutputStreamWriter;
  863. import java.net.InetAddress;
  864. import java.net.Socket;
  865. /**
  866. * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
  867. */
  868. public class JRubyClient extends JRubyService {
  869. public JRubyClient(String[] args) throws Exception {
  870. Configuration conf = new Configuration(args[0]);
  871. if(conf.isDebug()) {
  872. System.err.println("Starting client with port " + conf.getPort() + ", key " + conf.getKey() + " and command " + conf.getCommand());
  873. }
  874. Socket socket = new Socket(InetAddress.getLocalHost(), conf.getPort());
  875. BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
  876. if(conf.terminate()) {
  877. writer.write(CMD_TERM + " " + conf.getKey() + "\n");
  878. } else if(conf.noMore()) {
  879. writer.write(CMD_NO_MORE + " " + conf.getKey() + "\n");
  880. } else {
  881. writer.write(CMD_START + " " + conf.getKey() + " " + conf.getCommand() + "\n");
  882. }
  883. writer.flush();
  884. writer.close();
  885. socket.close();
  886. }
  887. public static void main(String[] args) throws Exception {
  888. new JRubyClient(args);
  889. }
  890. }// JRubyClient
  891. /*
  892. ***** BEGIN LICENSE BLOCK *****
  893. * Version: CPL 1.0/GPL 2.0/LGPL 2.1
  894. *
  895. * The contents of this file are subject to the Common Public
  896. * License Version 1.0 (the "License"); you may not use this file
  897. * except in compliance with the License. You may obtain a copy of
  898. * the License at http://www.eclipse.org/legal/cpl-v10.html
  899. *
  900. * Software distributed under the License is distributed on an "AS
  901. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  902. * implied. See the License for the specific language governing
  903. * rights and limitations under the License.
  904. *
  905. * Copyright (C) 2007 Ola Bini <ola@ologix.com>
  906. *
  907. * Alternatively, the contents of this file may be used under the terms of
  908. * either of the GNU General Public License Version 2 or later (the "GPL"),
  909. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  910. * in which case the provisions of the GPL or the LGPL are applicable instead
  911. * of those above. If you wish to allow use of your version of this file only
  912. * under the terms of either the GPL or the LGPL, and not to allow others to
  913. * use your version of this file under the terms of the CPL, indicate your
  914. * decision by deleting the provisions above and replace them with the notice
  915. * and other provisions required by the GPL or the LGPL. If you do not delete
  916. * the provisions above, a recipient may use your version of this file under
  917. * the terms of any one of the CPL, the GPL or the LGPL.
  918. ***** END LICENSE BLOCK *****/
  919. package org.jruby;
  920. import java.io.BufferedReader;
  921. import java.io.InputStreamReader;
  922. import java.net.InetAddress;
  923. import java.net.InetSocketAddress;
  924. import java.net.ServerSocket;
  925. import java.net.Socket;
  926. import java.util.List;
  927. import java.util.ArrayList;
  928. /**
  929. * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
  930. */
  931. public class JRubyServer extends JRubyService {
  932. private Configuration conf;
  933. private boolean stillStarting = true;
  934. private JRubyServer(String[] args) throws Exception {
  935. conf = new Configuration(args[0]);
  936. if(conf.isDebug()) {
  937. System.err.println("Starting server with port " + conf.getPort() + " and key " + conf.getKey());
  938. }
  939. ServerSocket server = new ServerSocket();
  940. server.bind(new InetSocketAddress(InetAddress.getLocalHost(),conf.getPort()));
  941. while(true) {
  942. Thread t1 = new Thread(new Handler(server.accept()));
  943. t1.setDaemon(true);
  944. t1.start();
  945. }
  946. }
  947. private class Handler implements Runnable {
  948. private Socket socket;
  949. public Handler(Socket socket) {
  950. this.socket = socket;
  951. }
  952. public void run() {
  953. try {
  954. BufferedReader rr = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
  955. String command = rr.readLine();
  956. rr.close();
  957. this.socket.close();
  958. this.socket = null;
  959. if(conf.isDebug()) {
  960. System.err.println("Got command: " + command);
  961. }
  962. String[] cmds = command.split(" ", 3);
  963. if(cmds[1].equals(conf.getKey())) {
  964. if(cmds[0].equals(CMD_TERM)) {
  965. if(conf.isDebug()) {
  966. System.err.println("Terminating hard");
  967. }
  968. System.exit(0);
  969. } else if(cmds[0].equals(CMD_NO_MORE)) {
  970. if(conf.isDebug()) {
  971. System.err.println("Accepting no more START");
  972. }
  973. stillStarting = false;
  974. } else if(cmds[0].equals(CMD_START)) {
  975. if(stillStarting) {
  976. if(conf.isDebug()) {
  977. System.err.println("Doing START on command " + cmds[2]);
  978. }
  979. new Main().run(intoCommandArguments(cmds[2].trim()));
  980. } else {
  981. if(conf.isDebug()) {
  982. System.err.println("Not doing START anymore, invalid command");
  983. }
  984. }
  985. } else {
  986. if(conf.isDebug()) {
  987. System.err.println("Unrecognized command");
  988. }
  989. }
  990. } else {
  991. if(conf.isDebug()) {
  992. System.err.println("Invalid key");
  993. }
  994. }
  995. } catch(Exception e) {}
  996. }
  997. }
  998. protected static String[] intoCommandArguments(String str) {
  999. List<String> args = new ArrayList<String>();
  1000. boolean inSingle = false;
  1001. int contentStart = -1;
  1002. for(int i=0,j=str.length();i<j;i++) {
  1003. if(str.charAt(i) == ' ' && !inSingle && contentStart != -1) {
  1004. args.add(str.substring(contentStart,i));
  1005. contentStart = -1;
  1006. continue;
  1007. }
  1008. if(str.charAt(i) == ' ') {
  1009. continue;
  1010. }
  1011. if(str.charAt(i) == '\'' && !inSingle) {
  1012. inSingle = true;
  1013. contentStart = i+1;
  1014. continue;
  1015. }
  1016. if(str.charAt(i) == '\'') {
  1017. inSingle = false;
  1018. args.add(str.substring(contentStart,i));
  1019. contentStart = -1;
  1020. continue;
  1021. }
  1022. if(contentStart == -1) {
  1023. contentStart = i;
  1024. }
  1025. }
  1026. if(contentStart != -1) {
  1027. args.add(str.substring(contentStart));
  1028. }
  1029. return (String[])args.toArray(new String[0]);
  1030. }
  1031. public static void main(String[] args) throws Exception {
  1032. new JRubyServer(args);
  1033. }
  1034. }// JRubyServer
  1035. /***** BEGIN LICENSE BLOCK *****
  1036. * Version: CPL 1.0/GPL 2.0/LGPL 2.1
  1037. *
  1038. * The contents of this file are subject to the Common Public
  1039. * License Version 1.0 (the "License"); you may not use this file
  1040. * except in compliance with the License. You may obtain a copy of
  1041. * the License at http://www.eclipse.org/legal/cpl-v10.html
  1042. *
  1043. * Software distributed under the License is distributed on an "AS
  1044. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  1045. * implied. See the License for the specific language governing
  1046. * rights and limitations under the License.
  1047. *
  1048. * Copyright (C) 2007 Ola Bini <ola@ologix.com>
  1049. *
  1050. * Alternatively, the contents of this file may be used under the terms of
  1051. * either of the GNU General Public License Version 2 or later (the "GPL"),
  1052. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  1053. * in which case the provisions of the GPL or the LGPL are applicable instead
  1054. * of those above. If you wish to allow use of your version of this file only
  1055. * under the terms of either the GPL or the LGPL, and not to allow others to
  1056. * use your version of this file under the terms of the CPL, indicate your
  1057. * decision by deleting the provisions above and replace them with the notice
  1058. * and other provisions required by the GPL or the LGPL. If you do not delete
  1059. * the provisions above, a recipient may use your version of this file under
  1060. * the terms of any one of the CPL, the GPL or the LGPL.
  1061. ***** END LICENSE BLOCK *****/
  1062. package org.jruby;
  1063. /**
  1064. * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
  1065. */
  1066. public abstract class JRubyService {
  1067. protected static class Configuration {
  1068. private final static int DEFAULT_PORT = 19222;
  1069. private String key;
  1070. private int port = DEFAULT_PORT;
  1071. private boolean terminate;
  1072. private boolean noMore;
  1073. private boolean debug;
  1074. private String command;
  1075. public Configuration(String args) {
  1076. int i=0;
  1077. int stop;
  1078. loop: for(int j=args.length();i<j;i++) {
  1079. if(args.charAt(i) == '-' && i+1 < j) {
  1080. switch(args.charAt(++i)) {
  1081. case 'k':
  1082. stop = args.indexOf(" ", (++i) + 1);
  1083. if(stop == -1) {
  1084. stop = args.length();
  1085. }
  1086. key = args.substring(i, stop).trim();
  1087. i = stop;
  1088. break;
  1089. case 'p':
  1090. stop = args.indexOf(" ", (++i) + 1);
  1091. if(stop == -1) {
  1092. stop = args.length();
  1093. }
  1094. port = Integer.parseInt(args.substring(i, stop).trim());
  1095. i = stop;
  1096. break;
  1097. case 't':
  1098. terminate = true;
  1099. i++;
  1100. break;
  1101. case 'n':
  1102. noMore = true;
  1103. i++;
  1104. break;
  1105. case 'd':
  1106. debug = true;
  1107. i++;
  1108. break;
  1109. case '-': // handle everything after -- as arguments to the jruby process
  1110. i++;
  1111. break loop;
  1112. default:
  1113. i--;
  1114. break loop;
  1115. }
  1116. } else if(args.charAt(i) != ' ') {
  1117. break loop;
  1118. }
  1119. }
  1120. if(i<args.length()) {
  1121. command = args.substring(i).trim();
  1122. }
  1123. }
  1124. public String getKey() {
  1125. return key;
  1126. }
  1127. public int getPort() {
  1128. return port;
  1129. }
  1130. public boolean terminate() {
  1131. return terminate;
  1132. }
  1133. public boolean noMore() {
  1134. return noMore;
  1135. }
  1136. public boolean isDebug() {
  1137. return debug;
  1138. }
  1139. public String getCommand() {
  1140. return command;
  1141. }
  1142. }
  1143. public static final String CMD_START = "START";
  1144. public static final String CMD_NO_MORE = "NO_MORE";
  1145. public static final String CMD_TERM = "TERM";
  1146. }// JRubyService
  1147. /*
  1148. ***** BEGIN LICENSE BLOCK *****
  1149. * Version: CPL 1.0/GPL 2.0/LGPL 2.1
  1150. *
  1151. * The contents of this file are subject to the Common Public
  1152. * License Version 1.0 (the "License"); you may not use this file
  1153. * except in compliance with the License. You may obtain a copy of
  1154. * the License at http://www.eclipse.org/legal/cpl-v10.html
  1155. *
  1156. * Software distributed under the License is distributed on an "AS
  1157. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  1158. * implied. See the License for the specific language governing
  1159. * rights and limitations under the License.
  1160. *
  1161. * Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
  1162. * Copyright (C) 2001-2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
  1163. * Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
  1164. * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
  1165. * Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
  1166. * Copyright (C) 2004-2006 Charles O Nutter <headius@headius.com>
  1167. * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
  1168. * Copyright (C) 2005 Kiel Hodges <jruby-devel@selfsosoft.com>
  1169. * Copyright (C) 2005 Jason Voegele <jason@jvoegele.com>
  1170. * Copyright (C) 2005 Tim Azzopardi <tim@tigerfive.com>
  1171. *
  1172. * Alternatively, the contents of this file may be used under the terms of
  1173. * either of the GNU General Public License Version 2 or later (the "GPL"),
  1174. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  1175. * in which case the provisions of the GPL or the LGPL are applicable instead
  1176. * of those above. If you wish to allow use of your version of this file only
  1177. * under the terms of either the GPL or the LGPL, and not to allow others to
  1178. * use your version of this file under the terms of the CPL, indicate your
  1179. * decision by deleting the provisions above and replace them with the notice
  1180. * and other provisions required by the GPL or the LGPL. If you do not delete
  1181. * the provisions above, a recipient may use your version of this file under
  1182. * the terms of any one of the CPL, the GPL or the LGPL.
  1183. ***** END LICENSE BLOCK *****/
  1184. package org.jruby;
  1185. import java.io.InputStream;
  1186. import java.io.PrintStream;
  1187. import org.jruby.exceptions.MainExitException;
  1188. import org.jruby.exceptions.RaiseException;
  1189. import org.jruby.exceptions.ThreadKill;
  1190. import org.jruby.runtime.ThreadContext;
  1191. import org.jruby.runtime.builtin.IRubyObject;
  1192. import org.jruby.util.SafePropertyAccessor;
  1193. import org.jruby.util.SimpleSampler;
  1194. /**
  1195. * Class used to launch the interpreter.
  1196. * This is the main class as defined in the jruby.mf manifest.
  1197. * It is very basic and does not support yet the same array of switches
  1198. * as the C interpreter.
  1199. * Usage: java -jar jruby.jar [switches] [rubyfile.rb] [arguments]
  1200. * -e 'command' one line of script. Several -e's allowed. Omit [programfile]
  1201. * @author jpetersen
  1202. */
  1203. public class Main {
  1204. private boolean hasPrintedUsage = false;
  1205. private final RubyInstanceConfig config;
  1206. public Main(RubyInstanceConfig config) {
  1207. this.config = config;
  1208. }
  1209. public Main(final InputStream in, final PrintStream out, final PrintStream err) {
  1210. this(new RubyInstanceConfig(){{
  1211. setInput(in);
  1212. setOutput(out);
  1213. setError(err);
  1214. }});
  1215. }
  1216. public Main() {
  1217. this(new RubyInstanceConfig());
  1218. }
  1219. public static void main(String[] args) {
  1220. Main main = new Main();
  1221. try {
  1222. int status = main.run(args);
  1223. if (status != 0) {
  1224. System.exit(status);
  1225. }
  1226. } catch (RaiseException re) {
  1227. throw re;
  1228. } catch (Throwable t) {
  1229. // print out as a nice Ruby backtrace
  1230. System.err.println(ThreadContext.createRawBacktraceStringFromThrowable(t));
  1231. System.exit(1);
  1232. }
  1233. }
  1234. public int run(String[] args) {
  1235. try {
  1236. config.processArguments(args);
  1237. return run();
  1238. } catch (MainExitException mee) {
  1239. if (!mee.isAborted()) {
  1240. config.getOutput().println(mee.getMessage());
  1241. if (mee.isUsageError()) {
  1242. printUsage();
  1243. }
  1244. }
  1245. return mee.getStatus();
  1246. } catch (OutOfMemoryError oome) {
  1247. // produce a nicer error since Rubyists aren't used to seeing this
  1248. System.gc();
  1249. String memoryMax = SafePropertyAccessor.getProperty("jruby.memory.max");
  1250. String message = "";
  1251. if (memoryMax != null) {
  1252. message = " of " + memoryMax;
  1253. }
  1254. System.err.println("Error: Your application used more memory than the safety cap" + message + ".");
  1255. System.err.println("Specify -J-Xmx####m to increase it (#### = cap size in MB).");
  1256. if (config.getVerbose()) {
  1257. System.err.println("Exception trace follows:");
  1258. oome.printStackTrace();
  1259. } else {
  1260. System.err.println("Specify -w for full OutOfMemoryError stack trace");
  1261. }
  1262. return 1;
  1263. } catch (StackOverflowError soe) {
  1264. // produce a nicer error since Rubyists aren't used to seeing this
  1265. System.gc();
  1266. String stackMax = SafePropertyAccessor.getProperty("jruby.stack.max");

Large files files are truncated, but you can click here to view the full file