B. Listati dei programmi
B.1 Il package device
Il package device contiene la sola
classe ControllableDevice superclasse dei
dispositivi controllabili.
La classe ControllableDevice
/*
* @(#)
ControllableDevice.java v.0.9 - Gennaio 1997 - by Donato Cappetta
*/
package
device;
/**
* Classe
astratta ControllableDevice che e' una superclasse
* per
i dispositivi elettronici controllabili.
*
* @see
java.lang.Object
* @version
0.9beta Gennaio 1997
* @author
Donato Cappetta <cappetta@diiie.unisa.it>
*/
public
abstract class
ControllableDevice {
/**
* Metodo
che informa se il dispositivo e gia'in uso.
*
* @return
boolean Dispositivo in uso o meno.
*/
public
abstract boolean
inUse();
/**
* Metodo
astratto che informa se il dispositivo puo' essere condiviso
* fra
piu utenti.
*
* @return
'true' se condivisibile o 'false' altrimenti.
*/
public
abstract boolean
isShareble();
/**
* Metodo
astratto che inizializza e istanzia le risorse per
* un nuovo
utente.
*/
public
abstract synchronized
void open();
/**
* Metodo
astratto che chiude e rilascia le risorse.
*/
public
abstract synchronized
void close();
/**
* Metodo
astratto che rappresenta i comandi che possono essere
* impartiti
al dispositivo.
*
* @param
obj Oggetto che informa il dispositivo le operazioni da compiere.
* @return
Risultato dell'operazione.
*/
public
abstract synchronized
Object execute(Object obj);
/**
* Metodo
che restituisce il nome della classe corrente.
*
* @return
Nome della classe corrente.
*/
public
String toString() {
return
this.getClass().getName();
}
} //end
class ControllableObject
B.2 Il package device.server
Questo package contiene le classi: ServerDevice
e ConnectionDevice come previsto in fase
di progetto, inoltre contiene l段nterfaccia ID_Messsage
che consente di stabilire un protocollo al livello delle applicazioni e
la classe IllegalSubclassException che
genera un弾ccezione quando si prova a caricare dinamicamente una classe
e questa non è sottoclasse di una specifica superclasse.
La classe ServerDevice
/*
* @(#)ServerDevice.java
v.0.9 Gennaio 1997 - by Donato Cappetta
*/
package
device.server;
import
java.io.*;
import
java.net.*;
import
java.util.Vector;
import
java.awt.*;
import
device.server.*;
import
device.ControllableDevice;
/**
* Applicazione
server per comunicazione client-server.
* In fase
di avvio ServerDevice carica in un vettore i dispositivi
* controllabili
che gli vengono forniti come parametri.<br>
* ServerDevice
sta in ascolto su una porta specificata in attesa
* di una
connessione. Accettata la connessione ServerDevice affida
* la comunicazione
con il client all'oggetto ConnectionDevice in
* esecuzione
in un Thread, e ServerDevice si pone di nuovo in attesa
* di una'altra
connessione.<br>
* Al thread
viene passato come parametro il vettore dei dispositivi
* e il
socket che ha accettato la connesione
* @see
java.lang.Thread
* @version
0.9 Gennaio 1997
* @author
Donato Cappetta <cappetta@diiie.unisa.it>
*/
public
class ServerDevice extends
Thread {
/**
* Variabile
per acquisire il valore della porta di ascolto
* dalla
linea di comandi.
* Valore
di default 4444.
*/
private
int port = 4444;
/**
* serverSocket
per l'ascolto della connessione.
*/
private
ServerSocket serverSocket = null;
/**
* Nome
e indirizzo della macchina su cui ServerDevice va in esecuzione.
*/
private
InetAddress inetAddress = null;
/**
* Oggetto
di tipo ControllableDevice per caricare
* dinamicamente
le classi.
*/
private
ControllableDevice cd = null;
/**
* Vettore
che contiene le istanze dei dispositivi controllabili
* caricati
dinamicamente.
*/
private
Vector vectorDevice = new Vector();
/**
* Variabile
booleana
*/
private
boolean bool = true;
/**
* Frame
e area di testo inseriti a scopo di debug.
*/
private
Frame frame = null;
/**
* L'area
di testo e dichiarata static in modo che anche altri thread
* possano
stampare messaggi.
*/
public
static TextArea ta = null;
/**
* Metodo
richiamato in caso di fallimento,
* stampa
l'eccezione ed esce.
*
* @param
str Messaggio di errore impostato dal programmatore
* @param
e Eccezione
*/
private
void fail (String str, Exception e) {
ta.appendText(str
+ ": " + e.getMessage() + '\n');
ta.appendText("ServerDevice
v.0.9 - Gennaio 1997 by Donato Cappetta." +'\n');
frame.dispose();
System.exit(0);
} //end
fail()
/**
* Costruttore.
*
* @param
args[] Lista delle classi di tipo ControllableDevice
* da caricare
dinamicamente.
* @param
port Porta di ascolto per il serverSocket, se port = 0
* si considera
la porta di default.
*/
public
ServerDevice(int port, String[] args) {
super("ServerDevice");
frame = new
Frame("Stato ServerDevice");
ta = new
TextArea();
ta.setEditable(false);
frame.add("Center",
ta);
frame.resize(300,400);
frame.show();
if ((port > 0x0) && (port <= 0xFFFF)) {
this.port = port;
}
try
{
ta.setText("ServerDevice
v.0.9 - Gennaio 1997 by Donato Cappetta" + '\n');
ta.appendText("Avvio
di ServerDevice sulla porta: " + this.port
+'');
inetAddress = InetAddress.getLocalHost();
ta.appendText("Identificazione
di questa macchina: " + inetAddress +'\n');
serverSocket = new
ServerSocket(this.port);
} catch
(UnknownHostException uhe) {
fail("ServerDevice->
Eccezione nell'individuare il nome di questa macchina. ", uhe);
} catch
(IOException ioe) {
fail("ServerDevice->
Eccezione nel creare un ServerSocket. ", ioe);
} //end
try catch()
for
(int i = 0; i
< args.length; i++) {
try
{
ta.appendText("\n"
+ i + ") Caricamento del dispositivo " + args[i]
+ " in corso ... ");
cd = (ControllableDevice)loadSubclassforName(args[i],
"device.ControllableDevice");
vectorDevice.addElement(cd);
ta.appendText("
Fatto " + '\n');
} catch(IllegalSubclassException
isce) {
ta.appendText('' + "Impossibile
caricare " + args[i] + ". Non sottoclasse
di ControllableDevice--> " + isce.getMessage());
} catch(ClassNotFoundException
cnfe){
ta.appendText('' + "Impossibile
caricare " + args[i] + ". Classe non trovata
--> " + cnfe.getMessage());
} catch(InstantiationException
ie) {
ta.appendText('' + "Impossibile
caricare " + args[i] + ". Eccezione nel creare
l'istanza della classe --> " + ie.getMessage());
} catch(
IllegalAccessException iae) {
ta.appendText('' + "Impossibile
caricare " + args[i] + ". Eccezione durane
l'accesso alla classe --> " + iae.getMessage());
} catch(UnsatisfiedLinkError
ule) {
ta.appendText('' + "DLL
non trovata --> " + ule.getMessage());
}// try-catch()
} //end
for.
ta.appendText('' + "----------------------------------------------------------------"
+ '');
ta.appendText("Controllo
dei dispositivi correttamente caricati: " +'\n');
for
(int i = 0; i
< vectorDevice.size(); i++) {
ControllableDevice cd = (ControllableDevice)vectorDevice.elementAt(i);
ta.appendText(i + ")
" + cd.toString() +'\n');
} //end
for
ta.appendText("----------------------------------------------------------------"
+ '');
this.start();
} //end
costruttore ServerDevice.
/**
* Un ciclo
infinito che ascolta e servire le connessioni.
* Per
ogni connesione accettata viene creato un nuovo thread che
* gestisce
la connessione.
* I parametri
che vengono passati a ConnectionDevice, in esecuzione nel
* thread,
sono il socket restituito dalla connesione accettata e il
* vettore
contenente le istanze dei dispositivi disponibili al
* controllo.
*/
public
void run() {
ta.appendText("\nServerDevice
in attesa di connessioni sulla porta " + port + "
... ");
while (bool) {
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException ioe) {
ta.appendText("ServerDevice --> Accept fallito: "
+ port +
", " + ioe.getMessage() +'');
ta.appendText("ServerDevice in attesa di connessioni
sulla porta " + port + " ... " + '\n');
continue;
} //end try-catch()
ConnectionDevice connectionDevice = new ConnectionDevice(clientSocket,
vectorDevice);
} //end
while()
} //end
run()
/**
* Metodo
che restituisce un'instanza di una classe, a partire
* da una
stringa che rappresenta il nome della classe.
*
* @param
classString Stringa che rappresenta il nome della classe.
* @param
superClassstring Stringa che rappresenta il nome della superclasse
* di classString.
* @return
Object Istanza della classe rappresentata da classString
* @exception
IllegalSubclassException La classe rappresentata da classString
* non
ha come superclasse superClassString.
* @exception
ClassNotFoundException
* @exception
InstantiationException
* @exception
IllegalAccessException
*
*/
private
Object loadSubclassforName(String classString, String superclassString)
throws IllegalSubclassException,
ClassNotFoundException,
InstantiationException, IllegalAccessException
{
Class classObject = null;
Class classTemp = null;
String className = null;
try
{
classObject = Class.forName(classString);
} catch
(ClassNotFoundException cnfe) {
throw
cnfe;
} //end
try-catch
for
(classTemp = classObject, className = classTemp.getName();
!(className.equals("java.lang.Object")
||
className.equals(superclassString));
) {
classTemp = classTemp.getSuperclass();
className = classTemp.getName();
} //end
for
if
((className == null) || className.equals("java.lang.Object"))
{
throw
new IllegalSubclassException(classString);
} else
if(className.equals(superclassString)) {
try
{
return
classObject.newInstance();
} catch
(InstantiationException ie) {
throw
ie;
} catch
(IllegalAccessException iae) {
throw
iae;
} //end
try-catch
} else
{
//throw
new Exception();
return
null;
} //end
if - else
} //end
loadSubclassforName()
} // end
class ServerDevice
La classe ConnectionDevice
/*
* @(#)
ConnectionDevice.java 0.9 Gennaio 1997 - by Donato Cappetta
*/
package
device.server;
import
device.ControllableDevice;
import
java.io.*;
import
java.net.*;
import
java.util.Vector;
/**
* Questa
classe e il thread che gestisce la comunicazione
* con
il client.
* ServerDevice
acceta la connesione e genera questa thread.
*
* @version
0.9beta Gennaio 1997
* @author
Donato Cappetta <cappetta@diiie.unisa.it>
*/
public
class ConnectionDevice extends
Thread implements device.server.ID_Message
{
/**
* Variabile
di classe che indica il numero delle connessioni.
*/
static
int connectionNumber = 1;
/**
* Socket
per la comunicazione con il client.
*/
private
Socket clientSocket = null;
/**
* Stream
di input associato al socket.
*/
private
ObjectInputStream is = null;
/**
* Stream
di output associato al socket.
*/
private
ObjectOutputStream os = null;
private
boolean bool = true;
private
boolean isOpenDevice = false;
/**
* Dispositivo
da controllare.
*/
private
ControllableDevice controllableDevice = null;
/**
* Vettore
di tutti i dispositivi disponibili per il controllo
*/
private
Vector vectorDevice = null;
/**
* Metodo
richiamato in caso di fallimento,
* stampa
l'eccezione ed esce.
* @param
str Messaggio di errore impostato dal programmatore
* @param
e Eccezione
*/
private
void fail (String str, Exception e) {
ServerDevice.ta.appendText(str
+ ": " + e.getMessage() + '');
ServerDevice.ta.appendText("ConnectionDevice
v.0.9 - Gennaio 1997 by Donato Cappetta." + '\n');
System.exit(1);
} //end
fail()
/**
* Costruttore.
Inizializza gli stream e avvia il thread.
* @param
clientSocket socket client per la connessione.
* @param
vectorDevice vettore dei dispositivi disponibili.
*/
public
ConnectionDevice(Socket clientSocket, Vector vectorDevice) {
super("Connessione:"
+ connectionNumber++);
this.vectorDevice
= vectorDevice;
this.clientSocket
= clientSocket;
ServerDevice.ta.appendText(''
+ this.toString() + '');
try
{
os = new
ObjectOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()));
try
{
is = new
ObjectInputStream(new BufferedInputStream(clientSocket.getInputStream()));
} catch
(StreamCorruptedException sce){
fail("Eccezione
: ", sce);
} catch(IOException
ioe){
throw
ioe;
}
} catch
(IOException ioe) {
try
{
this.clientSocket.close();
} catch
(IOException ioex){}
fail ("Eccezione
nel caricamento del socket streams. " , ioe);
} //end
try catch()
this.start();
} //end
costruttore ConnectionDevice()
/**
* Fornisce
un servizio.
*/
public
void run() {
String stringClass = null;
Object objInput = null;
Object objOutput = null;
byte
ID_Input, ID_Output;
boolean
isInVector = false;
try
{
try
{
//invia
un messagggio di acknowledgment al client
os.writeByte(ID_ACK);
os.flush();
} catch(IOException
ioe) {
//se ci
sono problemi di comunicazione rilancia l'eccezione.
throw
ioe;
} //end
try-catch()
//attende
il nome della classe
stringClass = is.readUTF();
if(stringClass
== null) { return;}
//System.out.println("ConnectionDevice-->
Dispositivo da controllare: " + stringClass);
ServerDevice.ta.appendText("Dispositivo
richiesto: " + stringClass +'\n');
//verifica
se il dispositivo e in elenco.
for
(int i = 0; i
< vectorDevice.size(); i++) {
ControllableDevice cd = (ControllableDevice)vectorDevice.elementAt(i);
if
(stringClass.equals(cd.toString())) {
controllableDevice = cd;
isInVector = true;
ServerDevice.ta.appendText("Dispositivo
esistente." + '\n');
break;
} //end
if
} //end
for
//se il
dispositivo non c'e' termina
if
(!isInVector) {
try
{
ServerDevice.ta.appendText("Dispositivo
inesistente. " + '\n');
os.writeByte(ID_STOP);
os.writeUTF("Dispositivo
richiesto inesistente.");
os.flush();
}catch
(IOException ioe){
throw
ioe;
}
throw
new Exception(" -->Dispositivo
inesistente.");
}
//se il
dispositivi non e in uso
if
(!controllableDevice.inUse()) {
//Se non
ci sono eccezioni invia un messaggio di ok
try
{
controllableDevice.open();
isOpenDevice = true;
os.writeByte(ID_OKDEVICE);
os.writeUTF("Dispositivo
pronto ... ");
os.flush();
ServerDevice.ta.appendText("Dispositivo
pronto ..." + '\n');
} catch
(IOException ioe) {
throw
ioe;
}
//se il
dispositivo e in uso ma condivisibile
} else
if (controllableDevice.inUse() &&
controllableDevice.isShareble()) {
try
{
os.writeByte(ID_OKDEVICE);
os.writeUTF("Dispositivo
pronto ...");
os.flush();
ServerDevice.ta.appendText("Dispositivo
pronto ..." + '\n');
}catch(IOException
ioe) {
throw
ioe;
}
//altrimenti
... STOP
}else{
try
{
os.writeByte(ID_STOP);
os.writeUTF("Dispositivo
in uso. ");
os.flush();
ServerDevice.ta.appendText("Dispositivo
in uso." + '\n');
}catch(IOException
ioe) {
throw
ioe;
}//end
try-catch()
//lancia
l'eccezione al gestore piu esterno
//che
chiude la connesione
throw
new Exception (" -->
Dispositivo in uso");
} //end
if else-if else
//corpo
del programma che si occupa della connessione
while
(bool) {
objInput = is.readObject();
objOutput = controllableDevice.execute(objInput);
try
{
//invia
il risulta a client
os.writeObject(objOutput);
os.flush();
} catch(IOException
ioe) {
throw
ioe;
}
} //end
while()
} catch(IOException
ioe) {
return;
} catch(Exception
e){
return;
} finally
{
ServerDevice.ta.appendText(this.toString()
+ " --> chiusa " + '');
try
{
if
(isOpenDevice) controllableDevice.close();
is.close();
os.close();
clientSocket.close();
this.stop();
} catch
(IOException ioe){
} catch
(Exception e) {}
} //end
finally
} //end
run()
/**
* Metodo
che restituisce una stringa che rappresenta la connesione.
* La stringa
apparira' nella lista.
* @return
Stringa che rappresenta la connesione.
*/
public
String toString() {
return
this.getName() + " connessione
da: "
+ clientSocket.getInetAddress().getHostName()
+ " :
" + clientSocket.getPort();
} //toString()
} //end
class ConnectionDevice.
L段nterfaccia ID_Message
/*
* @(#)
ID_Message.java 0.9beta Gennaio 1997 - by Donato Cappetta
*/
package
device.server;
/**
* Interfacce
che definisce delle costanti per un protocollo
* (di
alto livello) di comunicazione client-server.
* @see
java.lang.Object
* @version
0.9beta Gennaio 1997
* @author
Donato Cappetta <cappetta@diiie.unisa.it>
*/
public
interface ID_Message {
public
static final
byte ID_ERROR = -2;
public
static final
byte ID_EXCEPTION = -1;
public
static final
byte ID_NULL = 0;
public
static final
byte ID_TEST = 1;
public
static final
byte ID_COMMAND = 2;
public
static final
byte ID_OKDEVICE = 3;
public
static final
byte ID_MSG = 4;
public
static final
byte ID_CLASS = 5;
public
static final
byte ID_WAIT = 6;
public
static final
byte ID_ACK = 7;
public
static final
byte ID_STOP = 8;
public
static final
byte ID_OPEN = 9;
public
static final
byte ID_CLOSE = 10;
public
static final
byte ID_RESULT = 11;
} //end
interface ID_Message
La classe IllegalSubclassException
/*
* @(#)
IllegalSubclassException.java 0.9beta Gennaio 1997 - by Donato Cappetta
*/
package
device.server;
/**
* Eccezione
che viene lanciata se la classe da caricare dinamicamente
* non
e sottoclasse di una specificata superclasse.
* @see
java.lang.Object
* @version
0.9beta Gennaio 1997
* @author
Donato Cappetta <cappetta@diiie.unisa.it>
*/
public
class IllegalSubclassException extends
Exception {
private
String stringSubclass;
public
IllegalSubclassException() {
this.stringSubclass
= "";
}
public
IllegalSubclassException(String stringSubclass) {
this.stringSubclass
= stringSubclass;
}
public
String toString() {
return
"IllegalSubclassException: " + stringSubclass;
}
} //end
class IllegalSubclassExcpetion.
B.3 Il package device.client
Questo package contiene: la classe DeviceGUI
che rappresenta l段nterfaccia utente per il controllo del dispositivo e
la classe AppletGUI che consente di caricare
come applet la classe DeviceGUI o una sua
sottoclasse.
La classe AppletGUI
/*
* @(#)
AppletGUI.java 0.9beta Gennaio 1997 - by Donato Cappetta
*/
package
device.client;
import
device.client.DeviceGUI;
import
device.server.IllegalSubclassException;
import
java.awt.*;
import
java.net.URL;
/**
* Applet
che riceve come parametro il nome di una classe sottoclasse
* di DeviceGUI
e crea un'istanza di questa classe.
*
* @see
java.lang.Object
* @see
java.applet.Applet
* @version
0.9beta Gennaio 1997
* @author
Donato Cappetta <cappetta@diiie.unisa.it>
*/
public
class AppletGUI extends
java.applet.Applet {
private
URL urlBase = null;
private
String classGUI;
private
String buttonText;
private
String titleGUI;
private
String portId;
private
Button button;
private
Label label;
private
int port;
public
void init() {
setBackground(Color.white);
classGUI = getParameter("classGUI");
if
(classGUI == null) {
classGUI = "DeviceGUI";
}
buttonText = getParameter("buttonText");
if
(buttonText == null) {
buttonText = "Apri
pannello " + classGUI;
}
titleGUI = getParameter("titleGUI");
if
(titleGUI == null) {
titleGUI = "Interfaccia
GUI";
}
portId = getParameter("portId");
if
(portId != null) {
try
{
port = Integer.parseInt(portId);
} catch(NumberFormatException
nfe){
port = 4444;
} //end
try-catch()
} else
{
port = 4444;
} //end
if-else
setLayout(new
GridLayout(2,0));
add(button = new
Button(buttonText));
button.setFont(new
Font("Helvetica", Font.PLAIN, 12));
add(label = new
Label("", Label.CENTER));
urlBase = getCodeBase();
label.setText("connect
to: " + urlBase.getHost() + ": " +
port);
} //end
init()
public
boolean action(Event event, Object obj) {
if
(event.target instanceof Button) {
button.disable();
label.setText("Caricamento
della classe in corso...");
try
{
DeviceGUI frameDevice = (DeviceGUI)loadSubclassforName(classGUI,
"device.client.DeviceGUI");
if
(frameDevice != null) {
label.setText("Caricamento
Ok!");
frameDevice.setTitle(titleGUI);
frameDevice.init(urlBase.getHost(),
port);
frameDevice.resize(500,
300);
frameDevice.show();
label.setText("");
} else
{
label.setText("Valore
non valido " + classGUI + " -> null");
}
}catch
(IllegalSubclassException isce) {
label.setText("Eccezione:
" + isce.getMessage());
}catch(ClassNotFoundException
cnfe){
label.setText("Eccezione:
" + cnfe.getMessage());
} catch
(InstantiationException ie) {
label.setText("Eccezione:
"+ ie.getMessage());
} catch
( IllegalAccessException iae) {
label.setText("Eccezione:
"+ iae.getMessage());
} // try-catch()
}
return
true;
} //end
action()
/**
* Metodo
che restituisce un'instanza di una classe, a partire
* da una
stringa che rappresenta il nome della classe.
* @param
classString Stringa che rappresenta il nome della classe
* @param
superClassstring Stringa che rappresenta il nome della superclasse
* @return
Object Istanza della classe rappresentata da classString
* @exception
IllegalSubclassException La classe rappresentata da classString
* non
ha come superclasse superClassString.
* @exception
*/
private
Object loadSubclassforName(String classString, String superclassString)
throws IllegalSubclassException,
ClassNotFoundException,
InstantiationException, IllegalAccessException
{
Class classObject = null;
Class classTemp = null;
String className = null;
try
{
classObject = Class.forName(classString);
} catch
(ClassNotFoundException cnfe) {
throw
cnfe;
} //end
try-catch
for
(classTemp = classObject, className = classTemp.getName();
!(className.equals("java.lang.Object")
||
className.equals(superclassString));
) {
classTemp = classTemp.getSuperclass();
className = classTemp.getName();
} //end
for
if
((className == null) || className.equals("java.lang.Object"))
{
throw
new IllegalSubclassException(classString);
} else
if(className.equals(superclassString)) {
try
{
return
classObject.newInstance();
} catch
(InstantiationException ie) {
throw
ie;
} catch
(IllegalAccessException iae) {
throw
iae;
} //end
try-catch
} else
{
//throw
new Exception();
return
null;
} //end
if - else
} //end
loadSubclassforName()
public
String getAppletInfo(){
return
"AppletGUI v.0.9 - Gennaio 1997 <cappetta@diiie.unisa.it>";
}
} //end
class AppletGUI.
La classe DeviceGUI
/*
* @(#)
DeviceGUI.java 0.9beta Gennaio 1997 - by Donato Cappetta
*/
package
device.client;
import
java.net.*;
import
java.io.*;
import
java.awt.*;
/**
* Superclasse
interfaccia grafica utente per il controllo di
* un dispositivo
elettronico.<br>
* La classe
implementa i metodi necessari per una
* connessione
client-server.
* @see
java.lang.Object
* @version
0.9beta Gennaio 1997
* @author
Donato Cappetta <cappetta@diiie.unisa.it>
*/
public
class DeviceGUI extends
Frame implements device.server.ID_Message
{
/**
* La classe
puo essere caricata da un applet o dalla
* riga
di comando.
*/
private
boolean inAnApplet = true;
/**
* Se la
connesione va a buon fine viene settata connectOk.
*/
private
boolean isConnect = false;
/**
* Socket
per I/O di rete.
*/
private
Socket socket = null;
/**
* Indirizzo
url della risorsa ControllableDevice da gestire.
*/
private
String urlString = null;
/**
* Porta
riservata alla risorsa ControllableDevice;
*/
private
int port = 4444;
/**
* Stream
per i dati di input.
*/
protected
ObjectInputStream is = null;
/**
* Stream
per i dati di output.
*/
protected
ObjectOutputStream os = null;
/**
* Area
di testo per eventuali messaggi.
*/
protected
TextArea ta = null;
/**
* Barra
del menu per eventuali menu.
*/
protected
MenuBar mb = null;
/**
* Oggetto
per i dati in input.
*/
protected
Object objInput = null;
/**
* Oggetto
per i dati di output.
*/
protected
Object objOutput = null;
/**
* Il costruttore
crea un layout a bordi con un'area di testo
* a 'sud'
*/
public
DeviceGUI() {
this.setLayout(new
BorderLayout());
mb = new
MenuBar();
ta = new
TextArea(2,20);
ta.setEditable(false);
this.add("South",
ta);
ta.setText("DeviceGUI
v.0.9 - Gennaio 1997 by Donato Cappetta ");
} //end
costruttore DeviceGUI()
/**
* Metodo
che inizializza l'url e la porta con cui stabilire la connesione.
* @param
urlString Stringa URL del dispositivo elettronico da controllare.
* @param
port Porta a cui il client si deve connettere per ottenere il servizio.
*/
public
void init(String urlString, int
port) {
this.urlString
= urlString;
this.port
= port;
}
/**
* Metodo
che si occupa della connesione con il server.
* Crea
un nouvo socket con i paramenti url, port e associa
* gli
stream di I/O del socket a is e os.
*
* @Exception
UnknownHostException se l'Host e sconosciuto.
* @Exception
IOException errore nella creazione degli stream di I/O.
*/
private
void connect() throws UnknownHostException,
IOException {
try
{
ta.setText("Connect
to: " + urlString + ":" + port);
ta.appendText('' + "Attendere
...");
socket = new
Socket(urlString, port);
isConnect = true;
os = new
ObjectOutputStream(socket.getOutputStream());
try
{
is = new
ObjectInputStream(socket.getInputStream());
} catch(StreamCorruptedException
sce) {
throw
sce;
} catch
(IOException ioe) {
throw
ioe;
}
} catch(UnknownHostException
uhe) {
throw
uhe;
} catch(IOException
ioe) {
throw
ioe;
}
} //end
connect()
/**
* Metodo
che si occupa di disconnettere.
* Chiude
gli stream di I/O e il socket.
* @Exception
IOException eccezione durante la disconnesione.
*/
private
void disconnect() throws IOException {
try
{
ta.appendText(''+ "Disconnect
!!");
is.close();
os.close();
socket.close();
isConnect = false;
} catch(IOException
ioe) {
throw
ioe;
}
} //end
disconnect
/**
* Metodo
che tenta la connesione con il server.
* Se la
connesione va a buon fine e il dispostivo e
* disponibile
per il controllo ritorna 'true'.
* @param
stringDevice Nome del dispostivo da controllare.
* @return
'true' o 'false' se il disposito e disponibile o meno per
* il controllo.
*/
public
boolean startDevice(String stringDevice) {
String stringIn = null;
byte
ID_Input;
try
{
this.connect();
} catch(UnknownHostException
uhe) {
ta.appendText(''+ "Host
sconosciuto: " + uhe.getMessage());
return
false;
} catch
(IOException ioe) {
ta.appendText(''+ "Eccezione
di I/O con il server: " + ioe.getMessage());
return
false;
} catch
(Exception e) {
ta.appendText(''+ "Eccezione
con il server: " + e.getMessage());
return
false;
}
//se la
connesione va a buon fine
//attende
ib byte di acknowledgment
try
{
ID_Input = is.readByte();
if
(ID_Input == ID_ACK) {
ta.appendText(''+ "Acknowledgment
ok ! ");
} else
{
//ritorna
ta.appendText(''+ "Errore
di Acknowledgment--> " + ID_Input);
return
false;
}
//invia
stringa che rappresenta il dispositivo da controllare
ta.appendText(''+ "Dispositivo
da controllare -->" + stringDevice);
os.writeUTF(stringDevice);
os.flush();
} catch(IOException
e){
ta.appendText(''+ "Problemi
di connessione ...");
return
false;
}
//attende
una risposta di ok o stop dal server.
try
{
ID_Input = is.readByte();
stringIn = is.readUTF();
} catch(IOException
ioe){
ta.appendText(''+ "Problemi
di connessione ...");
return
false;
}
//analizza
la risposta
switch(ID_Input)
{
case(ID_OKDEVICE):
ta.appendText(''+ "Dispositivo
Ok --> " + stringIn);
return
true;
case(ID_EXCEPTION):
ta.appendText(''+ "Eccezione
dal dispositivo --> " + stringIn);
return
false;
case(ID_STOP):
ta.appendText(''+ "Stop
--> " + stringIn);
return
false;
default:
ta.appendText(''+ "Comando
sconosciuto -->" + stringIn);
return
false;
} //end
switch()
} //end
startDevice()
/**
* Metodo
che chiude la connessione con il server e rilascia il
* dispositivo
*/
public
void stopDevice() {
try
{
this.disconnect();
} catch
(IOException ioe) {
// ta.appendText('\n'+
"Eccezione di I/O durante la disconnesione: " + ioe.getMessage());
} catch
(Exception e) {
// ta.appendText('\n'+
"Eccezione durante la disconnessione: " + e.getMessage());
}
} //end
stopDevice()
/**
* La classe
DeviceGUI puo' essere caricata da un applet
* o dalla
linea di comando.
* @param
bool Valore 'true' o 'false'.
*/
public
void inAnApplet(boolean
bool) {
inAnApplet = bool;
}
/**
* @return
inAnApplet.
*/
public
boolean inAnApplet() {
return
inAnApplet;
}
public
boolean handleEvent (Event event) {
if
(event.id == Event.WINDOW_DESTROY) {
if
(isConnect) {
try
{
this.disconnect();
} catch(IOException
ioe) {}
}
if
(inAnApplet) {
dispose();
} else
{
System.exit(0);
}
}
return
super.handleEvent(event);
} //end
handleEvent()
} //end
class DeviceGUI.
B.3 Il package "corrente"
L段mplementazione delle classi per il controllo di strumenti che si
interfacciano con bus VXI e IEEE 488 non è stata inserita in un
package e per default esse fanno parte del package che è la directory
corrente in cui sono poste. Fanno parte della stessa directory le librerie
dinamiche (DLL) implementate in linguaggio C.
In questo package "corrente" si trovano: la classe IeeeVxi
(sottoclasse di ControllableDevice) che
viene caricata dinamicamente dal Server insieme alla libreria implementata
in linguaggio C di cui ne vengono riportati i sorgenti, le classi IeeeVxiGUI
(sottoclasse di DeviceGUI) e IeeeVxiPanel
che rappresentano rispettivamente il client e l段nterfaccia utente del
client, le classi DeviceDataInput e DeviceDataOutput
per i dati in input e output dagli strumenti ed infine il file HTML che
carica la classe AppletGUI la quale consente
di eseguire IeeeVxiGUI come applet.
La classe IeeeVxi
/*
* @(#)
IeeeVxi.java 0.9beta Gennaio 1997 - by Donato Cappetta
*/
import
device.server.ServerDevice;
/**
* Classe
concreta di ControllableDevice.
*
* @see
java.lang.Object
* @version
0.9beta Gennaio 1997
* @author
Donato Cappetta <cappetta@diiie.unisa.it>
*/
public
class IeeeVxi extends
device.ControllableDevice {
static
final String stringDLL = "IeeeVxi";
private
String stringPath = "/public";
/**
* Il dispositivo
inizialmente non e in uso.
*/
private
boolean inUse;
/**
* Il dispositivo
in genere non e condivisibile.
*/
private
boolean isShareble;
/**
* Costruttore
*/
public
IeeeVxi () {
inUse = false;
isShareble = false;
}
/**
* Metodo
che informa se il dispositivo e gia'in uso.
* @return
boolean Dispositivo in uso o meno.
*/
public
boolean inUse(){
return
inUse;
}
/**
* Metodo
che informa se il dispositivo puo' essere condiviso
* fra
piu utenti.
* @return
isShareble.
*/
public
boolean isShareble() {
return
isShareble;
}
/**
* Metodo
che inizializza e istanzia le risorse per
* un nuovo
utente.
*/
public
synchronized void
open() {
if
(!inUse) {
inUse = true;
}
} //end
open()
/**
* Metodo
che chiude e rilascia le risorse.
*/
public
void close() {
if
(!isShareble) {
inUse = false;
}
} //end
close()
/**
* Metodi
nativi implementati in linguaggio C
*/
public
native void leggiInput(String
bus, String strumento, String comando,
String query, String nomeFile,
String salvaInFile);
public
native String leggiStatus();
public
native String leggiVxiStatus();
public
native String leggiRisposta();
public
native void inviaAlloStrumento();
public
native void initVXILibrary();
public
native void closeVXILibrary();
/**
* Metodo
che rappresenta i comandi che possono essere
* impartiti
al dispositivo.
*
* @param
obj Oggetto che informa il dispositivo le operazioni da compiere.
* @return
Risultato dell'operazione.
*/
public
synchronized Object execute(Object obj) {
int
size = 0;
String queryRisposta = "s";
String queryFile = "s";
DeviceDataInput ddi = (DeviceDataInput)obj;
if
(!ddi.checkRisposta) {
queryRisposta = "n";
}
if
(ddi.nomeFile.equals("NULL")) {
queryFile = "n";
}
//chiamate
ai metodi nativi
leggiInput(ddi.bus,ddi.strumento,ddi.comando,
queryRisposta, ddi.nomeFile,queryFile);
initVXILibrary();
inviaAlloStrumento();
DeviceDataOutput ddo = new
DeviceDataOutput();
if
(ddi.bus.equals("IEEE")) {
ddo.statusByteIn = leggiStatus();
} else
{
ddo.statusByteIn = leggiVxiStatus();
}
//se si
attende risposta
if
(ddi.checkRisposta) {
ddo.risposta = leggiRisposta();
if
(ddi.bus.equals("IEEE")) {
ddo.statusByteOut = leggiStatus();
} else
{
ddo.statusByteOut = leggiVxiStatus();
} //end
if-else
//se il
risultato è stato salvato in file ...
if
(!ddi.nomeFile.equals("NULL")) {
ServerDevice.ta.appendText("Lettura
del file .. " + '\n');
java.io.File f = null;
java.io.FileInputStream fis
= null;
try
{
f = new
java.io.File(stringPath, ddi.nomeFile);
fis = new
java.io.FileInputStream(f);
size = fis.available();
ddo.b = new
byte[size];
fis.read(ddo.b);
fis.close();
} catch
(java.io.FileNotFoundException fnfe) {
//ServerDevice.ta.appendText("File
non trovato: " + fnfe.getMessage() + '\n');
} catch
(java.io.IOException ioe) {
//ServerDevice.ta.appendText("Impossibile
leggere dal file: " + ioe.getMessage() + '\n');
} catch
(Exception e) {
//ServerDevice.ta.appendText("Eccezione
nell'accesso al file: " + e.getMessage() + '\n');
} //end
try-catch()
} //end
if.
} else
{
ddo.risposta = "";
ddo.statusByteOut = "";
}
closeVXILibrary();
return
ddo;
}
/**
* Carica
la libreria dinamica all'avvio.
*/
static
{
try
{
System.loadLibrary(stringDLL);
} catch(java.lang.UnsatisfiedLinkError
ule) {
throw
ule;
}
}
} //end
class IeeeVxi.
La classe IeeeVxiGUI
/*
* @(#)
IeeeVxiGUI.java 0.9beta Gennaio 1997 - by Donato Cappetta
*/
import
java.awt.*;
import
java.io.*;
/**
* Classe
per il controllo di dispositivi elettronici
* basati
su bus VXI e IEEE.
* @see
java.lang.Object
* @version
0.9beta Gennaio 1997
* @author
Donato Cappetta <cappetta@diiie.unisa.it>