Package examples.socket.plugin

Source Code of examples.socket.plugin.DynamicDataSocket

/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* This program 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 program 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
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2003, by :
*     Corporate:
*         Astrium SAS
*         EADS CRC
*     Individual:
*         Nicolas Brodu
*         Christian Fleischer
*
* $Id: SocketDataSourceCollection.java,v 1.3 2008/02/25 11:33:45 ogor Exp $
*
* Changes
* -------
* 02-Dec-2003 : Creation Date (CF);
*
*/
package examples.socket.plugin;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//import javax.swing.Timer;
import javax.swing.JOptionPane;
import javax.swing.undo.CompoundEdit;

import java.lang.NumberFormatException;

import jsynoptic.base.ContextualActionProvider;
import jsynoptic.ui.LongAction;
import simtools.data.DataInfo;
import simtools.data.DynamicDataSourceCollection;
import simtools.data.UnsupportedOperation;
import simtools.data.ValueProvider;
import simtools.data.buffer.DelayedBuffer;

import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;


/****************************************************************************
* This class provides the low-level access to sockets that
* is used in the SocketDataSourceCollection later
****************************************************************************/

class DynamicDataSocket {

  protected ServerSocket server = null;
  protected Socket client = null;
  protected BufferedReader in = null;

    /*****************************************************************************
     * closes all socket-communication objects
     * and sets values to "null" to show that no connection exists
     *****************************************************************************/
   
    protected void close() {
    try{
      if (in != null)      // close only if valid
        in.close();      // close
      in= null;          // keep in mind that connection is closed

      if (server != null// close only if valid
        server.close()// close
      server= null;      // keep in mind that connection is closed
    } catch (IOException e) {
      System.out.println("Could not close.");
    }
  }

  /*****************************************************************************
   * connects the plugin to the port with the number "portNumber";
   * throws some exceptions if that is not possible;
   * the waiting is done with a timeout, and the
   * SocketTimeoutException is thrown, if the timeout is met.
   * sets also a buffered reader to get the data; the buffer reader
   * has a very short timeout for the polling-mode
     *****************************************************************************/
 
  public void open(int portNumber) throws SocketTimeoutException,IOException {
    try {
      server= new ServerSocket(portNumber)// create a new socket object as a server
      server.setSoTimeout(10000);            // set the timeout for the accept-operation
      client = server.accept();                  // wait (with timeout) for a client to connect
      client.setSoTimeout(1);                  // set the timeout for all read operations
      in = new BufferedReader(new InputStreamReader(client.getInputStream()))// create a comfortable buffered reader for the socket
    } catch (SocketTimeoutException E) {
      close();      // close the server-object before...
      throw E;    // passing the exception on...
    catch (IOException E) {
      close();      // close the server-object before...
      throw E;    // passing the exception on...
    }   
  }

  /*****************************************************************************
   * reads a line (waits for CR!!) from the client;
   * if a timeout in the bind(...) method is set it only waits that amount
   * of time before returning "null" if no data is read;
   * otherwise it just returns the string that has been read
   *****************************************************************************/
 
  public String readData() {

    try {
      return in.readLine();                // read a complete line (waits for CR!!!) from the client
    } catch (SocketTimeoutException e) {
      } catch (IOException e) {
      System.out.println("Read failed!");
    }
   
    return null;                          // return empty line if we couldn't read anything
  }

  /****************************************************************************
   * just the default-constructor
   *****************************************************************************/

  public DynamicDataSocket() {
    // currently nothing needs to be done here...
  }

  /****************************************************************************
   * we need to clean up some stuff here...
   *****************************************************************************/

  protected void finalize() {
    close()// release the socket connection (close)...
  }
}

/****************************************************************************
* This class is the DynamicDataSourceCollection for data
* that is received over a socket
*****************************************************************************/

public class SocketDataSourceCollection extends DynamicDataSourceCollection  implements ActionListener, ContextualActionProvider {

  protected DynamicDataSocket socket= new DynamicDataSocket()// the socket that is used
  //protected Timer timer= new Timer(10, this);                        // the timer that calls the read-method periodically (polling)
  protected Thread thread = new Thread() {
    public void run() {
      while (!isInterrupted()) actionPerformed(null);
    }
  };

  /****************************************************************************
   * Adds a new data source to the collection
   ****************************************************************************/
 
  public void addSource() { 
    DataInfo di = new DataInfo// Specify the data information
      "Socket source "+size(),   // Label of the data source : what is displayed
      "socket"+size(),            // Id of the data source : must be unique. Also used by the source providers (see the random plugin)
      "data received over a socket connection\n  (element number "+size()+" in a space separated line with CR)",     // a comment, optional
      "(unknown)"               // this data source unit, optional
    );
       
    createDataSource(di, ValueProvider.DoubleProvider)// create the source, with data type double
   
    try // Wrap a buffer around it so we see past values too
      bufferize(size() -1, new DelayedBuffer(ValueProvider.DoubleProvider, 1000));
    } catch (UnsupportedOperation e) {
      e.printStackTrace();
    }
  }
 
  /****************************************************************************
   * If a source is sorted, this can lead to some optimization.
  ****************************************************************************/
 
  public int sortedOrder(int i) {       
    if (i==0)
      return 1; // time is in ascending order
   
    return super.sortedOrder(i);
  }

  /****************************************************************************
   * Returns information about the collection itself
   ****************************************************************************/
 
  public DataInfo getInformation() {
    return new DataInfo(
      "Socket Connection",    // The name of this data source collection, as appears in the source pane
      "SocketConnection"   // A unique ID. This example supposes there is only one instance of this object
    );
  }

  /****************************************************************************
   * (Part of the ContextualActionProvide interface
   * This adds a contextual popup menu when
   * right-clicking on the collection in the source pane)
   *
   * Return the list of possible actions
   ****************************************************************************/
 
  public String[] getActions(double x, double y, Object o, int context) {
    if (context != SOURCELIST_CONTEXT)
      return null;

    return new String[] { "Add Source", "Bind to Socket", "Release Socket" };
  }

  /****************************************************************************
   * Analyses the String passed as "Input" and extracts the values
   * contained in it; the values are written into the data-buffers
   * in the order they appear in the string
   ****************************************************************************/
 
    protected void processInput(String _Input) {
      if (_Input == null)                      // nothing valid is read...
        return;                              // so return and don't put any data anywhere

    // some stupid apps, like labview, produce fractional numbers like 3,123 and not 3.123 !!
    // convert all "," to "."
    String Input= "";
    for (int i= 0; i < _Input.length(); i++)
      Input+= _Input.charAt(i) == ',' ? '.' : _Input.charAt(i);
       
      String[] StrValues= Input.split(" ");        // split the String at every space to separate the values from each other
    setDoubleValue(0, lastIndex+1);        // write the packet number in the default buffer 0
    int BuffNumber= 1;                    // number of the buffer where the data is put (first one after the default-buffer (packet index))...       
      for (int i= 0; i < StrValues.length && BuffNumber < size(); i++) {          // loop over all values in the string (but only as long as there are enough buffers (without default-buffer: -1!))
        try {
          //System.out.println(BuffNumber+"<"+StrValues[i]+">"); // DEBUG only => resource consuming
        setDoubleValue(BuffNumber, Double.parseDouble(StrValues[i]));    // write the values from the string into the buffer
        BuffNumber++;
      } catch (NumberFormatException E) {
      }
    }
     
    registerNewValues();                  // put all values in the buffers so that they are displayed
    }

  /****************************************************************************
   *  (Timer-Interface)
   * This method is called by the timer each time it triggers;
   * reads data from the socket
   ****************************************************************************/
 
  public void actionPerformed(ActionEvent e) { 
    processInput(socket.readData())// read the data from the socket and process it   
  }

  /****************************************************************************
   * Do one of the actions previously declared by getAction.
   *
   * @param x Coordinate, for example mouse position
   * @param y Coordinate, for example mouse position
   * @param o Object the action should work on.
   * @param action An action returned by a previous getActions call with the same x, y, o parameters
   *               It may be null, in which case the default action is requested for this x,y,o.
   * @return true if the action could be performed
   ****************************************************************************/
 
  public boolean doAction(double x, double y, Object o, String action, CompoundEdit undoableEdit) {

    // bind is selected, so try it!
    if (action.equals("Bind to Socket")) {
      new LongAction(LongAction.LONG_ACTION_SOURCE,this) {
        protected void doAction() {
          String input= JOptionPane.showInputDialog(null, "Enter a port number to open (e.g. 4444)\n(Opening will be done with a timeout after clicking on OK):","4444");
          if (input != null) {
            int portNumber= Integer.parseInt(input);
            try {       
            socket.open(portNumber);    // try to open the socket connection (wait for client)
//            timer.start();                  // start timer for polling on the socket
            thread.start();
            } catch (SocketTimeoutException e) {
              JOptionPane.showMessageDialog(null, "Couldn't bind to port "+String.valueOf(portNumber)+": \nTimeout.\nMaybe the client didn't connect in time?");
            } catch (IOException e) {
              JOptionPane.showMessageDialog(null, "Couldn't bind to port "+String.valueOf(portNumber)+". \nMaybe it is already in use (try \"Release Socket\") or blocked by a firewall.");
            }
          }
        }
      }.start(true);
      }
     
    // release is selected, so do it!
    if (action.equals("Release Socket")) {
//      timer.stop();      // no more polling on the socket
      thread.interrupt();
      socket.close();    // close the socket
    }

    // the user wants to add another source-channel, so add one
    if (action.equals("Add Source"))   
        addSource();      // add a new channel
     
    return true;
  }

  /****************************************************************************
   * Returns true if, and only if, it is possible to do the action right now
   * @param x Coordinate, for example mouse position
   * @param y Coordinate, for example mouse position
   * @param o Object the action should work on.
   * @param action An action returned by a previous getActions call with the same x, y, o parameters
   *               It may be null, in which case the default action is requested for this x,y,o.
   * @param context one of the context defined in the ContextualActionProvider class
   * @return true if the action can be performed
   ****************************************************************************/
 
  public boolean canDoAction(double x, double y, Object o, String action, int context) {   
    return true// This example object is always ready to perform the actions it declared
  }

  /****************************************************************************
   * This constructor sets one default-source and some data sources
   * (index of received packets = number of packets).
   ****************************************************************************/
 
  public SocketDataSourceCollection() {
      // Create a first source called "packet index", useful to make XY plots.
      // See addSource() for comments
      createDataSource(new DataInfo("packet index","packet index","number of packets received",""), ValueProvider.DoubleProvider);
     
      try // Wrap a buffer around it so we see past values too
      bufferize(0, new DelayedBuffer(ValueProvider.DoubleProvider, 1000));
      } catch (UnsupportedOperation e) {
        e.printStackTrace();
      }   
      for (int i= 0; i < 10; i++)
        addSource();
  }
 
}
TOP

Related Classes of examples.socket.plugin.DynamicDataSocket

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.