Anterior
 Volver
 Siguiente

 
Asunto: Re: Java: DII, DSI y clases holder
Fecha: Fri Dec 3 10:29:38 1999
De: Eduardo Martinez Gracia <edumart@fcu.um.es>

 
Hola Marcos:

Marcos Menárguez Tortosa wrote:
> 
> Hola a todos.
> 
> Tengo una duda sobre las invocaciones dinámicas (DII) y las clases holder.
> El mapeo IDL a Java indica que son necesarias clases "holder" para poder
> pasar parámetros out e inout, ya que Java sólo soporta el paso de parámetros
> por valor.
> 
> Al crear un invocación dinámica (Request) y crear sus argumentos:
> -¿hay que introducir las clases holder dentro del objeto any para los
> argumentos out e inout?
> 
> Para DSI (ServerRequest), cuando se piden los argumentos con el método
> "arguments" al que se le pasa una NVList:
> ¿Es necesario incluir los argumentos out?
> ¿Es necesario volver a llamar a "arguments" para establecer los argumentos
> out e inout?
> 
> Marcos.
> 

Puedo responder a tu primera pregunta basándome en el ejemplo 
TestDII.java que puedes encontrar en la distribución para Java de 
ORBacus, concretamente en el directorio JOB-3.1.3\ob\test

En el fichero Test1.idl tienes un interfaz TestInterface con, entre
otras, las siguientes definiciones:

interface TestInteface {
...
typedef sequence<string> StringSequence;
...
StringSequence opStringSequence(
  in StringSequence a0,
  inout StringSequence a1,
  out StringSequence a2);
...
}

Hay otras operaciones con parámetros de tipos básicos, pero creo que
esta deja más clara la solución.

En TestDII.java aparece un ejemplo de invocación dinámica de esta
operación.

// Primero se obtiene un pseudo-objeto Request llamando a la
// operación _request sobre la referencia del objeto al que se
// va a invocar:
// Supon que en 'ti' ya tienes una referencia a un TestInterface

Request request = ti._request("opStringSequence");

// Variables para parámetros y resultado
String[] seq = {"!!!","@@@","###");
String[] ret;
String[] inOut;
String[] out;

// Ahora, vamos añadiendo a la request los argumentos
// Empezamos con el de entrada, 'a0'
StringSequenceHelper.insert(request.add_in_arg(),seq);
// add_in_arg() devuelve una referencia a un objeto Any. Con la
operación
// insert del Helper creado para StringSequence al usar el compilador de
// IDL a Java estamos insertando el valor del parámetro de entrada en
// el objeto Any.

// Y ahora, lo interesante, 'a1' de entrada salida y 'a2' de salida
Any inOutAny = request.add_inout_arg();
StringSequenceHelper.insert(inOutAny, inOut);
// Observa que no se utiliza un StringSequenceHolder, sino directamente
// inOut, un String[], que es el mapping en Java de un StringSequence.
// Ahora 'a2'
Any outAny = request.add_out_arg();
outAny.type(StringSequenceHelper.type());
// Como no insertamos en outAny ningún valor, tenemos que dejar claro
// que ahí queremos tener un StringSequence. Para ello se emplea la
// operación type de Any. El parámetro de la operación es el TypeCode
// de StringSequence, que obtenemos a través de StringSequenceHelper.
// Antes de invocar, indicamos también el tipo del resultado
request.set_return_type(StringSequenceHelper.type());
// Ahora ejecutamos la operación
request.invoke();
// Consultamos el resultado, haciendo uso, de nuevo, de la clase
// StringSequenceHelper para extraer los valores de los Any.
ret = StringSequenceHelper.extract(request.return_value());
inOut = StringSequenceHelper.extract(inOutAny);
out = StringSequenceHelper.extract(outAny);

Por tanto, lo fundamental aquí son las clases Helper y el tipo del
valor que alberguen los objetos any correspondientes a los argumentos 
de entrada - salida y salida. 

Para la segunda pregunta, en el mismo directorio de ORBacus te aconsejo
que mires 'TestInterfaceExDSI_impl.java'. Allí tienes implementado
un servidor dinámico para el interfaz TestInterface. El código de
la operación opStringSequence es:

class TestInterfaceExDSI_impl extends DynamicImplementation
{
 ...
 // Aquí llegan todas las invocaciones 
 public void invoke(ServerRequest request)
 {
   String name = request.op_name();
   ...
   // ¿Están pidiendo la ejecución de opStringSequence?
   if (name.equals("opStringSequence"))
   {
     // Se crea la lista de nombres-valores.
     // Es curioso, el argumento de create_list es la longitud
     // de la lista. Tendría que ser 3 porque hay 3 argumentos
     NVList list = orb.create_list(0);
     // Estos son los objetos any para los argumentos
     Any any0 = orb.create_any();
     Any any1 = orb.create_any();
     Any any2 = orb.create_any();
     // Se indican los tipos de los argumentos de entrada
     any0.type(StringSequenceHelper.type());
     any1.type(StringSequenceHelper.type());
     // Se añaden a la lista de NVs, indicando su dirección
     // Probablemente add_value aumenta automáticamente la lista
     // que ha sido creada, inicialmente, de tamaño 0.
     list.add_value("", any0, org.omg.CORBA.ARG_IN.value);
     list.add_value("", any1, org.omg.CORBA.ARG_INOUT.value);
     list.add_value("", any2, org.omg.CORBA.ARG_OUT.value);
     // Ahora se saca de la petición los valores de los parámetros,
     // que se meten en la lista de NVs
     request.params(list);
     // Ahora toca extraer de esos anys los valores que tienen
     // El primer argumento es de entrada, así que basta con usar
     // StringSequenceHelper
     String[] arg0 = StringSequenceHelper.extract(any0);
     // Fíjate, Marcos, aquí aparecen en escena los Holder, por un
     // motivo que ahora mismo verás. En cualquier caso, el valor
     // del segundo argumento se mete en un StringSequenceHolder 
     // en lugar de un String[]:
     StringSequenceHolder arg1 = new StringSequenceHolder();
     arg1._read(any1.create_input_stream()); // Ufff!
     // Y este StringSequenceHolder para el argumento de salida
     StringSequenceHolder arg2 = new StringSequenceHolder();
     // Bien, supongamos que tenemos un objeto ti_ que es donde
     // realmente se implementa esta operación. Hasta ahora sólo
     // se han sacado los argumentos del request a String[] y 
     // StringSequenceHolders. Pues bien, se invoca opStringSequence
     // en ese ti_, y los Holders cobran sentido como los argumentos
     // de salida de esa operación:
     String[] ret = ti_.opStringSequence(arg0, arg1, arg2);
     // Ahora toca colocar en su sitio el resultado (ret) y los valores
     // de salida (arg1 y arg2):
     Any any = orb.create_any();
     StringSequenceHelper.insert(any,ret);
     request.result(any);
     any1.insert_Streamable(arg1);
     any2.insert_Streamable(arg2);
     // Confieso que lo de meter y sacar valores a un any con streams
     // se me escapa un poco :-)
     return; // AL FIN!
     ...
}
    
Bueno, Marcos, te agradezco la pregunta porque me ha obligado a
refrescar lo que sabía de CORBA y Java, y también he aprendido cosas :-)

-- 
------------------------------------------------------------------------
Eduardo Martinez Gracia
Departamento de Informatica, Inteligencia Artificial y Electronica
Tlf: 34 968364666                       Fax: 34 968364151
email: edumart@fcu.um.es                http://intelec.dif.um.es
Facultad de Informatica. Campus de Espinardo.
Universidad de Murcia. 30071 Murcia.
------------------------------------------------------------------------


 Anterior
 Volver
 Siguiente