Sunteți pe pagina 1din 94

Curso de Agentes Jade con JSF y Hibernate

1 Contenido
1 2 Qu es un agente de Software? ................................................................................................ 3 Diferencia entre objetos y agentes: ............................................................................................ 3 2.1 3 4 1. 2. 3. Propiedades de un agente: ................................................................................................. 3

Qu no es agente? ..................................................................................................................... 3 Introduccin ................................................................................................................................ 4 Caractersticas del framework JADE............................................................................................ 4 Plataforma de Agentes JADE ....................................................................................................... 5 Instalacin y ejecucin de la plataforma JADE ............................................................................ 8 3.1. 3.2. 3.3. 3.4. Distribucin e Instalacin: ................................................................................................ 8 Distribucin ......................................................................................................................... 8 Configuracin de jade en Windows .................................................................................... 8 Ejecucin de la plataforma JADE e interfaces grficas para usuarios. .......................... 9 Iniciar un Agente en la Plataforma JADE: ..................................................................... 11 Sintaxis de lnea de comandos: ....................................................................................... 12

4. 5.

Opciones de comando de lneas: ............................................................................................ 12 Ejecucin remota ..................................................................................................................... 16 5.1. Adherir una plataforma................................................................................................... 16 Por el protocolo IIOP ......................................................................................................... 16 Por el protocolo HTTP en una LAN .................................................................................... 18 Jade, Lans y routers ........................................................................................................... 19

6.

Programar agentes en JADE .................................................................................................... 19 6.1. 6.2. 6.3. Ciclo de vida de un agente............................................................................................... 20 Estados de un agente ....................................................................................................... 20 Transiciones entre estados: ............................................................................................ 21

7.

Programacin de Agentes Jade ............................................................................................... 23 7.1. 7.2. Ejemplo de ejecucin de agentes JADE mediante la consola de comando: ................. 24 Como crear un Agente en cdigo: ................................................................................... 25 A partir de otro agente:............................................................................................. 25

7.2.1.

7.2.2. 8.

A partir de una aplicacin Java:................................................................................. 26

Mensajes entre Agentes: ......................................................................................................... 28 8.1. Envi y Recepcin de mensajes ...................................................................................... 29 Metodos de ACLMessage: ......................................................................................... 30 Enviar un mensaje ..................................................................................................... 34 Recepcin del mensaje ............................................................................................. 35 Ejemplo de intercambio de mensajes entre dos agentes: ...................................... 35 Metodos bolck y blockingReceive ............................................................................ 38

8.1.1. 8.1.2. 8.1.3. 8.1.4. 8.1.5. 9. 10.

Parte grafica de un Agente seda con la extensin GuiAgent ................................................ 38 Comportamientos o Behaviour........................................................................................... 40 Aadir y eliminar comportamientos ..................................................................... 41 Mtodos de un comportamiento ............................................................................ 43 Mtodo action(): ....................................................................................................... 44 Mtodo done(): ......................................................................................................... 44 Mtodo block(): ......................................................................................................... 45 Mtodo blockReceive(): ............................................................................................ 46 Mtodos onStart() y onEnd(): ................................................................................... 46 Ejecucin de los comportamientos ........................................................................ 47

10.1. 10.2. 10.2.1. 10.2.2. 10.2.3. 10.2.4. 10.2.5. 10.3. 11.

Java Server Faces (JSF) ........................................................................................................ 48 Ejemplos de paginas JSF ........................................................................................... 50 Estructura de una aplicacin JSF ............................................................................ 52 Patrn MVC ................................................................................................................. 53

11.1. 11.2. 11.3. 12. 13. 14. 15.

Hibernate.............................................................................................................................. 54 Proyecto Web de Agentes jade con las tecnologas JSF y Hibernate ............................... 77 Ingenias (IDK) ...................................................................................................................... 87 Bibliogafia. ............................................................................................................................ 94

Qu es un agente de Software?

Los agentes son sistemas computacionales que habitan en entornos dinmicos complejos, perciben y actan de forma autnoma en ese entorno, realizando un conjunto de tareas y cumpliendo objetivos para los cuales fueron diseados. (P. Maes) Adems un agente pretende actuar como un usuario que busca cierta informacin de inters para el usuario real o para otro programa, lo cual es definido en sus comportamientos. Para Russell y Norvig un agente es cualquier cosa capaz de percibir su medioambiente mediante sensores y actuar en ese medio mediante actuadores. Todo agente tiene una funcin u objetivo. Por ejemplo, un agente humano de bolsa tiene el objetivo de comprar y vender acciones respondiendo a los estmulos iniciados por su cliente y captados por sus sentidos. Una aspiradora tiene la funcin de aspirar cuando capta que ha sido encendida y no aspirar cuando es apagada.

Diferencia entre objetos y agentes:

Los Objetos estn definidos por sus mtodos y atributos. Los Agentes estn definidos por sus comportamientos.

2.1 Propiedades de un agente:


Autnomo: Social: Reactivo Proactivo Movilidad Aprendizaje/Adaptacin

3 Qu no es agente?
Un agente no es un programa tradicional, pues reaccionan al entorno, tiene autonoma y persistencia. Un agente no es un objeto, porque son ms autnomos que estos, son ms flexibles (reactivos, proactivos y sociales). Un agente no es un sistema experto, porque los sistemas expertos no se acoplan a su entorno, no estn diseados para tener comportamientos reactivos ni proactivos, ni tampoco tienen habilidad social. JADE (Java Agent DEvelopment Framework)

4 Introduccin
Esta implementado en el lenguaje java. Es un middleware donde se implementan sistema mulitiagentes de acuerdo a las especificaciones FIPA (Foundation for Intelligent Physical Agents). La plataforma puede ser distribuida en distintas maquinas (pueden no tener el mismo sistema operativo).

1. Caractersticas del framework JADE


La siguiente es la lista de caractersticas que JADE ofrece al programador: Jade es una plataforma de agentes distribuida. Los agentes se implementan como hilos en Java y viven dentro de Agent Containers (contenedores de agente) que proporcionan el soporte para la ejecucin del agente. Interfaz grfica de usuario para administrar varios agentes y contenedores del agente desde un host remoto. Depuracin de herramientas para ayudar en el desarrollo de aplicaciones basadas en mltiples agentes JADE. Intra-plataforma de agente de movilidad, incluida la transferencia del estado y el cdigo (cuando sea necesario) del agente. Apoyo a la ejecucin de las actividades de los agentes mltiples, paralelas y simultneas a travs del modelo de comportamiento. JADE coloca horarios a los comportamientos de los agentes en una manera no preferente. FIPA-compliant plataforma de agente, que incluye la AMS (Sistema de Gestin del agente) y el DF (Facilitador de directorio). Estos componentes se activan automticamente en la plataforma de agentes al desplegarse. Muchos FIPA-compliant DFs se puede iniciar en tiempo de ejecucin con el fin de implementar las aplicaciones multi-dominio, donde dominio es un conjunto lgico de los agentes, cuyos servicios se anuncian a travs de un facilitador comn. Cada DF hereda una interfaz grfica de usuario y todas las capacidades estndar definidos por FIPA (es decir, capacidad de registrar, borrar el registro, la modificacin y la bsqueda de descripciones de agente, y de la capacidad de federar dentro de una red de DF). Transporte eficiente de mensajes ACL dentro de la plataforma Jade. De hecho, los mensajes se transfieren codificados como objetos Java, en lugar de cadenas, con el fin de evitar la clasificacin (marshalling) y la descalificacin (unmarshalling) de procedimientos. Al cruzar los lmites de la plataforma, el mensaje se convierte automticamente a / desde la sintaxis compatible con FIPA, codificacin y protocolo de transporte. Esta conversin es transparente a los agentes ejecutores que slo tienen que lidiar con los objetos Java.

Biblioteca de protocolos de interaccin FIPA listos para ser utilizados. El registro automtico y la baja de los agentes con la AMS. FIPA-compliant servicio de nombres: en el arranque agentes obtienen su GUID (identificador nico global) de la plataforma. Soporte para aplicaciones con contenido de lenguajes y ontologas.
InProcess Interface to allow external applications to launch autonomous agents. (traducir)

2. Plataforma de Agentes JADE


En este captulo se describen las clases JADE que apoyan el desarrollo de sistemas multiagente. Garantiza el cumplimiento de JADE sintctico y, en cumplimiento de lo posible, semntica con las especificaciones FIPA. El modelo estndar de una plataforma de agentes est definido por FIPA, como se representa en la Figura 1. Esta plataforma puede ser distribuida en diferentes host incluso con distintos sistemas operativos y la configuracin puede ser controlada a travs de una interfaz de usuario remota. Software

Plataforma de Agentes Agente Agente administrador de Sistema (AMS) El facilitador de la gua (DF)

Mensage

Transporte

Sistema

Mensage

Transporte Plataforma de Agentes

Sistema

Figura 1 Arquitectura de referencia para la Plataforma de Agentes FIPA

En esta plataforma se encuentran tres agente principales, los cuales se encargan de diversas tareas para el correcto funcionamiento de la plataforma. (ver Figura 2) El Agent Management System (AMS), este agente se encarga de la supervisar el acceso y utilizacin de la plataforma. Solo existe un AMS en toda la plataforma. El AMS provee las paginas blancas (white-pages) y el servicio de ciclo de vida (life-cycle), mantiene el directorio de los agentes identificados (AID) y su estado. Cada agente debe registrarse con un AMS a fin de obtener un AID valido. El Directory Facilitator (DF) este agente provee el servicio de pginas amarillas (yellow-pages) en la plataforma. Se encarga de publicar servicios de los agentes para que otros agentes puedan llamarlos y asi cumplir su objetivo(s). El Message Transport System, tambin se llama Agent Communication Channel (ACC), es el componente de software que controla todo el intercambio de mensajes dentro de la plataforma, incluidos los mensajes a/desde plataformasremotas. JADE cumple plenamente con esta arquitectura de referencia y cuando uno pone en marcha la plataforma JADE, el AMS y el DF se crean inmediatamente en un Contenedor Principal (MainContainer). Adems, el servicio de mensajera (la ejecucin del componente ACC) est siempre activada para permitir la comunicacin basada en mensajes.

Figura 2

Cada instancia de la plataforma Jade se llama contenedor (container) la cual puede albergar a distintos agentes. Un conjunto de contenedores activos forman una plataforma. En cada plataforma existe un Contenedor Principal, este debe ser el primer contenedor en ejecutarse, ya que este registra a los dems contenedores que se ejecuten en dicha plataforma. En la Figura 3 se representa dos plataformas Jade comunicndose a travs de la red/nube.

Figura 3

3. Instalacin y ejecucin de la plataforma JADE


Requisitos: Tener instalado y configurado el jdk (Java Development Kit) http://www.oracle.com/technetwork/java/javase/downloads/index.html Descargar la distribucin binaria de Jade de su pgina oficial, se debe tener una cuenta para poder realizar la descarga, esta cuenta es gratuita. http://jade.tilab.com/

3.1.Distribucin e Instalacin:
Distribucin En esta seccin se asume que ha descargado la distribucin binaria JADE (JADE-bin4.0.zip), la distribucin de cdigo fuente JADE (JADE-src-4.0.zip) y la distribucin JADE ejemplos (JADE-examples-4.0.zip). Una vez que los haya descomprimido en su disco duro que debe terminar con una estructura de directorios similar a la siguiente:

Figura 4

Configuracin de jade en Windows Descargar el archivo JADE-bin-4.0.zip de la pgina http://jade.tilab.com/ a la cual tendrn que inscribirse una vez descargado es solo descomprimirlo en cualquier parte del disco ejemplo c:\jade despus se configura variables de entorno en Windows , propiedades del sistema - Opciones Avanzadas Variables de Entorno: Luego en la parte de variables del sistema le dan Nueva : Nombre de Variable: CLASSPATH Valor de la variable: %CLASSPATH%;.;c:\jade\lib\jade.jar;c:\jade\lib\commonscodec\ commons-codec-1.3.jar

Figura 5

3.2.Ejecucin de la plataforma JADE e interfaces grficas para usuarios.


Una vez instalada la plataforma ejecutamos cmd (Windows) y escribimos lo siguiente: java jade.Boot gui (Figura 6).

Figura 6

Figura 7

Luego nos aparecer JADE Remote Agent Management GUI el cual nos mostrara todos los agentes que se crearan o ya creados, para esto ltimo si ya se han creado agentes sin haber iniciado primero el GUI se tendr que escribir la siguiente lnea, en la consola de comandos java jade.Boot container gui para que se logre ejecutar el GUI. (Figura 8)

Figura 8

En este caso el agente que se inici anterior al GUI es Mi_Agente. Agente Sniffer: Se utiliza para visualizar el envi de mensajes entre agentes. El usuario decide que agentes desea ver, y tambin permite guardar para un posterior anlisis. Agente Dummy: Permite ver los mensajes enviados entre Agentes, tambin se puede editar, componer y enviar mensajes ACL a otros agentes. Recibe y visualiza los mensajes de otros agentes (almacena y recupera los mensajes). Agente Introspector: Permite dar un seguimiento al ciclo de vida de los agentes as como ver tambin los mensajes que este intercambio, muestra las colas de entrada y salida de mensajes. DF gui: Permite al usuario interactuar con el DF. Ver que agentes se encuentran registrados y que servicio brinda. Registra y des-registra agentes. Puedes Modificar los servicios de los agentes registrados. Bsqueda de agentes registrados. Federar el DF con otros DFs y crear una red de dominios y subdominios de Pginas Amarillas.

3.3.Iniciar un Agente en la Plataforma JADE:


Java jade.Boot local-port 1099 NombredelAgente:Nombre_paquete.La_clase_del_agente (Argumentos)

Nombre del Agente: Se escribe cualquier nombre que se le desee poner al agente. Nombre del paquete: Se escribe el paquete en donde se encuentra la clase del agente. La clase del Agente: Ah se coloca el nombre del archivo Java que se extiende a un Agent o a un GuiAgent. Argumentos: Se colocan palabras que ayudan al agente a realizar ciertas tareas, comportamientos, etc. que lo necesiten, funciona similar a los argumentos del mtodo main de java. Son de tipo Objet[] En caso de haber ejecutado la plataforma jade antes de crear a los agentes ser necesario agregar container al cdigo anterior:

Java jade.Boot container NombredelAgente:Nombre_paquete.La_clase_del_agente (Argumentos)

Nota: esta sintaxis puede variar segn la versin de jade.

3.4.Sintaxis de lnea de comandos:


Java jade.Boot [opciones] [Nombre_agente]:[Paquete.Clase_Agente]([Argumentos]); [Nombre_Agente2]:[Paquete.Clase_Agente]([Argumentos])

Los argumentos estn separados por comas Las opciones pueden ser cualquiera de estas, segn el requerimiento: -container -gui -host Y otras que se detallan a continuacin.

4. Opciones de comando de lneas:


-container: Se utiliza para definir un nuevo contenedor en el cual se crearan l o los agentes -host: Especifica el nombre del host (nombre del ordenador) donde se encuentra el contenedor principal de la plataforma, su valor por defecto es localhost. -port: Especifica un nmero de puerto donde se ejecuta el contenedor principal, este valor por defecto es el 1099. -gui: Ejecuta el RMA de jade con el puerto predeterminado 1099. -local-host: Especfica el nombre de host en este contenedor que se va a ejecutar, y su valor es por defecto localhost. Un ejemplo tpico de este tipo de uso es para incluir el dominio completo del host (por ejemplo, kim.cselt.it-host cuando el host local tendra que regresar 'Kim') de manera que el principal contenedor puede ser contactado incluso de fuera del dominio local. -local-port: Especifica un nmero de puerto que puede ser el predeterminado u otro, para la creacion de la plataforma jade. Valor por defecto 1099. -platform-id: Esta opcin especifica el nombre simblico de la plataforma, esta opcin ser considerada solo en el caso de un contenedor principal, el valor por defecto es generar un nombre nico de los valores de nombre de host del contenedor principal y el nmero de puerto. -name: tal y como plataforma de Identificacin (mantenido por compatibilidad hacia atrs). -container-name: Se ejecuta solo al momento de iniciar la plataforma jade y reemplaza el nombre del contenedor principal de jade Main-Container con el que se le coloco. -services: Especifica una lista de clases, la aplicacin de JADE servicios a nivel de kernel, que se debe cargar y activar durante el arranque. Los nombres de clase deben estar separadas por punto y coma, y debe ser calificada en su totalidad. Los mensajes especiales y el administrador de servicio estn siempre activos y no es necesario especificar esta opcin. Si esta opcin no se da, por defecto la movilidad y los servicios de eventos de notificacin se inician.La siguiente tabla muestra los servicios disponibles con la distribucin estndar de JADE. Ms servicios (por ejemplo, el apoyo a la seguridad y la persistencia del agente estn disponibles como addons)

Nombre
Messaging

Clase de los Service


jade.core.messaging.MessagingService

Caractersticas
ACL message exchange and MTP management. Activated automatically Basic management of agent lifecycle. Container and platform shutdown. RMA support. Activated automatically Agent mobility support. Active by default Support for platformlevel event system notifications. This is required to support the Sniffer and Introspector tools (see 6.4and 6.5). Active by default Allows buffering and persistent storage for undelivered ACL messages (see 5 for details). Inactive by default Support for replicating the Main Container for fault tolerance purposes. Has to be activated on each node hosting a Main Container (see 4 for details). Inactive by default Support for being notified

AgentManagement

jade.core.management.AgentManagementService

AgentMobility

jade.core.mobility.AgentMobilityService

Notification

jade.core.event.NotificationService

PersistentDelivery

jade.core.messaging.PersistentDeliveryService

MainReplication

jade.core.replication.MainReplicationService

AddressNotification

jade.core.replication.AddressNotificationService

UDP Node Monitoring

Jade.core.nodeMonitoring.UDPNodeMonitoringServ ice

Fault Recovery

jade.core.faultRecovery.FaultRecoveryService

Topic Management

jade.core.messaging.TopicManagementService

Back-End Management

ade.imtp.leap.nio.BEManagementService

whenever the list of active Main Container copies changes, i.e. a new copy is added or an existing copy terminates (see 4 for details). Inactive by default Support for monitoring of platform nodes by means of UDP packets (see 2.3.7 for details) Inactive by default Support for recovering after a Main Container crash (typically used alternatively to the MainReplicationService to achieve Main Container fault tolerance) Inactive by default Support sending messages about a given topic. Such messages will be received by all agents that have previously registered to that topic Inactive by default Support for acting as mediator for split-containers. Inactive by default

-mtps: Especifica una lista de protocolos de transporte de mensajes externos para ser activados en el contenedor/container (de forma predeterminada el HTTP MTP esta activada en el contenedor principal/main-container y no se encuentra activado el MTP en otros contenedores)

-nomtp: Tiene prioridad sobre mtps y lo reemplaza. Debe ser usado para reemplazar el comportamiento predeterminado del main-container (por defecto la opcin nomtp esta deseleccionada) -backupmain: especifica que esta instancia de JADE es un main-container de copia de seguridad y, como tal, que debe unirse a un contenedor principal (por defecto esta opcin no est seleccionada) -smhost: Cuando una copia main-container esta iniciada, esta opcion debe ser utilizada para seleccionar el nombre de host en el Administrador de servicios que se va a exporter (por lo general es el local host). Esta opcin solo es til en los nodos donde el servicio Main-Replication se encuentre activa. -smport: Cuando una copia main-container esta iniciada, esta opcin debe ser utilizada para seleccionar el puerto TCP en el administrador de servicios que se va exportar (por lo general es el local host). Esta opcin solo es til en los nodos donde el servicio Main-Replication se encuentre activa. -smaddrs: cuando mltiples copias del main-container estn activadas en la plataforma, un contenedor perifrico se conecta a la que apunta el <-host, port> par de opciones. Con esta opcin, las direcciones de todas las dems copias se pueden enumerar, por lo que el contenedor es capaz de volver a conectar con otra copia si el actual no est disponible. Esta opcin es una alternativa de activar el servicio de Address-Notification, en lugar de establecer un protocolo de actualizacin, simplemente proporciona una lista fija de direcciones conocidas de copias del mainconteiner. -aclcodecs: Por defecto todos los mensajes entregados a los agentes que viven en plataformas remotas son codificadas por la cadena base ACLCodec. Esta opcin permite especificar una lista adicional ACLCodec que estar a disposicin de los agentes del contenedor puesto en marcha con el fin de codificar / descodificar mensajes. Con el fin de utilizar agentes codecs se tiene que establecer un valor en el campo aclRepresentation de la sobbre los enviados / recibidos ACLMessages. Mirar las especificaciones FIPA para los nombres estndar de estos cdecs. -nomobility: Desactiva la movilidad y el apoyo de clonacin en el contenedor de lanzamiento. De esta manera, el contenedor no aceptar las solicitudes de migracin de agentes o la clonacin agente, opcin que podra ser til para mejorar el nivel de seguridad para el host en este contenedor se est ejecutando. Tenga en cuenta que la plataforma puede incluir tanto los contenedores donde la movilidad est habilitada y contenedores donde se desactiva. Por defecto esta opcin no est seleccionada. -version: Imprime la versin de la plataforma JADE. -help: Imprime informacin bsica sobre los comandos. -conf: Especifica una propiedad del archivo. Todas las opciones especificadas en dicho archivo se utilizan para lanzar JADE. Ejemplos de ejecucin de lnea de comandos: Ejecucion de la plataforma jade con un puerto asignado 801:
java jade.Boot local-port 801

Ejecucion del gui con un puerto asignado:


java jade.Boot local-port 801 -gui

Ejecucion de un agente en la plataforma jade sin iniciar el gui:


java jade.Boot local-port 801 mi_nombre:miclase(argumento1,argumento2) java jade.Boot local-port 801 mi_nombre:mipaquete.miclase(argumento1,argumento2)

5. Ejecucin remota
JADE es una plataforma que permite la ejecucin de un sistema de agentes en el que stos puedan estar repartidos entre diversos hosts. Para ejecutar un agente en remoto tendramos que ejecutar la orden java jade.Boot -container -host nombreHost <nombre_del_agente>:<ruta_al_agente.class> desde la lnea de comandos. Tambin es posible crear un RMA que ponga en contacto la plataforma local con la remota. Esto significa que desde el RMA de ambas plataformas podremos contemplar los cambios producidos en el sistema de agentes, e interactuar con dichos agentes. Para ello tenemos que ejecutar la orden java jade.Boot -container -host nombreHost RMA1:jade.tools.rma.rma desde la lnea de comandos.

5.1.Adherir una plataforma


Para adherir una plataforma existen dos formas IIOP y HTTP para mayor informacin entrar a la siguiente pgina http://jade.tilab.com/doc/tutorials/JADEAdmin/HttpMtpTutorial.html Por el protocolo IIOP

Por consola ejecutamos el cmd de Windows Escribimos java jade.Boot gui mtp jade.mtp.iiop.MessageTransportProtocol Se crearan los archivos de texto MTPs-Main-Container.txt, APDescription.txt; el que nos interesa es el primero que tendr una informacin similar: IOR:000000000000001149444C3A464950412F4D54533A312E30000000000000000100000000000 0006E000102000000000D3139322E3136382E312E33330000130800000019AFABCB00000000024 CF6BEDC000000080000000000000000140000000000000200000001000000200000000000010001 00000002050100010001002000010109000000010001010000000026000000020002 Una vez hecho esto copiamos todo el contenido del archivo MTPs-Main-Container.txt nos vamos a gui, le damos click RemotePlatforms luego AddPlataform via AMS AID

Le damos click RemotePlatforms luego AddPlataform via AMS AID

Figura 9

Name: ams@frodo:1099/jade Click derecho en Addresses y luego click en Add colocar IOR:000000000000001149444C3A464950412F4D54533A312E3 00000000000000001000000000000006E000102000000000D3 139322E3136382E312E33330000130800000019AFABCB00000 000024CF6BEDC0000000800000000000000001400000000000 00200000001000000200000000000010001000000020501000 10001002000010109000000010001010000000026000000020 002 El gui o RMA mostrara la siguiente imagen la cual solo nos muestra los gentes de la otra plataforma Nota: No se visualizan los contenedores y tampoco podemos Figura 10 manejar los agentes (suspender, eliminar y crear) solo podemos enviar mensajes para esto ltimo no es necesario agregar una plataforma al RMA se explicara ms adelante lo de la comunicacin. Nota: Se crean en el directorio donde se ejecuta ejemplo si lo ejecutaran en este directorio

C:\Documents and Settings\jose> java jade.Boot gui mtp jade.mtp.iiop.MessageTransportProtocol Los archives se localizaran en C:\Documents and Settings\jose Por el protocolo HTTP en una LAN

Le damos click RemotePlatforms luego AddPlataform via AMS AID

Figura 11

Name: ams@frodo:1099/jade Click derecho en Addresses y luego click en Add colocar http://Frodo:7778/acc nos mostrara en el gui o RMA la siguiente imagen la cual solo nos muestra los gentes de la otra plataforma

Figura 12

Nota: No se visualizan los contenedores y tampoco podemos manejar los agentes (suspender, eliminar y crear) solo podemos enviar mensajes para esto ltimo no es necesario agregar una plataforma al RMA se explicara ms adelante lo de la comunicacin.

Figura 13

Jade, Lans y routers

Solo se cambia el nombre de la plataforma por la ISP ejemplo 65.95.65.3 sera as: Name: ams@65.95.65.3:1099/jade Addresses: http://65.95.65.3:7778/acc

6. Programar agentes en JADE


Programar un agente JADE consiste en: Definir una clase Java que representa al agente (la cual debe heredar de la clase jade.core.Agent). Implementar los comportamientos que va a manifestar. Un agente JADE cumple las siguientes caractersticas: Tiene un nombre nico en el entorno de ejecucin. Se implementa como un nico hilo de ejecucin (single-threaded). Tiene un mtodo de inicio (setup) y otro de fin (takeDown). (Ver Figura 12)

El mtodo protegido setup() sirve para inicializar el agente incluyendo instrucciones que especificarn la ontologa a utilizar y los comportamientos asociados al agente. Se invoca al comenzar la ejecucin del agente. El mtodo protegido takeDown() sirve para liberar recursos antes de la eliminacin del agente. Este mtodo es invocado cuando se realiza una llamada al mtodo doDelete(), que es el que realmente da por finalizada la ejecucin del agente. Ambos mtodos deben ser sobrescritos. En su implementacin se define una clase interna por cada uno de los comportamientos asociados al agente. Estos comportamientos se utilizan bsicamente para el envo y recepcin de mensajes, aunque tambin se pueden utilizar para realizar otras tareas. La clase Agent: Es una superclase comn que permite a los usuarios crear software de agentes. Suministra mtodos que permiten ejecutar las tareas bsicas de los agentes como: Pasar mensajes utilizando objetos ACLMessage, con correspondencia de patrones. Dar soporte al ciclo de vida de un agente. Planificar y ejecutar mltiples actividades concurrentemente. Los programadores de aplicaciones basadas en agentes deben escribir sus propios agentes como subclases Agent, aadiendo tantos comportamientos especficos como sean necesarios y explotando las capacidades de la clase Agent.

6.1.Ciclo de vida de un agente


Un agente est sujeto a un ciclo de vida en el que se definen los estados en los cuales se puede encontrar el agente, as como los cambios que se pueden realizar entre los diferentes estados. El ciclo de vida de un agente JADE sigue el ciclo propuesto por FIPA, es decir, cumple con la propuesta del estndar de interoperabilidad entre agentes ms aceptado.

6.2.Estados de un agente
Un agente puede estar en los siguientes estados: Iniciado: El objeto Agente est creado pero todava no se ha registrado en el AMS, no tiene nombre ni direccin y tampoco se puede comunicar con otros agentes. Activo: El Agente est registrado en el AMS, tiene un nombre, una direccin y puede acceder a todas las opciones de JADE. Suspendido: El Agente est parado. Su hilo de ejecucin est detenido y no ejecuta ningn Comportamiento. En espera: El Agente est bloqueado esperando por algo. Su hilo de ejecucin est dormido en un monitor de java y se despertar cuando se cumpla una cierta condicin (cuando reciba un mensaje).

Desconocido: El Agente ha sido eliminado. El hilo de ejecucin ha terminado y se ha eliminado del registro del AMS. Trnsito: Un Agente mvil entra en este estado mientras est migrando a una nueva localizacin. El sistema sigue guardando los mensajes en el buffer hasta que el agente vuelve a estar activo.

6.3.Transiciones entre estados:


Un agente puede cambiar de un estado a otro a travs de transiciones. Estas transiciones pueden ser ejecutadas a travs de mtodos disponibles en la clase Agent y ser capturados por mtodos que se pueden sobrescribir. Para saber en qu estado se encuentra un agente se puede usar el mtodo getAgentState( ) de la clase Agent que devuelve un objeto de la clase AgentState
public AgentState getAgentState()

Accin Crear Invocar Suspender

Descripcin Creacin o instalacin de un nuevo agente. Invocacin de un nuevo agente.

Mtodo que Mtodo que realiza la accin captura la accin Constructor setup()

Pone un agente en estado suspendido. Puede doSuspend() ser iniciado por el agente o por el AMS.

Contina con la ejecucin de un agente que se Reanudar encuentra en estado suspendido. Slo puede ser iniciado por el AMS. Esperar Pone un agente en estado de espera. Slo doWait() puede ser iniciado por el agente.

Contina con la ejecucin de un agente que se Despertar encuentra en estado de espera. Slo puede ser doWake() iniciado por el AMS. Mover Pone un agente en otro contenedor cambiando su estado al de trnsito. Slo puede ser iniciado doMove() por el agente. Contina con la ejecucin de un agente que se encuentra en estado de trnsito. Slo puede ser iniciado por el AMS. La terminacin UNMSMl o forzosa de un agente. Slo puede ser iniciado por el AMS y no doDelete() puede ser ignorado por el agente. takeDown() beforeMove() afterMove() y

Ejecutar

Destruir

Visin grfica

Figura 14

Flujo de control de un agente La Figura 15 muestra el flujo de vida de un agente bsico. Como se ve todo comienza desde el mtodo setup() el cual indica que el agente se encuentra vivo luego se ve si se ha invocado al mtodo doDelete() el cual invoca al mtodo takeDown() el cual termina con la vida del agente, si encaso no es invocado pasa a realizar una serie de actividades hasta encontrarse con su primer

comportamiento a ejecutar, el cual inicia la accin en el mtodo action() hasta finalizarlo si esto sucede se ejecuta el mtodo done() de este comportamiento para determinar si se ha terminado correctamente.

Figura 15

7. Programacin de Agentes Jade


Aqu se muestra el esqueleto de un agente el cual consta de de un mtodo setup() en el cual inicia el agente al crearse y takeDown()se invoca cuando se elimina o mata al agente si se invoca con el mtodo doDelete()del AID se esplicara mas adelante como usarlo.

import jade.core.Agent; public class MiAgente extends Agent { protected void setup(){ // Inicializacin del agente MiAgente System.out.println(Agente Iniciado); } protected void takeDown() { // Liberacin de recursos del agente System.out.println(Agente finalizado); } }

7.1.Ejemplo de ejecucin de agentes JADE mediante la consola de comando:


Se guarda el Archivo con el nombre MiAgente.Java luego se abre el cmd. Se compila el archivo Javac MiAgente.Java. (ver capitulo 2.3) Se crea al agente Ejemplo y Ejemplo2 sin paso de argumentos ambos tienen la misma clase Agente, pueden ser distintas. Java jade.Boot port 1099 Ejemplo:MiAgente; Ejemplo2:MiAgente Se crea al agente Ejemplo y Ejemplo2 con paso de argumentos las comas separan los argumentos.
Java jade.Boot port 1099 Ejemplo:MiAgente(Hola,help); Ejemplo2: MiAgente(hola2,help2)

NOTA: los comandos anteriores solo funcionan si es que la plataforma jade no ha sido levantada, si es levantada previamente ser necesario agregar container antes del port solo si el puerto es diferente al 1099, sino no es necesario. Ejemplo de cdigo de un Agente al cual se le pasa argumentos y los muestra en pantalla.
import jade.core.Agent; import java.util.Iterator; public class AgenteHolaMundo extends Agent { protected void setup(){ // Imprime un mensaje de bienvenida System.out.println("Mi nombre local es: "+getAID().getLocalName()); System.out.println("Mi GUID es: "+ getAID().getName()); System.out.println("Mis direcciones son:"); Iterator it = getAID().getAllAddresses(); while(it.hasNext()){ System.out.println("- "+it.next()); }

//pasando argumentos System.out.println("Mis argumentos son:"); Object[] args = getArguments(); if(args != null){ for(int i=0; i<args.length; i++){ System.out.println("- "+args[i]); } } //invoca al metodo takeDown() doDelete(); } protected void takeDown(){ System.out.println("Adios mundo cruel!"); System.exit(0); //termina el sistema, usar solo cuando se desea cerrar la plataforma jade } }

7.2.Como crear un Agente en cdigo:


7.2.1. A partir de otro agente: Se utiliza la clase AgentContainer para agregar o insertar un contenedor en la plataforma jade, la clase AgentController se utiliza para agregar un agente al contenedor. jade.wrapper.ContainerController este controlador brinda una funcionalidad de nivel superior del Agent Container, tales como instalacin y desinstalacin del MTPs, eliminar contenedores y creacion de agentes. El createNewAgent() mtodo de la clase ContainerController retorna un AgentController el cual envuelve todas las funcionalidades del agente, preservando al mismo tiempo su autonoma. Esta clase brinda mtodos que ayudan a definir el ciclo de vida de los agentes que estn contenidos en esta. Nota: el mtodo createNewAgent() no inicializa al agente para esto es necesario usar el mtodo star() de la clase AgentContainer. Agente_Crea_Agente y AgenteHolaMundo
import jade.core.Agent; import jade.wrapper.*; public class Agente_Crea_Agente extends Agent { protected void setup(){ AgentContainer c = getContainerController(); //Se asigna el contenedor del agente Agente_Crea_Agente para el agente que se va a crear try { AgentController a = c.createNewAgent( "NombredelAgente","AgenteHolaMundo", null ); // se inicializa al Agente a.start(); //Se activa al agente invocando al mtodo setup()

a.kill(); //Mata al agente invocando al mtodo takeDown ( ) catch (StaleProxyException e){} } protected void takeDown(){ System.out.println("Adios mundo cruel!"+getAID().getLocalName()); } }

7.2.2.A partir de una aplicacin Java: Se presentan dos formas de realizar esto: o La primera es ejecutando la clase Boot de jade, que sera igual a escribir los comandos anteriores, los cuales son contenidos un arreglo de String y es pasado al mtodo Boot.main(), este se encarga de ejecutar la plataforma jade con la lista de argumentos que se le envia.
package agentes; import jade.Boot; public class Agentes { public static void main(String[] args) { //para el ejemplo se uso la calse main pero puede ser en cualquier clase o mtodo de la aplicacin String [] list={"-container","AgenteSaludo:agentes.AgenteSaludo"}; //Este vector contiene la informacin de lo que se ejecutara en la plataforma de jade. Boot.main(list); } //end main } //end class Agentes

El siguiente cdigo puede ser usado tanto dentro de un agente como de una aplicacin JAVA. En este ejemplo se utilizan las clases jade.core.Runtime, jade.core.Profile y jade.wrapper la cuales permiten a JADE ejecutarse por aplicaciones externas de tipo JAVA. La instancia singleton de Runtime provee dos mtodos: createMainContainer() para crear un contenedor principal en JADE. createAgentContainer() para la creacion de un contenedor perifrico al Main-Container Esta clase requiere como parmetro al objeto Profile, este nos permite definir las opciones del contenedor a crear, por ejemplo, su host y port del contenedor principal, tambien podemos definir el nombre del contenedor a crear. Todas estas opciones de la clase Profile son especificadas usando el mtodo setParameter(String key, String value).

Tanto los mtodos createMainContainer() y createAgentContainer() retorna un objeto de tipo jade.wrapper.ContainerController, ver seccin 4.2.1
package agentes; import jade.core.Profile; import jade.core.ProfileImpl; import jade.core.Runtime; import jade.wrapper.ContainerController; import jade.wrapper.AgentController; public class Agentes { public static void main(String[] args) { //Si en caso de no haber iniciado la plataforma Jade, se aadir el mtodo Boot.main() con los argumentos necesarios, para el ejemplo: -port 60000 -file-dir jade/ //arg[0]= -port ; // arg*1+=60000 ; // arg[2]= -file-dir ; // arg[3]= jade/ ; // Boot.main(args); Runtime rt = Runtime.instance(); Profile p=new ProfileImpl(); // define propiedades (en qu contenedor, host, Puerto se va a crear) p.setParameter(Profile.MAIN_HOST, "UNMSM2"); //si en caso es necesario, como por ejemplo si es que se desea crear al agente en otro servidor u ordenador p.setParameter(Profile.MAIN_PORT, "60000"); //Cuando se ejecuta la plataforma jade con su puerto predeterminado 1099 no es necesario definir este campo. p.setParameter(Profile.CONTAINER_NAME, "jose");//se le asigna un nombre al contenedor ContainerController cc= rt.createAgentContainer(p); //se crea un contenedor en la plataforma jade if(cc!=null){ try{ //se inicia al agente en el contenedor asignado y luego se activa AgentController ac =cc.createNewAgent("a", "Ejemplo_Agentes.EjemploAgente", null); // nombre del agente, paquete y clase. ac.start(); } catch (Exception e){ e.printStackTrace(); } } //end if } //end main

} //end class

8. Mensajes entre Agentes:


La comunicacin entre agentes JADE seda mediante la clase ACLMessage la cual esta implementada segn las especificaciones de FIPA, a esta comunicacin se le llama FIPA-ACL. Un agente enva un mensaje creando un objeto del tipo ACLMessage al cual se le agregan los atributos adecuados al mensaje a enviar y este se enva por el mtodo send(). El agente receptor puede recibir el mensaje mediante el mtodo recieve() o blockingRecieve(), este ultimo bloquea todos los comportamientos del agente hasta recibir un mensaje. La comunicacin entre agentes es la que determina la programacin de estos y es la que permite conseguir la potencia de los sistemas multiagente. Determinan su interaccin/comunicacin con los dems agentes. Los agentes solo se pueden comunicar con aquellos que tengan su mismo lenguaje de comunicacin. Un lenguaje de comunicacin define su tipo de comunicacin o llamada performativa la cual contiene las siguientes constantes: informar, solicitar, preguntar,.. Los agentes se comunican por una serie de protocolos de comunicacin. El lenguaje de comunicacin de agentes (ACL) ofrece tambin la capacidad de enviar una serie de conocimientos el cual es expresado en un lenguaje de contenido. Los trminos del lenguaje de contenido, vocabulario comn a los distintos agentes se le llama ontologa.

Un mensaje FIPA-ACL puede contener los siguientes campos: performative: tipo de acto de comunicacin (accin que realiza el mensaje). Este campo es obligatorio y puede contener los siguientes valores. o o o o o o o o o o accept-proposal: aceptar una propuesta recibida previamente. agree: estar de acuerdo en realizar alguna accin. cancel: cancelar alguna accin recibida previamente. cfp: solicitar propuestas para realizar alguna accin dada. confirm: informar a un receptor que una proposicin es cierta. disconfirm: informar a un receptor que una proposicin es falsa. failure: informar a un agente que se intento una accin pero fallo. inform: informar a un receptor que una proposicin es cierta. inform-if: si el agente que recibe la accin cree que la informacin es verdadera informara de manera afirmativa, sino indicara que es falsa. inform-ref: permite que el emisor informe al receptor de un objeto que cree que corresponde a un descriptor, como puede ser un nombre u otradescripcion que lo identifique. not-understood: iforma a un receptor que el emisor no entiendio el mensaje.

propagate: el receptor trata al mensaje como si fuese dirigido directamente a l, y debe identificar a los agentes en este descriptor y enviarles el mensaje a ellos. o propose: enviar una propuesta para realizar una cierta accin. o proxy: el receptor debe seleccionar agentes objetivo denotados por una descripcin dada, y enviarles un mensaje embebido. o query-if: preguntarle a otro agente si una determinada proposicin es cierta. o query-ref: preguntar a otro agente por el objeto referenciado en una expresin. o refuse: rechazar realizar una accin. o reject-proposal: rechazar una propuesta durante una negociacin. o request: solicitar a un receptor que realice alguna accin. o request-when: solicitar al receptor que realice alguna accin cuando una proposicin dada sea cierta. o request-whenever: solicitar al receptor que realice alguna accin cada vez que una proposicin dada sea cierta. o subscribe: una intencin persistente de notificar al emisor de un determinado valor, y volver a notificarle cada vez que dicho valor cambie. sender: AID del emisor. receiver: lista de AIDs de los receptores. reply-to: receptor de un mensaje reply. content: contenido del mensaje. language: lenguaje en que se expresa el contenido. encoding: codificacin del contenido. ontology: ontologa usada para dar significado a los trminos del contenido. protocol: identificador del protocolo de interaccin. conversation-id: identificador de la conversacin. Esto es especialmente til cuando un agente mantiene varias conversaciones a la vez. reply-with: indica una expresin que tendr que ser usada por el agente que responda a dicho mensaje. Si un agente enva un mensaje que contiene: reply-with query1 el receptor responder con otro que contenga: in-reply-to query1. in-reply-to: Hace referencia a que este mensaje es una respuesta a otro anterior. reply-by: Indica el tiempo en que el mensaje ha de ser respondido.

8.1.Envi y Recepcin de mensajes Los agentes toman la decisin de la lectura de sus mensajes. El mecanismo de estos mensajes es asncrono. Todos los agentes poseen una cola de mensajes entrantes la cual es compartida por todos
los comportamientos.

Cuando un mensaje es enviado a un agente este se coloca en la cola de mensajes del otro
agente y se le comunica a este agente.

Uno o todos los comportamientos pueden ser bloqueados en la espera de la recepcin de


un mensaje: sincronizacin.

Todo mensaje intercambiado en la plataforma jade mediante agentes es una instancia de


la clase jade.lang.acl.ACLMessage.

Un agente puede:
o o Leer el primer mensaje en la cola. Leer el primer mensaje que satisfaga un requisito.

8.1.1.Metodos de ACLMessage:
void addReceiver(AID r)

Toma como parmetro un AID y lo aade a la lista de receptores.


void addReplyTo(AID dest)

Toma como parametro un AID y lo aade a la lista de Respuesta Reply-to.


void addUserDefinedParameter(java.lang.String key, java.lang.String value)

Aadir un nuevo usuario definido por los parmetros de este ACLMessage.


void clearAllReceiver()

Remueve todos los valores de: receptores


void clearAllReplyTo()

Remueve todos los valores de:reply_to.


java.lang.Object clearUserDefinedParameter(java.lang.String key)

Removes the key and its corresponding value from the list of user

defined parameters in this ACLMessage.


java.lang.Object clone()

Clona un ACLMessage object.


ACLMessage createReply()

Crea un nuevo ACLMessage de replica sobre el mensaje recepcionado.


Iterator getAllIntendedReceiver()

retrieve the whole list of intended receivers for this message.


static java.lang. getAllPerformativeNames() String[] Returns the list of the communicative acts as an array of String. Iterator getAllReceiver()

Reads :receiver slot.


Iterator getAllReplyTo()

Reads :reply_to slot.


Properties getAllUserDefinedParameters()

Return all user defined parameters of this ACLMessage in form of a Properties object
byte[] getByteSequenceContent() Reads :content slot. java.lang.String getContent() Reads :content slot. java.io.Serializ getContentObject() able This method returns the content of this ACLMessage when they

have been written via the method setContentObject.


java.lang.String getConversationId()

Reads :conversation-id slot.


java.lang.String getEncoding()

Reads :encoding slot.


Envelope getEnvelope()

Reads the envelope attached to this message, if any.


java.lang.String getInReplyTo() Reads :reply-to slot. static int getInteger(java.lang.String perf)

Returns the integer corresponding to the performative


java.lang.String getLanguage()

Reads :language slot.


java.lang.String getOntology()

Reads :ontology slot.


int getPerformative()

return the integer representing the performative of this object


static java.lang. getPerformative(int perf) String Returns the string corresponding to the integer for the

performative
java.lang.String getProtocol()

Reads :protocol slot.


java.lang.String getReplyBy()

Deprecated. Since the value of this slot is a Date by definition, then the getReplyByDate should be used that returns a Date
java.util.Date getReplyByDate() Reads :reply-by slot. java.lang.String getReplyWith() Reads :reply-with slot. AID getSender() Reads :sender slot. java.lang.String getUserDefinedParameter(java.lang.String key)

Searches for the user defined parameter with the specified key.
boolean hasByteSequenceContent()

This method allows to check if the content of this ACLMessage is a

byteSequence or a String
boolean removeReceiver(AID r)

Removes a value from :receiver slot.


boolean removeReplyTo(AID dest) Removes a value from :reply_to slot. boolean removeUserDefinedParameter(java.lang.String key)

Removes the key and its corresponding value from the list of user defined parameters in this ACLMessage.
void reset()

Resets all the message slots.


void setAllUserDefinedParameters(Properties userDefProps)

Replace all user defined parameters of this ACLMessage with the specified Properties object.
void setByteSequenceContent(byte[] byteSequenceContent) Writes the :content slot. void setContent(java.lang.String content) Writes the :content slot. void setContentObject(java.io.Serializable s)

This method sets the content of this ACLMessage to a Java object.


void setConversationId(java.lang.String str)

Writes the :conversation-id slot.


void setDefaultEnvelope()

Writes the message envelope for this message, using the :sender and :receiver message slots to fill in the envelope.
void setEncoding(java.lang.String str)

Writes the :encoding slot.


void setEnvelope(Envelope e)

Attaches an envelope to this message.


void setInReplyTo(java.lang.String reply)

Writes the :in-reply-to slot.


void setLanguage(java.lang.String str)

Writes the :language slot.


void setOntology(java.lang.String str)

Writes the :ontology slot.


void setPerformative(int perf)

set the performative of this ACL message object to the passed constant.
void setProtocol(java.lang.String str)

Writes the :protocol slot.


void setReplyByDate(java.util.Date date)

Writes the :reply-by slot.


void setReplyWith(java.lang.String reply)

Writes the :reply-with slot.


void setSender(AID s)

Writes the :sender slot.


java.lang.String toString()

Convert an ACL message to its string representation.

La performativa se debe aadir a los mensajes pasando el valor al constructor de ACLMessage, este valor es de carcter obligatorio. 8.1.2.Enviar un mensaje Pasos: Creamos el mensaje. Usamos los mtodos del ACLMenssage para rellenar los campos apropiados asi como agreagar la lista o un de destinatario. Invocar al mtodo send(ACLMessage) de la clase Agent, el cual es el encargado de enviar el mensaje Existen dos formas de enviar un mensaje: La primera es enviando una texto, mediante el mtodo setContent().
ACLMessage mensaje= new ACLMessage(ACLMessage.INFORM) ; mensaje.addRecever(id) ; //(nombre del agente id)

mensaje.setContent(Hola agente Receptor) ; mensaje.setLanguage(Espaol); send(mensaje);

Comportamientos: nicos, cclicos, discretos La segunda es eviando un objeto Serializable de Java, mediante el mtodo setContentObject(). Debe tenerse en cuenta que esta caracterstica no se ajusta a la de FIPA y que cualquier plataforma de agentes puede reconocer automticamente el uso de la codificacin Base64, por lo que los mtodos que deben utilizarse adecuadamente por los programadores y debe suponer que los agentes de la comunicacin saben a priori el uso de estos mtodos. Desde JADE 2.5, dos mtodos se han agregado que permiten crear / obtener una secuencia de bytes desde y hasta el contenido de la ACLMessage: get/setByteSequenceContent (). En algunas circunstancias (en particular cuando el ACLMessage se codifica en un formato de cadena), secuencias de bytes que puede crear el contenido del mensaje incompatibles e irreversible se debe tener gran cuidado al usar estos dos mtodos.

Try{ ACLMessage msg = new ACLMessage(ACLMessage.INFORM); msg.addReceiver(reader); Person p = new Person("Name1", "Surname1", new Date(), 1); msg.setContentObject(p); msg.setLanguage("JavaSerialization"); send(msg); } catch (IOException e ) { e.printStackTrace();}

8.1.3.Recepcin del mensaje


Para esto se utiliza el mtodo receive()o el blockingReceive() ambos de la clase Agent. El primero no bloquea los comportamientos del agente y esto hace que estos consuman recursos del cpu, el segundo bloquea todos los comportamientos del agente hasta que reciba un mensaje. ACLMessage msg = receive(); ACLMessage msg = blokingReceive();

8.1.4.Ejemplo de intercambio de mensajes entre dos agentes: El siguiente ejemplo consta de dos clases Receptor y Emisor. De la primera clase se instanciara el AgenteReceptor, este agente tiene como tarea la de recibir un mensaje y responder Hola Agente Emisor. De la segunda clase se instanciara el AgenteEmisor, este agente solo enva un mensaje Hola agente Receptor. A continuacin la implementacin de las clases. Clase Emisor:

import jade.core.*; import jade.core.behaviours.*; import jade.lang.acl.*; public class Emisor extends Agent { class EmisorComportaminento extends SimpleBehaviour { boolean fin = false; public void action() { System.out.println(Agente: +getLocalName() +": Comenzando el envi del mensaje al AgenteReceptor"); AID id = new AID(); id.setLocalName("AgenteReceptor "); // Creacin del objeto ACLMessage ACLMessage mensaje = new ACLMessage(ACLMessage.REQUEST); //Rellenando los campos necesarios para el mensaje mensaje.setSender(getAID()); mensaje.setLanguage("Espaol"); mensaje.addReceiver(id); mensaje.setContent("Hola, que tal AgenteReceptor "); //Enviando el mensaje a los destinatarios send(mensaje); System.out.println(getLocalName() +": Enviando hola a AgenteReceptor "); System.out.println(mensaje.toString()); fin = true; } public boolean done() { return fin; } } protected void setup() { addBehaviour(new EmisorComportaminento()); } }

Clase Receptor:

import jade.core.*; import jade.core.behaviours.*; import jade.lang.acl.ACLMessage; public class Receptor extends Agent { class ReceptorComportaminento extends SimpleBehaviour { private boolean fin = false; public void action() { System.out.println(" Esperando el mensaje"); //Obtiene el primer mensaje de la cola de mensajes ACLMessage mensaje = receive(); if (mensaje!= null) { System.out.println(El Agente +getLocalName() + ": acaba de recibir el siguiente mensaje: "); System.out.println(mensaje.toString()); fin = true; } } public boolean done() { return fin; } } protected void setup() { addBehaviour(new ReceptorComportaminento()); } }

Ejecucin de los agentes en la plataforma JADE 1. Se crea un Agente de la clase Receptor con el nombre AgenteReceptor (java jade.Boot container AgenteReceptor:Receptor) 2. Se crea un Agente de la clase Emisor con el nombre AgenteEmisor (java jade.Boot container AgenteEmisor:Emisor) Obtenemos la siguiente salida:
Agente AgenteEmisor: Comenzando el envi del mensaje al AgenteReceptor AgenteEmisor: Enviando hola a AgenteReceptor El Agente AgenteReceptor: acaba de recibir el siguiente mensaje:

(REQUEST :sender ( agent-identifier :name AgenteEmisor @ unmsm:1099/JADE http://unmsm:7778/acc )) :receiver (set ( agent-identifier :name AgenteReceptor@ unmsm:1099/JADE ) ) :content "Hola, que tal AgenteReceptor " :language Espaol )

:addresses (sequence

8.1.5.Metodos bolck y blockingReceive Estos mtodos provienen de la clase Behaviour, permiten bloquear los comportamientos de los agentes, con la finalidad de que no consuman recursos. El mtodo block(), bloquea el comportamiento donde se encuentra implementado. (Ver capitulo 10.2.3) El mtodo blockReceive(), detiene todos los comportamientos del agente. (Ver capitulo 10.2.4)

9. Parte grafica de un Agente seda con la extensin GuiAgent


En el siguiente ejemplo se muestra como se crea una ventana la cual crea a otro agente para esto se usan los archivo AgentVentana.java el cual se extiende GuiAgent y Venata.java el cual se extiende a un JFrame. Lo vamos hacer por partes: Primero creamos un archivo que se extiende a GuiAgent de la siguiente manera: Las clases principales a importar son import jade.gui.GuiAgent; import jade.gui.GuiEvent;

El Agente AgentVentana
import jade.gui.GuiAgent; //Esta la parte grafica de los agentes import jade.gui.GuiEvent; //Manejo de eventos public class AgentVentana extends GuiAgent { private Ventana gui; //Se instancia el JFrame Ventana private jade.wrapper.AgentContainer c; private AgentController aa; /* De esta manera se manejan los eventos generados en el JFrame Con variables estticas de tipo entero */ public static final int NuevoAgente=0; public static final int EliminarAgente=1; @Override public void setup() {

gui = new Ventana(this); gui.setTitle(getLocalName()); gui.pack(); gui.setVisible(true); } protected void onGuiEvent(GuiEvent ev) { c = getContainerController(); // procesa los eventos // ev.getType() nos devuelve el evento generado por el Jframe (valor entero) switch(ev.getType()){ case NuevoAgente: try { //se crea al agente aa = c.createNewAgent( gui.getNm_Agente(),"historiaclinica_agentes."+gui.getCs_Agente(), null ); aa.start(); //inicia al agente } catch (StaleProxyException e){} break; case EliminarAgente: try { aa.kill(); //mata al agente } catch (StaleProxyException e){} break; }

Ahora Se crea el archivo Ventana el cual se extiende a un JFrame esta clase no posee el mtodo main

La clase Ventana
import jade.gui.GuiEvent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class Ventana extends javax.swing.JFrame { private javax.swing.JTextField Cs_Agente; private javax.swing.JTextField Nm_Agente; private javax.swing.JButton eliminar; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JButton nuevo; private AgentVentana myAgent; //Esta variable del tipo GuiAgent //Se crea el constructor a usar por el Agente AgentVentana el cual se extiende a GuiAgent Ventana(AgentVentana aThis){ myAgent=aThis;

initComponents(); //Este mtodo es generado automticamente por el IDE de netbeans manejo ma=new manejo(); nuevo.addActionListener(ma); eliminar.addActionListener(ma); } private class manejo implements ActionListener{ //clase que maneja eventos no es necesario implementarla public void actionPerformed(ActionEvent evt){ if(evt.getSource()==nuevo){ @SuppressWarnings("static-access") GuiEvent ev = new GuiEvent((Object)this,myAgent.NuevoAgente); //se crea un objeto de tipo Manejo de eventos de un Agente en el primer campo se deja como esta, el otro campo recibe un entero del Agente Creado myAgent.postGuiEvent(ev); //Este metodo invoca al metodo onGuiEvent() de la clase AgentVentana } } } private void formWindowClosed(java.awt.event.WindowEvent evt) { myAgent.doDelete(); } private void formWindowClosing(java.awt.event.WindowEvent evt) { myAgent.doDelete(); } public String getNm_Agente(){ return Nm_Agente.getText(); } public String getCs_Agente(){ return Cs_Agente.getText(); } }

10.

Comportamientos o Behaviour

Los comportamientos definen las tareas o servicios que realiza el agente para alcanzar sus objetivos, esta es una funcionalidad incorporada al agente. Cada comportamiento pude limitarse a realizar tareas simples como, por ejemplo, enviar un mensaje y responder el mensaje, tambin se pueden crear comportamientos compuestos. (Ver figura 2) Cada comportamiento o tarea ser una instancia de la clase Behaviour.
Class Micomportamiento extends Behaviour{ .. }

Dentro de cada comportamiento se encuentran los mtodos que se deben implementar para el desarrollo de una tarea.

Para su implementacin es necesario importar el paquete: import jade.core.behaviours.*; O simplemente. import jade.core.behaviours.Behaviour; Los agentes estn programados de acuerdo a sus comportamientos, la cual se basa en los siguientes pasos:

1. 2. 3.

Determinar que debe ser capaz de realizar el agente. Asociar cada funcionalidad con un comportamiento. Escoger el tipo de comportamientos. Dejar a JADE la tarea del scheduling (un solo comportamiento, se est ejecutando en cada instante).

Existen diferentes tipos de comportamientos que ayudan al agente a realizar sus tareas para lograr cumplir sus objetivos.

10.1.

Aadir y eliminar comportamientos

La clase Agent provee dos mtodos para aadir y eliminar comportamientos a un agente: addBehaviour(Behaviour) y removeBehaviour(Behaviour). Estos mtodos permiten administrar los objetos Behaviour en la cola del planificador de comportamientos. Este planificador ejecuta los comportamientos segn la poltica round-robin que se encuentran en una cola FIFO. Estos comportamientos son aadidos o eliminados en el mtodo setup() en cualquier momento de la vida del agente, incluso desde otros agentes o tambin de otros comportamientos. La creacion de comportamientos puede verse como crear una clase privada dentro de la clase del agente y asociarlo a este por medio del mtodo addBehaviour(Behaviour), se puede ver a los comportamientos como un nuevo thread del agente. Aadir un comportamiento desde el mtodo setup del agente.
import jade.core.Agent; import jade.core.behaviours.*; public class Agente_Ejemplo1 extends Agent{ protected void setup() { // Aadiendo el Comportamiento addBehaviour(new Micomportamiento()); } protected void takeDown(){ System.out.println(Adios mundo); } //Definiendo el comportamiento private class Micomportamiento extends Behaviour{

public void action(){ System.out.println(Soy el agente: + getName()); System.out.println(Y este es mi comportamiento); } public boolean done(){ return true; } }//fin de la clase del comportamiento }//fin de la clase del agente

El siguiente ejemplo nos muestra como aadir un comportamiento desde otro comportamiento. Para ello la clase Behaviour cuenta con la variable myAgent la cual hace referencia al agente que est ejecutando el comportamiento, es decir, al agente que pertenece el comportamiento.
import jade.core.Agent; import jade.core.behaviours.*; public class Agente_Ejemplo2 extends Agent{ protected void setup() { // Aadiendo el Comportamiento addBehaviour(new Micomportamiento()); } protected void takeDown(){ System.out.println(Adios mundo); } //Definiendo el comportamiento private class Micomportamiento extends Behaviour{ public void action(){ System.out.println(Soy el agente: + getName()); System.out.println(Y este es mi comportamiento); myAgent.addBehaviour(new Micomportamiento2());//aadiendo otro comportamiento } public boolean done(){ return true; } }//fin de la clase del comportamiento //Definiendo el segundo comportamiento private class Micomportamiento2 extends Behaviour{ public void action(){ System.out.println(Este es mi segundo comportamiento); } public boolean done(){ return true; } }//fin de la clase del segundo comportamiento

}//fin de la clase del agente

Tambin se puede eliminar o remover comportamientos a travs del mtodo removeBehaviour(Behaviour). Del ejemplo anterior si quisiramos eliminar el primer comportamiento desde el segundo comportamientos tendramos que definir una variable de tipo comportamiento la cual ser agregada como el primer comportamiento y en el segundo comportamiento bastara con llamar al mtodo removeBehaviour(Behaviour) desde su mtodo action().
import jade.core.Agent; import jade.core.behaviours.*; public class Agente_Ejemplo3 extends Agent{ protected void setup() { // Aadiendo el Comportamiento Micomportamiento comp1=new Micomportamiento(); addBehaviour(comp1); } protected void takeDown(){ System.out.println(Adios mundo); } //Definiendo el comportamiento private class Micomportamiento extends Behaviour{ public void action(){ System.out.println(Soy el agente: + getName()); System.out.println(Y este es mi comportamiento); myAgent.addBehaviour(new Micomportamiento2);//aadiendo otro comportamiento } public boolean done(){ return true; } }//fin de la clase del comportamiento //Definiendo el segundo comportamiento private class Micomportamiento2 extends Behaviour{ public void action(){ System.out.println(Este es mi segundo comportamiento); myAgent.removeBehaviour(comp1);//borramos el primer comportamiento } public boolean done(){ return true; } }//fin de la clase del segundo comportamiento }//fin de la clase del agente

10.2.

Mtodos de un comportamiento

Como se menciono toda clase que herede Behaviour posee los mtodos action y done los cuales debern ser implementados: 10.2.1. Mtodo action(): 1. Define la accin del comportamiento al momento de ejecutarse el comportamiento. 2. Es invocado cuando se produce el evento del comportamiento. 3. Cuando se ejecuta este mtodo los dems comportamientos no podrn ejecutarse, por ello es recomendable no darle un tiempo alto de ejecucin.

10.2.2. Mtodo done(): Es invocado cuando finaliza el mtodo action() Es mtodo determina si a terminado correctamente o no el comportamiento. Retorna un boolean, si termina bien true en caso contrario false. Si el comportamiento ha terminado, este se elimina de la cola de comportamientos. Se puede finalizar (no remover) el comportamiento en cualquier momento, haciendo una llamada al mtodo done() para que evalu el comportamiento.

Ejemplo del funcionamiento de los mtodos action() y done() de un comportamiento.


import jade.core.Agent; import jade.core.behaviours.*; public class Agente_Ejemplo4 extends Agent{ protected void setup() { // Aadiendo el Comportamiento addBehaviour(new Micomportamiento()); } protected void takeDown(){ System.out.println(Las opciones han terminado); } //Definiendo el comportamiento private class Micomportamiento extends Behaviour{ prvate int state=0; public void action(){ switch(state){ case 1:System.out.println(opcion 1); break; case 2: System.out.println(opcion 2); break; case 3:{ System.out.println(opcion 3); myAgent.doDelete(); break;} } state++; } public boolean done(){

return(state>7); } }//fin de la clase del comportamiento }//fin de la clase del agente

10.2.3. Mtodo block(): Los comportamientos tambin pueden ser bloqueados utilizando el mtodo block(). Este mtodo permite bloquear un comportamiento hasta que se realice una accin por lo general el envi o recepcin de un mensaje. Este mtodo no afecta a los otros comportamientos del agente. Cuando el mtodo action() finaliza el mtodo block() coloca el comportamiento en la cola de comportamientos. Un comportamiento puede ser bloqueado durante un tiempo determinado expresado en milisegundos, pasando el valor al mtodo block(). Este mtodo no puede verse como el mtodo sleep() de los Threads, ya que este no para la ejecucion sino que espera que el mtodo action() finalice. Una vez finalizado, si el comportamiento no termina, este pasa a la lista de comportamientos bloqueados durante el tiempo que se indique en este o hasta que reciba un evento o mensaje.
import jade.core.Agent; import jade.core.behaviours.*; public class Agente_Block extends Agent{ protected void setup() { // Aadiendo el Comportamiento addBehaviour(new Micomportamiento()); } protected void takeDown(){ System.out.println(Adios mundo); } //Definiendo el comportamiento private class Micomportamiento extends Behaviour{ int n=1; public void action(){ System.out.println(nmero de ejecuciones: +n); //bloqueamos durante un segundo block(1000); System.out.println(despus de 1000 milisegundos); n++; } public boolean done(){ if(n>7) myAgent.doDelete(); return(n>7); }

}//fin de la clase del comportamiento }//fin de la clase del agente

10.2.4. Mtodo blockReceive(): Este mtodo se comporta similar al mtodo block(), con la diferencia que este detiene todos los comportamientos del agente, adems devuelve el mensaje recibido que libero el bloqueo. Su uso seda al momento de la recepcin de mensajes en algn comportamiento.
ACLMessage mensaje = blockingReceive();

Un comportamiento puede ser desbloqueado cuando se da alguna de estas condiciones: Cuando el agente asociado al comportamiento recibe un mensaje ACL. Cuando sucede este caso el comportamiento se saca de la cola de comportamientos bloqueados y se coloca en la cola de comportamientos activos. Al llegar un mensaje, todos los comportamientos de la cola de bloqueados verifican si es para ellos o no; en caso de no pertenecer al comportamiento este debe volver a bloquearse. Cuando el tiempo de bloqueo expira, es colocado en la cola de activos. Cuando es llamado el mtodo restar() por el comportamiento, este lo desbloquea automticamente y lo coloca en la cola de activos.

10.2.5. Mtodos onStart() y onEnd(): La clase Behaviour brinda dos mtodos opcionales al action() y al done(), los cuales son onStart() y onEnd(). Estos mtodos pueden ser sobrescritos por los programadores para realizar operaciones anteriores o posteriores al mtodo action(). Adems estos mtodos se implementan solo una vez. Mtodo onStart() se ejecuta antes al mtodo action(). Mtodo onEnd() se ejecuta antes de finalizar el comportamiento (se ejecuta despus de que el mtodo done() devuelva true) adems devuelve un entero que determina la finalizacin del comportamiento. Este valor es determinado por el programador de acuerdo a las condiciones que se implementen. El mtodo onEnd() es ejecutado cuando el comportamiento ya ha sido eliminado de la cola de comportamientos es decir cuando ya el comportamiento se ha completado. Si el mtodo reset() es llamado dentro de este no podr reiniciarse este comportamiento y adems se debe volver aadir de nuevo el comportamiento al agente. Este ejemplo muestra como se debe realizar lo mencionado anteriormente.
import jade.core.Agent; import jade.core.behaviours.*;

public class Agente_Start_End extends Agent{ protected void setup() { // Aadiendo el Comportamiento addBehaviour(new Micomportamiento()); } protected void takeDown(){ System.out.println(Adios mundo); } //Definiendo el comportamiento private class Micomportamiento extends Behaviour{ public void onStart(){ System.out.println(la primera ejecucion justo antes del action()); } public void action(){ System.out.println(Ejecucion del mtodo action()); } public boolean done(){ return true; } //Hacemos que el comportamiento se reinicie al finalizar Public int onEnd(){ System.out.println(Ejecucion del mtodo onEnd() que se realiza al momento de completar el comportamiento); reset(); myAgent.addBehaviour(this); return 0; } }//fin de la clase del comportamiento }//fin de la clase del agente

10.3.

Ejecucin de los comportamientos

Cada agente posee un planificador o scheduler de comportamientos. Esta multitarea se realiza de forma preemptiva para todos los comportamientos que se encuentren en la cola de activos, lo que significa que ningn comportamiento puede ser interrumpido hasta que este finalice (se da cuando finaliza el mtodo action()). Los comportamientos son parecidos a los threads, sin embargo no son ejecutados en forma concurrente, la forma de su ejecucion lo define el programador a diferencia de los threads de JAVA que la decisin de ser ejecutados es tomada por la maquina virtual. En un agente pueden estar activos varios comportamientos a la vez pero se ejecuta un nico thread, con el fin de ahorrar ciclos de CPU y la memoria que esto implica. El funcionamiento de los comportamientos esta implementado a 2 niveles.

Una cola circular de activos. Una cola de bloqueados.

Figura 9. Funcionamiento de un comportamiento.

11.

Java Server Faces (JSF)

El objetivo de la tecnologa JavaServer Faces es desarrollar aplicaciones web de forma parecida a como se construyen aplicaciones locales con Java Swing, AWT (Abstract Window Toolkit), SWT (Standard Widget Toolkit) o cualquier otra API similar. Tradicionalmente, las aplicaciones web se han codificado mediante pginas JSP (Java Server Pages) que reciban peticiones a travs de formularios y construan como respuesta pginas HTML (Hiper Text Markup Language) mediante ejecucin directa o indirecta -a travs de bibliotecas de etiquetas- de cdigo Java, lo que permita, por ejemplo, acceder a bases de datos para obtener los resultados a mostrar amn de realizar operaciones marginales como insertar o modificar registros en tablas relacionales, actualizar un carrito de la compra, etc. JavaServer Faces pretende facilitar la construccin de estas aplicaciones proporcionando un entorno de trabajo (framework) va web que gestiona las acciones producidas por el usuario en su

pgina HTML y las traduce a eventos que son enviados al servidor con el objetivo de regenerar la pgina original y reflejar los cambios pertinentes provocados por dichas acciones. En definitivas cuentas, se trata de hacer aplicaciones Java en las que el cliente no es una ventana de la clase JFrame o similar, sino una pgina HTML. Como el lector puede imaginar, cualquier evento realizado sobre una pgina JSF incurre en una carga sobre la red, ya que el evento debe enviarse a travs de sta al servidor, y la respuesta de ste debe devolverse al cliente; por ello, el diseo de aplicaciones JavaServer Faces debe hacerse con cuidado cuando se pretenda poner las aplicaciones a disposicin del mundo entero a travs de internet. Aquellas aplicaciones que vayan a ser utilizadas en una intranet podrn aprovecharse de un mayor ancho de banda y producirn una respuesta mucho ms rpida. Caractersticas principales

La tecnologa JavaServer Faces constituye un marco de trabajo (framework) de interfaces de usuario del lado de servidor para aplicaciones web basadas en tecnologa Java y en el patrn MVC (Modelo Vista Controlador). Los principales componentes de la tecnologa JavaServer Faces son: Una API y una implementacin de referencia para: Representar componentes de interfaz de usuario (UI-User Interface) y manejar su estado Manejar eventos, validar en el lado del servidor y convertir datos Definir la navegacin entre pginas Soportar internacionalizacin y accesibilidad, y Proporcionar extensibilidad para todas estas caractersticas. Una librera de etiquetas JavaServer Pages (JSP) personalizadas para dibujar componentes UI dentro de una pgina JSP.

Este modelo de programacin bien definido y la librera de etiquetas para componentes UI facilita de forma significativa la tarea de la construccin y mantenimiento de aplicaciones web con UIs en el lado servidor. Con un mnimo esfuerzo, es posible: Conectar eventos generados en el cliente a cdigo de la aplicacin en el lado servidor. Mapear componentes UI a una pgina de datos en el lado servidor. Construir una interfaz de usuario con componentes reutilizables y extensibles.

Como se puede apreciar en la Figura 16, la interfaz de usuario que se crea con la tecnologa JavaServer Faces (representada por miUI en el grfico) se ejecuta en el servidor y se renderiza en el cliente.

Figura 16 Diagrama de una aplicacin JSF

En la figura no queda qu es fsicamente miUI. La pgina JSP, miform.jsp, especifica los componentes de la interfaz de usuario mediante etiquetas personalizadas definidas por la tecnologa JavaServer Faces. LA UI de la aplicacin web (representada por miUI en la figura) maneja los objetos referenciados por la JSP, que pueden ser de los siguientes tipos: Objetos componentes que mapean las etiquetas sobre la pgina JSP. Oyentes de eventos, validadores y conversores registrados y asociados a los componentes. Objetos del modelo que encapsulan los datos y las funcionalidades de los componentes especficos de la aplicacin (lgica de negocio).

11.1. Ejemplos de paginas JSF


A. La siguiente pagina muestra una entrada de texto a la cual se le ingresa cualquier texto y lo pinta en la parte inferior luego de dar enter en el cuadro de texto.

Figura 17

<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>Facelet Title</title> </h:head> <h:body> <h:form id="formulario1"> <h:inputText id="nom" value="#{controlEjem.model1.nm}" label="Firstname"/> </h:form> <h:form id="formulario2"> <h:outputText id="valornom" value="#{controlEjem.model1.nm}"/> </h:form> </h:body> </html>

B. En esta pgina se agrega un botn el cual te dirige a otra pgina que solo muestra el contenido que se escribi en el cuadro de texto. Pagina ejemplo1.xhtml

Figura 18
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>Facelet Title</title> </h:head> <h:body> <h:form id="formulario1"> <h:inputText id="nom" value="#{controlEjem.model1.nm}" label="Firstname"/> <h:commandButton value="pagina siguiente" action="ejemplo2"/> </h:form> </h:body> </html>

Pagina ejemplo2.xhtml Muestra el contenido de lo que se escriba en la pgina anterior


<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>Facelet Title</title> </h:head> <h:body> <h:form id="formulario2"> <h:outputText id="valornom" value="#{controlEjem.model1.nm}"/> </h:form> </h:body> </html>

11.2. Estructura de una aplicacin JSF


Las aplicaciones JSF siguen un estndar de creacin en la estructura de sus directorios, los cuales se comprimen en un archivo war para su portabilidad. Esta estructura de directorio estndar es: Aplicacin/ Ficheros XHTML WEB-INF/ Archivos de configuracin Clases/ Archivos .class Lib/ Libreras La estructura del archivo WAR queda as: ejemploBasico.war index.xhtml ejemplo1.xhtml ejemplo2.xhtml META-INF/ MANIFEST.MF WEB-INF web.xml classes/ modelo/ Model1.class controlador/ ControlEjem.class lib/ jsf-api.jar jsf-impl.jar

11.3. Patrn MVC


Como se explico antes JSF te obliga de cierta manera a programar bajo el patrn MVC (modelo, vista, controlador). Donde el modelo es la representacin de los datos que manipulara el aplicativo. La vista contiene las pantallas (xhtml) a mostrar a los usuarios. El controlador maneja los eventos de pantalla, entre otras cosas.

Las paginas anteriores existe un conjunto de caracteres #{} sirven de nexo con los archivos java que pertenecen a la capa controlador. Antiguamente exista un archivo faces-config.xml pero actualmente se usa solo las anotaciones que est precedida del carcter arroba @. La capa controlador interacta con la del modelo para crear los objetos los cuales son rellenados desde la pgina. A continuacin se muestra las clases de las capas controlador y modelo para el ejemplo anterior. Capa Controlador: ControlEjm.java
package controlador; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import modelo.Model1; /** * @author UMSM */ @ManagedBean @RequestScoped public class ControlEjem { private Model1 model1 ; /** * Creates a new instance of ControlEjem */ public ControlEjem () { model1 = new Model1(); } public Model1 getModel1() { return model1; } public void setModel1(Model1 model1) { this.model1 = model1; } }

Capa Modelo: Model1.java


package modelo; // Generated 22/11/2012 07:02:08 AM by Hibernate Tools 3.2.1.GA public class Model1 implements java.io.Serializable { private String nm; public Model1 () { } public Model1 (String nm) { this.nm = nm; } public String getNm() { return this.nm; } public void setNm(String nm) { this.nm = nm; } }

12.

Hibernate

Hibernate es un marco de trabajo para persistencia de datos (en java). En la mayora de las aplicaciones empresariales, si no es que en todas, una parte muy importante es el almacenamiento de datos de forma que estos datos puedan sobrevivir ms all del tiempo que nuestra aplicacin est encendida (ya sea en una aplicacin standalone o en una aplicacin web). El almacn de datos ms comn son las bases de datos relacionales. La naturaleza de estas bases hace que no sea tan fcil usarlas en el almacenamiento de datos en aplicaciones orientadas a objetos (por las diferencias entre el modelo de datos de objetos y el modelo de datos relacionales), ya que para guardar un objeto debemos extraer cada una de sus propiedades que queremos persistir y armar con ellos una sentencia INSERT de SQL. De la misma forma, cuando queremos recuperar los datos de un objeto, debemos usar una sentencia SELECT de SQL y despus extraer el valor de cada una de las columnas recuperadas y llenar as nuestro objeto. Esto puede no parecer un problema en aplicaciones pequeas, pero cuando comenzamos a tener muchos objetos que debemos guardar se vuelve algo muy pesado y engorroso, adems de que consume mucho de nuestro tiempo que podramos dedicar a mejorar la lgica de la aplicacin, o a realizar pruebas de la misma. Esto se hizo de esta manera durante muchos aos, hasta que comenzaron a surgir las soluciones de Mapeo Objeto/Relacional (ORM por sus siglas en ingls). El mapeo objeto/relacional se refiere

a una tcnica de mapear representaciones de datos de un modelo de objetos a un modelo de datos relacionales con un esquema basado en SQL. Hibernate, como la definen sus autores, es una herramienta de mapeo objeto/relacional para ambientes Java. Adems no solo se encarga del mapeo de clases Java a tablas de la base de datos (y de regreso), sino que tambin maneja los queries y recuperacin de datos, lo que puede reducir de forma significativa el tiempo de desarrollo que de otra forma gastaramos manejando los datos de forma manual con SQL y JDBC, encargndose de esta forma de alrededor del 95% de las tareas comunes relacionadas con la persistencia de datos, manejando todos los problemas relativos con la base de datos particular con la que estemos trabajando, de forma transparente para nosotros como desarrolladores. Entonces, si cambiamos el manejador de base de datos no ser necesario que modifiquemos todo el SQL que ya tenamos para adaptarse al SQL que maneja la nueva base de datos. Solo ser necesario modificar una lnea en un archivo de configuracin de Hibernate, y este se encargar del resto. Existen dos formas de hacer los mapeos en Hibernate, la primera es a travs de archivos de mapeo en XML, que es la forma que veremos en este primer tutorial. La otra forma es usando anotaciones. Usaremos MySQL 5.1 como base de datos. Tambin deben bajar el conector para Java versin 5.1.7. Creamos una base de datos llamada "pruebahibernate". No se preocupen por crear alguna tabla, ya que haremos que sea el propio Hibernate el que las genere. Ahora comencemos con nuestra aplicacin. Lo primero que haremos es crear una biblioteca de NetBeans con los jars bsicos de Hibernate, de esta forma cada vez que queramos usar Hibernate en un proyecto solo tendremos que agregar esta biblioteca. En realidad no crearemos esta biblioteca desde cero, ya que NetBeans ya tiene una biblioteca de Hibernate 3.2.5, solo actualizaremos la biblioteca con la ltima versin de Hibernate, la 3.3.1 GA. As que descargamos la ltima versin del core de Hibernate desde la pgina de descarga de Hibernate. Una vez que descarguemos y descomprimamos el archivo correspondiente veremos que en la raz hay dos jars de Hibernate: "hibernate3.jar" y "hibernate-testing.jar". "hibernate3.jar" contiene las clases principales para el uso de Hibernate. Existen varias clases de soporte que son usadas por Hibernate para su funcionamiento UNMSMl. Algunas son opcionales y otras son requeridas. Afortunadamente estas se encuentran separadas en el mismo archivo que hemos descargado. Las clases obligatorias, que son las que nos interesan en este caso, se encuentran en el directorio "lib\required". Bien, entonces para actualizar la biblioteca abrimos el NetBeans y nos dirigimos al men "Tools -> Libraries":

En la ventana que se abre buscamos la biblioteca "Hibernate" y la seleccionamos. Con esto se mostrarn los archivos que la conforman. Seleccionamos todos los archivos y presionamos el botn "Remove" para eliminarlos de la biblioteca.

Una vez eliminados los archivos presionamos el botn "Add JAR/Folder..." para agregar los nuevos archivos:

Agregamos a la biblioteca los siguientes archivos:

hibernate3.jar

y del directorio de jars requeridos:


antlr-2.7.6.jar commons-collections-3.1.jar dom4j-1.6.1.jar javassist-3.4.GA.jar jta-1.1.jar

O sea, casi todos los archivos requeridos. Estamos excluyendo el archivo "slf4j-api-1.5.2.jar" porque si lo incluimos solo, se lanza una excepcin. Lo que ocurre es que slf4j es una fachada para el logging, o bitcora de la aplicacin. Esto significa que podemos usar el framework de logging que queramos (en teora). Sin embargo en la distribucin de Hibernate no se incluye ningn jar con una clase que implemente dicha fachada, por lo que debemos bajar uno nosotros mismos. Podemos hacer dos cosas, la primer es agregar el archivo "slf4j-api-1.5.2.jar" que viene con Hibernate a nuestra biblioteca y el zip con la versin correspontiente de slf4j. De l extraemos "slf4j-simple-1.5.2.jar" (o el archivo que se ajuste al framework de logging que estemos usando) y lo incluimos en la biblioteca. Lo otro que podemos hacer es, aprovechando que ya estamos bajando jars, descargar la ltima versin de slf4j de aqu (actualmente es la 1.5.6) y aprovechar para agregar los archivos "slf4j-api1.5.6.jar" y "slf4j-simple-1.5.6.jar" a nuestra biblioteca. Yo har esto ltimo. Una vez seleccionados estos archivos la biblioteca de Hibernate debe verse as:

Presionamos el botn "OK" y nuestra biblioteca ya estar actualizada. Ahora creamos un nuevo proyecto de NetBeans (men "File -> New Project... -> Java -> Java Application"). Le damos un nombre y una ubicacin al proyecto y nos aseguramos de que las opciones "Create Main Class" y "Set as Main Project" estn habilitadas. Presionamos el botn "Finish" y veremos aparecer en el editor nuestra clase "Main".

Agregamos la biblioteca de "Hibernate", que creamos hace unos momentos, a nuestro proyecto. Hacemos clic derecho en el nodo "Libraries" del proyecto. En el men contextual que se abre seleccionamos la opcin "Add Library...":

En la ventana que se abre seleccionamos la biblioteca "Hibernate":

Presionamos el botn "Add Library" para que la biblioteca se agregue a nuestro proyecto. Aprovechamos tambin para agregar el conector de MySQL. Debemos tener los siguientes archivos en nuestro proyecto:

El siguiente paso es crear una clase cuyas instancias sern almacenadas como fila de una tabla en base de datos. Este tipo de objetos son llamados "Entidades". Para este ejemplo crearemos una pequea y bsica agenda, as que las entidades sern objetos de la clase "Contacto". Los atributos que tendr esta sern un nombre, un correo, y un nmero telefnico. Adems, por regla, necesitamos un atributo que funcione como identificador para cada una de las entidades. En este caso he hecho que la clase implementa la interface "java.io.Serializable", esto no es obligatorio pero es una buena prctica. La clase "Contacto" queda de la siguiente forma:
public class Contacto implements Serializable { private long id; private String nombre; private String email; private String telefono; public Contacto() { } public Contacto(String nombre, String email, String telefono) { this.nombre = nombre; this.email = email; this.telefono = telefono; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public long getId() { return id; } private void setId(long id) { this.id = id; } public String getNombre() { return nombre; } public void setNombre(String nombre) {

this.nombre = nombre; } public String getTelefono() { return telefono; } public void setTelefono(String telefono) { this.telefono = telefono; } }

La clase "Contacto" usa la convencin de nombres JavaBeans para los getters y setters y visibilidad privada para los atributos. Este tambin es un diseo recomendado pero no obligatorio. Hibernate puede acceder a los campos o atributos de las entidades directamente. El constructor sin argumentos si es obligatorio ya que Hibernate crear instancias de esta clase usando reflexin cuando recupere las entidades de la base de datos. Este constructor puede ser privado (si es que no quieren permitir que alguien ms lo utilice), pero usualmente el nivel de acceso ms restrictivo que usaremos es el de paquete (el default), ya que esto hace ms eficiente la creacin de los objetos. La propiedad "id" mantendr, como dije antes, un valor nico que identificar a cada una de las instancias de "Contacto". Todas las clases de entidades persistentes deben tener una propiedad que sirva como identificador si queremos usar el conjunto completo de funcionalidades que nos ofrece Hibernate (y que veremos a lo largo de esta serie de tutoriales). De todas formas, la mayora de las aplicaciones necesitan poder distinguir objetos de la misma clase mediante algn tipo de identificador. Usualmente no manipulamos directamente este identificador (dejamos que sea la base de datos quien lo genere, cuando la entidad sea guardada, y Hibernate quien lo asigne al objeto), por lo tanto el setter del "id" es privado (fjense cmo lo he puesto en la clase "Contacto"). Hibernate puede acceder a los campos private directamente, as que no debemos preocuparnos por el hecho de que el identificador no pudiera ser establecido. El siguiente paso es crear el archivo de mapeo. Si recuerdan, anteriormente dije que Hibernate es una herramienta de mapeos Objeto/Relacional, o sea que mapea los atributos de los objetos con las columnas de una tabla de una base de datos relacional. Tambin dije que hay dos formas de hacerlo: mediante un archivo de mapeo en XML y mediante anotaciones y que en esta ocasin veramos solo como usar los archivos de mapeo. Crearemos un nuevo paquete que contendr los archivos de mapeo, no es obligatorio tener los archivos de mapeo en un paquete separado ya que ms adelante indicaremos donde se encuentra cada uno de los archivos, pero nos ayudar a mantener un poco de orden en nuestro proyecto. Hacemos clic derecho sobre el nodo "Source Packages" del proyecto para mostrar un men contextual. De ese men seleccionamos la opcin "New -> Java Package..":

Nombramos a este paquete como "mapeos" y presionamos el botn "Finish" para agregar el nuevo paquete. Ahora creamos un nuevo archivo XML que contendr el mapeo de la clase "Contacto" con la tabla "CONTACTOS" de la base de datos. Por convencin la extensin de estos archivos es ".hbm.xml" y tiene el mismo nombre de la entidad que est mapeando (aunque eso tampoco es necesario ya que podemos mapear ms de una clase o entidad dentro del mismo archivo). Hacemos clic derecho sobre el paquete que acabamos de crear. En el men contextual que se abre seleccionamos la opcin "New -> XML Document". Si no se muestra est opcin seleccionamos "Other..." y en la ventana que se abre seleccionamos "XML -> XML Document":

Le damos al archivo el nombre "Contacto.hbm" (el asistente se encargar de agregar de forma automtica el ".xml" al final):

Presionamos el botn "Next >" y se nos preguntar qu tipo de documento queremos crear: solo un documento XML bien formado, un documento regido por un DTD, o un documento regido por un Schema XML. Aunque el documento de mapeo est regido por un DTD nosotros elegiremos crear un documento XML bien formado ("Well-formed Document") ya que es ms fcil

simplemente pegarlo en el archivo que se crear que indicar mediante el asistente dnde se encuentra este archivo. Presionamos el botn "Finish" para que se nos muestre en el editor el nuevo archivo XML, el cual debe verse ms o menos as:

Modificaremos este archivo. Eliminamos todo el contenido del archivo y lo reemplazamos por este:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> </hibernate-mapping>

Teniendo esta declaracin, la cual indica el DTD que se usa para validar el archivo, el IDE nos ayudar a autocompletar las etiquetas y a asegurarnos que el archivo sea vlido. El elemento "<hibernate-mapping>" es el nodo raz del documento y, por lo tanto, el resto de los elementos irn entre estas dos etiquetas. El elemento con el que indicamos qu clase es la que estamos mapeando es el elemento "<class>" este elemento tiene los atributos "name" y "table" que nos permiten indicar el nombre completo de la clase y la tabla con la que ser mapeada, respectivamente:
<hibernate-mapping> <class name="hibernateUNMSMl.Contacto" table="CONTACTOS"> </class> </hibernate-mapping>

Con esto indicamos que las entidades de la clase "Contacto" sern almacenadas en la tabla "CONTACTOS". Ahora debemos indicar cul de los elementos de la clase entidad es el identificador. Este identificador ser mapeado con la llave primaria de la tabla, adems como nosotros no manejaremos el valor del identificador, le indicamos a Hibernate cmo queremos que este valor sea generado (la estrategia de generacin). Para esto usamos el elemento "<id>", indicando el nombre del atributo de la clase entidad que representa el identificador (que en este caso tambin se llama "id" ^-^). Opcionalmente en este elemento (como en el resto de los

elementos de mapeo de propiedades) podemos indicar con qu columna queremos que se mapee usando el atributo "column":
<hibernate-mapping> <class name="hibernateUNMSMl.Contacto" table="CONTACTOS"> <id name="id" column="ID"> <generator class="identity" /> </id> </class> </hibernate-mapping>

El elemento "<generator>" es el que nos permite indicar la estrategia de generacin del identificador usando su atributo "class". Existen varias estrategias que estn explicadas en esta pgina, pero las que usaremos ms frecuentemente son "identity" (con la que Hibernate se encarga de generar el query necesario para que el nuevo identificador sea igual a el ltimo identificador + 1) y "native" (con el que se usa la estrategia por default del manejador que estemos utilizando (dialecto)). Para terminar con el mapeo incluimos las declaraciones para el resto de las propiedades persistentes (las que queremos que sean almacenadas) de la clase entidad ("nombre", "email", y "telefono") usando el elemento "<property>" en el cual indicamos el nombre de la propiedad como aparece en la clase entidad y, opcionalmente, el tipo de la propiedad y la columna con la que ser mapeada usando los atributos "type" y "column" respectivamente:
<hibernate-mapping> <class name="hibernateUNMSMl.Contacto" table="CONTACTOS"> <id name="id" column="ID"> <generator class="identity" /> </id> <property name="nombre" type="string" column="NOMBRE" /> <property name="email" /> <property name="telefono" /> </class> </hibernate-mapping>

El archivo "Contacto.hbm.xml" final debe verse as:

Qu ocurre si no indicamos el tipo de la propiedad? En ese caso Hibernate utiliza nuevamente reflexin en nuestra clase para determinar el tipo del atributo y as elegir el tipo ms adecuado para la columna de la tabla (en caso de que dejemos que Hibernate genere las tablas).

Qu ocurre si no indicamos el nombre de la columna con la que mapea una propiedad? Esto depende de si Hibernate est generando las tablas de la base de datos o las hemos generado nosotros mismos. Si es Hibernate quien est generando las tablas no hay problema, simplemente dar a la columna correspondiente el mismos nombre de la propiedad. Por ejemplo, para la propiedad "email" crear una columna "email". Sin embargo, si nosotros hemos creado las tablas hay un riesgo potencial de un error. Hibernate buscar en las consultas una columna con el mismo nombre de la propiedad, pero si hemos usado un nombre distinto, por ejemplo en vez de "email" hemos llamado a la columna "E_MAIL" ocurrir una excepcin indicando que no se ha encontrado la columna "email", as que en ese caso debemos tener cuidado de indicar el nombre de las columnas como estn en la base de datos. Bien, despus de esta breve explicacin podemos proseguir. Ya que hemos configurado el mapeo de nuestra clase entidad debemos configurar Hibernate. Hibernate est en la capa de nuestra aplicacin que se conecta a la base de datos (la capa de persistencia), as que necesita informacin de la conexin. La conexin se hace a travs de un pool de conexiones JDBC que tambin debemos configurar. La distribucin de Hibernate contiene muchos pools de conexiones JDBC Open Source, como por ejemplo C3P0, pero en esta ocasin usaremos el pool de conexiones que Hibernate trae integrado. La configuracin de Hibernate puede hacerse en tres lugares:

Un archivo de propiedades llamado "hibernate.properties". Un archivo XML llamado "hibernate.cfg.xml". En cdigo dentro de la misma aplicacin.

En realidad los archivos pueden tener cualquier nombre, pero Hibernate buscar por default los archivos con los nombres que he mencionado, en una ubicacin predeterminada (la raz del classpath de la aplicacin). Si queremos usar archivos con otros nombres deberemos especificarlo en el cdigo. La mayora, por lo que he podido ver en Internet, preferimos usar el archivo XML ya que, entre otras cosas, los IDEs nos ayudan a su creacin y configuracin gracias a que est regido por un DTD. As que crearemos este archivo en nuestro proyecto. Hacemos clic derecho en el nodo "Source Packages" del proyecto. En el men contextual que se abre seleccionamos "New -> XML Document...":

Nombramos al archivo "hibernate.cfg", el IDE se encargar de colocarle la extensin ".xml". Ubicamos el archivo en el directorio "src":

Con esto lograremos que el archivo quede en la raz del classpath de la aplicacin, tambin conocido como el paquete default. Presionamos el botn "Next >" y en la pantalla siguiente indicamos que queremos crear un documento XML bien formado (como en el caso anterior). Presionamos el botn "Finish " para generar el archivo. Si nos fijamos en el archivo generado, este debe encontrarse en un paquete llamado "<default package>":

Borramos todo el contenido del archivo generado y colocamos las siguientes lneas:
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> </hibernate-configuration>

El DTD nos ayudar para que el IDE autocomplete las etiquetas. Como podemos ver, el elemento raz del archivo de configuracin es "<hibernate-configuration>" y, por lo tanto, todos los elementos los colocaremos entre estas dos etiquetas. Lo primero que debemos hacer es configurar un "session-factory", que bsicamente es lo que le dice a Hibernate cmo conectarse y manejar la conexin a la base de datos. Podemos tener ms de un "session-factory" en el archivo de configuracin (por si quisiramos conectarnos a ms de una base de datos), pero por lo regular solo ponemos uno:

<hibernate-configuration> <session-factory> </session-factory> </hibernate-configuration>

Lo siguiente es configurar la conexin a nuestra base de datos. En este archivo se configuran los parmetros bsicos y tpicos para una conexin (la URL, nombre de usuario, contrasea, driver, etc.). Cada uno de estos parmetros se configura dentro de una etiqueta "<property>" (al igual que casi todos los elementos del archivo de configuracin). Como dije antes, usar una base de datos MySQL para este ejemplo, as que mi configuracin queda de la siguiente forma:
<property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/pruebahibernate</property> <property name="connection.username">usuario</property> <property name="connection.password">password</property>

Despus, configuramos el pool de conexiones de Hibernate. En este caso como es un ejemplo muy simple, solo nos interesa tener una conexin en el pool, por lo que colocamos la propiedad "connection.pool_size" con un valor de "1": <property name="connection.pool_size">1</property> El siguiente paso es muy importante. Debemos indicar el "dialecto" que usar Hibernate para comunicarse con la base de datos. Este dialecto es la variante de SQL que usa la base de datos para ejecutar queries. Indicamos el dialecto con el fully qualified class name, o el nombre completo de la clase incluyendo el paquete. En el caso de MySQL 5 usamos "org.hibernate.dialect.MySQL5Dialect". En esta pgina pueden encontrar una lista ms o menos completa de los dialectos soportados por Hibernate, pero siempre es mejor revisar la documentacin de la versin que estn usando para estar seguros: <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> Otras dos propiedades importantes que podemos configurar son: "show_sql" que indica si queremos que las consultas SQL generadas sean mostradas en el stdout (UNMSMlmente la consola), y "hbm2ddl.auto", que indica si queremos que se genere automticamente el esquema de la base de datos (las tablas). "show_sql" puede tomar valores de "true" o "false", yo lo colocar en "true" (lo que puede ser bueno mientras estamos en etapas de desarrollo o pruebas, pero querrn cambiar su valor cuando su aplicacin pase a produccin). Por otro lado "hbm2ddl.auto" puede tomar los valores, segun la documentacin oficial(falta "none"), de "validate", "update", "create", y "create-drop" (aunque no todos los valores funcionan para todas las bases de datos). Yo los colocar de la siguiente forma: <property name="show_sql">true</property> <property name="hbm2ddl.auto">create-drop</property>

Con el valor "create-drop" hacemos que cada vez que se ejecute la aplicacin Hibernate elimine las tablas de la base de datos y las vuelva a crear. Para terminar con este archivo de configuracin, debemos indicar dnde se encuentra cada uno de los archivos de mapeo que hemos creado, usando el elemento "<mapping>". En nuestro caso solo hemos creado un archivo de mapeo, pero debemos colocar un elemento "<mapping>" por cada uno de los archivos que hayamos creado: <mapping resource="mapeos/Contacto.hbm.xml"/> En el elemento "resource" debemos colocar la ubicacin de los archivos de mapeo dentro de la estructura de paquetes de la aplicacin. El archivo de configuracin "hibernate.cfg.xml" final debe verse as:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- parametros para la conexion a la base de datos --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/pruebahibernate</property> <property name="connection.username">usuario</property> <property name="connection.password">password</property> <!-- Configuracion del pool interno --> <property name="connection.pool_size">1</property> <!-- Dialecto de la base de datos --> <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- Otras propiedades importantes --> <property name="show_sql">true</property> <property name="hbm2ddl.auto">create-drop</property> <!-- Archivos de mapeo --> <mapping resource="mapeos/Contacto.hbm.xml"/> </session-factory> </hibernate-configuration>

Esta es toda la configuracin que debemos hacer. Ahora veremos el cdigo necesario para guardar y recuperar objetos "Contacto" de la base de datos.

Lo primero que haremos es crear una clase ayudante o de utilidad llamada "HibernateUtil", que se har cargo de inicializar y hacer el acceso al "org.hibernate.SessionFactory" (el objeto encargado de gestionar las sesiones de conexin a la base de datos que configuramos en el archivo "hibernate.cfg.xml") ms conveniente. Dentro de esta clase declaramos un atributo static de tipo "SessionFactory", as nos aseguraremos de que solo existe una instancia en la aplicacin. Adems lo declararemos como final para que la referencia no pueda ser cambiada despus de que la hayamos asignado. private static final SessionFactory sessionFactory; Despus usamos un bloque de inicializacin esttico para inicializar esta variable en el momento en el que la clase sea cargada en la JVM. Para realizar esta inicializacin lo primero que se necesita es una instancia de la clase "org.hibernate.cfg.Configuration" que permite a la aplicacin especificar las propiedades y documentos de mapeo que se usarn (es aqu donde indicamos todo si no queremos usar un archivo XML o de propiedades). Si usamos el mtodo "configure()" que no recibe parmetros entonces Hibernate busca el archivo "hibernate.cfg.xml" que creamos anteriormente. Una vez que tenemos este objeto, entonces podemos inicializar la instancia de "SessionFactory" con su mtodo "buildSessionFactory()". Adems como este proceso puede lanzar "org.hibernate.HibernateException" (que extiende de "RuntimeException") la cachamos y lanzamos como un "ExceptionInInitializarError" (que es lo nico que puede lanzarse desde un bloque de inicializacin). El bloque de inicializacin queda de la siguiente forma:
static { try { sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (HibernateException he) { System.err.println("Ocurri un error en la inicializacin de la SessionFactory: " + he); throw new ExceptionInInitializerError(he); } }

Finalmente creamos un mtodo static llamado "getSessionFactory()" para recuperar la instancia de la "SessionFactory":
public static SessionFactory getSessionFactory() { return sessionFactory; } La clase "HibernateUtil" queda de la siguiente forma: import org.hibernate.HibernateException; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil {

private static final SessionFactory sessionFactory; static { try { sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (HibernateException he) { System.err.println("Ocurri un error en la inicializacin de la SessionFactory: " + he); throw new ExceptionInInitializerError(he); } } public static SessionFactory getSessionFactory() { return sessionFactory; } }

Bien ha llegado el momento, ahora escribiremos una clase DAO (no seguiremos el patrn al pie de la letra, es solo para mostrar cmo trabajar con Hibernate) que nos permitir realizar operaciones de base de datos. Creamos una clase llamada "ContactosDAO" y agregamos dos atributos, uno llamado "sesion" de tipo "org.hibernate.Session", y otro llamado "tx" de tipo "org.hibernate.Transaction". private Session sesion; private Transaction tx; Estos atributos nos servirn para mantener la referencia a la sesin a base de datos, y a la transaccin actual, respectivamente. Ahora agregaremos dos mtodos de utilidad. El primero nos ayudar a iniciar una sesin y una transaccin en la base de datos. Llamaremos a este mtodo "iniciaOperacion", y la implementacin es la siguiente:
private void iniciaOperacion() throws HibernateException { sesion = HibernateUtil.getSessionFactory().openSession(); tx = sesion.beginTransaction(); }

En el mtodo anterior obtenemos una referencia a "SessionFactory" usando nuestra clase de utilidad "HibernateUtil". Una vez que tenemos la "SessionFactory" creamos una conexin a la base

de datos e iniciamos una nueva sesin con el mtodo "openSession()". Una vez teniendo la sesin iniciamos una nueva transaccin y obtenemos una referencia a ella con "beginTransaction()". Ahora el segundo mtodo de utilidad (llamado "manejaExcepcion") nos ayudar a manejar las cosas en caso de que ocurra una excepcin. Si esto pasa queremos que la transaccin que estamos ejecutando se deshaga y se relance la excepcin (o podramos lanzar una propia). Por lo que el mtodo queda as:
private void manejaExcepcion(HibernateException he) throws HibernateException { tx.rollback(); throw new HibernateException("Ocurri un error en la capa de acceso a datos", he); }

Ahora crearemos los mtodos que nos permitirn realizar las tareas de persistencia de una entidad "Contacto", conocidas en lenguaje de base de datos como CRUD: guardarla, actualizarla, eliminarla, buscar un entidad "Contacto" y obtener todas los contactos que existen en la base de datos, as que comencemos. Afortunadamente Hibernate hace que esto sea fcil ya que proporciona mtodos para cada una de estas tareas. Primero veamos como guardar un objeto "Contacto". Para esto Hibernate proporciona el mtodo "save" en el objeto de tipo "org.hibernate.Session", que se encarga de generar el "INSERT" apropiado para la entidad que estamos tratando de guardar. El mtodo "guardaContacto" queda de la siguiente forma:
public long guardaContacto(Contacto contacto) { long id = 0; try { iniciaOperacion(); id = (Long)sesion.save(contacto); tx.commit(); }catch(HibernateException he) { manejaExcepcion(he); throw he; }finally { sesion.close(); } return id; }

Regresamos el "id" generado al guardar el "Contacto" solo por si queremos usarlo ms adelante en el proceso (como lo haremos nosotros), o si queremos mostrarle al usuario, por alguna razn, el identificador del "Contacto". Ahora veremos cmo actualizar un "Contacto". Para eso usamos el mtodo "update" del objeto "sesion" en nuestro mtodo "actualizaContacto":

public void actualizaContacto(Contacto contacto) throws HibernateException { try { iniciaOperacion(); sesion.update(contacto); tx.commit(); }catch (HibernateException he) { manejaExcepcion(he); throw he; }finally { sesion.close(); } }

Como podemos ver, el mtodo para actualizar es muy similar al mtodo para guardar la entidad. Lo mismo ocurre con el mtodo para eliminarla, "eliminaContacto":
public void eliminaContacto(Contacto contacto) throws HibernateException { try { iniciaOperacion(); sesion.delete(contacto); tx.commit(); } catch (HibernateException he) { manejaExcepcion(he); throw he; }finally { sesion.close(); } }

Ahora veremos unos mtodos un poco ms interesantes. Cuando queremos buscar una entidad podemos usar varios criterios. La forma ms fcil es buscar una entidad particular usando su "id". La clase "org.hibernate.Session" proporciona dos mtodos para esto: "load" y "get". Los dos hacen prcticamente lo mismo: en base al identificador y tipo de la entidad recuperan la entidad indicada, con la diferencia de que "load" lanza una excepcin en caso de que la entidad indicada no sea encontrada en la base de datos, mientras que "get" simplemente regresa "null". Pueden usar el que prefieran, en lo personal me gusta ms "get", as que lo usar para el mtodo "obtenContacto":
public Contacto obtenContacto(long idContacto) throws HibernateException { Contacto contacto = null; try { iniciaOperacion(); contacto = (Contacto) sesion.get(Contacto.class, idContacto);

} finally { sesion.close(); } return contacto; }

Finalmente veremos el mtodo "obtenListaContactos" que recupera todos los Contactos que estn guardados en la base de datos. Como en este caso regresaremos una lista de elementos deberemos crear una consulta. Cuando tenemos que crear una consulta con JDBC lo hacemos en SQL, sin embargo con Hibernate tenemos varias opciones:

Usar una query en SQL nativo. Crear una query en HQL (Hibernate Query Language). Crear una query usando Criteria que es un API para crear queries de una forma ms "orientada a objetos".

Critera es, a mi parecer, la forma ms fcil de crear las queries. Sin embargo, tambin en mi opinin, HQL es ms poderosa y tenemos ms control sobre lo que est ocurriendo, as que ser esta forma la que usaremos. Creando la consulta en HQL Hibernate la transformar al SQL apropiado para la base de datos que estemos usando. La consulta en realidad es muy simple: indicamos que queremos obtener datos (generar un "SELECT"), en este caso la clausula "SELECT" no es necesaria (aunque si existe) porque vamos a regresar todos los datos del objeto (podemos indicar solo unos cuantos atributos, eso es llamado proyeccin, pero se maneja de una forma distinta). Lo que si debemos indicar es de cul clase queremos recuperar las instancias, por lo que necesitamos la clausula "FROM" y el nombre de la clase (recuerden que en base al nombre de la clase Hibernate sabr en cul tabla estn almacenadas las entidades). Espero que esta explicacin se haya entendido, se que es un poco enredado, pero quedar ms claro con el ejemplo:
public List<Contacto> obtenListaContactos() throws HibernateException { List<Contacto> listaContactos = null; try { iniciaOperacion(); listaContactos = sesion.createQuery("from Contacto").list(); }finally { sesion.close(); } return listaContactos; }

Eso es todo, nuestra consulta para recuperar todos los Contactos que tenemos en la base de datos solo debemos usar la clausula "FROM Contacto". Si quieren una referencia ms amplia de HQL pueden encontrarla en el tutorial sobre HQL. Bien, eso es todo. La clase "ContactosDAO" queda de la siguiente forma (omitiendo los imports):

public class ContactosDAO { private Session sesion; private Transaction tx; public long guardaContacto(Contacto contacto) throws HibernateException { long id = 0; try { iniciaOperacion(); id = (Long) sesion.save(contacto); tx.commit(); } catch (HibernateException he) { manejaExcepcion(he); throw he; } finally { sesion.close(); } return id; } public void actualizaContacto(Contacto contacto) throws HibernateException { try { iniciaOperacion(); sesion.update(contacto); tx.commit(); } catch (HibernateException he) { manejaExcepcion(he); throw he; } finally { sesion.close(); } } public void eliminaContacto(Contacto contacto) throws HibernateException { try { iniciaOperacion(); sesion.delete(contacto); tx.commit(); } catch (HibernateException he) { manejaExcepcion(he); throw he; } finally {

sesion.close(); } } public Contacto obtenContacto(long idContacto) throws HibernateException { Contacto contacto = null; try { iniciaOperacion(); contacto = (Contacto) sesion.get(Contacto.class, idContacto); } finally { sesion.close(); } return contacto; } public List<Contacto> obtenListaContactos() throws HibernateException { List<Contacto> listaContactos = null; try { iniciaOperacion(); listaContactos = sesion.createQuery("from Contacto").list(); } finally { sesion.close(); } return listaContactos; } private void iniciaOperacion() throws HibernateException { sesion = HibernateUtil.getSessionFactory().openSession(); tx = sesion.beginTransaction(); } private void manejaExcepcion(HibernateException he) throws HibernateException { tx.rollback(); throw new HibernateException("Ocurri un error en la capa de acceso a datos", he); } }

Ahora, y para terminar el ejemplo, haremos uso de "ContactosDAO" para crear y recuperar algunas instancias de "Contacto". Creo que el cdigo es muy claro as que no lo explicar ^-^!. La clase "Main" queda de la siguiente forma:
public class Main { public static void main(String[] args) { ContactosDAO contactosDAO = new ContactosDAO();

Contacto contactoRecuperado = null; long idAEliminar = 0; //Creamos tes instancias de Contacto Contacto contacto1 = new Contacto("Contacto 1", "contacto1@contacto.com", "12345678"); Contacto contacto2 = new Contacto("Contacto 2", "contacto2@contacto.com", "87654321"); Contacto contacto3 = new Contacto("Contacto 3", "contacto3@contacto.com", "45612378"); //Guardamos las tres instancias, guardamos el id del contacto1 para usarlo posteriormente idAEliminar = contactosDAO.guardaContacto(contacto1); contactosDAO.guardaContacto(contacto2); contactosDAO.guardaContacto(contacto3); //Modificamos el contacto 2 y lo actualizamos contacto2.setNombre("Nuevo Contacto 2"); contactosDAO.actualizaContacto(contacto2); //Recuperamos el contacto1 de la base de datos contactoRecuperado = contactosDAO.obtenContacto(idAEliminar); System.out.println("Recuperamos a " + contactoRecuperado.getNombre()); //Eliminamos al contactoRecuperado (que es el contacto3) contactosDAO.eliminaContacto(contactoRecuperado); //Obtenemos la lista de contactos que quedan en la base de datos y la mostramos List<Contacto> listaContactos = contactosDAO.obtenListaContactos(); System.out.println("Hay " + listaContactos.size() + "contactos en la base de datos"); for(Contacto c : listaContactos) { System.out.println("-> " + c.getNombre()); } } }

En el momento que ejecutemos la aplicacin Hibernate crear la tabla correspondiente en la base de datos (llamada "contactos") y que tiene los siguientes campos:

Como podemos ver la tabla y los nombres de las columnas se generan en base al archivo de mapeo. En donde hemos colocado los nombres de las columnas se han usado estos nombres, en donde no lo hemos hecho se han tomado los mismos nombres que el de los atributos que estamos mapeando. Si observamos la salida de la consola podemos ver, que en la parte final, se indica esta creacin y adems las consultas que Hibernate ha generado (revueltas con los mensajes que sacamos a consola). He marcado con rojo los mensajes que mandamos a consola para que sea fcil distinguirlos.

Segun indica la salida en la base de datos solo debemos tener dos entidades, con los nombres "Nuevo Contacto 2" y "Contacto 3". Revisemos la tabla para ver que esto sea correcto:

Como podemos ver, esto es correcto, en la base de datos existen solo los registros indicados, con lo que podemos estar seguros de que nuestra aplicacin funciona!!! ^-^. Entonces, vimos que con Hibernate fue muy simple hacer la manipulacin de los datos de una base de datos relacional sin escribir una sola lnea de SQL. En aplicaciones de tamao mediano a grande esto nos ahorrar mucho tiempo (que UNMSMlmente usaramos en escribir el SQL para query, armar algunas de estas de forma dinmica, pasar los parmetros adecuados, recuperar los mismos de un ResultSet, entre otras cosas) para mejorar algunos otros aspectos de la aplicacin, como la interfaz grfica, la lgica del negocio, o realizar ms pruebas. Adems nuestro cdigo es ms simple y por lo tanto fcil de mantener. Lo nico malo es que ahora tenemos que crear mapeos de las entidades con las tablas de la base de datos en un archivo XLM. Es por esto que en el siguiente tutorial veremos cmo realizar este mismo ejemplo pero usando anotaciones en vez del archivo de mapeo

13. Proyecto Web de Agentes jade con las tecnologas JSF y Hibernate
Consta de dos proyectos un proyecto WEB y un proyecto de Escritorio en el que se implemtaran los agentes JADE y tendr un proyecto de tipo librera en donde se colocara todo el modelo generado apartir de la base de datos por Hibernate. Para este ejemplo se usara anotaciones en vez del archivo de mapeo xml, para el modelo generado por Hibernate. Para realizar la comunicacin entre un proyecto Jade y otro no Jade se necesita de un agente de tipo GatewayAgent que se encuentra en el paquete jade.wrapper.gateway. Tanto el proyecto WEB como el de JADE importan las libreras de HibernateJPA de netbeans 7.1.2 debido a que los dos van a utilizar la base de datos, el de WEB solo para mostrar el contenido de las tablas (reportes) y el de JADE lo hara para el registro. ProyectoWeb: Este proyecto es el que desea comunicarse con los agentes de la plataforma jade para lograr esto Jade dispone de una Agente de tipo GatewayAgent. Para lograr que este agente sea creado es necesario darle ciertos valores iniciales a la clase que inicia a este agente JadeGateway el cual consta de tres mtodos principales: Init: En este se colocan los valores de iniciacin del agente, JadeGateway.init("nombreClaseAgenteGateway", propiedadesdelagente); Execute: Es el comando que crea el agente y adems pasa el objeto al mtodo proccesCommand del agente. Shutdown: Elimina al agente.

ProyectoJade: Contiene a la clase AgenteBD de la cual se instancia al agente BD que se encargara deregistrar los valores obtenidos de la aplicacin web, en la clase ProyectoJade donde se encuentra el main se crearan todos los agentes que se crea conveniente derivadas de las clases de tipo agente, para nuestro caso solo habr un agente BD.

LibreraModelo: Este proyecto de tipo librera solo contiene el dominio o modelo de la base de datos representado en los archivos POJOs para el ejemplo contiene solo un archivo Model1 que representa a la tabla modelo de la base de datos y posee otro archivo llamado MensajeAgente que e usara para enviar el mensaje entre los agentes.

Codigo completo delos proyectos anteriores: LibreriaModelo:


package mensaje; import java.io.Serializable; /** * @author UNMSM */ public class MensajeAgente implements Serializable{ private String NombreAgente; private Object o; public String getNombreAgente() { return NombreAgente; } public void setNombreAgente(String NombreAgente) { this.NombreAgente = NombreAgente; }

public Object getO() { return o; } public void setO(Object o) { this.o = o; } public MensajeAgente(Object o, String nombreAgente) { this.o = o; this.NombreAgente = nombreAgente; } public MensajeAgente() { } } package modelo; import javax.persistence.*; /** * @author UNMSM */ @Entity @Table(name = "modelo") public class Model1 implements java.io.Serializable { @Column(name = "nm", nullable = false, length = 50) private String nm; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "id") private long id; public Model1() { } public Model1(String nm) { this.nm = nm; } public String getNm() { return this.nm; } public void setNm(String nm) { this.nm = nm; } public long getId() { return id; } public void setId(long id) { this.id = id; } }

Clases comunes para el proyecto JADE y WEB


package dao; import java.util.logging.Level; import java.util.logging.Logger; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; /** * * @author user */ public class DAO { private static final SessionFactory sessionFactory; private static final ThreadLocal session = new ThreadLocal(); private static final Logger log = Logger.getAnonymousLogger(); static { try { // Create the SessionFactory from standard (hibernate.cfg.xml) // config file. sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); } catch (Throwable ex) { // Log the exception. System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static Session getSession() { Session secion = (Session) DAO.session.get(); if (secion == null) { secion = sessionFactory.openSession(); DAO.session.set(secion); } return secion; } protected void begin() { getSession().beginTransaction(); } protected void commit() { getSession().getTransaction().commit(); } protected void rollback() { try { getSession().getTransaction().rollback(); } catch (HibernateException e) { log.log(Level.WARNING, "Cerrando", e); } DAO.session.set(null); }

public static void close() { getSession().close(); DAO.session.set(null); } protected DAO() { } }

package implementacion; import dao.DAO; import java.util.List; import mensaje.MensajeAgente; import modelo.Model1; import org.hibernate.HibernateException; import servicios.Interface; /** * * @author user */ public class ImpInterface extends DAO implements Interface { @Override public List listarDatos() throws Exception { List<Model1> listaContactos = null; try { begin(); listaContactos = getSession().createQuery("from Model1").list(); commit(); } finally { DAO.close(); } return listaContactos; } @Override public void regDato(Object o) throws Exception { System.out.println("Registrando dato ingresado por el usuario"); MensajeAgente m = (MensajeAgente) o; try { begin(); getSession().save((Model1)m.getO()); commit(); } catch (HibernateException e) { throw new Exception("Error de registro", e); } DAO.close(); } }

package servicios; import java.util.List; /** * @author UNMSM */ public interface Interface { public List listarDatos()throws Exception; public void regDato(Object o) throws Exception; }

ProyectoJade
package proyectojade; import jade.core.Profile; import jade.core.ProfileImpl; import jade.wrapper.AgentController; import jade.wrapper.ContainerController; import jade.wrapper.StaleProxyException; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author UNMSM */ public class ProyectoJade { /** * @param args the command line arguments */ private static ContainerController cc; private static AgentController ac; public static void main(String[] args) { jade.core.Runtime rt = jade.core.Runtime.instance(); Profile p = new ProfileImpl(); // p.setParameter(Profile.FILE_DIR, ProyectoJade.class.getResource("/mtps/").getPath()); p.setParameter(Profile.CONTAINER_NAME, "Administracion");//se le asigna un nombre al contenedor cc = rt.createAgentContainer(p); //se crea un contenedor en la plataforma jade if (cc != null) { try { ac = cc.createNewAgent("BD", "agenteSistema.AgenteBD", null); ac.start(); } catch (StaleProxyException ex) { Logger.getLogger(ProyectoJade.class.getName()).log(Level.SEVERE, null, ex); } } } }

package agenteSistema; import implementacion.ImpInterface; import jade.core.AID; import jade.core.Agent; import jade.core.behaviours.CyclicBehaviour; import jade.domain.DFService; import jade.lang.acl.ACLMessage; import java.util.logging.Level; import java.util.logging.Logger; import mensaje.MensajeAgente; import modelo.Model1; import servicios.Interface; /** * @author UNMSM */ public class AgenteBD extends Agent { Model1 m = new Model1(); Interface registro; protected void setup() { addBehaviour(new CyclicBehaviour(this) { @Override public void action() { System.out.println("Esperando mensaje"); ACLMessage msg = blockingReceive(); if (msg != null) { System.out.println("Mensaje recibido"); registro = new ImpInterface(); ACLMessage respuesta = new ACLMessage(ACLMessage.INFORM); respuesta.setPerformative(ACLMessage.INFORM); try { if (msg.getContentObject() instanceof MensajeAgente) { MensajeAgente m1 = (MensajeAgente) msg.getContentObject(); registro.regDato(m1); respuesta.addReceiver(new AID(m1.getNombreAgente(), AID.ISGUID)); respuesta.setContentObject((Model1) m1.getO()); send(respuesta); } } catch (Exception ex) { Logger.getLogger(AgenteBD.class.getName()).log(Level.SEVERE, null, ex); } } } }); } protected void takeDown() { try { DFService.deregister(this); } catch (Exception e) { } } }

ProyectoWeb Pagina index.xhtml


<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>Facelet Title</title> </h:head> <h:body> <h:form> <h:inputText value="#{controlEjem.model1.nm}" /> <h:commandButton value="Registrar" action="#{controlEjem.listar}" actionListener="#{controlEjem.registrar}" /> </h:form> </h:body> </html>

Pagina reporte.xhtml
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>Reporte</title> </h:head> <h:body> Reporte de registros de la base de datos <h:form> <h:inputHidden value="#{controlEjem}"/> <h:dataTable border="1" value="#{controlEjem.ln}" var="nom"> <h:column> <f:facet name="header"> <h:outputText value="id"/> </f:facet> <h:outputText value="#{nom.id}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="nombre"/> </f:facet> <h:outputText value="#{nom.nm}"/> </h:column> </h:dataTable> </h:form> </h:body> </html>

package controlador; import gateway.JadeGatewayFactory; import implementacion.ImpInterface; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import modelo.Model1; import servicios.Interface; /** * * @author user */ @ManagedBean @RequestScoped public class ControlEjem {

private modelo.Model1 model1; private List<Model1> ln;

public List<Model1> getLn() { return ln; } public void setLn(List<Model1> ln) { this.ln = ln; } public Model1 getModel1() { return model1; } public void setModel1(Model1 model1) { this.model1 = model1; } public String listar() { Interface in = new ImpInterface(); try { ln = new ArrayList(); ln = in.listarDatos(); } catch (Exception ex) { Logger.getLogger(ControlEjem.class.getName()).log(Level.SEVERE, null, ex); } return "reporte"; } public void registrar() throws Exception { JadeGatewayFactory.execute(model1); System.out.println("Respuesta de AgenteGateway"); }

public ControlEjem() { model1 = new Model1(); } }

package agente; import jade.core.AID; import jade.core.behaviours.CyclicBehaviour; import jade.lang.acl.ACLMessage; import jade.lang.acl.UnreadableException; import jade.wrapper.gateway.GatewayAgent; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import mensaje.MensajeAgente; import modelo.Model1; /** * * @author UNMSM */ public class AgenteGateway extends GatewayAgent { Model1 model1 = null; @Override protected void processCommand(java.lang.Object obj) { System.out.println(getLocalName() + " Realizando el mensage"); try { ACLMessage msg = new ACLMessage(ACLMessage.REQUEST); System.out.println("Creando mensaje"); if (obj instanceof Model1) { MensajeAgente msa = new MensajeAgente(); System.out.println("Entrando al mensaje"); model1 = (Model1) obj; msa.setO(model1); msa.setNombreAgente(getAID().getName()); msg.addReceiver(new AID("BD", AID.ISLOCALNAME)); msg.setContentObject(msa); System.out.println("Agente a enviar mensaje: " + getAID().getName()); send(msg); } } catch (IOException ex) { Logger.getLogger(AgenteGateway.class.getName()).log(Level.SEVERE, null, ex); } } public void setup() { addBehaviour(new CyclicBehaviour(this) { @Override public void action() { System.out.println("Iniciando el comportamiento"); ACLMessage msg = receive(); if (msg != null) {

try { if (msg.getContentObject() instanceof Model1) { System.out.println("Nombre del agente que envia un mensaje: " + msg.getSender().getLocalName()); Model1 m1=(Model1) msg.getContentObject(); model1.setId(m1.getId()); model1.setNm(m1.getNm()); releaseCommand(model1); } } catch (UnreadableException ex) { Logger.getLogger(AgenteGateway.class.getName()).log(Level.SEVERE, null, ex); } } else { block(); } } }); super.setup(); } }

package gateway; import jade.core.Profile; import jade.util.leap.Properties; import jade.wrapper.ControllerException; import jade.wrapper.StaleProxyException; import jade.wrapper.gateway.JadeGateway; /** * * @author UNMSM */ public class JadeGatewayFactory { public static void inicializaGateway() { Properties jadeProps = new Properties(); jadeProps.setProperty(Profile.MAIN_PORT, "1099"); jadeProps.setProperty(Profile.CONTAINER_NAME, "Gateway"); JadeGateway.init("agente.AgenteGateway", jadeProps); } public static void execute(Object command) { inicializaGateway(); try { JadeGateway.execute(command); JadeGateway.shutdown(); } catch (StaleProxyException ex) { ex.printStackTrace(); } catch (ControllerException ex) { ex.printStackTrace(); } catch (InterruptedException ex) { ex.printStackTrace(); } } }

14. Ingenias (IDK)


Creando un Agente Hola mundo en Ingenias

Crear diagrama de agentes. Click derecho sobre la carpeta Project -> Add AgentModel Lo llamaremos Hola Mundo

El contenido de este modelo consta de un agente, objetivo(goal), tarea, estado mental, frame fact.

Crear un diagrama de tareas y objetivos. Click derecho sobre la carpeta Project -> Add TaskAndGoalsModel Lo llamaremos SaludarUsuario

El contenido de este modelo consta: tarea saludar, Objetivo Saludar Usuario y FrameFact Contenidodelsaludo. Todos estos creados en el modelo de Agentes.

Crear un diagrama de componentes. Click derecho sobre la carpeta Project -> Add ComponentDiagram Lo llamaremos Componentes.

El contenido de este modelo consta: tarea saludar y de un CodeComponent (se deja con sus valores por defecto para este ejemplo). La tarea saludar viene del modelo de Agentes.

Definimos que va a realizar el componente a travs de la tarea. Le damos doble click al codecomponent agregado luego nos dirigimos a la parte de Code y digitamos un mensaje system.out.println(Hola Mundo); y luego presionamos aceptar. Como se muestra en la figura.

Generar cdigo: Modules-> Code Generator-> Ingenias Agent Framework generator -> generate La pestaa Log mostrara el resultado.

Ejecutar el cdigo generado. Se debe abrir dos consolas de comando desde la carpeta del proyecto. La primera ejecutara el RMA de jade de la siguiente manera ant runjade.

la segunda ejecutara al depurador IAF de ingenias y adems creara en iniciara a nuestro(s) agente del proyecto. Escribiendo lo siguiente ant run. El mensaje Hola Mundo aparece al final.

Crear un diagrama de despliegue

El contenido de este modelo consta: DeploymentPackage al cual nombraremos DespliegueTresAgentes y un DeploymentUnitByType al cual nombraremos AgentesSaludando, a este ltimo le definiremos el tipo de agente que ejecutara y cuntos de estos va a crear mediante el paquete de despliegue (DeploymentPackage). Como se muestra en la figura.

De esta figura en la parte de AgentTypeDeployed -> class.ingenias.editor.entitiesAgent -> Select existing En donde escogemos a nuestro agente hola mundo.

En la parte NumberInstances colocamos el nmero 3, el cual nos indica que se ejecutaran tres agentes hola mundo. Para ejecutar este despliegue se debe tener levantada la plataforma de jade como se mostro anteriormente y luego en la segunda consola ejecutar ant runDespliegueTresAgentes. Ver la figura.

En la parte final se muestran los tres mensajes Hola mundo de cada uno de los agentes y en el administrador de jade RMA se ven a los tres agentes creado en un container aparte del MainContainer.

15. Bibliogafia.
http://www.javatutoriales.com/2009/05/hibernate-parte-1-persistiendo-objetos.html http://jade.tilab.com/doc/index.html http://programacionjade.wikispaces.com/

S-ar putea să vă placă și