E’ un’entità virtuale che può essere localizzata dall’ORB e ricevere richieste di servizio da un cliente.
La sua esistenza è strettamente legata all’oggetto servente (servant) che esso rappresenta.
Non può esistere da solo: al fine di servire le richieste di un cliente, ad esso deve essere associato un oggetto servente.
Stati di un oggetto CORBA
Stato Non Attivo: è lo stato iniziale, caratterizzato dall’assenza di un’associazione con un servant.
Stato Attivo: in tale stato all’oggetto è associato un servant. Pertanto esso è pronto per servire le richieste di servizio.
Classe Servente: è l’entità reale responsabile dell’implementazione delle operazioni descritte nell’interfaccia IDL.
Skeleton Interfaces: sono responsabili del “collegamento” delle istanze della classe servente con la piattaforma sottostante, affinché quest’ultima possa inoltrare correttamente le richieste.
Object Adapter: rappresenta l’intermediario tra l’ORB e lo skeleton. Esso svolge una duplice attività:
ORB: ha il compito di ricevere le richieste destinate ad un oggetto CORBA e di inoltrarle all’Object Adapter opportuno.
Nella tecnica per ereditarietà, la classe servente è realizzata come estensione dello skeleton InterfaceNamePOA.
La classe servente dovrà fornire l’implementazione di tutti i metodi astratti, ovvero di tutti i metodi dichiarati nell’interfaccia InterfaceNameOperations
(contenente tutti metodi definiti nell’interfaccia IDL).
La tecnica di realizzazione per delega è utile qualora l’oggetto servente sia derivato da altre classi specifiche dell’applicazione. In tali casi il suo utilizzo è obbligatorio se si adotta il linguaggio Java, non prevedendo, quest’ultimo, l’ereditarietà multipla.
Nella tecnica per delega, denominata tie approach, la classe servente è associata allo skeleton mediante una classe di intermediazione, denominata InterfaceNamePOATie
.
InterfaceNamePOATie
fornisce un’implementazione dei metodi definiti nell’interfaccia IDL come semplice delega dei metodi della classe servente associata (classe ServentePerDelega
).
E’ a cura del programmatore la predisposizione del meccanismo di delega tra la classe InterfaceNamePOATie
e la classe servente.
InterfaceNamePOAtie
, alla quale si fornisce il riferimento all’oggetto delegato.ServentePerDelega oggettoDelegato = new ServentePerDelega(..);
InterfaceNamePOATie servizioA_servant = new InterfaceNamePOATie(oggettoDelegato);
Operazione IDL con parametro formale di ingresso e di tipo semplice.
Operazione IDL con parametro formale di ingresso-uscita e di tipo definito dall’utente.
Operazione IDL con tipo di ritorno definito dall’utente.
Operazione IDL con eccezione definita dall’utente.
Operazione IDL con valore di ritorno di tipo any.
//IDL
interface ServizioA {
void operazione(in string);
};
Le classi generate dal compilatore necessarie per la realizzazione della classe servente consistono della sola classe ServizioAPOA
(classe skeleton).
//classe servente per il servizioA
public class servizioAImpl extends ServizioAPOA {
public void operazione(String parametro) {
//utilizzo del parametro ricevuto
...
}
}
interface ServizioC {
struct StrutturaEsempio{
string campo1;
float campo2;
};
void operazione(inout StrutturaEsempio st);
};
Le classi generate dal compilatore necessarie per la realizzazione della classe servente:
ServizioCPOA
;StrutturaEsempio
(classe rappresentazione della struct IDL);StrutturaEsempioHolder
(contenitore per la struct).Al fine di realizzare una sorta di scambio per riferimento, il programmatore dovrà utilizzare la classeStrutturaEsempioHolder
.
La classe Holder svolge la funzione di contenitore dell’oggetto parametro di scambio.
Le classi Holder per i tipi definiti dall’utente sono generate dal compilatore IDL
Tutte le classi Holder per i tipi primitivi IDL sono definite nel package org.omg.CORBA.
Mostra codice//IDL
interface ServizioD{
struct StrutturaEsempio{
string campo1;
float campo2;
};
StrutturaEsempio operazione();
};
Le classi generate dal compilatore necessarie per la realizzazione della classe servente:
ServizioDPOA
;StrutturaEsempio
(classe rappresentazione della struct IDL).Come si può osservare, la creazione di un'eccezione da inoltrare ad un'applicazione remota, è del tutto analoga al caso in cui si sollevi un'eccezione locale alla classe servente.
//IDL
module modulo{
valuetype OggettoPassatoPerValore{
string metodo();
public string attributo;
};
interface ServizioF {
OggettoPassatoPerValore operazione() ;
};
};
Le classi e le interfacce generate dal compilatore necessarie per la realizzazione della classe servente sono:
ServizioFPOA
;OggettoPassatoPerValore
(rappresentazione del valuetype).package modulo;
//Esempio di implementazione della classe OggettoImpl
public class OggettoImpl extends OggettoPassatoPerValore {
//costruttore
public OggettoImpl(String attributo) {
this.attributo=attributo;
}
public String metodo() {
//ad esempio...
return attributo; }
}
Il programmatore della classe servente dovrà, in questo caso, fornire anche un’implementazione della classe relativa al tipo restituito dal metodo operazione().
Tale classe, denominata OggettoImpl , sarà un’estensione della classe astrattaOggettoPassatoPerValore
, fornita dal compilatore IDL.
//IDL
interface ServizioG {
any operazione() ;
};
Per la realizzazione della classe servente è necessaria la sola classeServizioGPOA
.
La creazione di un’istanza di un tipo Any è affidata ad un oggetto di piattaforma, nella fattispecie all’oggetto org.omg.CORBA.ORB
.
La classe servente dovrà pertanto possedere un riferimento a tale oggetto, in genere fornito dall’applicazione servente attraverso il costruttore.
Mostra codiceLo skeleton costituisce una vista astratta dell’oggetto servente.
Esso è in grado di ricevere una richiesta di invocazione di un metodo per l’oggetto servente incapsulato e di estrarre dalla richiesta i parametri necessari per realizzare l’up-call sull’oggetto incapsulato,
La richiesta di esecuzione di un metodo su un oggetto remoto è contenuta in apposito oggetto di piattaforma, denominatoServerRequest
.
Gli skeleton possono essere quindi realizzati in due modi distinti:
DynamicImplementation
(skeleton dinamici);InvokeHandler
(skeleton statici).Negli skeleton dinamici
L’oggettoSeverRequest
contiene tutte le informazioni necessarie per effettuare l’upcall sull’oggetto servente, consistenti del nome del metodo e della lista dei parametri effettivi.
Grazie a tale oggetto la gestione di una richiesta può essere effettuata anche dinamicamente, cioè senza alcuna conoscenza della firma del metodo da invocare.
Gli skeleton dinamici espletano il loro compito utilizzando i meccanismi noti in letteratura come Dynamic Skeleton Interface.
Negli skeleton statici l’interazione con l’oggettoSeverRequest
avviene mediante tre parametri:
InputStream
, è un contenitore per i valori dei parametri effettivi;ResponseHandler
, è un supporto per la restituzione dei risultati.Occorre osservare che i tre parametri, forniti non permettono la gestione della richiesta in maniera dinamica.
E’ necessario, infatti, analizzare l’interfaccia IDL e pertanto tali parametri sono direttamente codificati, dal compilatore IDL, dentro lo stub statico.
E’ una classe che rappresenta un’astrazione di tutti gli oggetti serventi.
Un oggetto servente è anche istanza della classeServant
.
L’oggetto risultante dall’istanziazione di una classe servente è pertanto idoneo a:
2. La modellazione a oggetti e il linguaggio UML (richiami)
3. Generalità su Java e la programmazione ad oggetti
6. Regole di traduzione da UML a Java/C++
7. Programmazione multi-thread
8. Sincronizzazione tra thread
9. Programmazione client-server con socket TCP/IP (Java networkin...
10. Programmazione di applicazioni client-server: il Pattern Proxy...
12. Design Patterns
13. Pattern architetturali - Esempi
14. Design pattern creazionali. Esempi
15. Design pattern strutturali. Esempi
16. Introduzione alle tecnologie middleware
17. Modelli di middleware: RPC, MOM, TP, TS