640 lines
15 KiB
Java
640 lines
15 KiB
Java
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
|
|
// Continuous Electron Beam Accelerator Facility
|
|
//
|
|
// This software was developed under a United States Government license
|
|
// described in the NOTICE file included as part of this distribution.
|
|
//
|
|
// Jefferson Lab HPC Group, 12000 Jefferson Ave., Newport News, VA 23606
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Core part of rsvcClient Java Package
|
|
//
|
|
// Author:
|
|
// Jie Chen
|
|
// Jefferson Lab HPC Group
|
|
//
|
|
// Revision History:
|
|
// $Log: rsvcClient.java,v $
|
|
// Revision 1.1.1.1 2000/05/23 15:12:50 pal
|
|
// cdev_psi_1.7.2
|
|
//
|
|
// Revision 1.1 1999/10/18 17:12:39 chen
|
|
// *** empty log message ***
|
|
//
|
|
//
|
|
//
|
|
import rsvcData;
|
|
import rsvcEvent;
|
|
import rsvcConfig;
|
|
import rsvcEventHandler;
|
|
import rsvcClientReader;
|
|
import java.io.*;
|
|
import java.net.*;
|
|
import java.util.*;
|
|
|
|
public final class rsvcClient
|
|
{
|
|
// connection flag
|
|
private boolean connected_ = false;
|
|
|
|
// Socket to the server
|
|
private Socket tcpsocket_ = null;
|
|
|
|
// server information
|
|
private String server_host_ = null;
|
|
private int server_port_ = 0;
|
|
|
|
// internal request id
|
|
private int eventid_ = 1234;
|
|
|
|
// internal client data reader
|
|
private rsvcClientReader reader_ = null;
|
|
|
|
// internal thread id for reader
|
|
private Thread readerthread_ = null;
|
|
|
|
|
|
// output stream
|
|
private OutputStream output_ = null;
|
|
|
|
|
|
/**
|
|
* Construct an empty rsvcClient object
|
|
*/
|
|
public rsvcClient ()
|
|
{
|
|
// empty
|
|
}
|
|
|
|
/**
|
|
* Override default finalize method.This allows Java virtual
|
|
* machine to clean up resource when this object is no longer
|
|
* needed.
|
|
*/
|
|
protected void finalize() throws Throwable
|
|
{
|
|
if (tcpsocket_ != null && connected_ == true) {
|
|
connected_ = false;
|
|
tcpsocket_.close ();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Connect to a server that is on a given host at a given port
|
|
*/
|
|
public synchronized void connect (String host, int port) throws UnknownHostException, IOException
|
|
{
|
|
try {
|
|
tcpsocket_ = new Socket (host, port);
|
|
}catch (UnknownHostException ue){
|
|
System.err.println (ue);
|
|
throw ue;
|
|
}catch (IOException e) {
|
|
System.err.println(e);
|
|
throw e;
|
|
}
|
|
|
|
// set connection flag
|
|
connected_ = true;
|
|
|
|
// cache server information
|
|
server_host_ = new String(host);
|
|
server_port_ = port;
|
|
|
|
|
|
OutputStream toutput = null;
|
|
try {
|
|
toutput = tcpsocket_.getOutputStream();
|
|
}catch (IOException e) {
|
|
System.err.println (e);
|
|
throw e;
|
|
}
|
|
|
|
output_ = toutput;
|
|
|
|
// create a single rsvcClient Data Reader and spawn a new thread
|
|
reader_ = new rsvcClientReader (this);
|
|
|
|
readerthread_ = new Thread (reader_);
|
|
readerthread_.start ();
|
|
}
|
|
|
|
/**
|
|
* Return underlying socket
|
|
*/
|
|
public Socket getSocket () throws NullPointerException
|
|
{
|
|
if (tcpsocket_ == null)
|
|
throw new NullPointerException ("Socket is invalid");
|
|
|
|
return tcpsocket_;
|
|
}
|
|
|
|
/**
|
|
* Return underlying reader thread
|
|
*/
|
|
public Thread getReaderThread () throws NullPointerException
|
|
{
|
|
if (readerthread_ == null)
|
|
throw new NullPointerException ("Reader Thread is not alive");
|
|
return readerthread_;
|
|
}
|
|
|
|
/**
|
|
* Disconnect from the server
|
|
*/
|
|
public synchronized void disconnect () throws IOException
|
|
{
|
|
if (tcpsocket_ == null || connected_ == false)
|
|
throw new IOException ("Socket is not connected to the server");
|
|
|
|
try {
|
|
tcpsocket_.close();
|
|
}catch (IOException e) {
|
|
throw e;
|
|
}
|
|
connected_ = false;
|
|
|
|
// remove all event handlers
|
|
reader_.cleanupEventHandlers ();
|
|
}
|
|
|
|
/**
|
|
* Is connection established
|
|
*/
|
|
public boolean connected ()
|
|
{
|
|
return connected_;
|
|
}
|
|
|
|
/**
|
|
* Register an event handler to handle disconnection event
|
|
*/
|
|
public synchronized boolean addDisconnectHandler (rsvcEventHandler handler)
|
|
{
|
|
return reader_.addDisconnectHandler (handler);
|
|
}
|
|
|
|
/**
|
|
* Handle server unexpected close
|
|
*/
|
|
public int handleClose ()
|
|
{
|
|
try {
|
|
tcpsocket_.close ();
|
|
} catch (IOException e) {
|
|
System.err.println (e);
|
|
connected_ = false;
|
|
return -1;
|
|
}
|
|
connected_ = false;
|
|
|
|
reader_.dispatchDiscEventHandlers ();
|
|
|
|
// clean up all callbacks
|
|
reader_.cleanupEventHandlers ();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* Create a memory based database with an event handler.
|
|
* Data coming back to the event handler contain table definition
|
|
*/
|
|
public rsvcEvent createMemDbase (String tablename, rsvcData data,
|
|
rsvcEventHandler handler) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, tablename);
|
|
try {
|
|
id = sendCommand (rsvcConfig.RSVC_CREATE_MEMTABLE, data,
|
|
handler);
|
|
}catch (IOException e) {
|
|
throw e;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* Open a database with a given name using an event handler.
|
|
* Data retured to the event handler contain definition of database
|
|
*/
|
|
public rsvcEvent openDatabase (String name, rsvcData data,
|
|
rsvcEventHandler handler) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
try {
|
|
id = sendCommand (rsvcConfig.RSVC_OPEN_DBASE, data,
|
|
handler);
|
|
}catch (IOException e) {
|
|
throw e;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* Insert data into a database with a given name.
|
|
* The last argument 'overwrite = 1' selects whether to overwite
|
|
* existing items in the database.
|
|
* Data must match table definition returned from the openDatabase call.
|
|
*/
|
|
public rsvcEvent insertValue (String name, rsvcData data,
|
|
rsvcEventHandler handler,
|
|
boolean overwrite) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
if (overwrite == true) {
|
|
try {
|
|
id = sendCommand (rsvcConfig.RSVC_OVERWRITE, data,
|
|
handler);
|
|
}catch (IOException e) {
|
|
throw e;
|
|
}
|
|
}
|
|
else {
|
|
try {
|
|
id = sendCommand (rsvcConfig.RSVC_INSERT, data,
|
|
handler);
|
|
}catch (IOException e) {
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* Get data out from the database with a given name.
|
|
* Outbound data either contain a tagged value to denote a key value
|
|
* such as : "id", "model+gold" or contain multiple tagged values that
|
|
* can be constructed into a key value
|
|
*/
|
|
public rsvcEvent getValue (String name, rsvcData data,
|
|
rsvcEventHandler handler) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
try {
|
|
id = sendCommand (rsvcConfig.RSVC_GET, data,
|
|
handler);
|
|
}catch (IOException e) {
|
|
throw e;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* Delete a data item from the database with a given name.
|
|
* Outbound data either contain a tagged value to denote a key value
|
|
* such as : "id", "model+gold" or contain multiple tagged values that
|
|
* can be constructed into a key value
|
|
*/
|
|
public rsvcEvent delValue (String name, rsvcData data,
|
|
rsvcEventHandler handler) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
try {
|
|
id = sendCommand (rsvcConfig.RSVC_DEL, data,
|
|
handler);
|
|
}catch (IOException e) {
|
|
throw e;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* Set value for a datum inside database with a given name.
|
|
* The outbound data item either contain a tagged value to denote
|
|
* a index value e.g.: "id", "model+gold"
|
|
* or contains multiple tagged values which can be constructed
|
|
* into a key value
|
|
* plus a subset of tagged values defined in the table definition
|
|
*/
|
|
public rsvcEvent setValue (String name, rsvcData data,
|
|
rsvcEventHandler handler) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
try {
|
|
id = sendCommand (rsvcConfig.RSVC_SET, data,
|
|
handler);
|
|
}catch (IOException e) {
|
|
throw e;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* Monitor on a data item inside a database with a given name.
|
|
* Any changes to this item will trigger an event coming back.
|
|
* The outbound data either contain a tagged value to denote a index value
|
|
* Example: "id", "model+gold"
|
|
* or contains multiple tagged values which can be constructed
|
|
* into a key value.
|
|
*/
|
|
public rsvcEvent monitorValue (String name, rsvcData data,
|
|
rsvcEventHandler handler) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
try {
|
|
id = sendMonitor (rsvcConfig.RSVC_MONITOR_ON, data,
|
|
handler);
|
|
} catch (IOException e) {
|
|
throw e;
|
|
}
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* Monitor off a data inside a database with a given name
|
|
* Outbound data either contain a tagged value to denote a index value
|
|
* Example: "id", "model+gold"
|
|
* or contains multiple tagged values which can be constructed
|
|
* into a key value.
|
|
*/
|
|
public rsvcEvent monitorOffValue (String name, rsvcData data,
|
|
rsvcEvent mid) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
try {
|
|
id = sendMonitorOff (rsvcConfig.RSVC_MONITOR_OFF, data, mid);
|
|
} catch (IOException e) {
|
|
throw e;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* monitor a single attribute of a data inside a database with a given name.
|
|
* any changes to this attribute will trigger an event.
|
|
* Data coming back to the event handler containing a whole data.
|
|
* Outbound data either contain a tagged value to denote a index value
|
|
* Example: "id", "model+gold"
|
|
* or contains multiple tagged values which can be constructed
|
|
* into a key value
|
|
*/
|
|
public rsvcEvent monitorAttr (String name, String attr, rsvcData data,
|
|
rsvcEventHandler handler) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
data.insert (rsvcConfig.RSVC_MONITOR_TAG, attr);
|
|
|
|
try {
|
|
id = sendMonitor (rsvcConfig.RSVC_MONITOR_ONATTR, data,
|
|
handler);
|
|
} catch (IOException e) {
|
|
throw e;
|
|
}
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* Stop monitoring a single attribute of a data inside a database.
|
|
* Outbound data either contain a tagged value to denote a index value
|
|
* Example: "id", "model+gold"
|
|
* or contains multiple tagged values which can be constructed
|
|
* into a key value .
|
|
*/
|
|
public rsvcEvent monitorOffAttr (String name, String attr, rsvcData data,
|
|
rsvcEvent mid) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
data.insert (rsvcConfig.RSVC_MONITOR_TAG, attr);
|
|
|
|
try {
|
|
id = sendMonitorOff (rsvcConfig.RSVC_MONITOR_OFFATTR, data,
|
|
mid);
|
|
} catch (IOException e) {
|
|
throw e;
|
|
}
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* query a particular database 'name'
|
|
* query msg can be like regular C logic expression for all
|
|
* attributes.
|
|
*/
|
|
public rsvcEvent query (String name, String qmsg,
|
|
rsvcEventHandler handler) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
rsvcData data = new rsvcData ();
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
|
|
data.insert (rsvcConfig.RSVC_QUERY_TAG, qmsg);
|
|
|
|
try {
|
|
id = sendCommand (rsvcConfig.RSVC_QUERY, data,
|
|
handler);
|
|
}catch (IOException e) {
|
|
throw e;
|
|
}
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* Monitor incoming entries inside database
|
|
* any insertion to a database will trigger an event
|
|
*/
|
|
public rsvcEvent monitorIncomingEntries (String name, rsvcData data,
|
|
rsvcEventHandler handler) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
try {
|
|
id = sendMonitor (rsvcConfig.RSVC_MONITOR_ENTRIES, data,
|
|
handler);
|
|
} catch (IOException e) {
|
|
throw e;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* Stop monitoring the incoming entries inside database.
|
|
*/
|
|
public rsvcEvent monitorOffIncomingEntries (String name, rsvcData data,
|
|
rsvcEvent mid) throws IOException
|
|
{
|
|
rsvcEvent id = null;
|
|
|
|
data.insert (rsvcConfig.RSVC_TABLE_NAME, name);
|
|
try {
|
|
id = sendMonitorOff(rsvcConfig.RSVC_MONITOR_OFFENTRIES, data,
|
|
mid);
|
|
}catch (IOException e) {
|
|
throw e;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
|
|
/**
|
|
* Generic monitor on command
|
|
*/
|
|
private synchronized rsvcEvent sendMonitor (int opcode, rsvcData data,
|
|
rsvcEventHandler handler) throws IOException
|
|
{
|
|
int status = rsvcConfig.RSVC_SUCCESS;
|
|
|
|
// create an event that is being shipped to server
|
|
rsvcEvent cbk = new rsvcEvent (data);
|
|
cbk.setEventid (eventid_);
|
|
cbk.setOpcode (opcode);
|
|
|
|
|
|
// write this event to server
|
|
int len = cbk.streamSize ();
|
|
// create a buffered data output
|
|
BufferedOutputStream boutput = new BufferedOutputStream (output_, len);
|
|
try {
|
|
cbk.streamOut (boutput);
|
|
}catch (IOException e) {
|
|
System.err.println (e);
|
|
status = rsvcConfig.RSVC_IOFAILED;
|
|
throw e;
|
|
}
|
|
|
|
if (status == rsvcConfig.RSVC_SUCCESS) {
|
|
try {
|
|
boutput.flush ();
|
|
}catch (IOException e) {
|
|
System.err.println (e);
|
|
status = rsvcConfig.RSVC_IOFAILED;
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
if (status == rsvcConfig.RSVC_SUCCESS) {
|
|
cbk.setHandler (handler);
|
|
reader_.addMonitorEventHandler (eventid_, cbk);
|
|
}
|
|
|
|
eventid_ ++;
|
|
return cbk;
|
|
}
|
|
|
|
|
|
/**
|
|
* Generic monitor on command
|
|
*/
|
|
private synchronized rsvcEvent sendMonitorOff (int opcode, rsvcData data,
|
|
rsvcEvent monitorEvent) throws IOException
|
|
{
|
|
int status = rsvcConfig.RSVC_SUCCESS;
|
|
|
|
if (reader_.containsMonitorEvent (monitorEvent) != true) {
|
|
throw new IOException ("Monitor Off using an invalid event");
|
|
}
|
|
|
|
// create new event with differen opcode
|
|
rsvcEvent cbk = new rsvcEvent (monitorEvent);
|
|
cbk.setOpcode (opcode);
|
|
|
|
// write this event to server
|
|
int len = cbk.streamSize ();
|
|
// create a buffered data output
|
|
BufferedOutputStream boutput = new BufferedOutputStream (output_, len);
|
|
try {
|
|
cbk.streamOut (boutput);
|
|
}catch (IOException e) {
|
|
System.err.println (e);
|
|
status = rsvcConfig.RSVC_IOFAILED;
|
|
throw e;
|
|
}
|
|
|
|
if (status == rsvcConfig.RSVC_SUCCESS) {
|
|
try {
|
|
boutput.flush ();
|
|
}catch (IOException e) {
|
|
System.err.println (e);
|
|
status = rsvcConfig.RSVC_IOFAILED;
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
return cbk;
|
|
}
|
|
|
|
|
|
/**
|
|
* Generic command call with ith an event handler.
|
|
* Data coming back to the event handler contain table definition
|
|
*/
|
|
private synchronized rsvcEvent sendCommand (int opcode, rsvcData data,
|
|
rsvcEventHandler handler) throws IOException
|
|
{
|
|
int status = rsvcConfig.RSVC_SUCCESS;
|
|
|
|
// create an event that is being shipped to server
|
|
rsvcEvent cbk = new rsvcEvent (data);
|
|
cbk.setEventid (eventid_);
|
|
cbk.setOpcode (opcode);
|
|
|
|
|
|
// write this event to server
|
|
int len = cbk.streamSize ();
|
|
// create a buffered data output
|
|
BufferedOutputStream boutput = new BufferedOutputStream (output_, len);
|
|
try {
|
|
cbk.streamOut (boutput);
|
|
}catch (IOException e) {
|
|
System.err.println (e);
|
|
status = rsvcConfig.RSVC_IOFAILED;
|
|
throw e;
|
|
}
|
|
|
|
if (status == rsvcConfig.RSVC_SUCCESS) {
|
|
try {
|
|
boutput.flush ();
|
|
}catch (IOException e) {
|
|
System.err.println (e);
|
|
status = rsvcConfig.RSVC_IOFAILED;
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
if (status == rsvcConfig.RSVC_SUCCESS) {
|
|
cbk.setHandler (handler);
|
|
reader_.addCommandEventHandler (eventid_, cbk);
|
|
}
|
|
|
|
eventid_ ++;
|
|
return cbk;
|
|
}
|
|
|
|
|
|
}
|