/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.apps.charvabsh; import bsh.ConsoleInterface; import bsh.EvalError; import bsh.Interpreter; import bsh.TargetError; import charva.awt.BorderLayout; import charva.awt.Color; import charva.awt.Container; import charva.awt.Toolkit; import charva.awt.event.ActionEvent; import charva.awt.event.ActionListener; import charva.awt.event.KeyAdapter; import charva.awt.event.KeyEvent; import charvax.swing.BoxLayout; import charvax.swing.JFrame; import charvax.swing.JLabel; import charvax.swing.JMenu; import charvax.swing.JMenuBar; import charvax.swing.JMenuItem; import charvax.swing.JOptionPane; import charvax.swing.JPanel; import charvax.swing.JScrollPane; import charvax.swing.JTextArea; import charvax.swing.border.TitledBorder; import gnu.java.io.NullOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.net.MalformedURLException; import java.net.URL; import javax.naming.NameNotFoundException; import org.jnode.shell.CommandShell; import org.jnode.shell.Shell; import org.jnode.shell.ShellException; import org.jnode.shell.ShellUtils; /** * A charva based beanshell interface. */ public class CharvaBsh { static String example = "int i=0;\nfor (i=0;i<2;i++)\nprint(i+\".\");\n return i;\n"; /** * Startup method. */ public static void main(String[] args) { Toolkit.getDefaultToolkit().register(); System.err.println("Starting Charva Shell"); CharvaShell testwin = new CharvaShell(); testwin.show(); } static class CharvaShell extends JFrame { private JPanel bshPanel = new JPanel(); private JPanel messagePanel = new JPanel(); private JLabel topLabel; private JLabel bottomLabel; private JTextArea editor; private JTextArea output; private Interpreter interpreter; void showSaveDialog() { String s = JOptionPane .showInputDialog(this, "Enter a filename to save", "Save what file", JOptionPane.QUESTION_MESSAGE); if (s == null) { output.append("\nFile Save Cancelled."); } else { output.append("\nSaving file=" + s); try { saveText(s); } catch (MalformedURLException e) { e.printStackTrace(); output.append(e.getMessage()); } catch (IOException e) { e.printStackTrace(); } } } void showLoadDialog() { String s = JOptionPane .showInputDialog(this, "Enter a filename to load", "Load what file", JOptionPane.QUESTION_MESSAGE); if (s == null) { output.append("\nFile Load Cancelled."); } else { output.append("\nLoading file=" + s); try { loadText(s); } catch (MalformedURLException e) { e.printStackTrace(); output.append(e.getMessage()); } catch (IOException e) { e.printStackTrace(); } } } void loadText(String filename) throws IOException { final URL url = new URL(filename); final InputStream is = url.openConnection().getInputStream(); try { int ch; final StringBuffer buf = new StringBuffer(); while ((ch = is.read()) >= 0) { buf.append((char) ch); } editor.setText(buf.toString()); repaint(); } finally { is.close(); } } void saveText(String filename) throws IOException { final URL url = new URL(filename); final OutputStream os = url.openConnection().getOutputStream(); String text = editor.getText(); try { for (int i = 0; i < text.length(); i++) { char ch = text.charAt(i); os.write(ch); } os.flush(); } finally { os.close(); } } void debug(String text) { output.setText(text); repaint(); } void done() { debug("Called done in CharvaBsh."); hide(); debug("Calling close"); Toolkit.getDefaultToolkit().close(); System.err.println("Finished with Done"); } void requestShell() { Toolkit.getDefaultToolkit().unregister(); debug("Finished requesting shell"); } public CharvaShell() { super("Charva Beanshell v1.0"); setForeground(Color.green); setBackground(Color.black); Container cp = super.getContentPane(); cp.setLayout(new BorderLayout()); addMenuBar(); messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.Y_AXIS)); topLabel = new JLabel("F12[evaluate], F1[clear-output], F5[clear-editor]"); messagePanel.add(topLabel); bottomLabel = new JLabel(""); messagePanel.add(bottomLabel); cp.add(messagePanel, BorderLayout.SOUTH); editor = new JTextArea(example, 8, 75); JScrollPane scrollEditor = new JScrollPane(editor); scrollEditor.setViewportBorder(new TitledBorder("Beanshell Editor")); output = new JTextArea("BSH output", 7, 75); output.setLineWrap(true); JScrollPane scrollOutput = new JScrollPane(output); scrollOutput.setViewportBorder(new TitledBorder("Beanshell Output")); bshPanel.setLayout(new BorderLayout()); bshPanel.add(scrollEditor, BorderLayout.NORTH); bshPanel.add(scrollOutput, BorderLayout.SOUTH); cp.add(bshPanel, BorderLayout.CENTER); editor.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent ke) { if (ke.getKeyCode() == KeyEvent.VK_F12) { evaluateText(); repaint(); } if (ke.getKeyCode() == KeyEvent.VK_F1) { output.setText(""); output.repaint(); } if (ke.getKeyCode() == KeyEvent.VK_F5) { editor.setText(""); editor.repaint(); } } }); editor.requestFocus(); // BSHOutputAdapter out = new BSHOutputAdapter(output); ConsoleInterface bshConsole = new BSHConsole(output); interpreter = new Interpreter(bshConsole); interpreter.setClassLoader(Thread.currentThread().getContextClassLoader()); CharvaBshCommandInvoker shell = new CharvaBshCommandInvoker(); try { interpreter.set("interpreter", interpreter); interpreter.set("shell", shell); } catch (EvalError evalError) { writeError(evalError); } setLocation(0, 0); setSize(80, 24); validate(); } private void addMenuBar() { JMenuBar menubar = new JMenuBar(); JMenu jMenuFile = new JMenu("File"); jMenuFile.setMnemonic('F'); JMenuItem exit = new JMenuItem("Exit"); exit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae_) { done(); } }); JMenuItem loadItem = new JMenuItem("Load"); loadItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae_) { showLoadDialog(); } }); JMenuItem saveItem = new JMenuItem("Save"); saveItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae_) { showSaveDialog(); } }); JMenuItem eval = new JMenuItem("Evaluate"); eval.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae_) { evaluateText(); repaint(); } }); menubar.add(jMenuFile); jMenuFile.add(eval); jMenuFile.add(exit); jMenuFile.add(saveItem); jMenuFile.add(loadItem); setJMenuBar(menubar); } private void evaluateText() { interpreter.setClassLoader(Thread.currentThread().getContextClassLoader()); String sourcecode = editor.getText(); // System.out.println( "Evaluating source string=" + sourcecode ); topLabel.setText("Evaluating..."); repaint(); // Interpreter interpreter = new Interpreter(); try { Object out = interpreter.eval(sourcecode); if (out != null) { bottomLabel.setText("Result=" + out); } else { bottomLabel.setText("Null Result."); } topLabel.setText("Press F12 to Evaluate."); repaint(); } catch (EvalError evalError) { writeError(evalError); } } private void writeError(EvalError evalError) { output.append("<Evaluation Error>\n" + evalError); if (evalError instanceof TargetError) { TargetError te = (TargetError) evalError; StringWriter wr = new StringWriter(); Throwable target = te.getTarget(); target.printStackTrace(new PrintWriter(wr)); String text = wr.toString(); output.append("\n" + text); } } } static class BSHConsole implements ConsoleInterface { BSHOutputAdapter out; Reader reader = new StringReader("456"); public BSHConsole(JTextArea output) { this.out = new BSHOutputAdapter(output); } public Reader getIn() { return reader; } public PrintStream getOut() { return out; } public PrintStream getErr() { return out; } public void println(Object o) { out.println(o); } public void print(Object o) { out.print(o); } public void error(Object o) { out.print(o); } } static class BSHOutputAdapter extends PrintStream { JTextArea target; public BSHOutputAdapter(JTextArea target) { this(target, new NullOutputStream()); } public BSHOutputAdapter(JTextArea target, OutputStream out) { super(out); this.target = target; } public void print(String s) { target.append(s); target.repaint(); } public void println(String s) { target.append(s + "\n"); target.repaint(); } public void println(Object obj) { if (obj == null) { println("null"); } else { println(obj.toString()); } } public void print(Object obj) { if (obj == null) { print("null"); } else { print(obj.toString()); } } public void println() { print("\n"); } public void print(int i) { print(i + ""); } public void println(int i) { println("" + i); } } static class CharvaBshCommandInvoker { private Shell shell; public CharvaBshCommandInvoker() { try { shell = ShellUtils.getShellManager().getCurrentShell(); } catch (NameNotFoundException e) { e.printStackTrace(); } } public void invoke(String command) { if (shell != null) { if (shell instanceof CommandShell) { CommandShell cs = (CommandShell) shell; try { cs.runCommand(command); } catch (ShellException ex) { System.err.println("Command invocation failed: " + ex.getMessage()); } } else { System.err.println("Shell wasn't a CommandShell: " + shell.getClass()); } } else { System.err.println("Shell is null."); } } } }