316 lines
7.8 KiB
Java
316 lines
7.8 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:
|
|
// rsvcClient Reader that is reading data out of socket
|
|
//
|
|
// Author:
|
|
// Jie Chen
|
|
// Jefferson Lab HPC Group
|
|
//
|
|
// Revision History:
|
|
// $Log: rsvcClientReader.java,v $
|
|
// Revision 1.1.1.1 2000/05/23 15:12:50 pal
|
|
// cdev_psi_1.7.2
|
|
//
|
|
// Revision 1.2 1999/12/14 15:38:15 chen
|
|
// Add scrollbar to display
|
|
//
|
|
// Revision 1.1 1999/10/18 17:12:39 chen
|
|
// *** empty log message ***
|
|
//
|
|
//
|
|
//
|
|
//
|
|
import java.io.*;
|
|
import java.net.*;
|
|
import java.util.*;
|
|
import rsvcData;
|
|
import rsvcEvent;
|
|
import rsvcEventHandler;
|
|
import rsvcClient;
|
|
|
|
public final class rsvcClientReader implements Runnable
|
|
{
|
|
// disconnection callback list (list of event handler)
|
|
private Vector discCbkList_ = null;
|
|
|
|
// all send/get command callback list
|
|
private Hashtable cmdCbkList_ = null;
|
|
|
|
// monitor callback list
|
|
private Hashtable monitorCbkTable_ = null;
|
|
|
|
// Input and output buffer
|
|
private DataInputStream input_ = null;
|
|
|
|
// Pointer back to rsvcClient
|
|
private rsvcClient client_;
|
|
|
|
/**
|
|
* Construct a rsvcClientReader from a established client object
|
|
*/
|
|
public rsvcClientReader (rsvcClient client)
|
|
{
|
|
client_ = client;
|
|
|
|
// create lists and a table for event handlers
|
|
discCbkList_ = new Vector ();
|
|
cmdCbkList_ = new Hashtable (20, (float)0.25);
|
|
monitorCbkTable_ = new Hashtable (20, (float)0.25);
|
|
|
|
InputStream tinput = null;
|
|
Socket socket = null;
|
|
|
|
try {
|
|
socket = client_.getSocket();
|
|
}catch (NullPointerException e) {
|
|
System.err.print (e);
|
|
System.exit (-1);
|
|
}
|
|
|
|
try {
|
|
tinput = socket.getInputStream();
|
|
}catch (IOException e) {
|
|
System.err.print (e);
|
|
System.exit (-1);
|
|
}
|
|
input_ = new DataInputStream (tinput);
|
|
}
|
|
|
|
/**
|
|
* Add an event handler to handle disconnection event.
|
|
* Return true if this event handler is registered successfully.
|
|
* Return false if this event handler is already here.
|
|
*/
|
|
public boolean addDisconnectHandler (rsvcEventHandler handler)
|
|
{
|
|
if (discCbkList_.contains (handler) == true)
|
|
return false;
|
|
discCbkList_.addElement (handler);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Clean up all event handlers
|
|
*/
|
|
public void cleanupEventHandlers ()
|
|
{
|
|
discCbkList_.removeAllElements ();
|
|
cmdCbkList_.clear ();
|
|
monitorCbkTable_.clear ();
|
|
}
|
|
|
|
/**
|
|
* Add an event handler to command event handler list
|
|
*/
|
|
public void addCommandEventHandler (int id,
|
|
rsvcEvent oevent)
|
|
{
|
|
// vector is thread safe
|
|
cmdCbkList_.put (new Integer(id), oevent);
|
|
}
|
|
|
|
/**
|
|
* Add an event handler to monitor event handler table
|
|
*/
|
|
public void addMonitorEventHandler (int id, rsvcEvent oevent)
|
|
{
|
|
// vector is thread safe
|
|
monitorCbkTable_.put (new Integer(id), oevent);
|
|
}
|
|
|
|
/**
|
|
* Find out whether a particular event is already in the
|
|
* monitor event handler table
|
|
*/
|
|
public boolean containsMonitorEvent (rsvcEvent event)
|
|
{
|
|
Integer key = new Integer (event.getEventid ());
|
|
return monitorCbkTable_.containsKey (key);
|
|
}
|
|
|
|
/**
|
|
* Dispatch all event handlers when the server goes down
|
|
*/
|
|
public void dispatchDiscEventHandlers ()
|
|
{
|
|
Enumeration list = discCbkList_.elements ();
|
|
rsvcEventHandler handler = null;
|
|
|
|
rsvcEvent event = new rsvcEvent ();
|
|
event.setStatus (rsvcConfig.RSVC_DISCONNECTED);
|
|
|
|
while (list.hasMoreElements ()) {
|
|
handler = (rsvcEventHandler)(list.nextElement());
|
|
handler.handleEvent (event);
|
|
}
|
|
}
|
|
|
|
public void run ()
|
|
{
|
|
// buffer for header
|
|
int headerlen = rsvcEvent.headerLen ();
|
|
byte[] header = new byte[headerlen];
|
|
ByteArrayInputStream bainput = new ByteArrayInputStream (header);
|
|
|
|
// buffer for payload
|
|
int datasize = 4096;
|
|
int prevsize = 4096;
|
|
byte[] payload = new byte[datasize];
|
|
ByteArrayInputStream plinput = new ByteArrayInputStream (payload);
|
|
|
|
// event data object
|
|
rsvcEvent event = new rsvcEvent ();
|
|
|
|
while (true) {
|
|
// read header
|
|
try {
|
|
input_.readFully (header);
|
|
}catch (IOException e) {
|
|
System.err.println ("Server is down");
|
|
client_.handleClose ();
|
|
break;
|
|
}
|
|
|
|
// reset input stream buffer
|
|
bainput.reset ();
|
|
try {
|
|
datasize = rsvcEvent.readHeader (bainput);
|
|
}catch (IOException e) {
|
|
System.err.println ("Receiving header error" + e);
|
|
client_.handleClose ();
|
|
break;
|
|
}
|
|
|
|
|
|
if (datasize > prevsize) {
|
|
datasize = 2*datasize;
|
|
prevsize = datasize;
|
|
payload = new byte[datasize];
|
|
plinput = new ByteArrayInputStream (payload);
|
|
}
|
|
|
|
// read raw bytes of length 'datasize'
|
|
try {
|
|
input_.readFully (payload, 0, datasize);
|
|
}catch (IOException e) {
|
|
System.err.println ("Server is down here");
|
|
client_.handleClose ();
|
|
break;
|
|
}
|
|
|
|
// convert above raw bytes into an event
|
|
plinput.reset ();
|
|
try {
|
|
event.streamIn (plinput);
|
|
}catch (IOException e) {
|
|
System.err.println ("Payload data format error: " + e);
|
|
client_.handleClose ();
|
|
break;
|
|
}
|
|
|
|
// dispatch this event to an appropriate destination
|
|
if (dispatchEvent (event) != 0) {
|
|
client_.handleClose ();
|
|
break;
|
|
}
|
|
}
|
|
System.out.println ("rsvcClientReader Thread is finished");
|
|
|
|
}
|
|
|
|
private int dispatchEvent (rsvcEvent event)
|
|
{
|
|
int op = event.getOpcode ();
|
|
int status = 0;
|
|
|
|
if (op < rsvcConfig.RSVC_MONITOR_ON)
|
|
// all simple command transaction events
|
|
status = dispatchCmdEventFromServer (event);
|
|
else if (op < rsvcConfig.RSVC_OP_UNKNOWN)
|
|
// all monitor events
|
|
status = dispatchMonitorEventFromServer (event);
|
|
else {
|
|
System.err.println ("rsvcClient: Invalid option code: " + String.valueOf(op));
|
|
status = -1;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
private int dispatchCmdEventFromServer (rsvcEvent event)
|
|
{
|
|
Integer key = new Integer (event.getEventid());
|
|
int status = event.getStatus ();
|
|
Object obj = null;
|
|
rsvcEventHandler handler = null;
|
|
rsvcEvent oevent = null;
|
|
|
|
// retrieve object from event which has key value
|
|
obj = cmdCbkList_.get (key);
|
|
|
|
if (obj != null) {
|
|
oevent = (rsvcEvent)obj;
|
|
|
|
if (oevent.match (event) == false) {
|
|
System.err.println ("Incoming and outgoing events are not match");
|
|
return -1;
|
|
}
|
|
|
|
try {
|
|
handler = oevent.getHandler ();
|
|
} catch (NullPointerException e) {
|
|
System.err.println (e);
|
|
return -1;
|
|
}
|
|
handler.handleEvent (event);
|
|
|
|
if (status != rsvcConfig.RSVC_INCOMPLETE)
|
|
cmdCbkList_.remove (event);
|
|
}
|
|
else {
|
|
System.out.println ("rsvcClient: Event from server does not match");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
private int dispatchMonitorEventFromServer (rsvcEvent event)
|
|
{
|
|
Integer key = new Integer (event.getEventid ());
|
|
int status = event.getStatus();
|
|
Object obj = null;
|
|
rsvcEventHandler handler = null;
|
|
rsvcEvent oevent = null;
|
|
|
|
obj = monitorCbkTable_.get (key);
|
|
if (obj != null) {
|
|
oevent = (rsvcEvent)obj;
|
|
try {
|
|
handler = oevent.getHandler ();
|
|
}catch (NullPointerException e) {
|
|
System.err.println (e);
|
|
return -1;
|
|
}
|
|
handler.handleEvent (event);
|
|
|
|
if (status != rsvcConfig.RSVC_SUCCESS &&
|
|
status != rsvcConfig.RSVC_INCOMPLETE) {
|
|
// if an event is bad or finished, remove it
|
|
monitorCbkTable_.remove (event);
|
|
}
|
|
}
|
|
else if (status != rsvcConfig.RSVC_SUCCESS) {
|
|
System.out.println ("rsvcClient: monitor event from server does not match any");
|
|
System.out.println (event.toString());
|
|
}
|
|
return 0;
|
|
}
|
|
}
|