MokaByte Numero 31  - Giugno 1999
La programmazione
di Lotus Domino in Java
di 
Giovanni Puliti
Grazie al supporto per Java, il famoso server per il workgroup di Lotus, rende possibile non solo la  personalizzazione, ma anche l’interfacciamento con il mondo esterno
In collaborazione con Computer Programming

Forse non molto conosciuti dal grande pubblico, i prodotti Lotus Notes e Lotus Domino sono in campo aziendale fra i più diffusi ed apprezzati prodotti di workgroup: grazie all’esperienza maturata dalla casa produttrice in anni di lavoro nel settore della condivisione delle risorse e gestione della sicurezza, sono infatti utilizzati da un numero sempre maggiore di aziende per la gestione del lavoro quotidiano e per lo scambio e condivisione di informazioni.Lotus Domino è un server al quale i vari client (Lotus Notes) si interfacciano per lo svolgimento di tutta una serie di funzionalità: dallo scambio di documenti alla condivisione di rubriche comuni; dalla gestione della posta elettronica al controllo e sincronizzazione di database distribuiti. Infine anche nel settore dalla produzione di web interattivo (in questo caso il client può essere qualsiasi browser, fra cui anche Notes) offrono interessanti funzionalità.Tutto il sistema, sia il client che il server, è stato progettato per offrire la massima personalizzabilità e programmabilità, grazie al supporto offerto da LotusScript, e di recente utilizzando un linguaggio di programmazione ad oggetti vero e proprio come Java.In questo articolo vedremo come sia possibile creare programmi che si interfaccino con Notes/Domino sia per la personalizzazione delle funzioni, sia per il collegamento con il mondo esterno. Per un corretto funzionamento delle tecniche che vedremo e degli esempi allegati, si faccia riferimento alla versione 4.6 di Domino.
Non entreremo nel dettaglio del funzionamento di Domino e di Notes, trattazione che esula dagli scopi di questo articolo, rimandando per maggiori approfondimenti alla bibliografia ed ai vari articoli pubblicati su questa rivista e sulle altre di Infomedia.
 
 
 

Cosa è Domino

Si è detto che Domino è un server dedicato alla condivisione di risorse: la principale peculiarità e punto di forza del prodotto, è l’utilizzo del formato database per la raccolta di ogni genere di dati. 
Tutto può essere inglobato in un db di tipo nsf: documenti multimediali, applicazioni, ma anche semplicemente mail, messaggi, file di testo o altro. 
Tutto quello che si desidera inserire nel sistema di gestione condiviso, viene gestito tramite database. Anche i file di configurazione del sistema, quelli di impostazione dei profili utente e gli archivi di posta sono database. Con i debiti adattamenti, questo tipo di concezione la ritroviamo in (o deriva da) Unix dove tutte le risorse di sistema vengono viste come file.
Ogni db inoltre è personalizzabile per mezzo di Lotus Script o Java in modo da creare delle vere e proprie applicazioni.
Questa caratteristica, che all’inizio porta un po’ di confusione nell’utente/programmatore alle prime armi, ha il grosso vantaggio di uniformare la metodologia di gestione delle varie risorse. 
Tenendo presente che, in maniera quasi automatica, un database può essere pubblicato su internet senza sforzi aggiuntivi, si comprende la potenza del sistema: un archivio di prodotti ad esempio, può essere trasformato in pagine html (è il server stesso che se ne preoccupa in maniera dinamica), con la possibilità di eseguire ricerche e aggiornamenti in tempo reale (modificato il database con il client Notes, la parte web delle pagine html resta sempre aggiornata) oppure sincronizzazione con altri database (l’altra grossa potenza del sistema).
La pubblicazione dinamica su web è un meccanismo molto simile a quello che da poco è stato introdotto con le pagine ASP o ancora più recentemente con JSP: in questo caso pero’ la parte di interfacciamento web si integra con un back-end aziendale altamente sofisticato, con un livello di sicurezza molto elevato.
Possiamo dunque affermare in maniera forse un po’ sintetica, ma sicuramente efficace, che in Domino tutto è un database, e tutte le operazioni di gestione possono essere eseguite semplicemente modificando tali oggetti: per quello che vedremo in seguito, questo punto è molto importante. 
Prima di procedere occorre fare una precisazione sulla natura del dualismo Notes Domino: il primo è il client e può essere utilizzato anche in stand alone (senza appoggiarsi ad un server Domino) per gestire i db nsf, o leggere la posta collegandosi con un server POP3 o SMNTP.Domino invece è un server che offre una serie di servizi orientati alla gestione del lavoro di gruppo: gestione posta elettronica, sincronizzazione database fra i vari client, server http, oltre ad altre funzionalità avanzate.
Vedremo che è possibile scrivere programmi che si interfaccino con i vari database nsf ed su tali archivi eseguano certe operazioni. A volte questo significa l’interazione con il client (ad esempio se vogliamo scrivere un agente), a volte con il server (nel caso dei servlet o di applicazioni esterne che debbano manipolare un determinato db). Molto brevemente possiamo dire che, dal punto di vista del motore di gestione dei dati e dei vari servizi, i due prodotti sono praticamente integrati l’uno nell’altro, e che per gli scopi del nostro articolo possono essere pensati come una cosa sola. 
 
 
 

L’interfacciamento con il mondo esterno 

Esistono varie tipologie di programmi Java per la gestione ed interazione con Domino/Notes. La prima distinzione a cui si può pensare è legata all’ambiente di esecuzione della applicazione stessa: possiamo infatti avere applicazioni esterne che per mezzo di una particolare interfaccia si colleghino con Domino, oppure applicazioni che risiedano dentro il sistema e che vengano eseguite dal sistema stesso.In entrambi i casi si devono utilizzare le Java Notes Object Interface (NOI) API, un set di classi Java create da Lotus proprio per tale scopo. La strada più semplice per "entrare" in Domino dall’esterno, è creare una applicazione Java che utilizzi tali packages: in tal modo è possibile aprire i vari database, ed effettuare le classiche operazioni di lettura, scrittura, modifica. Per quello che si è detto poco sopra, questo tipo di operazione può significare sia la gestione di dati, ma anche del sistema stesso.Una applicazione interna invece si distingue per il fatto che viene eseguita dal sistema (dato che si utilizza Java l’agente viene gestito dalla JVM del server). Anche in questo caso abbiamo due tipologie di programmi: gli agenti, che agiscono direttamente nell’ambito di un database e qui spendono il loro ciclo di vita, oppure i servlet. 
In questo caso un servlet Domino è a tutti gli effetti un servlet standard derivante dalla HttpServlet del JDK 1.2 ed in esecuzione all’interno della JVM del web server di Domino.
La differenza fondamentale fra un servlet ed un agente è che quest’ultimo è un qualcosa che non può esser pensato al di fuori del database sul quale viene fatto lavorare: ad esempio possiamo pensare a un agente che esegua (ad intervalli regolari o su comando) operazioni di pulizia ed riordino del database stesso. 
Un servlet invece viene eseguito tutte le volte che se ne richiede l’esecuzione secondo il classico schema di esecuzione init()+doGet()/doPost(). 
Un servlet tipicamente viene utilizzato per estendere le funzionalità del web server andando a prelevare informazioni nei vari file nsf (i database di Domino).
 
 
 

Perché Java

Anche se ormai Java ha assunto una popolarità enorme, verrebbe da chiedersi come mai prodotti come Domino e Notes si appoggino così fortemente Java per la gestione e comunicazione verso l’esterno. 
La riposta viene direttamente analizzando le principali caratteristiche del linguaggio. La portabilità di Java infatti si sposa perfettamente con la politica di IBM (la casa madre di Lotus) che fa della copertura globale delle varie piattaforme, uno dei sui punti di forza.
Dato infatti che sono disponibili versioni del prodotto per i più importanti sistemi operativi disponibili sul mercato, è possibile sia portare i database da una piattaforma ad una altra, sia, grazie alla portabilità di Java, i programmi (agenti, applicazioni, servlet).
La sicurezza che Java offre invece diviene quasi indispensabile se si pensa a come IBM si sia impegnata in tal senso.
La facilità poi con cui in Java sia possibile interfacciarsi con il mondo delle reti, risulta essere un punto a favore per l’impiego in un prodotto fortemente orientato al lavoro di gruppo network-based. 
Il fatto infine che Java sia un linguaggio conosciuto da molti, permette una facile integrazione di coloro, che inizialmente possono avere una ridotta conoscenza del sistema, ma hanno una buona familiarità con Java.
Si deve comunque dire che sebbene Java rappresenti la strada più semplice per la programmazione in Domino, esiste l’alternativa del LotusScript (che pero’ offre poche possibilità in confronto a Java), oltre alla possibilità di interfacciarsi, tramite CORBA, ad un mondo composto da un numero praticamente infinito di opzioni e possibili alternative. 
Java è solo una delle strade possibili, forse la più semplice ed immediata, ma non l’unica. 
 
 
 

Installazione

Indipendentemente dal tipo di programma che si desidera realizzare (agente, applicazione o servlet), per poter accedere ai database di Notes è necessario installare le classi contenute nel package NOI. 
Come al solito non si tratta di una operazione complessa, dato che è sufficiente seguire la procedura standard: copiare in una directory nel file system il file Notes.jar (che contiene tutte le classi del package lotus.notes), e modificare il classpath in modo che la JVM possa trovare tale file.É anche necessario aggiungere al path di sistema la directory dove sono presenti tutti i vari programmi server e client: tipicamente collocati in xxx\xxx\notes.
Fatte queste poche operazioni, si può passare alla realizzazione vera e propria dei programmi. 
Vediamo quindi quali siano e cosa sia necessario fare per creare una delle tre tipologie di programmi: applicazioni esterne, agenti, servlet.
 
 
 
 

Applicazioni

La prima cosa di cui tener conto è che una qualsiasi applicazione deve estendere la class NotesThread (contenuta nel package lotus.notes) che estende a sua volta la Thread del JDK. 
Questo passaggio è necessario per poter utilizzare la particolare gestione multi-thread presente in Notes/Domino. 
Dal punto di vista implementativo, si possono seguire due strade: o specializzare la classe NotesThread (vedi esempio primaApplicazioneThread.java) oppure implementare l’interfaccia Runnable (primaApplicazioneRunnable.java). Nel primo caso l’esecuzione del programma avviene per mezzo del metodo NotesThread.runNotes, che viene invocato automaticamente all’invocazione del metodo start(), così come Thread.start() invoca Thread.run().
Nel secondo caso invece all’interno del main viene creato un NotesThread e mandato in esecuzione. In questo caso si dice che la classe Thread standard viene utilizzata come entry point per l’esecuzione del codice.
Non ci sono ulteriori particolarità di cui tener conto.
 
 
 

Agenti

Un agente è un particolare programma che "vive" dentro un database nsf: un agente può eseguire operazioni sul db automaticamente ad intervalli prestabiliti, o su comando.
Per realizzare un agente Notes in Java la cosa più importante da tener presente è la derivazione dalla classe AgentBase. 
AgentBase esegue alcune importanti operazioni, come le inizializzazioni di basso livello del motore di gestione dati o la creazione di una sessione (indispensabile per l’esecuzione dell’agente stesso). AgentBase si occupa anche di certi servizi minori, come ad esempio la creazione di un timerThread: in tal caso l’obiettivo è controllare che l’agente non prenda il sopravvento sul sistema ed in tal caso procedere ad uccidere l’agente stesso (il termine tecnico piuttosto pittoresco è "terminated with extreme prejudice").
Tutto il codice che dovrà essere eseguito dall’agente deve essere inserito nel metodo NotesMain, punto di inizio dell’agente stesso. Questo passo è fondamentale: AgentBase infatti estende NotesThread, che deve essere eseguito secondo la sua procedura personale, in modo che, tra le altre cose, venga utilizzato il metodo runNotes. 
Dato che ci deve essere l’assoluta certezza che il metodo AgentBase.runNotes() sia invocato dalla classe NotesThread, e non dalla classe in costruzione, esso è dichiarato final.
Nell’esempio primoAgente.java si può vedere nel dettaglio come realizzare l’agente: si noti che non viene specificato il nome del database, essendo quello in cui l’agente stesso viene eseguito (e ricavato con il metodo AgentContext).
 
 
 

Servlet

Infine la parte più semplice: diciamo che non ci sono particolari accorgimenti da tenere presente nella produzione di un servlet. 
In questo caso il servlet viene visto come una applicazione esterna al motore di gestione dei db; non vi è nessun riferimento in questo caso a NotesThread, essendo di fatto i servlet threadizzati e quindi tale gestione avviene in maniera del tutto trasparente.
Come si può osservare dall’esempio del file primoNotesServlet.java, il processo è molto semplice, e praticamente si segue la normale procedura utilizzata per la realizzazione di un servlet standard.
La procedura per attivare il supporto per i servlet ed installarne uno specifico è un po’ particolare, e per questo si veda il riquadro "I servlet in Domino".
 
 
 

Manipolazione di dati

Dopo aver visto i concetti di base che, seppur in forma molto sintetica, dovrebbero essere sufficienti per muovere i primi passi, resta da vedere come aprire un db e leggere/scrivere i dati al suo interno.
Moltissime sarebbero le cose da dire, soprattutto relativamente alla natura e strutturazione di un database Notes: non essendoci lo spazio per entrare nel dettaglio di questi aspetti, rimandiamo alla bibliografia in fondo all’articolo.
Molto sinteticamente ecco alcune nozioni di base: l’elemento base in un db nsf è il documento, che potrebbe essere assimilabile al concetto di record di un database relazionale (d’ora in poi RDB). Ogni documento poi è composto da item (le colonne in RDB).
Tutto l’insieme dei documenti viene collezionato in un form (tabella in RDB), e su ogni form è possibile creare delle viste (recordset in RDB) la cui funzione è quella di dare una visione particolare (sub set di documenti o merge particolari).
E’ questa sicuramente una semplificazione un po’ troppo rigida, dato che la potenza di un db nsf sta proprio nella flessibilità, ma per mancanza di spazio e necessità di sintesi possiamo assumere che sia sufficientemente corretta.
Le classi contenute nel package lotus.notes permettono la manipolazione di tutti gli elementi tipici di un file nsf (database, utenti, form, documenti collezioni di documenti, viste, item)
Ad esempio se si desidera aprire un database possiamo utilizzare le seguenti istruzioni
 
try{ 
NotesThread.sinitThread(); 
lotus.notes.Session s = Session.newInstance(); 
lotus.notes.Database db = s.getDatabase(null, "ArticoliJava"); 

catch (NotesException nte){}


Come si può notare, dopo aver creato una sessione (operazioni necessaria in Notes, e che equivale ad una specie di login), possiamo ottenere il database per mezzo del metodo session.getDataBase(). 
Come si può notare per fare riferimento al db basta indicarne il nome (niente estensione, sono tutti nsf), e non importa specificare la sua collocazione: secondo la convenzione (non obbligatoria) tipica di Notes, tutti i db sono collocati nella stessa directory di sistema e questo semplifica notevolmente le cose. 
Si pensi ad esempio, se si decidesse di portare la propria applicazione dalla piattaforma Windows NT ad un Unix, alla fatica risparmiata per non dover gestire le differenti convenzioni nei path per mezzo File.pathSeparatorChar.
Una volta ottenuto il database possiamo eseguire alcune semplici operazioni per ricavarne i valori. Ad esempio potremmo per prima cosa ottenere il nome delle colonne di una certa vista
 
 

lotus.View NotesView; 
NotesView = NotesDb.getView("Pubblicati"); 
Vector NotesViewColumns = NotesView.getColumns();
Nel vettore NotesViewColumns adesso sono contenute le varie colonne della vista Pubblicati. Possiamo eseguire una qualche ricerca ad esempio con il metodo FTSearch: questo esegue una ricerca testuale e di fatto modifica la vista lasciandoci dentro solo i documenti che soddisfano la ricerca (una specie di screening).
 
NotesView.FTSearch("FIELD Autore contains Puliti"); 
Document doc=NotesView.getFirstDocument();


Adesso con un semplice ciclo è possibile stampare tutti il valore di tutti i documenti rimasti nella lista
 

while (doc!=null){ 
String title=doc.getItemValueString("titolo"); 
doc=NotesView.getNextDocument(doc); 
}


Al solito tutte queste operazioni devono essere inserite in blocchi di protezione try-catch.Il metodo FTSearch, per quanto comodo, è pero’ piuttosto lento. In alternativa si può utilizzare il più veloce lotus.notes.View.getAllDocumentsByKey, come ad esempio
 

DocumentCollection dc=NotesView.getAllDocumentsByKey(key,false);


L’oggetto DocumentCollection restituito rappresenta una collezione di documenti non associati a nessuna vista, e per questo non gestibili per mezzo di una View.Se invece si desidera inserire dei dati nel db, possiamo scrivere 
 

lotus.notes.Document d= NotesDb.createDocument(); 
d.appendItemValue("titolo",title); 
d.appendItemValue("autore",auth); 
boolean ret=d.computeWithForm(true,true); 
d.save();


La prima riga serve per creare un documento nuovo e vuoto. Successivamente si inseriscono uno ad uno i vari item (le colonne del RDB). Infine molto importante l’esecuzione di Document.computeWithForm(): serve per processare il nuovo documento con la form in questione (quella attiva in quel momento nel db). Questo passaggio serve anche per eseguire determinati filtri o istruzioni associati alla form.
Se il processamento è valido il nuovo documento viene definitivamente inserito al suo posto (nella form), altrimenti resta sciolto e non associato a nessuna form.
 
 
 

Conclusione

Concludiamo questa breve panoramica introduttiva alla programmazione Java di Domino 4.6. Le cose da dire sarebbero ancora veramente molte, ma spero che quel poco che abbiamo visto in questo articolo sia sufficiente per avere un’idea delle possibilità offerte e per iniziare a fare un po’ di prove. 
Come si è potuto notare le operazioni in alcuni casi sono un po’ macchinose, e sicuramente meno agili e sintetiche delle equivalenti del linguaggio SQL che si usano in genere per mezzo di JDBC su un database relazionale.
E’ bene notare pero’ un aspetto molto importante: pur non essendo la struttura di un db di Notes ad oggetti, la sua organizzazione particolare si sposa piuttosto bene con tale filosofia di programmazione Per questo, dopo un po’ di fatica iniziale, si potrà notare come in realtà il modello organizzativo sia molto vicino a Java, quasi fosse stato pensato per questo linguaggio.
Sicuramente mi sento di consigliare a tutti coloro che utilizzano Notes/Domino da tempo, di iniziare a fare delle prove con le NOI per Java, ma anche a chi conosce bene Java di avvicinarsi a Domino per la porta di servizio, iniziando a fare delle prove di programmazione.
Per maggiori approfondimenti sui temi visti rimando alla lettura del forse unico testo disponibile attualmente [DomProg].
Per quanto riguarda invece la gestione di Notes e dei database, esistono molte pubblicazioni in merito, una delle quali potrebbe essere ad esempio [MastNotes]. Per quanto invece riguarda gli approfondimenti relativi ai servlet, esiste una bibliografia praticamente sterminata: mi limito a suggerire le varie pubblicazioni apparse su MokaByte [ServletIntro], [ServletWeb], [SerlvetStato].
 
 
 

Bibliografia 

  • [DomProg] "Programming Domino 4.6 with Java" di Bob Balaban Ed IDG, ISBN 1-5585-1583-6
  • [MastNotes] "Mastering Lotus Notes" 3rd, di K. Brown, F Koutchouk, S. Habernan Ed. Sybex
  • [ServletIntro] "Java Servlet" di Fabrizio Giudici - MokaByte 11, Sett ‘98 (www.mokabyte.it/1998/09
  • [ServletWeb] " Servlet, JDBC e JavaServer: quando l'unione fà la forza (e semplifica la vita)" di Giovanni Puliti MokaByte 20, Giu ‘98 (www.mokabyte.it/1998/06)
  • [SerlvetStato] " Gestire le sessioni con le servlet" di Gerardo Poggiali – MokaByte 26 Gen ‘99 (www.mokabyte.it/1999/01)
  • [JDK12] "Speciale JDK 1.2" - Dev 55 Settembre 98.

  
 

MokaByte rivista web su Java

MokaByte ricerca nuovi collaboratori
Chi volesse mettersi in contatto con noi può farlo scrivendo a mokainfo@mokabyte.it