From: krakjoe Date: Fri, 29 Nov 2013 09:16:07 +0000 (+0000) Subject: ... X-Git-Tag: php-5.6.0alpha1~110^2~30^2~49 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f0a0f12e1e317d6ac2e053cea71925aedd3009c;p=php ... --- diff --git a/tutorials/java/build/built-jar.properties b/tutorials/java/build/built-jar.properties index 3a123e3581..e642ca0347 100644 --- a/tutorials/java/build/built-jar.properties +++ b/tutorials/java/build/built-jar.properties @@ -1,4 +1,4 @@ -#Fri, 29 Nov 2013 08:22:06 +0000 +#Fri, 29 Nov 2013 09:01:15 +0000 /usr/src/phpdbg/tutorials/java= diff --git a/tutorials/java/dist/phpdbg-ui.jar b/tutorials/java/dist/phpdbg-ui.jar index c4dbea33ad..a2c3c7521e 100644 Binary files a/tutorials/java/dist/phpdbg-ui.jar and b/tutorials/java/dist/phpdbg-ui.jar differ diff --git a/tutorials/java/src/phpdbg/ui/DBGThread.java b/tutorials/java/src/phpdbg/ui/DBGThread.java new file mode 100644 index 0000000000..ee778258fc --- /dev/null +++ b/tutorials/java/src/phpdbg/ui/DBGThread.java @@ -0,0 +1,99 @@ +package phpdbg.ui; + + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * Manage input and output data + * @author krakjoe + */ +public class DBGThread extends Socket implements Runnable { + private final Boolean reader; + private final Main main; + private Boolean quit; + + public DBGThread(final String host, final Integer port, final Main main, Boolean reader) throws IOException { + super(host, port); + + this.main = main; + this.reader = reader; + this.quit = false; + + synchronized(main) { + if (!main.isConnected()) { + main.setConnected(true); + } + } + } + + public void quit() { + synchronized(this) { + quit = true; + this.notifyAll(); + } + } + + @Override public void run() { + try { + synchronized(this) { + do { + if (reader) { + String command; + OutputStream output = getOutputStream(); + + this.wait(); + + command = main.getInputField().getText(); + /* send command to stdin socket */ + if (command != null) { + output.write( + command.getBytes()); + output.write("\n".getBytes()); + output.flush(); + } + main.getInputField().setText(null); + } else { + InputStream input = getInputStream(); + /* get data from stdout socket */ + byte[] bytes = new byte[1]; + do { + /* this is some of the laziest programming I ever done */ + if (input.available() == 0) { + this.wait(400); + continue; + } + + if (input.read(bytes, 0, 1) > -1) { + main.getOutputField() + .appendANSI(new String(bytes)); + } + } while (!quit); + } + } while(!quit); + } + } catch (IOException | InterruptedException ex) { + if (!quit) { + main.messageBox(ex.getMessage()); + } + } finally { + try { + close(); + } catch (IOException ex) { /* naughty me */ } finally { + synchronized(main) { + if (main.isConnected()) { + main.setConnected(false); + } + } + } + } + } +} diff --git a/tutorials/java/src/phpdbg/ui/History.java b/tutorials/java/src/phpdbg/ui/History.java new file mode 100644 index 0000000000..2950087ef8 --- /dev/null +++ b/tutorials/java/src/phpdbg/ui/History.java @@ -0,0 +1,49 @@ +package phpdbg.ui; + + +import java.util.ArrayList; + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * Implement a simple history list for command input + * @author krakjoe + */ +public class History extends ArrayList { + private Integer position = new Integer(0); + + public History() { + super(); + } + + @Override public boolean add(String text) { + String last = last(); + if (text != null) { + if (last == null || !last.equals(text)) { + if (super.add(text)) { + position = size(); + return true; + } + } + } + return false; + } + + public String last() { + if (position >= 1) { + position--; + return get(position); + } else return new String(); + } + + public String next() { + if (position+1 < size()) { + position++; + return get(position); + } else return new String(); + } +} \ No newline at end of file diff --git a/tutorials/java/src/phpdbg/ui/JTerminalPane.java b/tutorials/java/src/phpdbg/ui/JTerminalPane.java new file mode 100644 index 0000000000..eb93891688 --- /dev/null +++ b/tutorials/java/src/phpdbg/ui/JTerminalPane.java @@ -0,0 +1,162 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package phpdbg.ui; + +/** + * + * @author krakjoe + */ +import javax.swing.*; +import javax.swing.text.*; +import java.awt.Color; + +public class JTerminalPane extends JTextPane { + + private static final Color D_Black = Color.getHSBColor( 0.000f, 0.000f, 0.000f ); + private static final Color D_Red = Color.getHSBColor( 0.000f, 1.000f, 0.502f ); + private static final Color D_Blue = Color.getHSBColor( 0.667f, 1.000f, 0.502f ); + private static final Color D_Magenta = Color.getHSBColor( 0.833f, 1.000f, 0.502f ); + private static final Color D_Green = Color.getHSBColor( 0.333f, 1.000f, 0.502f ); + private static final Color D_Yellow = Color.getHSBColor( 0.167f, 1.000f, 0.502f ); + private static final Color D_Cyan = Color.getHSBColor( 0.500f, 1.000f, 0.502f ); + private static final Color D_White = Color.getHSBColor( 0.000f, 0.000f, 0.753f ); + private static final Color B_Black = Color.getHSBColor( 0.000f, 0.000f, 0.502f ); + private static final Color B_Red = Color.getHSBColor( 0.000f, 1.000f, 1.000f ); + private static final Color B_Blue = Color.getHSBColor( 0.667f, 1.000f, 1.000f ); + private static final Color B_Magenta = Color.getHSBColor( 0.833f, 1.000f, 1.000f ); + private static final Color B_Green = Color.getHSBColor( 0.333f, 1.000f, 1.000f ); + private static final Color B_Yellow = Color.getHSBColor( 0.167f, 1.000f, 1.000f ); + private static final Color B_Cyan = Color.getHSBColor( 0.500f, 1.000f, 1.000f ); + private static final Color B_White = Color.getHSBColor( 0.000f, 0.000f, 1.000f ); + private static final Color cReset = Color.getHSBColor( 0.000f, 0.000f, 0.000f ); + + private Color colorCurrent = cReset; + private String remaining = ""; + + public JTerminalPane() { + super(); + } + + public void append(Color c, String s) { + StyleContext sc = StyleContext.getDefaultStyleContext(); + AttributeSet aset = sc.addAttribute( + SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c); + setCaretPosition(getDocument().getLength()); + setCharacterAttributes(aset, false); + replaceSelection(s); + } + + public void appendANSI(String s) { + int aPos = 0; + int aIndex; + int mIndex; + String tmpString; + boolean stillSearching; + + String addString = remaining + s; + + remaining = ""; + + if (addString.length() > 0) { + aIndex = addString.indexOf("\u001B"); + if (aIndex == -1) { + append(colorCurrent,addString); + return; + } + + if (aIndex > 0) { + tmpString = addString.substring(0,aIndex); + append(colorCurrent, tmpString); + aPos = aIndex; + } + + stillSearching = true; + while (stillSearching) { + mIndex = addString.indexOf("m",aPos); + if (mIndex < 0) { + remaining = addString.substring(aPos,addString.length()); + stillSearching = false; + continue; + } + else { + tmpString = addString.substring(aPos,mIndex+1); + colorCurrent = getANSIColor(tmpString); + } + aPos = mIndex + 1; + + aIndex = addString.indexOf("\u001B", aPos); + + if (aIndex == -1) { + tmpString = addString.substring(aPos,addString.length()); + append(colorCurrent, tmpString); + stillSearching = false; + continue; + } + tmpString = addString.substring(aPos,aIndex); + aPos = aIndex; + append(colorCurrent, tmpString); + } + } + } + + public Color getANSIColor(String ANSIColor) { + switch (ANSIColor) { + case "\u001B[30m": + return D_Black; + case "\u001B[31m": + return D_Red; + case "\u001B[32m": + return D_Green; + case "\u001B[33m": + return D_Yellow; + case "\u001B[34m": + return D_Blue; + case "\u001B[35m": + return D_Magenta; + case "\u001B[36m": + return D_Cyan; + case "\u001B[37m": + return D_White; + case "\u001B[0;30m": + return D_Black; + case "\u001B[0;31m": + return D_Red; + case "\u001B[0;32m": + return D_Green; + case "\u001B[0;33m": + return D_Yellow; + case "\u001B[0;34m": + return D_Blue; + case "\u001B[0;35m": + return D_Magenta; + case "\u001B[0;36m": + return D_Cyan; + case "\u001B[0;37m": + return D_White; + case "\u001B[1;30m": + return B_Black; + case "\u001B[1;31m": + return B_Red; + case "\u001B[1;32m": + return B_Green; + case "\u001B[1;33m": + return B_Yellow; + case "\u001B[1;34m": + return B_Blue; + case "\u001B[1;35m": + return B_Magenta; + case "\u001B[1;36m": + return B_Cyan; + case "\u001B[1;37m": + return B_White; + case "\u001B[0m": + return cReset; + default: + return B_White; + } + } +} diff --git a/tutorials/java/src/phpdbg/ui/Main.form b/tutorials/java/src/phpdbg/ui/Main.form new file mode 100644 index 0000000000..4d4323517e --- /dev/null +++ b/tutorials/java/src/phpdbg/ui/Main.form @@ -0,0 +1,179 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/tutorials/java/src/phpdbg/ui/Main.java b/tutorials/java/src/phpdbg/ui/Main.java new file mode 100644 index 0000000000..62942cbcd8 --- /dev/null +++ b/tutorials/java/src/phpdbg/ui/Main.java @@ -0,0 +1,364 @@ +package phpdbg.ui; + + +import static java.awt.event.KeyEvent.VK_DOWN; +import static java.awt.event.KeyEvent.VK_ENTER; +import static java.awt.event.KeyEvent.VK_UP; +import java.io.IOException; +import javax.swing.JOptionPane; +import javax.swing.JTextArea; +import javax.swing.JTextField; + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * + * @author krakjoe + */ +public class Main extends javax.swing.JDialog { + /** + * Creates user interface + * @param parent + * @param modal + */ + public Main(java.awt.Frame parent, boolean modal) { + super(parent, modal); + initComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + stdoutPopupMenu = new javax.swing.JPopupMenu(); + resetStdout = new javax.swing.JMenuItem(); + mainSplit = new javax.swing.JSplitPane(); + input = new javax.swing.JTextField(); + outputScrollPane = new javax.swing.JScrollPane(); + output = new phpdbg.ui.JTerminalPane(); + host = new javax.swing.JTextField(); + stdoutPort = new javax.swing.JTextField(); + stdinCheckBox = new javax.swing.JCheckBox(); + stdoutCheckBox = new javax.swing.JCheckBox(); + openButton = new javax.swing.JButton(); + stdinPort = new javax.swing.JTextField(); + hostLabel = new javax.swing.JLabel(); + + resetStdout.setText("Clear"); + resetStdout.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + resetStdoutActionPerformed(evt); + } + }); + stdoutPopupMenu.add(resetStdout); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("phpdbg jui"); + + mainSplit.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + mainSplit.setToolTipText(""); + + input.setToolTipText(""); + input.setEnabled(false); + input.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyReleased(java.awt.event.KeyEvent evt) { + inputKeyReleased(evt); + } + }); + mainSplit.setLeftComponent(input); + + outputScrollPane.setViewportView(output); + + mainSplit.setRightComponent(outputScrollPane); + + host.setText("127.0.0.1"); + host.setToolTipText("Set the hostname, or IPv4 address of the machine running the phpdbg remote console server"); + + stdoutPort.setText("8000"); + stdoutPort.setToolTipText(""); + + stdinCheckBox.setSelected(true); + stdinCheckBox.setText("stdin:"); + stdinCheckBox.setToolTipText("Set the port for stdin, or uncheck to disable stdin"); + + stdoutCheckBox.setSelected(true); + stdoutCheckBox.setText("stdout:"); + stdoutCheckBox.setToolTipText("Set the port for stdout, or unset to disable stdout"); + + openButton.setActionCommand("open"); + openButton.setLabel("open"); + openButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + openButtonActionPerformed(evt); + } + }); + + stdinPort.setText("4000"); + stdinPort.setToolTipText(""); + + hostLabel.setText("Hostname:"); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(mainSplit) + .addGroup(layout.createSequentialGroup() + .addComponent(hostLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(host, javax.swing.GroupLayout.DEFAULT_SIZE, 359, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(stdinCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(stdinPort, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(stdoutCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(stdoutPort, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(openButton))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(mainSplit, javax.swing.GroupLayout.DEFAULT_SIZE, 428, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(host, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(openButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(stdoutPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(stdinCheckBox) + .addComponent(stdoutCheckBox) + .addComponent(stdinPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(hostLabel))) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void inputKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_inputKeyReleased + switch (evt.getKeyCode()) { + case VK_ENTER: { + if (in != null) { + history.add(input.getText()); + synchronized(in) { + in.notifyAll(); + } + } + } break; + + case VK_UP: { + String last = history.last(); + if (last.length() > 0) { + input.setText(last); + } + } break; + + case VK_DOWN: { + String next = history.next(); + if (next.length() > 0) { + input.setText(next); + } + } break; + } + }//GEN-LAST:event_inputKeyReleased + + private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed + try { + if (!connected) { + Integer ports[] = new Integer[2]; + String address = getHost(); + + if (address != null) { + ports[0] = stdinCheckBox.isSelected() ? getStdinPort() : -1; + ports[1] = stdoutCheckBox.isSelected() ? getStdoutPort() : -1; + + if (ports[0] != 0 && ports[1] != 0) { + if (stdinCheckBox.isSelected()) { + if (ports[0] > 0) { + in = new DBGThread( + address, ports[0], this, true); + new Thread(in).start(); + } + } + + if (stdoutCheckBox.isSelected()) { + if (ports[1] > 0) { + out = new DBGThread( + address, ports[1], this, false); + new Thread(out).start(); + } + } + } + } + } else { + if (in != null) { + in.quit(); + } + if (out != null) { + out.quit(); + } + } + } catch (IOException ex) { + messageBox(ex.getMessage()); + } + }//GEN-LAST:event_openButtonActionPerformed + + private void resetStdoutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetStdoutActionPerformed + // TODO add your handling code here: + output.setText(null); + }//GEN-LAST:event_resetStdoutActionPerformed + + public Boolean isConnected() { + return connected; + } + + public void setConnected(Boolean isConnected) { + synchronized(this) { + if (isConnected) { + connected = true; + openButton.setText("Disconnect"); + host.setEnabled(false); + stdinPort.setEnabled(false); + stdinCheckBox.setEnabled(false); + if (stdinCheckBox.isSelected()) { + input.setEnabled(true); + } else input.setEnabled(false); + stdoutPort.setEnabled(false); + stdoutCheckBox.setEnabled(false); + } else { + connected = false; + openButton.setText("Connect"); + host.setEnabled(true); + stdinPort.setEnabled(true); + input.setEnabled(false); + stdinCheckBox.setEnabled(true); + stdoutPort.setEnabled(true); + stdoutCheckBox.setEnabled(true); + } + } + } + + public JTextField getInputField() { return input; } + public JTerminalPane getOutputField() { return output; } + + public String getHost() { + String address = host.getText(); + if (address != null && address.length() > 0) { + return address; + } else { + messageBox("Invalid hostname provided !"); + } + + return null; + } + + public Integer getStdinPort() { + try { + return Integer.parseInt(stdinPort.getText()); + } catch (NumberFormatException ex) { + messageBox("Invalid stdin port provided !"); + } + + return 0; + } + + public Integer getStdoutPort() { + try { + return Integer.parseInt(stdoutPort.getText()); + } catch (NumberFormatException ex) { + messageBox("Invalid stdout port provided !"); + } + + return 0; + } + + public synchronized void messageBox(String message) { + JOptionPane.showMessageDialog(this, message); + } + /** + * @param args the command line arguments + */ + public static void main(final String args[]) { + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + + /* Create and display the dialog */ + java.awt.EventQueue.invokeLater(new Runnable() { + @Override public void run() { + dialog = new Main(new javax.swing.JFrame(), true); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(java.awt.event.WindowEvent e) { + if (in != null) + in.quit(); + + if (out != null) + out.quit(); + + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + + private static DBGThread in; + private static DBGThread out; + private static Main dialog; + private static Boolean connected = false; + private static History history = new History(); + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JTextField host; + private javax.swing.JLabel hostLabel; + private javax.swing.JTextField input; + private javax.swing.JSplitPane mainSplit; + private javax.swing.JButton openButton; + private phpdbg.ui.JTerminalPane output; + private javax.swing.JScrollPane outputScrollPane; + private javax.swing.JMenuItem resetStdout; + private javax.swing.JCheckBox stdinCheckBox; + private javax.swing.JTextField stdinPort; + private javax.swing.JCheckBox stdoutCheckBox; + private javax.swing.JPopupMenu stdoutPopupMenu; + private javax.swing.JTextField stdoutPort; + // End of variables declaration//GEN-END:variables +}