Zona HTML Zona Java Zona PHP Zona ASP Zona Bases de datos
Inicio > Tutoriales > Plataformas > Linux > Curso práctico de Corba en GNU/Linux
-Tutoriales

Curso práctico de Corba en GNU/Linux


Descripción del lenguaje OMG/IDL

El lenguaje OMG/IDL es uno de los pilares de la plataforma OMA de OMG, y en especial de CORBA.

La especificación del lenguaje se puede consultar dentro del estándar de CORBA, en el capítulo 3. Son un total de 40 páginas cuyo índice lo podéis observar en la siguiente figura:

Figura 1: Indice del capítulo 3 del estándar de CORBA sobre OMG/IDL

Esta es la fuente definitiva que a la que el lector tiene que acudir y de ella vamos a tomar datos del lenguaje a lo largo de este apartado.

Gracias a este lenguaje descriptivo podemos especificar las interfaces de nuestros módulos CORBA, sin ligarnos a ningún lenguaje concreto.

Además es un lenguaje muy adecuado para el diseño del sistema ya que permite pensar en el diseño del sistema, sin tener que descender a detalles de implementación.

Para evitar ambigüedades a nivel de diseño es un lenguaje fuertemente tipado, al estilo de Java. Es un lenguaje cuya sintaxis está bastante cercana a la de ANSI C++ o Java, al ser orientado a objetos. Tiene facilidades como la definición de módulos e interfaces, herencia de interfaces o excepciones. Es un lenguaje lo suficientemente descriptivo como para poder detallar interfaces de objetos que van a ser distribuidos.

En la siguiente figura podemos observar las palabras claves reservadas en este lenguaje:

Figura 2: Palabras reservadas de OMG/IDL

Pasamos a describir el lenguaje con mayor detalle a continuación, así como ejemplos de los principales traducciones de OMG IDL a lenguajes como C, C++ y Java.

. Descripción del lenguaje

OMG/IDL es un lenguaje sencillo al ser declarativo. Una muestra de su sencillez es que su gramática está compuesta de 82 reglas en total, pudiéndose consultar dicha gramática dentro del capítulo 3 del estándar de CORBA.

La mejor forma de entender el lenguaje es mediante un ejemplo que iremos explicando a lo largo de este apartado. El ejemplo que utilizaremos será la interfaz IDL Mensajes.idl resultado de la fase de diseño de la solución que desarrollamos en el apartado anterior. Reproducimos dicha interfaz al completo para que el lector la pueda tener a mano ya que será utilizada a menudo como referencia.

1: // Módulo de intercambio de mensajes entre usuarios
2: module Mensajes {
3: 	interface comun {
4: 		// Version de la aplicacion
5: 		readonly attribute string version;
6: 
7: 		// Nombre de usuario
8: 		typedef string usuario;
9: 		// Lista de usuarios
10: 		typedef sequence lista_usuarios;
11: 
12: 		// Excepcion de usuario no presente
13: 		exception ClienteNoPresente {usuario nombre;};
14: 
15: 		struct alarma {
16: 			unsigned short codigo;
17: 			string mensaje;
18: 		};
19: 	}; 
20: 	
21: 	// Interfaz a implementar por el cliente
22: 	interface cliente {
23: 		// Función básica de recepcion de mensajes
24: 		// Devuelve "true" ante recepcion correcta
25: 		boolean recibeMensaje (in string mensaje);
26: 		// Mensajes de aviso especiales del servidor
27: 		boolean recibeAviso (in comun::alarma mensaje);
28: 		// Mensajes directos a otros usuarios
29: 		void enviaMensaje (in comun::usuario destino, in string mensaje);
30: 	};
31: 
32: 	// El operador es informado de accesos al servicio
33: 	interface operador:cliente {
34: 		boolean nuevaConexion(in string nombre);
35: 	};
36: 
37: 	// Interfaz a implementar por el servidor
38: 	interface servidor {
39: 		// Conexion de un operador
40: 		string conectar_operador (in operador interfaz, in string clave);
41: 		// Devuelve una cadena con el nombre del servidor
42: 		string conectar (in cliente interfaz);
43: 		// Desconecta un usuario del sistema
44: 		boolean desconectar (in cliente interfaz);
45: 		// Mira si un usuario esta conectado y recibe la interfaz al mismo
46: 		cliente presente (in string nombre) raises (comun::ClienteNoPresente);
47: 		// Devuelve una lista de los usuarios presentes en el sistema
48: 		void listaUsuarios (out comun::lista_usuarios lista);
49: 	};
50: 
51: };

. Módulos e interfaces

Este ejemplo es bastante completo y nos va a permitir profundizar en diferentes aspectos de OMG IDL.

La primero que observamos es la forma de encapsular en módulos las interfaces. Un módulo debe de ser un conjunto de interfaces que proporcionan una funcionalidad concreta dentro del sistema. En nuestro caso este módulo es el encargado de definir el módulo de Mensajes de una herramienta de trabajo cooperativo.

Dentro del módulo hemos definido dos interfaces: una para los clientes y otra para el servidor central. La arquitectura sigue los esquemas centralizados, es decir, que un servidor central controla la forma de interactuar entre los diferentes clientes. Pero también se pueden obtener las interfaces a otros clientes y comunicarnos con ellos de forma directa.

Comprobamos aquí que CORBA se adapta sin problemas a paradigmas como el de cliente/servidor o de igual a igual sin ningún tipo de problema.

. Operaciones y tipos de datos

Las funciones se agrupan en interfaces cuando tienen un propósito común. Dichas funciones tienen parámetros de entrada, con sus tipos correspondientes y parámetros de salida. Es necesario especificar el parámetro de retorno, aunque este sea void.

Es característicos de OMG/IDL que los parámetros que se pasan a la función pueden ser de tres tipos:

  1. in: parámetros que se envían del cliente al servidor.
  2. out: parámetros en los que se reciben datos del servidor.
  3. inout: parámetros en los que se envían datos al servidor y se reciben datos de respuesta del servidor.

Esta característica de CORBA en el paso de parámetros complica la gestión de memoria dentro de la implementación. En los tipos de parámetros in la gestión de memoria del parámetro es sencilla: el cliente se encarga de la reserva y liberación de memoria.

Pero en los parámetros out y inout aparece el problema de que, el cliente puede reservar una cantidad de memoria para el parámetro, cantidad que puede ser modificada por el objeto para que entre en el parámetro la respuesta.

En el estándar se han dividido 20 tipos de parámetros en 6 tipos de paso de parámetros. Por ejemplo, para parámetros de longitud fija (incluyendo las estructuras), el llamante reserva y libera el espacio excepto en el caso de any.

Las referencias a objetos también son gestionadas en el cliente. Pero por ejemplo, si el parámetro es inout, la implementación del objeto va a invocar la operación CORBA::Object_release en el valor original para reasignar el parámetro (algo que también afecta en el lado del cliente). Para guardar el valor original de la referencia al objeto, deberemos utilizar CORBA::duplicate antes de invocar la operación.

Hay casos en los parámetros out y inout en los que la implementación debe de reservar la memoria, pero debe ser liberada en el cliente.

Dentro del estándar estas detallados todos los casos y hay que ser cuidadoso para evitar agujeros de memoria en nuestras aplicaciones.

Los tipos de estos datos son los que solemos encontrarnos en cualquier lenguaje de programación: integer (signed/unsigned long, short), float, double, boolean, octet, any.

También tenemos tipos estructurados como: struct, discriminated union, enumerations, sequence, string y array.

Un tipo especial de datos son los atributos. Un ejemplo de su uso lo encontramos en la línea 5. Los atributos al ser procesados por el compilador de IDL generan una función (get) si son de solo lectura (como en nuestro caso), o dos funciones (get y set) si son de lectura y escritura. El acceso al atributo se ha de realizar de forma obligatoria a través de estas operaciones.

De todos estos tipos de datos quizás merezca mención especial el tipo any en el que podemos meter cualquier otro tipo de dato de OMG/IDL. Un tipo de datos muy flexible que no solemos encontrar en los lenguajes usuales.

Por último comentar que existe un tipo especial de operación, aquellas del tipo oneway. Son operaciones que se invocan sin esperar ningún valor de retorno, no siendo bloqueantes. Por ello en este tipo de operaciones el tipo de retorno ha de ser void y todos los parámetros han de ser del tipo in. Un ejemplo de este tipo de operación lo observamos en la línea 27, donde el servidor envía las alarmas a los clientes, sin esperar que estos le respondan nada.

. Excepciones

Algo importante en la invocación de operaciones sobre objetos CORBA es que, aunque para el desarrollador sean invocaciones comunes sobre objetos, el mecanismo para sus ejecución es complejo: han de pasar por los cabos del cliente, por el ORB, por el adaptador de objetos, encontrar el objeto adecuado, viajar por los cabos del servidor, realizar la invocación sobre el objeto y recorrer el mismo viaje de vuelta.

Es sencillo que en todo este trasiego puedan aparecer problemas. Y para informar al cliente de dichos problemas aparecen las excepciones. Ante problemas en la invocación de estas operaciones, el ORB nos puede devolver excepciones de diferentes tipo, según el problema aparecido.

Pero es más dentro de nuestro código también podemos crear excepciones para la gestión de errores, o para comunicar situaciones excepcionales. Tal es el caso de la función de la línea 39, que en el caso de que un usuario no este conectado lo devuelve como una excepción.

. Herencia

La herencia es un mecanismo de reutilización de funcionalidad. En nuestro caso la utilizamos para definir la interfaz de un operador, que es un cliente con una operación más, la de recibir información de conexiones.

 
Patrocinados
 

Copyright © 1999-2006 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad

Hospedaje web y servidores dedicados linux por Ferca Network