Das Interface Repository ist ein Bestandteil des ORB und dient als Archiv für
IDL-Definitionen, ähnlich einer Datenbank. Sowohl das IR selbst, als auch die
in ihm enthaltenen Einträge werden dabei durch Corba-Objekte repräsentiert,
so daß die Abfrage des IR im Rahmen der üblichen verteilten Methodenaufrufe
geschieht.
Da das IR auf der Client-Seite den IDL-Stub hinsichtlich der vollständigen
Beschreibung der IDL-Definition ersetzen soll, muß es folglich alle
Informationen einer IDL-Datei bereitstellen. Damit bietet es sich an, den
Aufbau des IRs in Analogie zu einer solchen Datei zu wählen.
Betrachten wir also den Aufbau einer IDL-Datei an einem Beispiel:
//IDL
module DataObjectOperations
typedef long objectindex;
exception noPermissions{};
interface DataObject1Operations : BaseOperations
<Typ-Definitionen>
<Konstanten-Definitionen>
<Exception-Definitionen>
<Attribut-Definitionen>
[ <Resultattyp> ] <Operationsname> ( <Argumente> )
raises( noPermissions );
// ... weitere Operations-Definitionen
;
// ... weitere Interface-Definitionen
// ... weitere Modul-Definitionen
;
Es fällt dabei nun auf, daß wie in vielen anderen Programmiersprachen IDL-Definitionen in anderen Definitionen enthalten sein können. Setzt man diese 'Enthalten-sein-in'-Relation in ein Objektmodell um, so ergibt sich für die Anordnung der Einträge im IR ein hierarchischer Aufbau, in dem Objekte die Bezeichnungen Container und Contained besitzen können (s. Abb.4), für einige Objekte im IR gilt sogar beides: Eine Moduldefinition ModuleDef ist einerseits ein Container, da es z.B. Interface- und Type-Definitionen sowie weitere Modulbeschreibungen beinhalten kann, andererseits ist es selbst im Repository-Objekt oder einem anderen Modul enthalten.
Da das Interface Repository nun transparent in die Objektumgebung von Corba 2.0
eingebettet werden soll, müssen folglich das Repository-Objekt selbst
und die Eigenschaften der in ihm enthaltenen Einträge in IDL spezifiziert
werden. Dies geschieht in der vom Corba 2.0-Standard hergeleiteten Datei
CORBA2.0/ir.idl [Re96]. Die Tatsache, daß allein die IDL-Definitionen des IR von der OMG
standardisiert sind, erlaubt es dabei wiederum verschiedenen
Softwareherstellern, mit eigenen Implementationen des IRs in Konkurrenz
zueinander zu treten, ohne dem Standard dabei einen Abbruch zu tun. In der
Praxis sieht dies jedoch leider noch anders aus: Das IR des in den Beispiel-
Programmen benutzten Orbix-ORB verwendet eigene IDL-Definitionen, die in
einigen Punkten von der OMG-Spezifikation abweichen.
Wir wollen nun etwas konkreter auf die IDL-Struktur des Interface Repository
und seiner Objekte eingehen. Die oben angesprochene Enthalten-sein-Relation
wird durch Vererbung der Klassen Container und Contained
ausgezeichnet, die ihrerseits wieder das Basisinterface IRObject erben
(s. Abb.5).
Dabei stellt der Container z. B. Methoden zum Auffinden von enthaltenen Objekten sowie Listen über seinen Inhalt zur Verfügung, während die Contained-Schnittstelle eine einheitliche Beschreibung des gesuchten IR-Objektes bereitstellt. Die von diesen Basisschnittstellen abgeleiteten Definitionen sorgen nun für die spezifischen Beschreibungen der IR-Objekte. Betrachten wir z.B. die Corba-Spezifikation von InterfaceDef in ir.idl:
//IDL interface InterfaceDef : Container, Contained, IDLType { attribute InterfaceDefSeq base_interfaces; boolean is_a(in RepositoryId interface_id); struct FullInterfaceDescription { Identifier name; RepositoryId id; RepositoryId defined_in; VersionSpec version; OpDescriptionSeq operations; AttrDescription attributes; RepositoryIdSeq base_interfaces; TypeCode type; }; FullInterfaceDescription describe_interface(); ... }Trägt man durch Idl-Kompilieren unter Verwendung des Compilerflags -R ein Interface in das IR ein, so wird ein Objekt vom Typ InterfaceDef angelegt und in das Repository-Objekt gelegt. Nun lassen sich die Informationen dieses Eintrags auf zwei verschiedene Arten abfragen: Einerseits kann man durch Kommunikation mit dem Repository-Objekt über die Container-Methode lookup_name() eine Referenz auf den Eintrag erlangen, zum anderen kann man, wenn man bereits von der Serverseite ein Implementationsobjekt zu diesem Interface erhalten hat, in diesem Objekt die Methode _get_interface() aufrufen, welche ebenfalls den Eintrag liefert. Im ersten Fall könnte dies z.B. in Java für das interface testif konkret folgendermaßen aussehen[Io96]:
//Java import IE.Iona.Orbix2.*; import IE.Iona.Orbix2.CORBA.*; ... try { String id; // Repository-Referenz besorgen: _RepositoryRef rep = Repository._bind(":IR","deeppurple.uni-muenster.de"); // rep in _ContainerRef umwandeln, um auf dessen Methoden zugreifen zu // koennen: _ContainerRef container = Container._narrow(rep); // Interface-Definition fuer "testif" suchen und einer Variable vom Typ // ContainedRef zuweisen: _ContainedRef contd = container.lookup_name("testif",10,"all",true).buffer[0]; // contd in _InterfaceDefRef umwandeln: _InterfaceDefRef if = interfaceDef._narrow(contained); // Genaue Beschreibung des Interface extrahieren: FullInterfaceDescription fulld = if.describe_interface(); ... } catch (SystemException e){}Ein ähnliches Verfahren wird im Beispielprogramm Itool.java zum Durchsuchen des Interface Repository benutzt.