SlideShare a Scribd company logo
The Road to Damascus – A Conversion 
Experience: 
LS and @Formula to SSJS 
Matthew Fyleman, Product and Project Manager 
MWLUG 2014
Who am I? 
• Matthew Fyleman 
• 21 Years as a Notes/Domino Developer 
• Mostly Working on: 
– Xpages conversions 
– Product development
What is this Talk About? 
• Based on My Experiences 
• Converting LotusScript and @Formula 
to SSJS 
• Tools that can help – particularly 
regular expressions
What am I talking about? 
• When should you convert existing code? 
• Conversion Options 
– NotesAgent.run() with parameter doc 
– Search and Replace 
– Dedicated Tools 
• Search and Replace 
– Preparation 
– Introduction to Regular Expressions 
– Examples and Demonstration 
– Tips and Traps 
• Dedicated Tools 
• Questions
When should you convert code? 
Never!
When should you convert code? 
What is the problem? 
• It is always going to be slow 
• GIGO 
• You will introduce new bugs 
• Re-developing will be quicker, cheaper 
and you will end up with a better result 
• But if you really must ...
Conversion Options 
What are your options? 
• NotesAgent.run() 
– Quick and Dirty 
– Agent must run independently 
– Only use when agents are available and time is critical 
• Search and Replace 
– LotusScript -> JavaScript (and Java) 
– Less useful for @Formula 
• Dedicated Tools 
– @Formula
LotusScript to SSJS - Preparation 
• Search and Replace is most useful for LS conversion 
– Syntactically similar 
• Easiest if you do a little refactoring first 
– Option Declare 
– doc.field(0) -> doc.getItemValue(“Field“)(0) 
– Camel Case Notes Objects 
– Make Sure Method calls are consistently named 
• Best to Avoid All-In-One-Go 
– Function or Sub at a Time
Regular Expressions 
• Regular Expressions are your new BFF 
• Sophisticated Pattern Matching 
• Elements from search can be carried through to 
replace 
• The Search and Replace built in to DDE can use 
Regular Expressions 
• Useful outside LS conversion (e.g. Validation) 
– See Planet Lotus - http://planetlotus.org/profiles/ross-swick_97733
Starting Simple – Dim 
• Tidy up first – Option Declare, remove clustering e.g.: 
Dim x as Integer,y as Integer,z as Integer 
• We want to match any variable name in the pattern: 
Dim <var name> As <Any valid type> 
• Fairly simple: 
Dim[ ]+[A-Za-z0-9_]+[ ]+As[ ]+(Integer|String|Boolean|Double|Variant) 
• But how do we replace? 
– Modify the search: 
Dim[ ]+([w]*)[ ]+As[ ]+String 
– Use this for replace 
var 1 = “”;
Starting Simple – Dim (2) 
• For Notes Objects, Things are simpler 
Dim <var name> As Notes<rest of object name> 
- Ignore ... As New NotesSession for now 
• Also, initialising in SSJS, = null is ok: 
var <var name>:Notes<rest of object name> = null; 
• So our terms are: 
– Search: 
Dim[ ]+([w]*)[ ]+As[ ]+(Notes[w]*) 
– Replace: 
var 1:2 = null;
Less simple – If Statements 
• For the most part, simple S & R (but order is important): 
End If to } 
[ ]*Then to ) { 
Else[ ]+If[ ]* to } else if ( 
If[ ]* to if ( 
• But what about: 
If (x = 10) Then 
• Use Search: If[ ]+([w()[].<>" ]*)=([w()[].<> "]*)[ ]+Then 
• Use Replace: if (1==2) { 
• NB: Works but not optimal! 
• Other comparison operators not a problem
! – session objects 
• The problem: 
• Session object is global in ssjs: ‘session’ 
• In LS it is created: 
Dim sess As New NotesSession 
• Need to find all LS session objects, and replace with session 
• How do you get a list of session object names? 
You need a coffee!
Adding Java 
• Java String Object has regex search and replace 
String source = “Dim x As String”; 
String result = source.replaceAll(“Dim[ ]+([w]*)[ ]+As[ ]+String”, “var $1 = “”;”); 
• Pattern and Matcher objects make this even more powerful 
Pattern p = Pattern.compile(pattern); 
Matcher m = p.matcher(this.source); 
int startPos = 0; 
while (m.find(startPos)) { 
if (!itemList.contains(m.group(1))) { 
itemList.add(m.group(1)); 
} 
startPos = m.end() + 1; 
}
Field Handling 
• Similar Issue to Session 
• Need to find all document object names, and replace field 
handling methods 
• Will probably need to handle dot notation 
– Arrgghh! 
• How do you search for dot notation? 
<doc name>.([^GetItemValue])([0-9]+) 
• Still hard work!
Search and Replace: Tips & Traps 
• There are other types than string! 
– Always review and test converted code thoroughly 
• Date handling is a pain 
– Script libraries can help here – Java? 
• Watch out for User interaction and particularly dialogues 
Work out your strategies in advance!
Converting Formula 
• @Formula JavaScript Wrappers help a lot 
– Mostly just ‘;’ to ‘,’, and converting lists to arrays 
• Some constructions are obvious: 
@SetField(“Field”, Value); 
• Goes to: 
doc.replaceItemValue(“Field”, Value); 
• Or 
S: @SetField([ ]*([w”]*)[ ]*,[ ]*([w”]*)[ ]*); 
R: doc.replaceItemValue(1, 2); 
• But there are some issues ... 
@
Formula – List Processing 
• No direct equivalent in SSJS for *+, *= *>= etc. 
when applied to Lists 
• Need to plan for this 
• Java Class/Library to provide direct substitute 
• Unfortunately, Java does not permit operator 
overloading, so has to be a set of methods 
@!
Formula - @If, @Do and @While 
@If(@Contains(_WFData_neu;_Key);""; 
@Do( 
@Set("_Sachgebiet_Zuordnung";@DbLookup("NOTES":"NOCACHE";"":_ADM$StructureDB;"Workflows";"WFArbeitsanweisung";"Sachgebietzuordnung")); 
@If(_Sachgebiet_Zuordnung = "" | !@Contains(_Sachgebiet_Zuordnung;_Key2);@Do( 
@Prompt([Ok];"Hinweis";"In der System Struktur VBM wurde für das aktuelle Sachgebiet kein Workflow definiert. Das Dokument wird zum ehemaligen 
Kompetenzträger zurückgegeben, damit dieser ein neues Sachgebiet auswählen kann."); 
@Set("_Kompetenzträger";Bearbeiter1); 
@Set("_tmpintern";5) 
); 
@Do( 
@Prompt([Ok];"Hinweis";"In der System Struktur VBM wurde für das aktuelle Sachgebiet ein neues Sachgebiet konfiguriert. Das Dokument wird zum 
Kompetenzträger zurückgegeben, damit dieser das neue Sachgebiet auswählen kann."); 
@Set("_neues_Sachgebiet";@Left(@Right(_Sachgebiet_Zuordnung;_key2);"||")); 
@Set("_Elements";@Elements(@Explode(@Left(@Left(@Right(_WFData_neu;"||Sachgebiet#");"||"); _neues_Sachgebiet) + _neues_Sachgebiet; "$" ))); 
@Set("_KompetenzträgerData";@Explode(@Left(@Right(_WFData_neu;"||Kompetenzträger#");"||"); "$")); 
@Set("_Kompetenzträger";@Subset(@Subset(_KompetenzträgerData;_Elements);-1)); 
@Set("_tmpintern";6) 
) 
) 
) 
); @!!
Focusing on @If 
• @Formula is a FUNCTION language 
• @If is a function not a statement 
@!!! • In practice: 
@SetField(“Author”; @If(Status=“1”; Manager; Salesman)); 
• Needs to convert to: 
if (Status == “1”) { 
var author = doc.getItemValueString(“Manager”); 
} else { 
var author = doc.getItemValueString(“Salesman”); 
} 
doc.replaceItemValue(“Author”, author);
Tools 
• Search and Replace can be used for @Formula -> 
SSJS ... 
• ... but it can only take you so far 
• A dedicated tool can go further 
– Only real alternative to manual translation for complex 
statements 
– Time consuming to create 
– Still not a silver bullet
Third Party Tools 
• Espresso - http://www.ultrapico.com/Expresso.htm 
– Good for learning regex, and serious regex dev 
– Free! 
• GREP 
– Sophisticated regex file search 
– Where regex started (UNIX grep)!
Resources and Information 
• We4IT – www.we4it.com 
• OpenNTF – www.openntf.org 
• Regex Quick Reference 
http://www.night-ray.com/regex.pdf 
• Loads of websites for all aspects of regex development 
• Mastering Regular Expressions – Jeffrey E.F. Friedl – 
O’Reilly Publishing
Questions?
matthew.fyleman@we4it.com

More Related Content

The Road To Damascus - A Conversion Experience: LotusScript and @Formula to SSJS

  • 1. The Road to Damascus – A Conversion Experience: LS and @Formula to SSJS Matthew Fyleman, Product and Project Manager MWLUG 2014
  • 2. Who am I? • Matthew Fyleman • 21 Years as a Notes/Domino Developer • Mostly Working on: – Xpages conversions – Product development
  • 3. What is this Talk About? • Based on My Experiences • Converting LotusScript and @Formula to SSJS • Tools that can help – particularly regular expressions
  • 4. What am I talking about? • When should you convert existing code? • Conversion Options – NotesAgent.run() with parameter doc – Search and Replace – Dedicated Tools • Search and Replace – Preparation – Introduction to Regular Expressions – Examples and Demonstration – Tips and Traps • Dedicated Tools • Questions
  • 5. When should you convert code? Never!
  • 6. When should you convert code? What is the problem? • It is always going to be slow • GIGO • You will introduce new bugs • Re-developing will be quicker, cheaper and you will end up with a better result • But if you really must ...
  • 7. Conversion Options What are your options? • NotesAgent.run() – Quick and Dirty – Agent must run independently – Only use when agents are available and time is critical • Search and Replace – LotusScript -> JavaScript (and Java) – Less useful for @Formula • Dedicated Tools – @Formula
  • 8. LotusScript to SSJS - Preparation • Search and Replace is most useful for LS conversion – Syntactically similar • Easiest if you do a little refactoring first – Option Declare – doc.field(0) -> doc.getItemValue(“Field“)(0) – Camel Case Notes Objects – Make Sure Method calls are consistently named • Best to Avoid All-In-One-Go – Function or Sub at a Time
  • 9. Regular Expressions • Regular Expressions are your new BFF • Sophisticated Pattern Matching • Elements from search can be carried through to replace • The Search and Replace built in to DDE can use Regular Expressions • Useful outside LS conversion (e.g. Validation) – See Planet Lotus - http://planetlotus.org/profiles/ross-swick_97733
  • 10. Starting Simple – Dim • Tidy up first – Option Declare, remove clustering e.g.: Dim x as Integer,y as Integer,z as Integer • We want to match any variable name in the pattern: Dim <var name> As <Any valid type> • Fairly simple: Dim[ ]+[A-Za-z0-9_]+[ ]+As[ ]+(Integer|String|Boolean|Double|Variant) • But how do we replace? – Modify the search: Dim[ ]+([w]*)[ ]+As[ ]+String – Use this for replace var 1 = “”;
  • 11. Starting Simple – Dim (2) • For Notes Objects, Things are simpler Dim <var name> As Notes<rest of object name> - Ignore ... As New NotesSession for now • Also, initialising in SSJS, = null is ok: var <var name>:Notes<rest of object name> = null; • So our terms are: – Search: Dim[ ]+([w]*)[ ]+As[ ]+(Notes[w]*) – Replace: var 1:2 = null;
  • 12. Less simple – If Statements • For the most part, simple S & R (but order is important): End If to } [ ]*Then to ) { Else[ ]+If[ ]* to } else if ( If[ ]* to if ( • But what about: If (x = 10) Then • Use Search: If[ ]+([w()[].<>" ]*)=([w()[].<> "]*)[ ]+Then • Use Replace: if (1==2) { • NB: Works but not optimal! • Other comparison operators not a problem
  • 13. ! – session objects • The problem: • Session object is global in ssjs: ‘session’ • In LS it is created: Dim sess As New NotesSession • Need to find all LS session objects, and replace with session • How do you get a list of session object names? You need a coffee!
  • 14. Adding Java • Java String Object has regex search and replace String source = “Dim x As String”; String result = source.replaceAll(“Dim[ ]+([w]*)[ ]+As[ ]+String”, “var $1 = “”;”); • Pattern and Matcher objects make this even more powerful Pattern p = Pattern.compile(pattern); Matcher m = p.matcher(this.source); int startPos = 0; while (m.find(startPos)) { if (!itemList.contains(m.group(1))) { itemList.add(m.group(1)); } startPos = m.end() + 1; }
  • 15. Field Handling • Similar Issue to Session • Need to find all document object names, and replace field handling methods • Will probably need to handle dot notation – Arrgghh! • How do you search for dot notation? <doc name>.([^GetItemValue])([0-9]+) • Still hard work!
  • 16. Search and Replace: Tips & Traps • There are other types than string! – Always review and test converted code thoroughly • Date handling is a pain – Script libraries can help here – Java? • Watch out for User interaction and particularly dialogues Work out your strategies in advance!
  • 17. Converting Formula • @Formula JavaScript Wrappers help a lot – Mostly just ‘;’ to ‘,’, and converting lists to arrays • Some constructions are obvious: @SetField(“Field”, Value); • Goes to: doc.replaceItemValue(“Field”, Value); • Or S: @SetField([ ]*([w”]*)[ ]*,[ ]*([w”]*)[ ]*); R: doc.replaceItemValue(1, 2); • But there are some issues ... @
  • 18. Formula – List Processing • No direct equivalent in SSJS for *+, *= *>= etc. when applied to Lists • Need to plan for this • Java Class/Library to provide direct substitute • Unfortunately, Java does not permit operator overloading, so has to be a set of methods @!
  • 19. Formula - @If, @Do and @While @If(@Contains(_WFData_neu;_Key);""; @Do( @Set("_Sachgebiet_Zuordnung";@DbLookup("NOTES":"NOCACHE";"":_ADM$StructureDB;"Workflows";"WFArbeitsanweisung";"Sachgebietzuordnung")); @If(_Sachgebiet_Zuordnung = "" | !@Contains(_Sachgebiet_Zuordnung;_Key2);@Do( @Prompt([Ok];"Hinweis";"In der System Struktur VBM wurde für das aktuelle Sachgebiet kein Workflow definiert. Das Dokument wird zum ehemaligen Kompetenzträger zurückgegeben, damit dieser ein neues Sachgebiet auswählen kann."); @Set("_Kompetenzträger";Bearbeiter1); @Set("_tmpintern";5) ); @Do( @Prompt([Ok];"Hinweis";"In der System Struktur VBM wurde für das aktuelle Sachgebiet ein neues Sachgebiet konfiguriert. Das Dokument wird zum Kompetenzträger zurückgegeben, damit dieser das neue Sachgebiet auswählen kann."); @Set("_neues_Sachgebiet";@Left(@Right(_Sachgebiet_Zuordnung;_key2);"||")); @Set("_Elements";@Elements(@Explode(@Left(@Left(@Right(_WFData_neu;"||Sachgebiet#");"||"); _neues_Sachgebiet) + _neues_Sachgebiet; "$" ))); @Set("_KompetenzträgerData";@Explode(@Left(@Right(_WFData_neu;"||Kompetenzträger#");"||"); "$")); @Set("_Kompetenzträger";@Subset(@Subset(_KompetenzträgerData;_Elements);-1)); @Set("_tmpintern";6) ) ) ) ); @!!
  • 20. Focusing on @If • @Formula is a FUNCTION language • @If is a function not a statement @!!! • In practice: @SetField(“Author”; @If(Status=“1”; Manager; Salesman)); • Needs to convert to: if (Status == “1”) { var author = doc.getItemValueString(“Manager”); } else { var author = doc.getItemValueString(“Salesman”); } doc.replaceItemValue(“Author”, author);
  • 21. Tools • Search and Replace can be used for @Formula -> SSJS ... • ... but it can only take you so far • A dedicated tool can go further – Only real alternative to manual translation for complex statements – Time consuming to create – Still not a silver bullet
  • 22. Third Party Tools • Espresso - http://www.ultrapico.com/Expresso.htm – Good for learning regex, and serious regex dev – Free! • GREP – Sophisticated regex file search – Where regex started (UNIX grep)!
  • 23. Resources and Information • We4IT – www.we4it.com • OpenNTF – www.openntf.org • Regex Quick Reference http://www.night-ray.com/regex.pdf • Loads of websites for all aspects of regex development • Mastering Regular Expressions – Jeffrey E.F. Friedl – O’Reilly Publishing