/** * *
Titulo: Servidor de respuestas a preguntas
*Descripcion: Esta clase gestiona el servidor. *
* @author Diego Gonzalez Barrientos * @version 1.0 */ //Paquete en el que se encapsula todo el codigo del servidor package servidorpreguntas; //Paquetes requeridos para el programa import javax.bluetooth.*; import javax.microedition.io.*; import java.io.*; import java.util.Vector; import java.awt.Color; import java.awt.Paint; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.labels.ItemLabelAnchor; import org.jfree.chart.labels.ItemLabelPosition; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.BarRenderer; import org.jfree.chart.renderer.category.CategoryItemRenderer; import org.jfree.data.category.CategoryDataset; import org.jfree.data.general.DatasetUtilities; import org.jfree.ui.ApplicationFrame; import org.jfree.ui.RefineryUtilities; import org.jfree.ui.TextAnchor; /**Clase que implementa el servicio de preguntas, recepciona respuestas y acepta conexiones de clientes */ public class SPP_Server { /** Metodo constructor de la clase Servidor *@param pregunta Pregunta que se planteara para ser contestada *@param numero_alternativas numero de alternativas para la pregunta *@param alternativa_correcta alternativa correcta dentro las especificadas *@param numero_clientes Numero de clientes que se espera respondan la pregunta */ public SPP_Server(String pregunta,int numero_alternativas,int alternativa_correcta,int numero_clientes,String[] contenidoAlternativas) { this.pregunta = pregunta; this.numero_alternativas = numero_alternativas; this.alternativa_correcta = alternativa_correcta; this.numero_clientes = numero_clientes; this.arregloAlternativas = contenidoAlternativas; } /**Metodo principal de la clase, basicamente provee el servicio de administrador de respuestas a la pregunta */ public void run_server() { try { //Referencia al dispositivo local device = LocalDevice.getLocalDevice(); //Configurando la visibilidad del dispositivo device.setDiscoverable(DiscoveryAgent.GIAC); //Creando Hebra que aceptara conexiones de clientes HebraEsperando.add(new ThreadedWaiting (device,uuid,"Servicio de Preguntas",this)); //Iniciando Hebras creadas for (int i = 0; i < HebraEsperando.size(); i++) ((ThreadedWaiting) HebraEsperando.elementAt(i)).start(); } catch ( BluetoothStateException e ) { e.printStackTrace(); } } /**Funcion que permite imprimir informacion de debugeo *@param s mensaje que se imprimira en pantalla */ public void log( String s ) { SPP_Main.log( s ); } /**Funcion que permite finalizar las conexiones establecidas */ public void doneTrue() { for (int i = 0; i < HebraEsperando.size(); i++){ ((ThreadedWaiting) HebraEsperando.elementAt(i)).doneTrue(); ((ThreadedWaiting) HebraEsperando.elementAt(i)).serverClose(); } } /**Referencia al dispositivo donde se ejecuta el programa */ public LocalDevice device; /**Referencia a Agente que busca dispositivos y servicios */ public DiscoveryAgent agent; /** Pregunta que se realiza */ public static String pregunta; /**Numero de alternativas para la pregunta */ public static int numero_alternativas; /**Alternativa de la pregunta que es la correcta */ public static int alternativa_correcta; /**Numero de clientes que se espera respondan la pregunta */ public static int numero_clientes; /**Contenido de alternativa */ public static String[] arregloAlternativas; /**Arreglo que contiene la letra para las alternativas */ public static String[] alt_arreglo = new String[]{"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p"}; /**UUID que especifica el servicio provisto */ public final static UUID uuid = new UUID("102030405060708090A0B0C0D0E0F012", false); /**Vector que mantiene la lista de las Hebras en espera de conexiones */ public Vector HebraEsperando = new Vector(); /**Referencia al manejador del servidor */ public StreamConnectionNotifier server; } /**Clase que maneja las conexiones de los servicios creados */ class ThreadedWaiting extends Thread { /**Constructor. *@param device Referencia al dispositivo *@param uuid Identificador del servicio *@param appName Nombre del servicio *@param spp_servidor Instancia del servidor */ public ThreadedWaiting(LocalDevice device, UUID uuid, String appName, SPP_Server spp_servidor) { this.device = device; this.uuid = uuid; this.appName = appName; this.spp_servidor = spp_servidor; contador = new int[SPP_Server.numero_alternativas]; for (int i = 0; i < SPP_Server.numero_alternativas; i++) contador[i] = 0; counter=0; } /**Metodo que gestiona el cierre del servidor */ public void serverClose(){ try{ server.close(); } catch(IOException es) {} } /**Metodo que incrementa contador de respuestas contestadas, y de alternativa contestada *@param posicion alternativa contestada por cliente */ synchronized public void increaseCounter(int posicion){ contador[posicion]++; counter++; } /** Metodo que permite cerrar conexiones establecidas para el servicio */ public void doneTrue(){ done = true; for (int i = 0; i < HebraEnviando.size(); i++) { ((ThreadedSending) HebraEnviando.elementAt(i)).doneTrue(); } } /** Metodo principal de la clase que inicia el servicio especificado y espera por conexiones de clientes */ public void run() { StreamConnection c = null; try { //Url que especifica el servicio String url = "btspp://localhost:" + uuid.toString() +";name="+ appName; log("url del servidor: " + url ); server = (StreamConnectionNotifier)Connector.open( url ); ServiceRecord rec = device.getRecord( server ); DataElement titulo = new DataElement(DataElement.STRING,(String)appName); rec.setAttributeValue( 0x0008, new DataElement( DataElement.U_INT_1, 0xFF ) ); rec.setAttributeValue(0x4321,titulo); DataElement base = new DataElement(DataElement.DATSEQ); DataElement de = new DataElement(DataElement.STRING, appName); base.addElement(de); rec.setAttributeValue(0x4444, base); log("Nombre de servicio: " + appName); // Util.printServiceRecord( rec ); rec.setDeviceServiceClasses( SERVICE_TELEPHONY ); } catch (Exception e){ e.printStackTrace(); log(e.getClass().getName()+" "+e.getMessage()); } log("Ingresando a aceptar conexiones de clientes ..."); while((!done)&&((counter)<(SPP_Server.numero_clientes))) { try { c = server.acceptAndOpen(); if((!done)&&(counter