/* ======================================================== */
/* == POD 98-99 --                                          */
/* -------------------------------------------------------- */
/* == Client/serveur d'expression arithmetiques             */
/* -- Fichier : Service.java                                */
/*                                                          */
/* Le service :                                             */
/*           - ouvre les flux d'entree et sortie de la      */
/*            'socket' de service;                          */
/*           - lit la requete de calcul;                    */
/*           - renvoie le resultat du calcul;               */
/*           - attend un aquittement;                       */
/*            et c'est tout.                                */
/* Le service est lance par le serveur (voir 'Serveur.java')*/
/* La 'socket' de service est fournie par le serveur ainsi  */
/* que le numero de service et le fichier de trace.         */
/* ======================================================== */
import java.io.* ;
import java.net.* ;
import java.lang.* ;

// La "fonction" de service
class Service extends Thread 
{
    // Numero de service
    static int numero = 0;
    // Socket de service
    Socket sock ;
    // Flux d'entree (des requetes et messages clients
    ObjectInputStream in;
    // Flux de sortie (reponses au client)
    ObjectOutputStream out;
    // Le canal de sortie pour le fichier de trace
    PrintWriter trace;

    // Constructeur
    public Service (Socket s, PrintWriter t, int n)
    {  
	// Numero de service : initialisation
	numero = n;
	// Socket de service : initialisation
	sock = s;
	// Fichier de trace : initialisation
	trace = t;
    
	try 
	    {
		// Flux d'entree : creation
		in = new ObjectInputStream (sock.getInputStream());
		// Flux de sortie : creation
		out = new ObjectOutputStream (sock.getOutputStream());
	    }
	catch (IOException e)
	    {
		try {sock.close();} catch (IOException ee) {} 
		trace.println("*** Erreur ouverture transaction "+numero);
		System.err.println(e.getMessage());
		return ;
	    }
	
	// Trace : debut de transaction
	trace.println("*** Debut transaction "+numero);
    }
    
    // La methode qui court
    public void run () 
    {
	try
	    {
		// Trace : adresse du client
		String message = "* transaction #" + numero + " avec " + 
		    sock.getInetAddress().getHostName() ;
		
		// Lecture de la requete de calcul
		Arith exp = (Arith) in.readObject();
		if (exp==null) { throw new IOException(); }
		// Trace : expression a evaluer
		trace.println(message + " :>" + exp.toString());

		// Reponse : valeur de l'expression
		out.writeObject (new Integer(exp.eval()));
		out.flush();
		
		// Lecture aquittement
		String ligne = (String) in.readObject();
		if (! ligne.equals("OK!")) { throw new IOException(); }
		trace.println(message + " - Acquitement recu");
	    }
	catch (IOException e) 
	    { trace.println( "* transaction #" + numero  +
			     " interrompue par le client"); } 
	catch (ClassNotFoundException e)
	    { System.err.println("La classe d'un persistant est inconnue"); 
	    this.destroy();}
	finally
	    { 
		try {sock.close(); } 
		catch (IOException e) {}  
		finally { trace.println("*** Fin transaction " + numero); };
     } 
  }
}

