6- Compléments illustrés en JAVA Agenda - MIAGe

publicité
Agenda
† Développement par délégation
6- Compléments illustrés en JAVA
Thierry DESPRATS
„
„
„
Rappel et limites de l’approche par héritage
Approche par délégation
Exemple
† Type générique, Meta-Type
„
„
„
„
Le type Any
Le type TypeCode
Exemple
Gestion dynamique de valeurs d’any
† Mode d’invocation dynamique
Université Paul SABATIER – Toulouse III
IRIT- SIERA
„
„
„
„
http://www.irit.fr/~Thierry.Desprats
[email protected]
Référentiel d’Interfaces (IR)
Composition dynamique de requêtes
Invocation dynamique et modalités
Exemples
Compléments CORBA
© 2005-06 Th. Desprats
Approche statique par délégation (1/7)
Approche statique par délégation (2/7)
† Rappel approche par héritage
† Illustration du mode par héritage :
„ Principe :
org.omg.Portable.ObjectImpl
† La classe d’implémentation Java hérite du squelette
de l’interface à implémenter
public class EuroImpl extends _EuroPOA {
„ Limites de l’approche par héritage en java:
† Pas d’héritage multiple en JAVA : impossible de
réutiliser les classes d’implémentation
(pas de répercussion des héritages IDL sur les
implémentations JAVA)
† Impossibilité d’associer une seule classe
d’implémentation JAVA à plusieurs interfaces CORBA
Compléments CORBA
© 2005-06 Th. Desprats
3
org.omg.Portable.Servant
extends
Stub
_EuroStub.java
implements
Interface
2
extends
Skeleton
_EuroPOA.java
implements
Operations
extends
Servant
EuroImpl.java
Euro.java
Compléments CORBA
EuroOperations.java
© 2005-06 Th. Desprats
4
1
Approche statique par délégation (3/7)
Approche statique par délégation (4/7)
† Approche par délégation
† Illustration du mode par délégation :
„
Principe :
†
La classe d’implantation va concerner non plus l’interface IDL
de l’objet, mais l’interface d’opérations de l’objet
org.omg.Portable.ObjectImpl
public class EuroImpl implements EuroOperations {
†
†
„
Utilisation de la classe de délégation « tie » générée lors de la
compilation IDL de l’interface Toto vers Java :
TotoTie.java
Il s’agit d’une implantation par défaut de l’interface à laquelle
elle est associée qui va déléguer le travail des opérations et
attributs vers une classe d’implantation quelconque
Impacts sur le développement :
Côté client : aucune modification
†
Côté serveur : associer une instance de la classe de délégation
à une instance d’une classe implémentant l’interface
d’opérations requise
EuroPOA.java
extends
_EuroStub.java
Interface
© 2005-06 Th. Desprats
5
EuroPOATie.java
implements
délégation
Operations
EuroImpl.java
Euro.java
Compléments CORBA
extends
Stub
implements
†
org.omg.Portable.Servant
extends
EuroOperations.java
Compléments CORBA
© 2005-06 Th. Desprats
Approche statique par délégation (5/7)
Approche statique par délégation (6/7)
† Extrait de EuroPOATie.java
† Ecriture du serveur ServeurConvertisseur.java :
package Convertisseur;
…
public class EuroPOATie extends EuroPOA
{
private EuroOperations _tie;
private org.omg.PortableServer.POA _poa;
„ 3/ Incarnation de l’objet
// Création d’une instance de la classe d’implémentation
EuroImpl monEuro = new EuroImpl();
public EuroPOATie(EuroOperations tieObject)
{ _tie = tieObject;
}
public EuroPOATie(EuroOperations tieObject, org.omg.PortableServer.POA poa)
{ _tie = tieObject; _poa = poa;
}
public EuroOperations _delegate() {
return _tie;
public void _delegate(EuroOperations delegate_) {
}
_tie = delegate_;
public org.omg.PortableServer.POA _default_POA()
{
if (_poa != null) return _poa; else return super._default_POA();
public double taux()
{ return _tie.taux();
public void taux(double value)
…
Compléments CORBA
6
}
// Association
EuroPOATie monEurotie = new EuroPOATie(moneuro);
// Fabrication d’un Identifiant(OID) pour attribution par le POA
byte[] monEuroId = args[0].getBytes();
// Activer le servant dans le POA et lui attribuer l'ID
poa.activate_object_with_id(monEuroId, monEurotie);
}
// le POA dispose désormais de la référence
}
{ _tie.taux(value); }
© 2005-06 Th. Desprats
7
Compléments CORBA
© 2005-06 Th. Desprats
8
2
Approche statique par délégation (7/7)
Type générique, Meta-type (1/17)
† Illustration d’implantation unique
† Définition
† Contrat idl :
† Type IDL
module Exemple {
† Type générique capable de contenir une valeur de
n’importe quelle autre type CORBA (standard ou
utilisateur).
interface A { void f(); };
interface B(:A) { void g(); };
};
† Utilisation
† Classe d’implantation unique :
Public class AetBImpl implements [AOperations], BOperations {
† Comme type de paramètre, de retour d’opération,
ou comme type de base d’un type construit
public void f() { System.out.println(“il pleut“); };
public void g() { System.out.println(“il neige“); };
(exemple : type d’un membre d’une structure)
};
† Projection en JAVA
† Serveur :
…
† Classes :
org.omg.CORBA.Any
org.omg.CORBA.AnyHolder
AetBImpl toto new AetBImpl;
ATie a_tie = new ATie(toto);
BTie b_tie = new BTie(toto);
…
Compléments CORBA
any
© 2005-06 Th. Desprats
9
Compléments CORBA
© 2005-06 Th. Desprats
Type générique, Meta-type (2/17)
Type générique, Meta-type (3/17)
† Création d’une variable any en Java :
† Illustration en Java :
org.omg.CORBA.Any a = orb.create_any();
org.omg.CORBA.Any b = orb.create_any();
org.omg.CORBA.Any c = orb.create_any();
† Méthode de org.omg.CORBA.orb :
create_any()
† Exemple :
// Affectation d’un chaîne
a.insert_string(“Il fait beau“);
// Création d’un Any : a ne contient aucune valeur
org.omg.CORBA.Any a = orb.create_any();
// Affectation d’un entier
b.insert_long(64);
† Insertion/Extraction de valeur :
// Affectation d’une structure
individu i = new individu();
i.nom = “Desprats”;
i.prenom = “Thierry”;
i.adresse = “Rue Corba”;
individuHelper.insert(c,i);
† Valeur d’un type primitif toto :
„ Insertion : insert_toto(valeur)
„ Extraction : extract_toto()
† Valeur d’un type construit toto :
// Récupération des valeurs
String s = extract_string(a);
long t = extract_long(b);
individu j = individuHelper.extract(c);
„ Insertion : totoHelper.insert(any, valeur)
„ Extraction : totoHelper.extract(any)
Compléments CORBA
10
© 2005-06 Th. Desprats
11
Compléments CORBA
© 2005-06 Th. Desprats
12
3
Type générique, Meta-type (4/17)
Type générique, Meta-type (5/17)
† Le Meta-type TypeCode :
† Le type énuméré TCKind :
„ Type IDL TypeCode
„ Type IDL TCKind
„ En Java : org.omg.CORBA.TypeCode
„ Objectif : donner les moyens de description
de tout type CORBA :
„ En Java : org.omg.CORBA.TCKind
„ Objectif : énumérer les genres de types
CORBA :
= = > tout type IDL (standards et utilisateurs) est
associé à un TypeCode
„ La nature des informations d’un TypeCode
dépend du type qu’il décrit :
= = > Les types sont classés par « genres » appelés
TCKind
Compléments CORBA
© 2005-06 Th. Desprats
13
// Définition du type TCKind
Enum TCKind {
tk_null, tk_void, tk_short, tk_long, tk_ushort, tk_ulong,
tk_float, tk_double, tk_boolean, tk_char, tk_octet, tk_any,
tk_TypeCode, tk_Principal, tk_objref, tk_struct, tk_union,
tk_enum, tk_string, tk_sequence, tk_array, tk_alias,
tk_except, tk_longlong, tk_fixed, tk_value, tk_value_box
tk_native, tk_abstract_interface
};
Compléments CORBA
© 2005-06 Th. Desprats
Type générique, Meta-type (6/17)
Type générique, Meta-type (7/17)
† Obtention d’un TypeCode :
† Utilisation d’un TypeCode (1/3):
Méthodes de org.omg.CORBA.TypeCode :
„ Pour un type primitif toto :
„ Connaître le genre d’un type :
† Méthode de org.omg.CORBA.orb :
get_primitive_tc(tcKind du type toto)
†
kind() retourne un TCKind
„ Connaître le nom d’un type non primitif :
†
† Exemple :
// Récupération du type code associé à long
org.omg.CORBA.TypeCode tc = orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_long);
name() retourne un string
„ Connaître le « Repository ID » d’un type non primitif :
†
id() retourne un identifiant de la forme :
[ IDL:] [préfixe] [chemin] [version]
exemple :
„ Pour un type construit toto :
module Exemple {
struct individu {string nom; string prenom; string adresse;};
interface A { void f();};
};
† Méthode de totoHelper :
type()
† Exemple :
On obtient les repository IDs suivants :
pour le module Exemple :
pour l’interface A :
pour le type individu :
// Récupération du type code associé à la structure Individu
org.omg.CORBA.TypeCode tc = individuHelper.type();
Compléments CORBA
14
© 2005-06 Th. Desprats
15
Compléments CORBA
IDL:Exemple:1.0
IDL:Exemple/A:1.0
IDL:Exemple/individu/:1.0
© 2005-06 Th. Desprats
16
4
Type générique, Meta-type (8/17)
Type générique, Meta-type (9/17)
† Utilisation d’un TypeCode (2/3):
† Utilisation d’un TypeCode (3/3):
„ Connaître le type de référence d’un alias :
„ Connaître les membres d’un type composé :
(structures, unions, énumérations, exceptions, value types)
†
†
†
member_count() retourne le nombre de membres présents dans le type
member_name() retourne le nom du type dont l’index est précisé
member_type() retourne le type code du membre dont l’index est précisé
„ Exemple : à partir de cette description :
† Content_type() retourne un TypeCode
„ Connaître le type de référence d’un tableau :
† Content_type() retourne un TypeCode
„ Connaître la taille d’un tableau :
† length() retourne la taille
struct individu {string nom; string prenom; string adresse;};
qu’afficherait à l’écran le code suivant ?
org.omg.CORBA.TypeCode tc = individuHelper.type();
if (tc.kind().value() = = org.omg.CORBA.TCKind._tk_struct)
{ System.out.println(“Nom de la structure: “+tc.name());
System.out.println(“ID de la structure: “+tc.id());
System.out.println(“Nombre de membres : “+tc.member_count());
for( int i=0; i<tc.member_count(); i++)
{ System.out.println(“Nom du membre : “+tc.member_name(i));
System.out.println(“Type du membre : “+tc.member_type(i));
}}
Compléments CORBA
© 2005-06 Th. Desprats
17
„ Comparer des TypeCodes :
† equal() retourne un booléen (égalité stricte)
† equivalent() retourne un booléen (égalité indirecte)
„ Connaître le type d’une valeur Any :
† type() retourne le TypeCode de la valeur contenue dans un any
Compléments CORBA
© 2005-06 Th. Desprats
Type générique, Meta-type (10/17)
Type générique, Meta-type (11/17)
† Exemple:
† Exemple
„ Interface polymorphe :
typedef sequence <long> longSeq
struct individu {string nom; string prenom; string adresse;};
exception TypeInconnu { };
interface Polymorphe { void pass(in any valeur) raises TypeInconnu); };
„ Servant Java :
public class PolymorpheImpl extends PolymorphePOA
{ public void pass(org.omg.CORBA.Any val) throws TypeInconnu
{ org.omg.CORBA.TypeCode tc = valeur.type();
switch (getEquivalentKind(tc))
{ case org.omg.CORBA.TCKind_tk_long :
int l = valeur.extract_long();
System.out.println(“recu un entier de valeur: “+l);
break;
case org.omg.CORBA.TCKind_tk_string :
String s = valeur.extract_string();
System.out.println(“recu une string de valeur: “+s);
break;
Compléments CORBA
© 2005-06 Th. Desprats
19
:
18
Servant Java
case org.omg.CORBA.TCKind_tk_string :
String s = valeur.extract_string();
System.out.println(“recu une string de valeur: “+s);
break;
case org.omg.CORBA.TCKind_tk_struct :
if (tc.equal(individuHelper.type()))
{ individu i = individuHelper.extract(valeur);
System.out.println(“recu un individu : “+i.nom+” “
+i.prenom”+” “+i.adresse); }
else throw new TypeInconnu();
break;
case org.omg.CORBA.TCKind_tk_sequence :
if (tc.equal(longSeqHelper.type()))
{ int [] seq = longSeqHelper.extract(valeur);
System.out.println(“recu une sequence d’entiers :”);
for (int = i; i<seq.length; i++)
System.out.println(“Elt n° “+i+“:”+seq[i]); }
else throw new TypeInconnu();
break;
default
throw new TypeInconnu(); } }
Compléments CORBA
© 2005-06 Th. Desprats
20
5
Type générique, Meta-type (12/17)
Type générique, Meta-type (13/17)
† Exemple :
† Exemple : Client
„ Servant Java
Private int getEquivalentKind(org.omg.CORBA.TypeCode tc)
{ switch (tc.kind().value()
{ case org.omg.CORBA.TCKind_tk_alias :
try
{ return tc.content_type().kind().value(); }
catch (org.omg.CORBA.TypeCodePackage.BadKind ex) { }
return org.omg.CORBA.TCKind._tk_null;
default :
return tc.kind().value();
}
}
}
„ Serveur : classique
...
PolymorpheImpl poly = new PolymorpheImpl();
...
Compléments CORBA
© 2005-06 Th. Desprats
21
...
try {
Polymorphe poly = //IOR récupéré aupès du NS
org.omg.CORBA.Any a = orb.create_any();
a.insert_long(1515);
poly.pass(a);
a.insert_string(“Marignan”);
poly.pass(a);
individu i = new individu (“Francois”, “Premier”, “Chambord”);
individuHelper.insert(a,i);
poly.pass(a);
int[] seq = new int[8];
for(int i = 0; i<seq.length; i++) seq[i] = i;
longSeqHelper.insert(a,seq);
poly.pass(a);
a.insert_float((float)3.14);
poly.pass(a);
}
catch (TypeInconnu ex)
{ System.out.println(“serveur a recu type inconnu :”); }
...
Compléments CORBA
© 2005-06 Th. Desprats
Type générique, Meta-type (14/17)
Type générique, Meta-type (15/17)
† Création de Type codes (1/3)
† Création de Type codes (2/3)
„ Intérêt : dans un mode d’invocation dynamique on ne
dispose pas des classes Helper !
(pas de génération IDL vers Java)
= = > être capable de créer ses propres type codes qui
sont indispensables à l’emploi du type Any requis dans
les mécanismes dynamiques
„ Classe Orb.omg.CORBA.Orb fournit des opérations pour
chaque type descriptible en IDL
Les autres types :
†
†
†
†
†
†
†
†
„ Types primitifs :
† Inutile d’en créer un (ils l’ont déjà)
† Récupération par : get_primitive_tc(in TcKind kind)
Compléments CORBA
„
© 2005-06 Th. Desprats
23
22
†
†
create_string_tc(in unsigned long bound)
create_wstring_tc(in unsigned long bound)
create_enum_tc(in RepositoryID id, in Identifier Name,
in EnumMemberSeq members)
create_struct_tc(in RepositoryID id, in Identifier Name,
in StructMemberSeq members)
create_exception_tc(in RepositoryID id, in Identifier
Name, in StructMemberSeq members)
create_interface_tc(in RepositoryID id, in Identifier
Name)
create_sequence_tc(in unsigned long bound, in TypeCode
element_type)
create_array_tc(in unsigned long bound, in TypeCode
element_type)
create_alias_tc(in RepositoryID id, in Identifier Name,
in TypeCode original_type)
…
Compléments CORBA
© 2005-06 Th. Desprats
24
6
Type générique, Meta-type (16/17)
Type générique, Meta-type (17/17)
† Création de Type codes (3/3)
† Gestion dynamique de valeurs Any
„ Exemple :
struct individu {string nom; string prenom; string adresse;};
Code construisant le Type code correspondant :
org.omg.CORBA.StructMember [] members = new org.omg.CORBA.StructMember[3];
members[0] = new org.omg.CORBA.StructMember();
members[0].name = “nom“;
members[0].type = orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_string);
members[1] = new org.omg.CORBA.StructMember();
members[1].name = “prenom“;
members[1].type = orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_string);
members[2] = new org.omg.CORBA.StructMember();
members[2].name = “adresse“;
members[2].type = orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_string);
Org.omg.CORBA.TypeCode tc =
orb.create_struct_tc(“IDL:Exemple/individu:1.0”,”individu”, members);
Compléments CORBA
© 2005-06 Th. Desprats
25
„ Problème : extraction et insertion de valeurs Any pour
les types non primitifs lorsqu’on ne dispose pas des
Helper (contexte dynamique)
„ Solution : mécanisme de gestion dynamique de ces
valeurs
„ Interfaces héritant de DynAny :
DynEnum, DynStruct, DynUnion, DynSequence, DynArray, DunValue
„ Classes org.omg.DynamicAny
„ Permettent de créer une valeur correspondant à un type
de données puis générer un Any qui contiendra cette
valeur et inversément ce qui permettra de manipuler
une valeur contenue dans un Any.
Compléments CORBA
© 2005-06 Th. Desprats
Invocation dynamique (1/7)
Invocation dynamique (2/7)
† Référentiel d’interfaces (1/3)
† Référentiel d’interfaces (2/3)
„
Objectifs de l’IR :
†
†
†
„
„
Les relations entre interfaces de l’IR :
„
„
„
Opérations pour chaque interface
Recherche, création
Récupération de descriptions, de Repository ID, de type
code (sous forme canonique ou non)
26
répertorier les descriptions IDL des objets CORBA
fournir un ensemble d’interfaces pour obtenir des informations
sur la description d’un type
Accès par la référence initiale InterfaceRepository
Organisation :
†
chaque type IDL est associé à une interface du référentiel
Compléments CORBA
© 2005-06 Th. Desprats
27
Compléments CORBA
© 2005-06 Th. Desprats
28
7
Invocation dynamique (3/7)
Invocation dynamique (4/7)
† Référentiel d’interfaces (3/3)
„
† Création dynamique de requête
Exemple de l’interface OperationDef :
„
„
Interface DII (Dynamic Invocation Interface)
Classe org.omg.CORBA.Object propose plusieurs méthodes
pour créer des requêtes vers l’objet qu’elle référence
Deux méthodes :
enum OperationMode {OP_NORMAL, OP_ONEWAY };
enum ParameterMode {PARAM_IN, PARAM-OUT, PARAM_INOUT };
struct ParameterDescription { Identifier name; TypeCode type;
IDLType type_def; ParameterMode mode; };
typedef sequence<ParameterDescription> ParDescriptionSeq;
typedef Identifier ContextIdentifier;
typedef sequence<ContextIdentifier> ContextIdSeq;
typedef sequence<ExceptionDef> ExceptionDefSeq;
typedef sequence<ExceptionDescription> ExcDescriptionSeq;
struct OperationDescription {
Identifier name;
RepositoryID id;
…
TypeCode result;
OperationMode mode
ContextIdSeq contexts;
PardescriptionSeq parameters;
ExcDescriptionSeq exceptions; };
interface Operationdef : Contained {
…
readonly attribute TypeCode result;
attribute ParDescriptionSeq params;
attribute OperationMode mode;
OperationDescription describe();
…
Compléments CORBA
© 2005-06 Th. Desprats
29
Compléments CORBA
Invocation dynamique (5/7)
Invocation dynamique (6/7)
invoke appel bloquant
send_oneway appel asynchrone (oneway)
send_deferred appel non bloquant
poll_response teste la présence de la réponse
get_response récupère la réponse
„ Méthodes de la classe org.omg.CORBA.ORB
† send_multiple_request_oneway(Request[]) envoi +sieurs
requêtes oneway
† send_multiple_request_deferred envoi non bloquant
† poll_next_response teste la présence d’une réponse
† get_next_response récupère une réponse
© 2005-06 Th. Desprats
†
Créer une requête simple précisant uniquement le nom de
l’opération à invoquer puis opérations pour rajouter
successivement paramètres, retour, exception, contexte…
Créer en un seul appel une requête complète :
„
Méthode à deux formes :
orb.omg.CORBA.Request _create_request (
org.omg.CORBA.Context ctx,
String operation,
org.omg.CORBA.NVList arg_list,
org.omg.CORBA.NamedValue result,
[
org.omg.CORBA.ExceptionList exlist,
org.omg.CORBA.ContextList ctxlist,
]
);
© 2005-06 Th. Desprats
30
org.omg.CORBA.Object obj = // récupération de l’IOR de l’Objet cible
„ Sémantiques d’invocation possibles :
„ Méthodes de la classe org.omg.CORBA.Request
Compléments CORBA
†
† Exemple :
† Invocation dynamique de requête
†
†
†
†
†
„
31
// préparation des paramètres
org.omg.CORBA.NVList param_list = orb.create_list(0);
org.omg.CORBA.Any param1 = orb_create_any();
org.omg.CORBA.Any param2 = orb_create_any();
param_list.add_value(“”, param1, org.omg.CORBA.ARG_IN.value);
param_list.add_value(“”, param2, org.omg.CORBA.ARG_IN.value);
param1.insert_float((float) 3.14);
param2.insert_float(5);
// préparation du type de retour
org.omg.CORBA.Any ret_value = orb_create_any();
org.omg.CORBA.NamedValue retour = orb.create_named_value(“”, ret_value,0);
ret_value.type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_float));
// puis de la liste des exceptions
org.omg.CORBA.StructMember [] members = new org.omg.CORBA.StructMember[0];
org.omg.CORBA.TypeCode tc_exception =
orb.create_exception_tc(“IDL:ObjectCible/DivisionParZero:1.0”,
“DivisionParZero“, members);
org.omg.CORBA.ExceptionList exceptions = orb.create_exception_list();
Compléments CORBA
© 2005-06 Th. Desprats
32
8
Invocation dynamique (7/7)
† Exemple :
// et enfin du contexte
org.omg.CORBA.ContextList cl = orb_create_context_list();
org.omg.CORBA.Context c = orb.get_default_context();
// Création de la requête à partir des préparations précédentes
Org.omg.CORBA.Request req =
obj._create_request(c,”division”,param_list,retour,exceptions,cl);
//Invocation de l’opération
req.invoke();
// Récupération éventuelle d’une exception
java.lang.Exception exception = req.env().exception();
if (exception != null)
{ if exception instanceof org.omg.CORBA.UnknownUserException)
System.out.println(”une Division par zero s’est produite”);
else
throw (org.omg.CORBA.SystemException) except; }
// sinon on extrait le résultat
float res= ret_value.extract_float();
System.out.println(“Resultat de la division :”+res);
Compléments CORBA
© 2005-06 Th. Desprats
33
9
Téléchargement