Macro di esempio
Per creare macro utili, che sfruttino tutte le capacità dell'Editor di macro, sono disponibili macro di esempio da utilizzare come punto di partenza.
Interazioni di base con l'host
Questo esempio illustra le interazioni di base seguenti:
- Invio di dati all'host
- Attesa della visualizzazione di schermi
- Utilizzo della parola chiave
yield
in attesa delle funzioni asincrone - Lettura del testo dallo schermo
- Visualizzazione di informazioni di base all'utente
- Gestione di errori di base
Per impostazione predefinita, per tutte le macro sono disponibili gli oggetti seguenti:
-
session - Punto di entrata principale per accedere all'host. Consente di connettersi, disconnettersi e fornisce l'accesso a PresentationSpace.
L'oggetto PresentationSpace ottenuto da session rappresenta lo schermo e fornisce molte funzionalità comuni, ad esempio il recupero e l'impostazione della posizione del cursore, l'invio di dati all'host e la lettura dello schermo.
-
wait - Fornisce un modo semplice per attendere che si verifichino i vari stati dell'host prima di continuare a inviare altri dati o a leggere dallo schermo.
-
UI - Fornisce funzionalità di interfaccia utente di base. Mostra i dati o richiede informazioni all'utente.
// Creare una nuova funzione macro var macro = createMacro(function*(){ 'use strict'; // Per impostazione predefinita, per tutte le macro sono disponibili gli oggetti seguenti: // 1. session - Punto di ingresso principale per accedere all'host. Consente di connettersi, disconnettersi e fornisce accesso a PresentationSpace. // L'oggetto PresentationSpace ottenuto da session rappresenta lo schermo e fornisce molte capacità comuni, ad esempio ottenimento e impostazione della // posizione del cursore, invio di dati all'host e lettura dello schermo. // 2. wait - Fornisce un modo semplice per attendere che si verifichino i vari stati dell'host prima di continuare a inviare altri dati o a leggere dallo schermo. // 3. ui - Fornisce capacità di base di interazione con l'utente. Mostra i dati o richiede informazioni all'utente. // Dichiarare una variabile per la lettura e la visualizzazione di alcuni dati dello schermo. // La procedura consigliata è dichiarare tutte le variabili all'inizio di una funzione. var numberOfAccounts = 0; // Iniziare ottenendo l'oggetto PresentationSpace, che fornisce molte operazioni comuni dello schermo. var ps = session.getPresentationSpace(); try { // Può impostare e ottenere la posizione del cursore ps.setCursorPosition(new Position(24, 2)); // Utilizzare la funzione sendKeys per inviare caratteri all'host ps.sendKeys('cics'); // SendKeys viene utilizzata anche per inviare all'host tasti quali PA e PF. // Vedere tutte le opzioni disponibili in "Tasti di controllo" nella documentazione ps.sendKeys(ControlKey.ENTER); // Attendere che il cursore si trovi nella posizione corretta. // L'oggetto wait fornisce numerose funzioni per attendere che si verifichino determinati stati // in modo che sia possibile inviare altri tasti o leggere i dati dello schermo. yield wait.forCursor(new Position(24, 2)); // È possibile combinare caratteri e tasti di controllo in una chiamata sendKeys. ps.sendKeys('data' + ControlKey.TAB + ControlKey.TAB + 'more data' + ControlKey.ENTER); // La parola chiave "yield" deve essere utilizzata prima di tutte le chiamate alle funzioni "wait" e "ui". // Indica al browser di interrompere l'esecuzione della macro fino a quando la // funzione wait (asincrona) restituisce il risultato. Consultare la documentazione per informazioni sulle funzioni // che richiedono la parola chiave yield. yield wait.forCursor(new Position(10, 26)); ps.sendKeys('accounts' + ControlKey.ENTER); // È possibile anche attendere che il testo venga visualizzato in aree specifiche dello schermo yield wait.forText('ACCOUNTS', new Position(3, 36)) ; ps.sendKeys('1' + ControlKey.ENTER); // Tutte le funzioni wait scadranno se i criteri non vengono soddisfatti entro il limite di tempo definito. // È possibile aumentare i timeout con un parametro aggiuntivo nelle funzioni wait (in millisecondi) // Tutti i timeout sono specificati in millisecondi e il valore predefinito è 10 secondi (10000ms). yield wait.forCursor(new Position(1, 1), 15000); ps.sendKeys('A' + ControlKey.ENTER); // PS fornisce la funzione getText per leggere il testo dalla schermata numberOfAccounts = ps.getText(new Position(12, 3), 5); // Utilizzare l'oggetto ui per visualizzare alcuni dati dalla schermata ui.message('Numero di account attivi: ' + numberOfAccounts); // try/catch consente di rilevare gli errori e segnalarli in un'ubicazione centrale } catch (error) { // Utilizzare di nuovo l'oggetto ui per visualizzare un messaggio che informa che si è verificato un errore yield ui.message('Error: ' + error.message); } //Fine della macro generata }); // Eseguire la macro e restituire i risultati a Macro Runner // L'istruzione return è necessaria poiché l'applicazione la utilizza // per sapere se la macro è stata eseguita correttamente e se è terminata return macro();
Interazione con l'utente
Questo esempio illustra come utilizzare i metodi API forniti per richiedere input o fornire informazioni all'utente tramite un messaggio.
var macro = createMacro(function*(){
'use strict';
// L'oggetto "ui" fornisce funzioni per richiedere informazioni all'utente e visualizzare informazioni
// Dichiarare variabili da utilizzare successivamente
var username;
var password;
var flavor;
var scoops;
//Begin Generated Macro
var ps = session.getPresentationSpace();
try {
// Richiedere all'utente di immettere il proprio nome e memorizzarlo in una variabile.
// Notare che la parola chiave 'yield' è necessaria per bloccare l'esecuzione in attesa dell'input dell'utente.
username = yield ui.prompt('Please enter your username');
// Richiedere all'utente di immettere un valore, proponendo una risposta predefinita.
flavor = yield ui.prompt('What is your favorite flavor of ice cream?', 'Chocolate');
// Richiedere all'utente di immettere informazioni riservate utilizzando l'opzione 'mask'. Durante l'immissione il testo sarà nascosto.
// Se un parametro non viene utilizzato, è possibile usare 'null' per specificare che non deve essere usato.
// Qui lo illustriamo specificando che non è necessario mostrare un valore predefinito.
password = yield ui.prompt('Please enter your password', null, true);
// La funzione prompt restituisce null se l'utente fa clic sul pulsante 'Cancel' anziché sul pulsante 'OK'.
// Un modo per gestire questo caso consiste nell'eseguire il wrapping della chiamata in un blocco try/catch.
scoops = yield ui.prompt('How many scoops would you like?');
if (scoops === null) {
// Termina la macro.
return;
// In alternativa potrebbe generare un Error che potrebbe essere catturato nel "catch" sotto
}
// Utilizzare i valori raccolti per ordinare il gelato
ps.sendKeys(username + ControlKey.TAB + password + ControlKey.ENTER);
yield wait.forCursor(new Position(5, 1));
ps.sendKeys(flavor + ControlKey.TAB + scoops + ControlKey.ENTER);
// Visualizzare un messaggio all'utente. Utilizzando la parola chiave 'yield' davanti alla chiamata,
// l'esecuzione della macro verrà bloccata fino a quando l'utente sceglie il pulsante 'OK'.
yield ui.message('Order successful. Enjoy your ' + scoops + ' scoops of ' + flavor + ' ice cream ' + username + '!');
} catch (error) {
// Qui abbiamo usato l'oggetto ui per visualizzare un messaggio che informa che si è verificato un errore
yield ui.message(error.message);
}
//Fine della macro generata
});
return macro();
Spostamento nei dati
Questo esempio illustra come spostarsi in un numero variabile di schermi ed elaborare i dati di ogni schermo.
// Creare una nuova funzione macro.
var macro = createMacro(function*(){
'use strict';
// Creare una o più variabili da utilizzare successivamente
var password;
var accountNumber;
var transactionCount = 0;
var row = 0;
// Ottenere un riferimento all'oggetto PresentationSpace.
var ps = session.getPresentationSpace();
try {
// Immettere nome utente e password per accedere all'applicazione.
yield wait.forCursor(new Position(19, 48));
ps.sendKeys('bjones' + ControlKey.TAB);
yield wait.forCursor(new Position(20, 48));
password = yield ui.prompt('Password:', null, true);
ps.sendKeys(password);
ps.sendKeys(ControlKey.ENTER);
// Immettere un comando dell'applicazione.
yield wait.forCursor(new Position(20, 38));
ps.sendKeys('4');
ps.sendKeys(ControlKey.ENTER);
// Creare l'elenco delle transazioni per un conto.
yield wait.forCursor(new Position(13, 25));
ps.sendKeys('2');
// Immettere un numero di conto. In questo esempio ne è stato inserito uno per maggior chiarezza.
yield wait.forCursor(new Position(15, 25));
accountNumber = yield ui.prompt('Account Number:', '167439459');
ps.sendKeys(accountNumber);
ps.sendKeys(ControlKey.ENTER);
// Attendere fino a quando raggiunge lo schermo del profilo del conto
yield wait.forText('ACCOUNT PROFILE', new Position(3, 33));
// Cercare il testo che indica che è stata raggiunta l'ultima pagina del record
while (ps.getText(new Position(22, 12), 9) !== 'LAST PAGE') {
// Quando non è ancora stata raggiunta l'ultima pagina del record, passare alla pagina successiva di record.
ps.sendKeys(ControlKey.PF2);
yield wait.forCursor(new Position(1, 1));
// Se la posizione del cursore non cambia da uno schermo di record all'altro e non è presente testo sullo schermo, /
/ è possibile attendere che uno schermo venga aggiornato. È possibile specificare
// il periodo di tempo di attesa dopo che è stato inviato un tasto AID per il completo aggiornamento dello schermo.
// Ad esempio:
// yield wait.forFixedTime(1000);
// Per ogni riga, incrementare la variabile count se contiene dati.
for (row = 5; row <= 21; row++) {
// Sullo schermo sono presenti 2 colonne. Verificare i dati nella colonna 1.
// In questo esempio, sappiamo che se è presente uno spazio in una posizione
// particolare, esiste una transazione.
if (ps.getText(new Position(row, 8), 1) !== ' ') {
transactionCount++;
}
// Verificare i dati nella colonna 2.
if (ps.getText(new Position(row, 49), 1) !== ' ') {
transactionCount++;
}
}
}
// Dopo essere passati in tutte le pagine di record, visualizzare il numero di record in una casella di messaggio.
yield ui.message('There are ' + transactionCount + ' records found for account ' + accountNumber + '.');
// Disconnettersi dall'applicazione
ps.sendKeys(ControlKey.PF13);
ps.sendKeys(ControlKey.PF12);
// try/catch consente di rilevare gli errori e segnalarli in un'ubicazione centrale
} catch (error) {
// Qui viene utilizzato l'oggetto ui per visualizzare un messaggio che informa che si è verificato un errore
yield ui.message(error.message);
}
});
// Qui viene eseguita la macro e i risultati vengono restituiti a Macro Runner
// L'istruzione return è necessaria poiché l'applicazione la utilizza
// per sapere se la macro è stata eseguita correttamente
return macro();
Chiamata di un servizio Web
Questo esempio illustra come effettuare una chiamata AJAX / REST direttamente da una macro a un servizio Web. È possibile integrare i dati dall'applicazione host alla chiamata al servizio Web o dal servizio Web all'applicazione host.
In questo esempio, viene chiamato il servizio REST CICSAcctsDemo di Verastream Host Integrator (VHI). È però possibile adattare facilmente il codice per chiamare qualsiasi servizio Web. Non si è limitati a VHI.
Nell'esempio, la chiamata passa attraverso un proxy configurato nel server di sessione (mostrato sotto) per evitare la complicazione "Same Origin Policy". Se si utilizza un servizio Web che supporta Cross-origin Resource Sharing (CORS) e si utilizza un browser recente, il proxy non è necessario.
Poiché la libreria jQuery è disponibile nelle macro, è possibile utilizzare direttamente la funzione $.post() per richiamare i servizi REST.
Questo esempio dimostra anche come eseguire il wrapping di una chiamata REST jQuery in una nuova promessa. La promessa restituita dalla funzione personalizzata sotto consente di utilizzare "yield" nel codice macro principale. Questo consente all'esecuzione della macro principale di attendere fino al completamento della chiamata del servizio prima di continuare.
var macro = createMacro(function*() {
'use strict';
// Creare alcune variabili da utilizzare successivamente
var username;
var password;
var accountNumber;
var accountDetails;
// Creare una funzione che effettuerà una chiamata AJAX / REST al servizio Web VHI.
// Può essere modificata per chiamare qualsiasi servizio, non solo VHI.
// Se non si utilizza CORS, è probabile che la richiesta debba passare
// attraverso un proxy nel server di sessione. Per ulteriori informazioni, vedere le note dell'esempio.
/**
* Funzione helper codificata manualmente per incapsulare i parametri AJAX / REST, richiamare il
* servizio REST e restituire i risultati in un oggetto Promise.
* @param {Number} acctNum per inviare la query REST.
* @param {String} username per accedere al servizio REST.
* @param {String} password per accedere al servizio REST.
* @return {Promise} contenente i risultati di $.post() compatibili con yield.
*/
var getAccountDetails = function (acctNum, username, password) {
var url = "proxy1/model/CICSAcctsDemo/GetAccountDetail";
var args = {"filters": {"AcctNum": acctNum}, "envVars": {"Username": username, "Password": password}};
// Eseguire il wrapping di una chiamata jQuery AJAX / HTTP POST in un nuovo oggetto Promise.
// L'oggetto Promise restituito qui consente alla macro di eseguire yield / wait
// per il completamento.
return Promise.resolve($.post(url, JSON.stringify(args)))
.catch(function (error) {
// Mappare gli errori che si verificano nella chiamata jQuery all'oggetto Promise.
throw new Error('REST API Error: ' + error.statusText);
});
};
// Inizio della macro generata
var ps = session.getPresentationSpace();
try {
// Qui è possibile interagire con l'host, accedere all'app host ecc.
// Raccogliere nome utente e password
username = yield ui.prompt('Username:');
password = yield ui.prompt('Password:', null, true);
accountNumber = yield ui.prompt('Account Number:');
if (!username || !password || !accountNumber) {
throw new Error('Username or password not specified');
}
// Richiamare il servizio REST esterno e utilizzare yield / wait per completare la chiamata.
accountDetails = yield getAccountDetails(accountNumber, username, password);
// Sono ora disponibili i dati del servizio esterno.
// È possibile integrare i dati nell'app host locale o semplicemente mostrarli all'utente.
// Per questo esempio, verranno semplicemente visualizzati i dettagli del conto.
if (accountDetails.result && accountDetails.result.length > 0) {
yield ui.message(accountDetails.result[0].FirstName + ' $' + accountDetails.result[0].AcctBalance);
} else {
yield ui.message('No records found for account: ' + accountNumber);
}
} catch (error) {
// Se si è verificato un errore durante la chiamata AJAX / REST
// o nella raccolta di nomeutente / password, l'operazione terminerà qui.
yield ui.message(error.message);
}
});
// Eseguire la macro
return macro();
Supporto di scripting proxy tra origini
Se sono presenti servizi Web che non supportano CORS, le chiamate AJAX/REST avranno esito negativo se tentano di accedere a un server diverso da quello in cui è stata originata l'applicazione Host Access for the Cloud. Si tratta di una funzione di sicurezza del browser.
Il server Host Access for the Cloud fornisce un modo esplicito per agire da proxy per i server remoti attendibili.
-
Aprire
..\<directory-installazione>\sessionserver\microservice\sessionserver\service.yml
per effettuare modifiche. -
Nella sezione
env
, aggiungere:- name: zfe.proxy.mappings value: percorso-proxy=indirizzo-destinazione-proxy
Dove
percorso-proxy
si riferisce alla mappatura URL desiderata eindirizzo-destinazione-proxy
si riferisce all'URL dove la chiamata verrà trasferita tramite proxy. -
In questo esempio:
- name: zfe.proxy.mappings value: percorso-proxy=indirizzo-destinazione-proxy
Le chiamate effettuate a
<server:port>/proxy1
saranno delegate ahttp://remote-vhi-server:9680/vhi-rs/
-
È possibile specificare più mappature proxy utilizzando una virgola per separare le singole mappature
-
Tenere presente che anche quando un server REST supporta intestazioni CORS, alcuni browser meno recenti potrebbero non supportarle, perciò questi esempio potrebbe comunque essere rilevante.
Suggerimento
Il file service.yml
può essere sostituito quando si distribuisce nuovamente Host Access for the Cloud. Creare sempre una copia di backup dei file.
Utilizzo delle celle dati e degli attributi
Questa macro illustra come utilizzare DataCell e AttributeSet per ispezionare testo e attributi in una determinata riga/colonna sullo schermo. In questo esempio si può vedere:
-
Come ottenere una raccolta di DataCell per una determinata posizione e lunghezza.
-
Come eseguire l'iterazione sui DataCell per creare una stringa di testo
-
Come, per confronto, è possibile eseguire un'operazione simile anche utilizzando getText().
-
E infine, come eseguire operazioni con gli attributi, ottenere un elenco di stringhe o determinare se stringhe specifiche sono impostate in una determinata posizione dello schermo.
var macro = createMacro(function*() {
'use strict';
// Ottenere PresentationSpace per interagire con l'host
var ps = session.getPresentationSpace();
// Dichiarare le variabili da utilizzare successivamente
var cells;
var text;
var attrs;
// Impostare il valore di timeout predefinito per le funzioni "wait"
wait.setDefaultTimeout(10000);
// Macro di esempio per operazioni con DataCell e Attributi
try {
yield wait.forCursor(new Position(24, 2));
// Ottenere DataCell dallo spazio di presentazione.
// Riga 19, col 3 è il prompt, lunghezza 35 caratteri
// "Choose from the following commands:"
ells = ps.getDataCells({row:19, col:3}, 35);
text = '';
// È possibile visualizzare il testo utilizzando getText
yield ui.message("Screen text: " + ps.getText({row:19, col:3}, 35));
// Oppure è possibile assemblare il testo da DataCell a ogni posizione
for(var index = 0; index < cells.length; index++) {
text = text.concat(cells[index].getChar());
}
// E visualizzare il testo
yield ui.message("Cells text: " + text);
// Ottenere gli attributi per la prima DataCell (cell[0])
attrs = cells[0].getAttributes();
// Visualizzare se sono presenti attributi nella cella dati
yield ui.message("Attribute set is empty: " + attrs.isEmpty());
// Visualizzare il numero di attributi impostato set
yield ui.message("Number of attributes: " + attrs.size());
// Visualizzare quali attributi sono impostati
yield ui.message("Attributes: " + attrs.toString());
// Ora visualizzare se l'attributo high intensity è impostato
yield ui.message("Is high intensity: " + attrs.contains(Attribute.HIGH_INTENSITY));
// Ora visualizzare se l'attributo underline è impostato
yield ui.message("Is underline: " + attrs.contains(Attribute.UNDERLINE));
// Ora visualizzare se sono impostati gli attributi alphanumeric, intensified e pen-detectable
yield ui.message("Is alphanumeric, intensified and pen-detectable: " +
attrs.containsAll([Attribute.ALPHA_NUMERIC, Attribute.HIGH_INTENSITY, Attribute.PEN_DETECTABLE]));
// Ora visualizzare se sono impostati gli attributi underline, intensified e pen-detectable
yield ui.message("Is underline, intensified and pen-detectable: " +
attrs.containsAll([Attribute.UNDERLINE, Attribute.HIGH_INTENSITY, Attribute.PEN_DETECTABLE]));
} catch (error) {
yield ui.message(error);
}
//Fine della macro generata
});
// Eseguire la macro
return macro();
Utilizzo di Field e FieldList
Questa macro di esempio illustra come utilizzare funzioni comuni per interagire con i campi nell'API Macro. Ad esempio, come ottenere il testo dei campi, visualizzare informazioni sui campi e utilizzare field.setText come alternativa a sendKeys per interagire con l'host.
Nota
A causa delle considerazioni sul browser, ui.message
comprime stringhe di spazi in un solo spazio. Gli spazi vengono mantenuti nel codice JavaScript effettivo.
var macro = createMacro(function*() {
'use strict';
// Ottenere PresentationSpace per interagire con l'host
var ps = session.getPresentationSpace();
// Dichiarare variabili da utilizzare successivamente use
var fields;
var field;
var searchString = 'z/VM';
// Impostare il valore di timeout predefinito per le funzioni "wait"
wait.setDefaultTimeout(10000);
// Macro di esempio per operazioni con FieldList e Field
try {
yield wait.forCursor(new Position(24, 2));
// Ottenere l'elenco di campi.
fields = ps.getFields();
// Scorrere l'intero elenco di campi e visualizzare le informazioni sul campo.
for(var index = 0; index < fields.size(); index++) {
field = fields.get(index);
yield ui.message("Field " + index + " info: " + field.toString());
}
yield ui.message("Now, find a field containing the text '" + searchString + "'");
field = fields.findField(new Position(1, 1), searchString);
if(field !== null) {
yield ui.message("Found field info: " + field.toString());
yield ui.message("Found field foreground is green? " + (Color.GREEN === field.getForegroundColor()));
yield ui.message("Found field background is default? " + (Color.BLANK_UNSPECIFIED === field.getBackgroundColor()));
}
// Cercare ora un campo comando e modificarlo.
field = fields.findField(new Position(23, 80));
if(field !== null) {
field.setText("cics");
}
yield ui.message("Click to send 'cics' to host.");
ps.sendKeys(ControlKey.ENTER);
// Attendere il nuovo schermo; ottenere nuovi campi.
yield wait.forCursor(new Position(10, 26));
fields = ps.getFields();
// Trovare il campo utente e impostarlo.
field = fields.findField(new Position(10, 24));
if(field !== null) {
field.setText("myusername");
}
// Trovare il campo della password e impostarlo.
field = fields.findField(new Position(11, 24));
if(field !== null) {
field.setText("mypassword");
}
yield ui.message("Click to send login to host.");
ps.sendKeys(ControlKey.ENTER);
// Attendere il nuovo schermo; ottenere nuovi campi.
yield wait.forCursor(new Position(1, 1));
fields = ps.getFields();
// Trovare il campo comando e impostare il comando di disconnessione.
field = fields.findField(new Position(24, 45));
if(field !== null) {
field.setText("cesf logoff");
}
yield ui.message("Click to send logoff to host.");
ps.sendKeys(ControlKey.ENTER);
} catch (error) {
yield ui.message(error);
}
//Fine della macro generata
});
// Eseguire la macro
return macro();
Macro di accesso automatico per mainframe
In questo esempio l'oggetto Autosignon viene utilizzato per creare una macro che usa le credenziali associate a un utente per ottenere un pass ticket da DCAS (Digital Certificate Access Server).
var macro = createMacro(function*() {
'use strict';
// Ottenere PresentationSpace per interagire con l'host
var ps = session.getPresentationSpace();
// Variabile per il pass ticket di accesso
var passTicket;
// ID applicazione di accesso
var appId = 'CICSV41A';
// Impostare il timeout predefinito per le funzioni "wait"
wait.setDefaultTimeout(10000);
// Inizio della macro generata
try {
yield wait.forCursor(new Position(24, 2));
// Ottenere un pass ticket da DCAS.
passTicket = yield autoSignon.getPassTicket(appId);
ps.sendKeys('cics');
ps.sendKeys(ControlKey.ENTER);
yield wait.forCursor(new Position(10, 26));
// Sostituire il nome utente generato con sendUserName(passTicket) ...
yield autoSignon.sendUserName(passTicket);
// ps.sendKeys('bvtst01' + ControlKey.TAB + ControlKey.TAB);
ps.sendKeys(ControlKey.TAB + ControlKey.TAB);
yield wait.forCursor(new Position(11, 26));
// Sostituire la password generata con sendPassword(passTicket) ...
yield autoSignon.sendPassword(passTicket);
// var userInput3 = yield ui.prompt('Password:', '', true);
// if (userInput3 === null) {
// throw new Error('Password not provided');
// }
// ps.sendKeys(userInput3);
ps.sendKeys(ControlKey.ENTER);
yield wait.forCursor(new Position(1, 1));
yield ui.message('Logged in. Log me off.');
ps.sendKeys('cesf logoff');
ps.sendKeys(ControlKey.ENTER);
} catch (error) {
yield ui.message(error);
}
//Fine della macro generata
});
// Eseguire la macro
return macro();
Utilizzo di Trasferimento file (IND$File)
Questa serie di macro di esempio illustra come utilizzare l'API Trasferimento file per richiamare un elenco di file, scaricare un file e caricare un file in un host 3270.
Nota
Per poter eseguire queste macro, effettuare l'accesso e passare al prompt dei comandi.
Elenco di file
Questa macro illustra come utilizzare l'API Trasferimento file per richiamare un elenco di file in un host 3270 tramite il trasferimento IND$File. L'oggetto di trasferimento IND$File viene richiamato dalla factory trasferimento file, quindi utilizzato per ottenere una matrice di oggetti HostFile da TSO o CMS.
var macro = createMacro(function*() {
'use strict';
try {
var fileTransfer = fileTransferFactory.getInd$File();
var hostFiles = yield fileTransfer.getHostFileListing();
yield ui.message('Found ' + hostFiles.length + ' files');
if (hostFiles.length > 0) {
var firstFile = hostFiles[0];
var msg1 = 'The catalog name is ' + firstFile.getParent() + '. ';
var msg2 = 'The first file is ' + firstFile.getName();
yield ui.message(msg1 + msg2);
}
} catch (error) {
yield ui.message(error);
}
});
// Eseguire la macro
return macro();
Effettuare il download del file
Questa macro illustra come utilizzare l'API Trasferimento file per scaricare un file da un host 3270 tramite il trasferimento IND$File. L'oggetto di trasferimento IND$FILE viene richiamato dalla factory trasferimento file. In questo esempio, il metodo di trasferimento è impostato su ASCII per dimostrare l'utilizzo della funzione setTransferOptions.
La macro di esempio scarica il primo file restituito da una chiamata a getHostFileListing creando un URI di download tramite una chiamata alla funzione getDownloadUrl. La macro può essere utilizzata sia in ambiente CMS che TSO ma è necessario specificare la scelta nella prima riga oppure modificare leggermente il codice per il sistema desiderato.
var hostEnvironment = 'CMS'; // 'TSO'
// Costruire il percorso file, ad esempio catalog/file.name o catalog/partition/file
function getPath (fileNode) {
var prefix = fileNode.getParent() ? fileNode.getParent() + '/' : '';
return prefix + fileNode.getName();
}
var macro = createMacro(function*() {
'use strict';
try {
var fileTransfer = fileTransferFactory.getInd$File();
// Le opzioni di transferMethod sono 'binary' e 'ascii'
fileTransfer.setTransferOptions({transferMethod: 'ascii'});
// Questo esempio recupera il primo file restituito nell'elenco
var hostFiles = yield fileTransfer.getHostFileListing();
var firstHostFile = hostFiles[0];
if (hostEnvironment === 'CMS') {
yield wait.forText('Ready', new Position(1,1), 5000);
}
// Download
// Se si conosce già il percorso del file desiderato, passare il percorso a getDownloadURL()
var downloadUrl = fileTransfer.getDownloadURL(getPath(firstHostFile));
// Questo modifica la posizione del browser. I risultati potrebbero essere diversi a seconda del browser
window.location = downloadUrl;
// Per leggere il contenuto del file in una variabile anziché scaricarlo,
// è possibile utilizzare jQuery
// var fileContents = yield $.get(downloadUrl);
} catch (error) {
yield ui.message(error);
}
});
// Eseguire la macro
return macro();
Upload di file
Questa macro illustra come utilizzare l'API Trasferimento file per caricare un file in un host 3270 tramite il trasferimento IND$File. La macro di esempio richiede all'utente di scegliere un file dal file system locale attivando la finestra di selezione dei file del browser. Richiama poi il catalogo corrente su TSO o l'identificatore di unità su CMS chiamando getHostFileListing. Infine viene chiamata la funzione sendFile per consegnare all'host il file locale selezionato.
La macro può essere utilizzata sia in ambiente CMS che TSO ma è necessario specificare la scelta nella prima riga. In questo esempio il metodo di trasferimento è impostato su ascii, ma è possibile impostarlo su binary.
var hostEnvironment = 'CMS'; // 'TSO'
// Apre la finestra di selezione file del browser a livello di codice
function promptForFileToUpload () {
return new Promise(function (resolve, reject) {
// Non si ricevono notifiche se l'utente annulla la finestra di selezione file, quindi rifiutare dopo 30 secondi
var timerId = setTimeout(reject.bind(null, 'Timed out waiting for file selection'), 30000);
var fileSelector = document.createElement('input'); fileSelector.setAttribute('type', 'file');
fileSelector.onchange = function (evt) {
var file = evt.target.files[0];
clearTimeout(timerId);
resolve(file);
};
fileSelector.click();
});
}
var macro = createMacro(function*() {
'use strict';
try {
var fileTransfer = fileTransferFactory.getInd$File();
// Le opzioni di transferMethod sono 'binary' e 'ascii'
fileTransfer.setTransferOptions({transferMethod: 'ascii'});
var localFile = yield promptForFileToUpload();
// Richiamare il nome del catalogo corrente e aggiungervi il nome del file selezionato
var hostFiles = yield fileTransfer.getHostFileListing();
var destination = hostFiles[0].getParent() + '/' + localFile.name;
if (hostEnvironment === 'CMS') {
yield wait.forText('Ready', new Position(1,1), 5000);
}
var result = yield fileTransfer.sendFile(localFile, destination);
} catch (error) {
yield ui.message(error);
}
});
// Eseguire la macro
return macro();