2. Chi sono
Il creatore di Dominopoint (2004)
CEO Grydan SAS
12 anni di consulenza su Notes/Domino
Amministratore, Sviluppatore e Docente
Email: d.grillo@grydan.it
Mobile: +39 392.29.45.549
5. Debug: _dump(obj)
Il comando SSJS _dump(obj) può essere
utilizzato in qualunque punto SSJS della tua
applicazione (validation, event handler, eventi
etc..) per tracciare lo stato corrente di un
qualunque oggetto passato come valore
6. Debug: OpenNTF Debug Toolbar
Tool pubblicato su OpenNtf.org che vi aiuta nel
tracking delle variabili di sessione, dotato di API
inspector integrato e console dove scrivere i
messaggi utilizzando SSJS
7. Debug: OpenNTF Debug Toolbar
A seconda del livello di attenzione:
dBar.info(message:String, context:String);
dBar.warn(message:String, context:String);
dBar.debug(message:String, context:String);
dBar.error(message:String, context:String);
Effettuare un dump di qualunque oggetto:
dBar.dump( anyObject );
Monitorare il Timing di un’azione:
dBar.startTimer( timerId:String );
dBar.stopTimer( timerId:String );
8. Debug: OpenLog Xpages
Per centralizzare gli errori in un unico repository è possibile
utilizzare anche la versione modificata da Matt White nel
prodotto TaskJam di OpenLog
http://www.bleedyellow.com/blogs/m.leusink/entry/using_openlog_for_logging_debugging_xpa
ges1?lang=en
9. Debug: OpenLog Xpages
Scaricare OpenLog Database da OpenNtf.org (creato da Julian
Robichaux)
Scaricare TaskJam (tool di Elgujii) scritto da Matt White.
Copiare OpenLogXPages SSJS libreria nella tua applicazione
Modificare la variabile logDbPath facendola puntare al DB
OpenLog
Aggiungere OpenLogXpages script library nelle tue risorse
Usare le istruzioni per scrivere in OpenLog
– log.logEvent( "Hello world" );
– log.logError( e.toString(), null, e );
http://www.bleedyellow.com/blogs/m.leusink/entry/using_openlog_for_logging_debugging_xpa
ges1?lang=en
10. Xpages Log File Reader
Currently these files are supported:
Log.nsf
All the files in the IBM_TECHNICAL_SUPPORT folder, e.g. the console.log and xpages.log
Error and Trace logs in the dominoworkspacelogs folder
Startup.log
Additional you will have access to read all the relevant server settings in these files:
notes.ini
xsp.properties
java.policy
rcpinstall.properties
11. Debug: Java for Xpages
E’ possibile debuggare il codice Java/XPages
Va abilitato sul Notes.INI del server Domino
utilizzando
– JavaEnableDebug=1
– JavaDebugOptions=transport=dt_socket,server=y,
suspend=y,address=*portnumber*
http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Debug_Java_for_XPages_in_NSFs
12. Debug: discovery method F4
Dato un componente inserito in una XPages
con drag & Drop, come faccio a capire i
metodi e proprietà utilizzabili in SSJS?
Risposta 1: Utilizzo la documentazione Java
delle API a questo URL
http://public.dhe.ibm.com/software/dw/lotus/Domino
-Designer/JavaDocs/XPagesExtAPI/8.5.2/index.html
13. Risposta 2
Al salvataggio/modifica di ogni
Debug: tasto F4 XPages/Custom Control viene generato
Dato un componente file Java sorgente con lo stesso nome
inserito in una XPages con accessibile con il Package Explorer
drag & Drop, come faccio a
capire i metodi e
sotto il ramo localxsp
proprietà?
14. Risposta 2
Si prende nota del nome del componente di cui si
vogliono conoscere i metodi
Debug: tasto F4
Dato un componente
inserito in una XPages con
drag & Drop, come faccio a
capire i metodi e
proprietà?
Si va a cercare la creazione dell’oggetto con il
Find/Replace nel sorgente java
15. Si seleziona il costruttore del’oggetto
Debug: tasto F4
Dato un componente
inserito in una XPages con
drag & Drop, come faccio a
capire i metodi e
proprietà?
Premendo il tasto F4 apparirà un elenco di metodi e
proprietà utilizzabili da SSJS molto comodo
16. Debug: FireBug & Web Developer ToolBar
Utile per il Debug lato client della vostra App
17. Debug: Outline
L’outline è uno strumento sottovalutato, ma ci permette di
capire come è strutturata la nostra XPages. Utilissimo per fare
reverse engineering
18. Validazione: server o client
La validazione fa parte del lifecycle di una
XPages può essere sia server o client a
seconda dell’apposito setting presente
nell’application proprierties
21. Validazione: summary with link
Voglio un summary con gli errori e link alle
caselle di testo come posso fare?
22. Validazione: summary with link
Custom Control
BeforePageLoad routine che va a leggere da tutti i
componenti della pagina corrente ed eventuali messaggi di
errore generati (facesContext.getClientIdsWithMessages() e
facesContext.getMessages(clientId)
Genera un object array di valori scritto in una ViewScope
Repeat Control che scorre la ViewScope
2 Computed Value (uno show the message e l’altro setta il
focus)
25. Validazione: altre 9 tipologie
validateExpression: scrivere un’espressione SSJS se ritorna true allora
passa la validazione altrimenti ferma
validateConstraint: scrivi un’espressione regEx per la validazione
validateRequired: caso campo obbligatorio diverso da vuoto
26. xAgent
Fare in modo che una Xpages si comporti come una
servlet (in notes tradizionale come ?OpenAgent)
– rendered="false" (attributo <xp:view>)
– Usando il writer scrivere code afterRenderResponse
– Usano Stream scrivere codice beforeRenderResponse
– Puoi avere o un writer o uno stream
– facesContext.responseComplete();
– Nella 8.5.2 erano Syncronized nella 8.5.3 concorrenti per
utente e database (concorrenti)
27. xAgent: esempio semplice
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
<xp:this.beforeRenderResponse><![CDATA[#{javascript:try {
var uName = session.createName(session.getEffectiveUserName());
var exCon = facesContext.getExternalContext();
var response = exCon.getResponse();
var writer = response.getWriter();
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
writer.write("<?xml version="1.0" encoding="UTF-8"?>n");
writer.write("<test>Ciao "+uName.getAbbreviated()+"</test>");
facesContext.responseComplete();
}
catch (e) {
_dump(e);
}}]]></xp:this.beforeRenderResponse></xp:view>
28. xAgent: esempio Pdf – preparare
Scaricare il JAR di Itext
Passare alla prospettiva Java nel Designer
Creare due folder sotto il ramo WebcontentWEB-INF
una chiamata src ed una chiamata lib
Copiare i file JAR di Itext dentro lib folder
Aggiungere al Build-Path le library presenti nella folder
lib e il source code presente nella src folder
29. xAgent: esempio Pdf- come fare
Crearsi il proprio package Java che lavora con
Itext [non è necessario per cose semplici]
30. xAgent: esempio PDF
Il mio code SSJS dovrà avere
importPackage(it.grydan.xpages.pdf)
Posso scrivere direttamente nell’XAgent il
richiamo alle funzioni della mio codice Java
31. xAgent: esempio PDF
http://www.eknori.de/2011-10-25/xpages-to-pdf-with-itext/
importPackage(com.itextpdf);
importPackage(java.io);
//Initialization
var con = facesContext.getExternalContext();
var response:com.ibm.xsp.webapp.XspHttpServletResponse = con.getResponse();
//setting response headers for browser to recognize data
response.setContentType(“application/pdf”);
response.setHeader(“Cache-Control”, “no-cache”);
response.setDateHeader(“Expires”, -1);
response.setHeader( “Content-Disposition”, “attachment; filename=”test.pdf”" );
// Setup the PDF Output Stream
var newPDF:com.itextpdf.text.Document = new com.itextpdf.text.Document();
var writer = com.itextpdf.text.pdf.PdfWriter.getInstance(newPDF,response.getOutputStream());
var htmlWorker = new com.itextpdf.text.html.simpleparser.HTMLWorker(newPDF);
32. // Open the PDF and write the PDF header info
newPDF.open();
newPDF.addAuthor(“Ulrich Krause”);
newPDF.addCreationDate();
newPDF.addCreator(“IBM Lotus Domino V8.5.3 :iText Library”);
newPDF.addTitle(“PDF Demo”);
//add a Hello World text to the PDF
var helloWorld = new com.itextpdf.text.Paragraph(“Hello world1″)
newPDF.add(helloWorld);
//Create a table with 3 cells, width = 100%
var table = new com.itextpdf.text.pdf.PdfPTable(3); // 3 columns.
var cell1 = new com.itextpdf.text.pdf.PdfPCell(new com.itextpdf.text.Paragraph(“Table Cell 1″));
var cell2 = new com.itextpdf.text.pdf.PdfPCell(new com.itextpdf.text.Paragraph(“Table Cell 2″));
var cell3 = new com.itextpdf.text.pdf.PdfPCell(new com.itextpdf.text.Paragraph(“Table Cell 3″));
table.setWidthPercentage(100);
table.addCell(cell1);
table.addCell(cell2);
table.addCell(cell3);
newPDF.add(table);
// Add a Chunk to the PDF; chunks do not add a CRLF when the leght exceeds page width. Better
use phrases
newPDF.add(new com.itextpdf.text.Chunk(“This is a chunk. “));
// Add a Phrase to the PDF
newPDF.add(new com.itextpdf.text.Phrase(“This is a phrase. “));
33. // Add a ordered List to the PDF
var orderedList = new com.itextpdf.text.List(com.itextpdf.text.List.ORDERED);
orderedList.add(new com.itextpdf.text.ListItem(“Item 1″));
orderedList.add(new com.itextpdf.text.ListItem(“Item 2″));
orderedList.add(new com.itextpdf.text.ListItem(“Item 3″));
newPDF.add(orderedList)
// Add a link to the PDF
var anchor = new com.itextpdf.text.Anchor(“eknori.de”);
anchor.setReference(“http://www.eknori.de”);
newPDF.add(anchor);
// Add HTML to the PDF
var str = “<html><head><title>titlu</title></head><body><table><tr><td><br /><br /><a
href=’http://www.eknori.de’>Link 2 eknori.de</a><br /><br /><br
/>Test</td></tr></table></body></html>”;
htmlWorker.parse(new java.io.StringReader(str));
// Finish
newPDF.close();
writer.close();
facesContext.responseComplete();
34. XAgent: esempio Pdf & Html
D: Voglio generare un PDF da una pagina
corrente basadomi su un template HTML?
R: Usando Itext library (Jar) ed XMLWorker(Jar)
è una delle soluzioni, con qualche limitazione
XMLWorkerHelper worker = XMLWorkerHelper.getInstance();
try{
worker.parseXHtml(pdfwriter, document, new java.io.StringReader(parseHTML));
} catch(Exception e){
document.add(new Phrase(e.toString()));
}
35. XAgent: passaggio parametri
In caso di POST verso il server:
param.get(‘PARAMETRO’)
In caso di GET verso il server:
context.getUrlParameter(‘PARAMETRO’);
36. Performance
Lentezza Designer dopo inserimento di una vista, a causa del DDE
inserendo una vista come datasource Notes potreste avere dei problemi
di lentezza in fase di editing: rendete il datasource calcolato e sarà più
performance.
Peformance Profiling Tool scaricabile da Openntf.org
http://www.openntf.org/projects/pmt.nsf/ProjectLookup/XPages%20Tool
box permette di capire codice di blocco individuali che sono lenti ad
essere eseguiti
XPagesPreload=1 e XPagesPreloadDB=account/w-apps.nsf per il primo
startup
Disabilitare Build Automatically e farlo manuale
Lavorare in replica locale da migliori performance
Utilizzare compression Javascript&CSS (flag nelle application proprierties)
37. Ckeditor var myToolbar = "[['Font','FontSize'], n"
+"['Preview', 'Bold','TextColor','BGColor'], n"
+"['Italic','Underline','Strike','-
Presente dalla 8.5.2, editor RichText ','Subscript','Superscript']]";
return myToolbar;
Converte un RT notes in MIME al salvataggio
3 tipi di editor (Full, Large, Medium,Slim)
Custom editor
38. Ckeditor
Focus sull’elemento da CSJS
– CKEDITOR.instances['#{id:inputRichText1}'].on('instanceReady', function(e){this.focus()})
Leggere il contenuto da CSJS
– var richCKEditor = CKEDITOR.instances["#{id:inputRichText1}"];
– alert (richCKEditor.getData())
Aggiungere HTML da SSJS:
– getComponent(‘CONROLLO’).setValueFromString(‘HTMLCODE’)
Aggiungere HTML da CSJS
– var date1 = new Date();
– for( var i in CKEDITOR.instances){
– rteditor = CKEDITOR.instances[i];
– if( rteditor.name == '#{id:richTextField1}'){
– rteditor.insertHtml("<br><p><--------" + date1.toLocaleDateString() + " : "+
date1.toLocaleTimeString() + "-----------></p><br>")
– }}
API http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html
39. Sessioni e Logout
Dopo aver effettuato un login con Single server
nei cookie avremo i cookie istanzianti
N.B. Cancellando i cookie scade la sessione corrente (nella
8.5.3 SessionID è un cookie prima URL parameter con
problematiche di script)
43. Comandi URL
Apertura di un documento
– "/"+session.evaluate("@WebDbName")[0]+"/%24%24OpenDominoDocument.xsp?docu
mentId="+unid+"&action=openDocument"
Creazione di un documento
– "/"+session.evaluate("@WebDbName")[0]+"/XpagesNAME.xsp?action=newDocument
Creazione di un documento risposta
– "/"+session.evaluate("@WebDbName")[0]+"/XpagesNAME.xsp?action=newDocument&
parentId="+docid
Modifica di un documento
– view.getPageName()+"?action=editDocument&documentId="+document1.getNoteID();
Aprire un allegato
– http(s)://[yourserver]/[application.nsf] /xsp/.ibmmodres/domino/OpenAttachment/
[application.nsf]/[UNID|/$File/[AttachmentName]?Open
44. Sessioni persistenti
D: Voglio fare in modo che la mia sessione non
scada e sia una sessione persistente come posso
fare?
R: Se hai installato UP1 o Extension Library usa il
Keep-Alive control
47. Multivalue field multipli
Come fare editing dinamico di più multivalori
per riga (esempio per compilazione voci di un
ordine)
48. Multivalue field multipli
Creo nella BeforePageLoad una variabile di View inizializzata a
zero se nuovo documento altrimenti con un object array in
caso di campi multivalore
Repeat control che scorre la ViewScope
Binding dei campi e validation
Bottone Aggiungi/Rimuovi che lavorano in memory sulla
ViewScope
QuerySave sul DataSource che scompone la viewScope e la
scrive nel backend
52. Relazionali: accesso senza ExtLib
Necessario Il Driver (solitamente JAR) da
inserire nel LIB folder
Costruire il Build Path
Realizzare Package Java di interfaccia
Richiamare Codice Java da SSJS con
ImportPackage(NOMEPACKAGE)
No CONNECTION POOL!
57. Relazionali: con Extlib - driver
jvm/lib/ext : non raccomandato uso semplice, posizionati in
una folder in cui c’è l’autorizzazione ad eseguire chiamate, ma
richiede accesso a FileSystem
Inside NSF non raccomandato causa + istanze del JAR a
seconda di quanti database lo utilizzano, potrebbe essere
necessario modificare il java.policy nel server path
jvm/lib/security
Installare il driver via OSGi plugin [raccomandato]
dinamicamente caricato e gestisto dal JDBC Driver Manager,
miglior gestione del connection pool
58. Relazionali: extlibx example mySQL
Una volta installato via Creare sotto folder
WEB-INFjdbc il file con estensione .jdbc
62. Multilingua
D: Come tradurre elementi iniettati in SSJS?
R: Creare label component in lingua source che
poi vengono tradotti con i file proprierties..ed
utilizzare
getComponent(‘labelName').getValue()
63. Come tradurre il contenuto delle
view?
Putroppo non è possibile farlo nativamente, ma
tramite dojo.query() è possibile individuare un’area
e fare delle find & replace del testo in funzione della
lingua localizzata negli eventi AfterPageLoad() e
AfterRestoreView()
if ( context.getLocaleString().match('en') ) {
dojo.query(".xspDataTable td.").forEach(function(node, index, arr){
searchText.split(‘ciao').join; (‘hello')
}
}
65. Multilingua: cambio lingua al volo
<xp:comboBox id="comboBox1" value="#{sessionScope.Language}">
<xp:selectItem itemLabel="Chinese" itemValue="zh"></xp:selectItem>
<xp:selectItem itemLabel="German" itemValue="de"></xp:selectItem>
<xp:selectItem itemLabel="Turkish" itemValue="tr"></xp:selectItem>
<xp:eventHandler event="onchange" submit="true" refreshMode="complete" />
</xp:comboBox>
The itemValue is the language code the XPage can be switched to, and can be easily modified to
fullify your requirements. The locale to use is stored in a sessionScope variable named
"Language".
To activate the XSnippet you have to modify the faces-config.xml of your XPages application by
adding these lines:
<faces-config>
<lifecycle>
<phase-listener>ch.hasselba.xpages.jsf.core.LocalizationSetter</phase-listener>
</lifecycle>
</faces-config>
66. XPiNC
Funzionano anche le ExtLib
Comodo per unica interfaccia
SSJS = if (@ClientType()=="Notes")
Funzionano le repliche
Attenzione al traffico dati live to server!
Vengono trasferiti XML, risorse, sorgenti e
package Java ad ogni GET