Files
2022-12-13 12:44:04 +01:00

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;
}
}