Práctica Linda. Práctica numero 5

Se trata de modelar el mundo de los filósofos con Linda. En realidad se propone una variante del clasico problema de los filósofos. No vamos a tratar el acceso a los tenedores compartidos, sino la posibilidad de entrar en la mesa o salir de la mesa. Teneis que construir programas que hagan de filósofos.



Figura que muestra un día en la vida de un monasterio (Communications of the ACM, january 1998. Vo. 31. Number 1, pag. 12).

En el mundo de los filósofos que planteamos, tenemos la posibilidad de entrar y salir de la mesa cuando queramos. La posición de los filósofos en la mesa se representa mediante tupla relación que indican quien está a la izquierda y a la derecha de cada filosofo p.e. [MESA, KANT, SENECA], [MESA, SENECA, PLATON], [MESA, PLATON, ARISTOTELES] [MESA, ARISTOTELES, KANT].

Las tuplas de la mesa compartida, empezaran por el valor de MESA y tendran tres elementos de tipo cadena. Para introducirte en la mesa debes coger una de estas relaciones e introducir las relaciones correspondientes con tu mesa.




La practica consta de varios pasos.
En nuestro ejercicio los filosofos no comen. Pero puedes ampliar, jugando en tu mesa. Basta que cada filósofo entre con un tenedor con su nombre. Para comer necesitas el tuyo y el del compañero de la izquierda p.e. Debeis entregar los clientes JAVA, LISP o en el lenguaje que prefieras. A linda puedes acceder como servicio Web via SOAP. Presentación practica/Filosofos . Encontrarás un ejemplo de cliente Java en http://luna1/isbc/, y el WSDL en http://alkaid:8080/axis/RLinda.jws?wsdl. Los pasos a seguir para crear clientes en Allegro common Lisp a partir del WSDL los tienes en http://www.franz.com/support/tech_corner/soap-wsdl-061404.lhtml

Ejemplo sesion Lisp

CL-USER(2): :cd D:\Lisp\LindaPract
D:\Lisp\LindaPract\
CL-USER(3): (use-package :net.xmp.soap)

T
CL-USER(4): CL-USER(4): (decode-wsdl-namespaces :file "RLinda.wsdl")
#
NIL
NIL
NIL
CL-USER(5): (setf *wsdl* (decode-wsdl-file "RLinda.wsdl"))

#
CL-USER(6): CL-USER(6): (make-client-interface *wsdl* 0 "RLinda.cl")
((("Output in file:" :KEY :FILE) "RLinda.cl")
(("Defined functions:" :KEY DEFUN)
(CLIENT-4 "Send client message echo " WSDL-2::|echo|)
(CLIENT-7 "Send client message rd " WSDL-2::|rd|)
(CLIENT-1 "Send client message out " WSDL-2::|out|)
(CLIENT-8 "Send client message in " WSDL-2::|in|))
(("Defined SOAP elements:" :KEY DEFINE-SOAP-ELEMENT) "echoResponse"
WSDL-2::|echo| "rdResponse" WSDL-2::|rd| "outResponse" WSDL-2::|out|
"inResponse" WSDL-2::|in|)
(("Defined packages:" :KEY DEFPACKAGE) #:WSDL-2 #:NET.XMP.SCHEMA
#:COMMON-LISP-USER)
(("Lisp package of generated file:" :KEY IN-PACKAGE)
#:COMMON-LISP-USER)
(("Other entries:" :KEY DEFINE-NAMESPACE-MAP) :CLIENT-NAMESPACES)
(("Other entries:" :KEY DEFVAR) *CLIENT-SERVICE-URL*))
CL-USER(7): :ld RLinda.cl
; Loading D:\Lisp\LindaPract\RLinda.cl
CL-USER(8): (client-1 :tuple "<tupleDescription><tuple><string>SOAP</string><integer>2</integer></tuple></tupleDescription>")
(WSDL-2::|outResponse|
(:|outReturn|
"out_OK from: <tupleDescription><tuple><string>SOAP</string><integer>2</integer></tuple></tupleDescription>>"))
NIL
#

CL-USER(8): (client-7 :template "<tupleDescription><tuple><wildcard /><integer>2</integer></tuple></tupleDescription>")
(WSDL-2::|rdResponse|
(:|rdReturn| "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<tupleDescription>
<tuple>
<string>SOAP <integer>2&It/integer>
</tuple>
</tupleDescription>
"))
NIL
#
Allegro cuenta con un parser XML . basta con que incorpores el paquete y definas la siguiente funcion, ya puedes convertir tuplas planas en listas! Es facil de modificar para convertir xml en tuplas anidadas...
CL-USER(19): (require :pxml)
; Fast loading C:\Archivos de programa\acl80\code\PXML.fasl
; Fast loading from bundle code\EF-UNICODE.fasl.
; Fast loading from bundle code\efft-unicode-base.fasl.
T
CL-USER(20): (DEFUN TUPLE2LIST (XMLTUPLE)
(MAPCAR #'SECOND
(CDADAR (net.xml.parser:PARSE-XML
XMLTUPLE))))
TUPLE2LIST
CL-USER(21):(tuple2list "<tupleDescription><tuple><string>MESA</string><string>PLATON</string><string>SENECA</string></tuple></tupleDescription>")
("MESA" "PLATON" "SENECA")

Ejemplo Cliente Java

/**
* This file is a part of the RLinda implementation.
* Copyright (C) 2006 Javier Fabra (jfabra@unizar.es)
*
* NOTE: Use Java 1.5!!
*/

import java.io.*;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import javax.xml.rpc.ServiceException;


import org.serviciosweb.rlinda.client.*;

// bibliotecas de Axis
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.utils.Options;

import javax.xml.rpc.ParameterMode;

public final class RLindaClient_RMI {

public static void main (String [] args) throws MalformedURLException, RemoteException, NotBoundException, ServiceException {

String endpoint = "http://alkaid:8080/axis/RLinda.jws";

// creamos un nuevo servicio consumidor
Service service = new Service();

// creamos la estructura que manejará la llamada al SW
Call call = (Call) service.createCall();

// CONSTRUCCIÓN DEL MENSAJE SOAP
// establecemos el endpoint de la llamada
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
// establecemos los parámetros de la llamada su tipo:
// uno de entrada y uno de salida, ambos del tipo String.
call.addParameter( "tuple", XMLType.XSD_STRING, ParameterMode.IN );
call.setReturnType( XMLType.XSD_STRING );

// INVOCACIÓN DEL SERVICIO WEB
// Invocamos al SW pasando los parámetros de entrada dentro de un
// vector genérico de objetos que los contiene.
// La invocación devolverá un String.
String param = "<tupleDescription><tuple><string>SOAP</string><integer>2</integer></tuple></tupleDescription>";

// establecemos la operación dentro del servicio
call.setOperationName( "out" );

String ret = (String) call.invoke( new Object [] { param });

System.out.println("El OUT() me devuelve: " + ret);

param = "<tupleDescription><tuple><wildcard /><integer>2</integer></tuple></tupleDescription>";

call.setOperationName( "rd" );
ret = (String) call.invoke( new Object [] { param });
System.out.println("El RD() me devuelve: " + ret);

call.setOperationName( "in" );
ret = (String) call.invoke( new Object [] { param });
System.out.println("El IN() me devuelve: " + ret);