| Index | Next | Prev. |

B. Listati dei programmi



 Viene riportata in questa appendice l段mplementazione delle classi suddivise per package.

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>