From: danigm Date: Wed, 25 Jun 2008 23:01:27 +0000 (+0200) Subject: La documentación de la practica X-Git-Url: http://git.danigm.net/?p=pcd.git;a=commitdiff_plain;h=639d6a3009afe2a6e1aba97ec5d1c58b26c46e5c La documentación de la practica --- diff --git a/pcd.pdf b/pcd.pdf new file mode 100644 index 0000000..a06b58c Binary files /dev/null and b/pcd.pdf differ diff --git a/pcd.tex b/pcd.tex new file mode 100644 index 0000000..c5247b2 --- /dev/null +++ b/pcd.tex @@ -0,0 +1,1012 @@ +\documentclass{article} + +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[spanish]{babel} +\usepackage{times} + +\usepackage{color} +\definecolor{gray97}{gray}{.97} +\definecolor{gray75}{gray}{.75} +\definecolor{gray45}{gray}{.45} + +\usepackage{listings} +\lstset{ frame=Ltb, + framerule=0pt, + aboveskip=0.5cm, + framextopmargin=3pt, + framexbottommargin=3pt, + framexleftmargin=0.4cm, + framesep=0pt, + rulesep=.4pt, + backgroundcolor=\color{gray97}, + rulesepcolor=\color{black}, + % + stringstyle=\ttfamily, + showstringspaces = false, + basicstyle=\small\ttfamily, + commentstyle=\color{gray45}, + keywordstyle=\bfseries, + % + numbers=left, + numbersep=15pt, + numberstyle=\tiny, + numberfirstline = false, + breaklines=true, + } + +% minimizar fragmentado de listados +\lstnewenvironment{listing}[1][] + {\lstset{#1}\pagebreak[0]}{\pagebreak[0]} + +\lstdefinestyle{consola} + {basicstyle=\scriptsize\bf\ttfamily, + backgroundcolor=\color{gray75}, + } + +\lstdefinestyle{java} + {language=java, } + +\lstdefinestyle{idl} + {language=IDL, } + +\lstdefinestyle{Python} + {language=Python, } + +\title{Práctica PCD 07/08 - Subastas} +\author{Daniel García Moreno } +\date{\today} + +\begin{document} +\maketitle + +\tableofcontents + +\section{Cómo compilar y ejecutar} + +\subsection{Compilar} + Para compilar hay que ejecutar: + \texttt{javac src/subastas/*.java -d bin/} + desde el directorio PCD. Los .class se guardarán en el directorio + bin. + +\subsection{Ejecutar} + + El cliente y servidor se comunican a través de un fichero .ior, + así que el servidor tiene que tener permiso de escritura en el directorio + desde el cual se ejecute y el cliente tiene que ejecutarse desde + el mismo directorio despues de haber ejecutado el servidor. + + \begin{itemize} + \item \textbf{Servidor:} + \texttt{java -classpath PCD/bin subastas.Servidor} + \item \textbf{Cliente:} + \texttt{java -classpath PCD/bin subastas.Cliente} + \end{itemize} + + Para conocer los comandos disponibles en el cliente basta con + escribir el comando 'help' que mostrará una lista con todos los + posibles comandos. + + Hay que tener en cuenta que para poder hacer alguna operación con + alguna de las subastas creadas hay que hacer una busqueda para que + se inicialice el vector de subastas, y el id será el indice en + esta busqueda. + +\section{Explicación del diseño} + +\subsection{Interfaces IDL} + Las tres interfaces que hay que implementar se han implementado + dentro del modulo subastas. + + \subsubsection{clienteSubastas} + + La interfaz clienteSubastas está implementada según la + especificación del trabajo y además contiene una operación + nuevoValor que sirve para resolver el primer problema especificado + en el documento. + + \subsubsection{coordinadorSubasta} + + Para la interfaz gestorSubasta se ha declarado un tipo de dato + sequence para la lista de clientes. + + En esta interfaz se definen los atributos y las operaciones + especificadas en el documento. Además se define la operación + cerrarSubasta que será llamado para cerrar una subasta y así + evitar el segundo problema. + + \subsubsection{gestorSubastas} + + Para la interfaz gestorSubasta se ha definido un tipo sequence + para la lista de subastas que hay que devolver en la operación + localizarSubasta. + + Por lo demás se ha implementado según lo especificado en el + documento. + +\subsection{Sirvientes} + + Se han implementado los sirvientes: + + \subsubsection{clienteSubastasImpl} + Este sirviente implementa la interfaz clienteSubastas por + herencia. Se han implementado las operaciones según la + especificación. Cuando se actualiza el valor de una suabasta el + cliente será informado por el coordinador subasta e imprimirá el + nuevo valor. + + \subsubsection{coordinadorSubastaImpl} + Al igual que el sirviente anterior este está implementado por + herencia. Se han definido las operaciones según lo especificado en + el documento. + + Se han definido los métodos \texttt{abrirSubasta}, + \texttt{ganador}, \texttt{pujar}, \texttt{ultimaPuja} y + \texttt{cerrarSubasta} como synchronized puesto que serán llamados + desde diferentes clientes. Para la sincronización entre clientes + se utilizan los métodos proporcionados por java y vistos en clase, + wait y notifyAll. Cuando se cambia el estado se ejecuta notifyAll. + + Las esperas de los clientes se realizan mediante wait y el + atributo estado. + + \subsubsection{gestorSubastasImpl} + Como los dos sirvientes anteriores este también se ha implementado + por herencia. + + Este sirviente es un objeto fábrica. Crea coordinadores de + subastas. + + Para evitar el segundo problema especificado en el documento se ha + utilizado la clase SubastaKiller que implementa la interfaz + Runnable para ser lanzado en un hilo. Este hilo duerme durante el + tiempo especificado y después cierra la subasta especificada + llamando al método cerrarSubasta del coordinadorSubasta. + + El resto de operaciones está implementado según la especificación + del documento. + +\subsection{SubastaKiller} + Para solventar el problema de que una subasta no acabe nunca por + culpa de un cliente se ha implementado esta clase que implementa + la interfaz Runnable. Este hilo duerme durante un tiempo + especificado y después cierra la subasta. + +\subsection{Servidor} + El servidor crea un gestorSubastasImpl y crea un fichero + \texttt{server.ior} donde escribe el ior correspondiente a este + objeto. Y se lanza el servidor. + +\subsection{Cliente unificado} + Esta es la parte con más código del trabajo aunque no por ello la + más compleja. + + Se han definido los suiguientes comandos: + + \begin{verbatim} + /** + * COMANDOS DISPONIBLES + * + * GESTOR SUBASTAS + * --------------- + * salir -> sale del bucle + * crear valor tiempo desc -> crea una subasta + * buscar desc -> busca una subasta y muestra todas las coincidencias + * borrar id -> borra una subasta si esta cerrada + * + * COORDINADOR SUBASTA + * ------------------- + * abrir id -> abre la subasta por id + * estado id -> devuelve el estado de una subasta + * valor id -> devuelve el valor actual de una puja + * ganador_prov id -> dice el identificador del cliente que va ganando la puja + * ganador id -> muestra el ganador, si la puja no esta cerrada aun, bloquea al cliente + * clientes id -> muestra todos los identificadores de los clientes de la subasta + * inscribir id cliente_id -> inscribe un cliente en una subasta + * pujar id cliente_id valor + * ultima id cliente_id + * + * CLIENTE SUBASTAS + * ---------------- + * crearcliente identificacion + * cldisp -> muestra los clientes disponibles + */ + \end{verbatim} + + Cuando se ejecuta un cliente muestra una línea de comandos que + permite llamar a cualquiera de estos comandos. No se han capturado + los errores por lo que si se llama a alguno con una sintaxis + inadecuada el programa dará errores. + + Este cliente unificado permite tanto crear y gestionar subastas + como crear clientes y trabajar con más de un cliente desde un + mismo cliente unificado. + +\section{Código fuente} + +\subsection{Definción de interfaces en IDL} +\begin{lstlisting}[style=java] + +module subastas{ + + + interface clienteSubastas{ + readonly attribute string identificacion; + void finSubasta(); + void nuevoValor(in float valor); + }; + + typedef sequence lista_clientes; + interface coordinadorSubasta{ + /** + * coordinadorSubasta: interfaz de objetos que gestionan el + * desarrollo de la subasta de cada bien subastado por la empresa. + + * La subasta pasara por tres estados: + * Inscripcion + * Abierta + * Cerrada + * + */ + + readonly attribute clienteSubastas ganador_provisional; + readonly attribute lista_clientes clientes; + + readonly attribute float valor; + readonly attribute string descripcion; + // Inscripcion -> Abierta -> Cerrada + readonly attribute string estado; + + void inscribirCliente(in clienteSubastas cl); + void abrirSubasta(); + boolean pujar(in float cantidad, in clienteSubastas cl); + void ultimaPuja(in clienteSubastas cl); + clienteSubastas ganador(); + void cerrarSubasta(); + }; + + typedef sequence lista_subastas; + interface gestorSubastas{ + coordinadorSubasta crearSubasta(in float valor, in string desc, in long tiempo); + void destruirSubasta(in coordinadorSubasta cs); + lista_subastas localizarSubasta(in string palabra); + }; + +}; + +\end{lstlisting} + +\subsection{clienteSubastasImpl.java} + +\begin{lstlisting}[style=java] + +package subastas; + +/** + * @author danigm + * + */ +public class clienteSubastasImpl extends clienteSubastasPOA { + private String identificacion; + private boolean fin=false; + private float valor_subasta=0; + public clienteSubastasImpl(String id) { + super(); + identificacion = id; + } + + public void finSubasta() { + fin = true; + } + + public String identificacion() { + return identificacion; + } + + public void nuevoValor(float valor) { + valor_subasta = valor; + System.out.println("NUEVO VALOR " + valor); + } + +} +\end{lstlisting} + + +\subsection{coordinadorSubastaImpl.java} + +\begin{lstlisting}[style=java] + +package subastas; +import java.util.Vector; + +/** + * @author danigm + * + */ +public class coordinadorSubastaImpl extends coordinadorSubastaPOA { + private clienteSubastas ganador_provisional; + private Vector clientes; + private float valor; + private String descripcion; + // Inscripcion -> Abierta -> Cerrada + private String estado; + + public coordinadorSubastaImpl(float v_inicial, String desc) { + super(); + estado = "Inscripcion"; + ganador_provisional=null; + clientes = new Vector(); + valor = v_inicial; + descripcion = desc; + } + + synchronized public void abrirSubasta() { + if(estado.equals("Inscripcion")){ + estado = "Abierta"; + notifyAll(); + } + } + + public clienteSubastas[] clientes() { + clienteSubastas[] cs = new clienteSubastas[clientes.size()]; + for (int i=0; i valor){ + valor = cantidad; + ganador_provisional = cl; + for (int i=0; i subastas; + + private POA poa; + public gestorSubastasImpl(POA arg_poa) { + super(); + subastas = new Vector(); + poa = arg_poa; + } + + public coordinadorSubasta crearSubasta(float valor, String desc, int tiempo) { + coordinadorSubasta c = null; + coordinadorSubastaImpl coord = new coordinadorSubastaImpl(valor, desc); + org.omg.CORBA.Object obj; + try { + obj = poa.servant_to_reference(coord); + c = coordinadorSubastaHelper.narrow(obj); + subastas.add(c); + } catch (ServantNotActive e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (WrongPolicy e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + SubastaKiller sk = new SubastaKiller(c, tiempo); + + return c; + } + + public void destruirSubasta(coordinadorSubasta cs) { + if (cs.estado().equals("Cerrada")){ + subastas.remove(cs); + } + } + + public coordinadorSubasta[] localizarSubasta(String palabra) { + coordinadorSubasta[] encontradas = new coordinadorSubasta[subastas.size()]; + int j=0; + for(int i=0; i sale del bucle + * crear valor tiempo desc -> crea una subasta + * buscar desc -> busca una subasta y muestra todas las coincidencias + * borrar id -> borra una subasta si esta cerrada + * + * COORDINADOR SUBASTA + * ------------------- + * abrir id -> abre la subasta por id + * estado id -> devuelve el estado de una subasta + * valor id -> devuelve el valor actual de una puja + * ganador_prov id -> dice el identificador del cliente que va ganando la puja + * ganador id -> muestra el ganador, si la puja no esta cerrada aun, bloquea al cliente + * clientes id -> muestra todos los identificadores de los clientes de la subasta + * inscribir id cliente_id -> inscribe un cliente en una subasta + * pujar id cliente_id valor + * ultima id cliente_id + * + * CLIENTE SUBASTAS + * ---------------- + * crearcliente identificacion + * cldisp -> muestra los clientes disponibles + */ + + coordinadorSubasta[] subastas = null; + clienteSubastas[] clientes = new clienteSubastas[100]; + int n_clientes = 0; + + boolean salir = false; + String comando = ""; + System.out.println("== INICIO =="); + while(!salir){ + System.out.print(">>"); + try{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + comando = br.readLine(); + }catch(Exception e){ e.printStackTrace();} + String[] partesDelComando = comando.split(" "); + if(comando.equals("salir")){ + salir = true; + System.out.println("Adios ;)"); + break; + } + else if(comando.equals("help")){ + System.out.println( + "* COMANDOS DISPONIBLES\r\n" + + "*\r\n " + + "* GESTOR SUBASTAS\r\n"+ + "* --------------\r\n"+ + "* salir -> sale del bucle\r\n"+ + "* crear valor tiempo desc -> crea una subasta\r\n"+ + "* buscar desc -> busca una subasta y muestra todas las coincidencias\r\n"+ + "* borrar id -> borra una subasta si esta cerrada\r\n"+ + "* \r\n"+ + "* COORDINADOR SUBASTA\r\n"+ + "* -------------------\r\n"+ + "* abrir id -> abre la subasta por id\r\n"+ + "* estado id -> devuelve el estado de una subasta\r\n"+ + "* valor id -> devuelve el valor actual de una puja\r\n"+ + "* ganador_prov id -> dice el identificador del cliente que va ganando la puja\r\n"+ + "* ganador id -> muestra el ganador, si la puja no esta cerrada aun, bloquea al cliente\r\n"+ + "* clientes id -> muestra todos los identificadores de los clientes de la subasta\r\n"+ + "* inscribir id cliente_id -> inscribe un cliente en una subasta\r\n"+ + "* pujar id cliente_id valor\r\n"+ + "* ultima id cliente_id\r\n"+ + "* \r\n"+ + "* CLIENTE SUBASTAS\r\n"+ + "* ----------------\r\n"+ + "* crearcliente identificacion\r\n"+ + "* cldisp -> muestra los clientes disponibles\r\n"); + } + + // Opciones de gestorSubastas + else if(partesDelComando[0].equals("crear")){ + String desc = ""; + float valor = 0; + int time = 0; + valor = Float.valueOf(partesDelComando[1]); + time = Integer.valueOf(partesDelComando[2]); + for(int i=3; i " + subastas[i].estado()); + } + else if(partesDelComando[0].equals("borrar")){ + int id = 0; + id = Integer.valueOf(partesDelComando[1]); + gs.destruirSubasta(subastas[id]); + System.out.println("Subasta borrada"); + } + + // Opciones de coordinadorSubasta + else if(partesDelComando[0].equals("abrir")){ + int id = 0; + id = Integer.valueOf(partesDelComando[1]); + subastas[id].abrirSubasta(); + System.out.println(subastas[id].estado()); + } + else if(partesDelComando[0].equals("estado")){ + int id = 0; + id = Integer.valueOf(partesDelComando[1]); + System.out.println(subastas[id].estado()); + } + else if(partesDelComando[0].equals("valor")){ + int id = 0; + id = Integer.valueOf(partesDelComando[1]); + System.out.println(subastas[id].valor()); + } + else if(partesDelComando[0].equals("ganador_prov")){ + int id = 0; + id = Integer.valueOf(partesDelComando[1]); + System.out.println(subastas[id].ganador_provisional().identificacion()); + } + else if(partesDelComando[0].equals("ganador")){ + int id = 0; + id = Integer.valueOf(partesDelComando[1]); + System.out.println(subastas[id].ganador().identificacion()); + } + else if(partesDelComando[0].equals("clientes")){ + int id = 0; + id = Integer.valueOf(partesDelComando[1]); + clienteSubastas[] clientes2 = subastas[id].clientes(); + for (int i=0; i< clientes2.length; i++){ + System.out.println(i+": "+clientes2[i].identificacion()); + } + } + else if(partesDelComando[0].equals("inscribir")){ + int id = 0; + String cliente_id=""; + clienteSubastas cl=null; + id = Integer.valueOf(partesDelComando[1]); + cliente_id = partesDelComando[2]; + cl = buscar(cliente_id, clientes); + subastas[id].inscribirCliente(cl); + System.out.println("Cliente inscrito"); + } + + else if(partesDelComando[0].equals("pujar")){ + int id = 0; + float valor = 0; + String cliente_id=""; + clienteSubastas cl=null; + id = Integer.valueOf(partesDelComando[1]); + cliente_id = partesDelComando[2]; + valor = Float.valueOf(partesDelComando[3]); + cl = buscar(cliente_id, clientes); + if(subastas[id].pujar(valor, cl)) + System.out.println("Vas ganando"); + else + System.out.println("No es suficiente"); + } + else if(partesDelComando[0].equals("ultima")){ + int id = 0; + String cliente_id=""; + clienteSubastas cl=null; + id = Integer.valueOf(partesDelComando[1]); + cliente_id = partesDelComando[2]; + cl = buscar(cliente_id, clientes); + subastas[id].ultimaPuja(cl); + System.out.println("Has dejado de pujar"); + System.out.println(subastas[id].estado()); + } + + // creacion de clientes + else if(partesDelComando[0].equals("crearcliente")){ + String id=""; + clienteSubastas cl=null; + id = partesDelComando[1]; + cl = crearCliente(id, poa); + clientes[n_clientes++] = cl; + } + else if(partesDelComando[0].equals("cldisp")){ + for(int i=0; i>") + if comando.split()[0] == 'salir': + break + elif comando.split()[0] == 'inscribir': + subasta = subastas[int(comando.split()[1])] + subasta.inscribirCliente(cl) + elif comando.split()[0] == 'pujar': + subasta = subastas[int(comando.split()[1])] + valor = float(comando.split()[2]) + if subasta.pujar(valor, cl): + print "Vas ganando" + else: + print "No es suficiente" + elif comando.split()[0] == 'ultima': + subasta = subastas[int(comando.split()[1])] + subasta.ultimaPuja(cl) + print "Has dejado de pujar" + + elif comando.split()[0] == 'buscar': + try: + desc = comando.split()[1] + except: + desc = '' + subastas = gestor_subasta.localizarSubasta(desc) + for i,s in enumerate(subastas): + print i, s._get_descripcion(), s._get_estado() + + elif comando.split()[0] == 'ganador': + subasta = subastas[int(comando.split()[1])] + print subasta.ganador()._get_identificacion() + + elif comando.split()[0] == 'ganador_prov': + subasta = subastas[int(comando.split()[1])] + print subasta._get_ganador_provisional()._get_identificacion() + + elif comando.split()[0] == 'estado': + subasta = subastas[int(comando.split()[1])] + print subasta._get_estado() + + elif comando.split()[0] == 'valor': + subasta = subastas[int(comando.split()[1])] + print subasta._get_valor() + + elif comando.split()[0] == 'clientes': + subasta = subastas[int(comando.split()[1])] + clientes = subasta._get_clientes() + for i, c in enumerate(clientes): + print i, c._get_identificacion() + + elif comando.split()[0] == 'help': + help_str = ''' + COMANDOS DISPONIBLES + -------------------- + buscar desc -> muestra la lista de subastas + ganador id -> muestra el ganador de una subasta + inscribir id -> te inscribe en una puja + pujar id cantidad -> puja cantidad en la puja con id + ultima id -> dejas de pujar en la puja id + ganador_prov id -> muestra el ganador provisional + estado id -> muestra el estado de una puja + valor id -> muestra el valor actual de una puja + clientes id -> muestra los clientes que hay en una puja + salir -> sale del cliente + help -> muestra esta ayuda + + ''' + print help_str + +\end{lstlisting} + +\subsubsection{cliente.py} +\begin{lstlisting}[style=Python] + +import subastas__POA + +class clienteSubastas_i(subastas__POA.clienteSubastas): + def __init__(self, id): + self.identificacion = id + + def finSubasta(self): + pass + + def nuevoValor(self, valor): + print "NUEVO VALOR: ", valor + + def _get_identificacion(self): + return self.identificacion + +\end{lstlisting} + +\end{document} diff --git a/server.ior b/server.ior index 6ec2662..c373d91 100644 --- a/server.ior +++ b/server.ior @@ -1 +1 @@ -IOR:000000000000002049444c3a73756261737461732f676573746f7253756261737461733a312e3000000000010000000000000082000102000000000a3132372e302e302e3100ad0a00000031afabcb00000000207e88189f00000001000000000000000100000008526f6f74504f410000000008000000010000000014000000000000020000000100000020000000000001000100000002050100010001002000010109000000010001010000000026000000020002 +IOR:000000000000002049444c3a73756261737461732f676573746f7253756261737461733a312e3000000000010000000000000082000102000000000a3132372e302e302e3100811200000031afabcb0000000020c145ee8d00000001000000000000000100000008526f6f74504f410000000008000000010000000014000000000000020000000100000020000000000001000100000002050100010001002000010109000000010001010000000026000000020002