Manuale per la progettazione d'interfaccia Tivoli Service Desk 6.0 Developer's Toolkit
In questa sezione sono descritti i seguenti argomenti:
Prima che l'applicazione TSD Script possa interagire con l'host, è necessario che essa sia inizializzata. EHLLAPI utilizza un handle per riferirsi alla connessione che ha stabilito e dichiara una variabile di tipo EHLLAPI, come questa:
conn:EMUCONNECTION;
Successivamente, è necessario associare l'handle a una sessione di terminale specifica. Il comando EHLLAPI utilizzato per associare la sessione è:
EMUConnect(conn, 'A');
In questo comando, l'handle conn è associato alla sessione di terminale A.
Poiché tutti i comandi EHLLAPI richiedono che venga specificata una connessione, è necessario che un'applicazione interfaccia stabilisca queste connessioni.
EHLLAPI supporta più connessioni alle sessioni di terminale, così un'applicazione interfaccia appare come nel seguente esempio:
VARIABLES conn1:EMUCONNECTION; conn2:EMUCONNECTION; ACTIONS EMUConnect(conn1, 'A'); EMUConnect(conn2, 'B'); END;
TSD Script Interpreter associa diversi attributi a queste connessioni. Ad esempio, su una connessione il tempo limite del watch può essere impostato su un secondo mentre su un'altra può essere impostato su 10 secondi. TSD Script Interpreter raggiunge il tempo limite corretto dall'handle della connessione specificato al momento dell'emissione del comando watch.
Premendo un tasto si segnala all'host di eseguire un'operazione. Ad esempio, quando si modificano i dati, è possibile desiderare di eliminare il contenuto di un campo. Per eseguire ciò, premere il tasto comando denominato ERASE_EOF (elimina completamente il contenuto del campo).
Anche quando l'elaborazione richiesta dall'host è complessa, inoltrare i dati può essere semplice quanto premere INVIO.
EHLLAPI fornisce un comando per inviare i dati all'host tramite i tasti comandi. Il comando accetta codici a numeri interi che rappresentano i tasti di comando. TSD Script contiene anche costanti che servono da mnemonic per i numeri interi. Il codice per premere INVIO è:
EMUPressKey(conn, $EMUEnter);
Ogni volta che un'applicazione inoltra i dati all'host per l'elaborazione, deve attendere un periodo di tempo prima di ricevere una risposta dall'host. E' necessario che l'interfaccia sia in grado di interrompersi e attendere la fine di questo periodo. Questi periodi sono denominati watch.
Esistono diversi comandi TSD Script concepiti per fornire alle applicazioni la capacità di eseguire questi watch. Quando viene emesso uno di questi comandi, l'applicazione si interrompe fino a quando non viene soddisfatta la condizione o il limite di tempo del watch non scade. I codici di ritorno dei comandi watch indicano quali azioni sono state effettuate.
Le condizioni per cui è necessario che un'applicazione attenda, dipendono dalla situazione. Generalmente, un'applicazione attende la scomparsa dell'inibitore di immissione. Altri watch sono:
Ad esempio, se si desidera che un'applicazione attenda fino a quando non scompare l'inibitore di immissione, è possibile immettere il comando:
EMUWaitForNoX(conn);
Quando si utilizza il comando EMUWaitForNoX, prestare attenzione all'utilizzo dell'indicatore X da parte dell'applicazione della mainframe. Alcune applicazioni consentono alla X di "lampeggiare", ciò significa che la X scompare momentaneamente, poi ricompare per alcuni secondi.
Il comando EMUWaitForNoX dispone di un parametro facoltativo noto come durata intervallo. Durata intervallo specifica per quanto tempo visualizzare la X prima che TSD Script Interpreter ritenga che il watch sia stato completato con esito positivo. Nel caso in cui non viene specificata la durata intervallo, viene utilizzato un valore di default di 500 millisecondi.
Il precedente comando con una durata intervallo facoltativa di un secondo verrà visualizzato come segue:
EMUWaitForNoX(conn, 1000);
La chiave per la specifica di un comando watch consiste nell'impostare il comando watch in modo che fornisca all'utente più informazioni possibili. Ad esempio, supporre di utilizzare un'applicazione della mainframe che richiede un nome e un indirizzo e prevede che si prema il tasto INVIO per elaborare i dati.
Il comando watch sarà:
rc := EMUWaitForStringAt(conn, 'ADD OPERATION SUCCESSFUL',11,11);
Una volta premuto INVIO, nell'OIA viene visualizzata per un momento una X, poi un messaggio nella posizione 11,11 che conferma l'esito positivo dell'operazione di immissione, ad esempio:
MSG000695 ADD OPERATION SUCCESSFUL
Il codice di ritorno precedente indica che l'operazione è stata completata e l'inserimento ha avuto esito positivo. Se il codice di ritorno indica che il watch ha avuto esito negativo, è necessario controllare il codice per verificare se la mainframe è ancora in fase di elaborazione o se l'inserimento ha avuto esito negativo. Si tenga presente che questo ulteriore codice viene eseguito solo in condizioni di errore.
Se si utilizza:
rc :=EMUWaitForNoX(conn);
si sa solo che l'host ha terminato. Il codice deve ancora controllare il messaggio di riuscita ed è necessario eseguire il controllo per ogni istanza del comando.
Sebbene entrambi i segmenti di codice richiedono lo stesso numero di controlli, il primo metodo ottimizza l'elaborazione.
Non si verificano ulteriori controlli a meno che non esista un errore. Di conseguenza, le azioni a esito positivo (quelle che più spesso ci si aspetta) vengono eseguite più velocemente di quelle a esito negativo.
EHLLAPI fornisce numerose funzioni per immettere e modificare i dati. Queste comprendono comandi per:
In situazioni in cui gli utenti immettono una stringa nella posizione attuale del cursore host, il seguente esempio mostra un comando campione:
EMUTypeIn(conn, 'HELLO WORLD');
E' importante notare che non è possibile eseguire un comando TypeIn quando il cursore host si trova in un'area in cui l'host non consente le sequenze di tasti.
Una sequenza di comandi viene utilizzata così spesso che è stato implementato uno speciale comando TSD Script per sostituire la sequenza. Questo comando esegue ERASE_EOF prima di immettere la stringa fornita. Il comando viene visualizzato come nell'esempio:
EMUClrTypeIn(conn, 'HELLO WORLD');
Molte applicazioni consentono di spostarsi tra i campi su uno schermo o di utilizzare i tasti freccia. Generalmente, spostarsi tra i campi è più veloce a meno che non si stanno utilizzando tutti i campi. In questo caso, utilizzare un comando del cursore che consente di spostarsi direttamente tra i campi.
E' necessario rivisualizzare la lunghezza massima di ciascun campo. Se l'interfaccia EHLLAPI tenta di immettere quando il cursore si trova in una posizione non valida sullo schermo host, l'host blocca la tastiera fino a quando non viene premuto RIPRISTINA. Per evitare il problema, assicurarsi che i dati da immettere abbiano un'estensione inferiore al campo di ricezione o che sia stata fornita una lunghezza di troncamento per i comandi EMUTypeIn o EMUClrTypeIn.
Poiché molte applicazioni della mainframe sono applicazioni ad immissione dati, molti scritp EHLLAPI consistono in semplici operazioni ripetute:
Queste sequenze vengono utilizzate così spesso che le funzioni ad alto livello sono state implementate per compiere le operazioni ripetitive. Queste funzioni sono note come definizioni. Le definizioni o funzioni di definizione, consentono di mettere in relazione le posizioni dell'host con i campi del record TSD Script.
Un'applicazione può richiamare un comando TSD Script, EMUMapUpload, per riempire tutti i campi. TSD Script Interpreter elabora più velocemente le voci del file di definizione che la sequenza di comandi EHLLAPI più semplici. Sono state introdotte innovazioni relative ai file di definizione. Come regola generale, è necessario considerare un file di definizione se si dispone di più di cinque o sei campi su uno schermo. Per ulteriori informazioni, consultare "File di definizione e Programma di utilità di definizione."
L'utilizzo dei comandi di lettura è meno complesso di quello dei comandi di invio. Innanzitutto, la posizione del cursore host non è pertinente in un'operazione di lettura. Inoltre, un'applicazione può leggere i dati da un qualsiasi punto sullo schermo host.
In modo più semplice, un comando di lettura viene visualizzato come nel seguente esempio:
EMUFillBuffer(conn, inString, row, column, length);
Questo comando legge caratteri di lunghezza che iniziano una fila, una colonna e colloca il valore risultante nella variabile inString.
Se si pianifica di leggere campi di dati da uno schermo, è necessario conoscere la lunghezza massima di ciascun campo che si desidera leggere. Per visualizzare l'intera lunghezza dei campi, è necessario che l'applicazione host elimini completamente il contenuto dei campi di dati per prepararli ai nuovi dati. Generalmente, i campi vuoti vengono riempiti con sottolineature, ciò consente di visualizzare la lunghezza massima di ciascun campo.
Come per i comandi di invio, esiste un comando di definizione per scaricare uno schermo di dati.
EMUMapDownload consente di leggere molti campi da uno schermo host e di collocarne i valori nei campi di una variabile del record TSD Script.
Possono verificarsi situazioni per cui si desidera catturare un intero schermo host (o una parte rettangolare di esso) e memorizzarlo in un file di testo. Lo scenario più probabile è quando l'applicazione incontra uno schermo che non riconosce.
Per registrare quanti più avvenimenti è possibile, l'applicazione cattura lo schermo corrente in un file di testo e invia un messaggio di notifica che avverte del problema. Chi dovrà risolvere il problema, utilizzerà il file per risolvere il problema e assicurarsi che l'applicazione arrivi a quello schermo. TSD Script fornisce il comando EMUOutFile per tagliare lo schermo a un file.
Generalmente, si conosce ciò che si desidera che un'interfaccia effettui. Questa sezione è concepita per essere di ausilio per il miglioramento delle specifiche dell'interfaccia prima di cominciare a scriverla.
Il primo passo nella progettazione di un'interfaccia è di assicurarsi di conoscere l'applicazione per cui viene scritta l'interfaccia.
E' necessario gestire l'applicazione di destinazione fino a quando non si conosce esattamente come:
Inoltre, è necessario conoscere le "entrate e uscite" dell'applicazione.
Durante il lavoro, prendere nota dei passi necessari per compiere azioni specifiche. Questi passi potrebbero diventare il codice dell'interfaccia.
Ricercare i requisiti "nascosti". Analizzare i tipi di dati con cui l'applicazione deve lavorare. Nel caso di gestione di problemi/chiamate, è possibile trattare problemi aperti con la massima priorità, mentre i problemi chiusi possono avere una priorità "diversa".
Conoscere le regole di lavoro che la propria società (o reparto) utilizza, prima di codificare tali regole in un'interfaccia, è necessario determinare se queste regole sono ancora applicabili alla situazione attuale. Determinare e risolvere questi problemi prima di progettare l'interfaccia.
Assicurarsi di disporre di un metodo per identificare gli schermi utilizzati. Generalmente, le applicazioni della mainframe hanno un identificativo in qualche punto dello schermo. Il codice dell'interfaccia controllerà che è stato visualizzato lo schermo corretto (esso può richiamare una routine di errore o, altrimenti, uscire) prima di effettuare una immissione dati. Questo è un modo semplice ed efficace di fornire traccia dei problemi per il futuro.
La concorrenza è un'altra questione a cui prestare attenzione prima della scrittura di un'interfaccia. In qualsiasi situazione in cui si dispone di due sistemi che contengono gli "stessi" dati, esiste la possibilità di modificare lo stesso oggetto dati su entrambi i sistemi contemporaneamente.
Innanzitutto, decidere come l'applicazione rileva una tale eventualità. Il metodo più consueto è di controllare la data e l'ora di aggiornamento su un record che sta per essere sovrascritto.
Inoltre, determinare cosa è necessario che si verifichi al momento del rilevamento di una "collisione". Questa azione può essere semplice come la cattura del record di destinazione su un file flat e l'invio di un segnale sonoro all'amministratore. In relazione a ciò è possibile che venga applicata una regola di lavoro come quella che consente al "proprietario" del record di avere la precedenza su qualsiasi altro utente che apporta modifiche.
Quando si progetta un'interfaccia, risulta più efficace, generalmente, utilizzare un metodo deduttivo (dal generale al particolare). Tuttavia, quando si implementa un'interfaccia è meglio utilizzare un metodo induttivo. Con questo metodo, si identificano e implementano le unità di lavoro di volume più grande per l'interfaccia. Poi, si testa ciascun pezzo individualmente. Questi pezzi possono, quindi, diventare componenti di un modulo che esegue funzioni a un più alto livello.
La procedura che segue permette di ottenere ulteriori informazioni per testare una funzione.
E' necessario testare tutte le routine individualmente. Le routine che non dispongono di emissioni visibili possono utilizzare il TSD Script Debugger per visualizzare i risultati. Altrimenti, è necessario scrivere un gruppo di eventi per visualizzare i risultati.
Quando si testano routine che interrogano dati, si consiglia di bloccare le tabelle SQL il meno possibile. L'utilizzo di SQLSelect per effettuare il loop attraverso un ciclo di caricamento e un fetch, blocca le tabelle più a lungo del necessario o di quanto sia accettabile.
Una volta testate tutte le routine, è possibile testare le istruzioni per la routine principale. E' possibile che la routine principale richieda un'inizializzazione, che comprende:
Avvertenza: Prestare attenzione ai luoghi in cui si inserisce il componente di una routine in un'altra. Assicurarsi che i componenti della routine lascino sempre l'applicazione host su uno schermo noto.
Strutturare le routine principali in modo che una chiave di errore in un componente della routine disponga di implicazioni appropriate in fase di elaborazione. In altre parole, la routine principale non dovrebbe continuare se un componente della routine indica che si è verificato un errore irreversibile.
E' necessario che le applicazioni dell'interfaccia vengano scritte tenendo sempre presente la gestione errori. E' possibile che si verifichino diversi eventi durante l'operazione di interfaccia.
Esistono diverse opzioni per la gestione di errori, a seconda del tipo di errore rilevato. Le opzioni comprendono:
Il migliore approccio è una combinazione delle precedenti opzioni. E' possibile installare una routine generale di gestione di errore che notifichi l'errore all'utente e registri informazioni rilevanti. E' possibile modificare, in seguito, la routine per gestire gli errori più recuperabili. Gli errori irrecuperabili danno sempre come risultato un segnale d'allarme.
Manuale Tivoli Service Desk 6.0 Developer's Toolkit Legacy API