Would it be possibe to use DominoWiki to show LotusScript?

Well it would but first things first… VERY nice. I really like the DominoWiki – the wiki is really easy to install, configure and work with. I think I’ll introduce the other guys at the office to the concept.

After proper credit has been given let me get back to the initial focus of the post. The wiki should mainly be used to share code examples within my team of developers but I like code to look like code which it doesn’t when you just paste it into DominoWiki.

My first and obvious problem was that all datatypes showed up as WikiWords. This is understandable due to their CamelCase nature. The fix was easy though – enclose all code in the <nowiki> tag which basically tells DominoWiki not to parse the text. Nice.

This a new problem emerged – the code was displayed using the same font as the rest of the text. This made it hard to read and see what was introduction and what was code. Hmmm… Using the <code> HTML tag inside the <nowiki> tag helped me there. I now had nice Courier formatted code.

But wait a minute… Didn’t Julian Robichaux do a script library for converting LotusScript code into HTML so it would display on the web like it does in the Domino Designer. Well I believe he did. 🙂

I went and fetched the code and hacked a little at the WikiPage.class script library. Now I can embed the <lotusscript> tag inside a <nowiki> tag and have nice formatted LotusScript in my wiki.


<nowiki>

<lotusscript>

Some LotusScript code...

</lotusscript>

</nowiki>

Really nice if I have to say so myself.



(Click image to open a bigger version)

Below is the patched version of the wikiFormat method from the WikiPage.class script library (remember to also get the ls2html script library from http://www.nsftools.com (I had to make small tweaks to the library to make it compile under Notes 6.5.4). The code has been formatted with ls2html – what else… 🙂

.lotusscript { font-family: courier; font-size: 9pt; color: black; }
.ls-comment { color: green; }
.ls-quote { color: black; }
.ls-datatype { color: black; }
.ls-operator { color: blue; }
.ls-keyword { color: blue; }
.ls-statement { color: blue; }
.ls-function { color: blue; }
.ls-class { color: black; }
.ls-constant { color: purple; }

Public Function wikiFormat (txt As String) As String '** call all of the wiki formatting functions, in a somewhat specific '** order (we also need to ignore anything in a <nowiki></nowiki> '** block, so you'll see the logic for that in here as well) Dim s1 As String, s2 As String, s3 As String, s4 As String Dim a1 As Variant Dim i As Integer Dim pos As Long Dim style As StyleDef Const NOWIKI_START = "&amp;lt;nowiki&amp;gt;" Const NOWIKI_END = "&amp;lt;/nowiki&amp;gt;" Const LS_START = "&amp;lt;lotusscript&amp;gt;" Const LS_END = "&amp;lt;/lotusscript&amp;gt;" 'create default style as I like it (using courier for code) Call GetDefaultLsStyleDef(style) style.script = "font-family: courier,sans-serif; font-size: 9pt; color: black;" '** convert rn linefeeds to just n s1 = parseLinefeeds(txt) '** remove all user-entered HTML from the page s1 = removeHTML(s1) '** ignore things that are within <nowiki></nowiki> sections a1 = Split(s1, NOWIKI_START, -1, 5) For i = 0 To Ubound(a1) If (i = 0) Then '** text before the first <nowiki> tag (if any), so we need to '** parse the whole block of text s1 = a1(i) s2 = "" Else '** check to see if there's a </nowiki> tag in here anywhere; '** if there is, we only want to parse everything after it, but if '** there's not we have to assume that all the text in this block '** is inside of the <nowiki> block, so we'll ignore everything '** in that case. pos = Instr(1, a1(i), NOWIKI_END, 5) If (pos > 0) Then s1 = Mid(a1(i), pos + Len(NOWIKI_END)) s2 = Left(a1(i), pos - 1) Else s1 = "" s2 = a1(i) End If End If s1 = parseWikiWords(s1) s1 = parseLists(s1) s1 = parseRules(s1) '** it's possible that the user would expect us to only look for '** bold, italic, and header matches along a single line. If that's '** the case, you can adjust the matchCondition filter. matchCondition = "*" matchCriteria = True 'matchCondition = "*[" &amp; chr(10) &amp; "]*" ' on a single line only 'matchCriteria = False s1 = parseBold(s1) s1 = parseItalics(s1) s1 = parseHeaders(s1) s1 = parseMonospace(s1) '** parse anything inside of single or double brackets ( [ ] or [[ ]] ) s1 = parseBrackets(s1) s3 = s3 &amp; s2 &amp; s1 Next a1 = Split(s3, LS_START, -1, 5) For i = 0 To Ubound(a1) If (i = 0) Then '** text before the first <lotusscript> tag - just add it to the '** result string s4 = s4 &amp; a1(i) Else '** check to see if there's a </lotusscript> tag in here anywhere; '** if there is, we only want to get the text before it, but if '** there's not we have to assume that all the text in this block '** is inside of the <lotusscript> block, so we'll get all remaining '** text in that case. pos = Instr(1, a1(i), LS_END, 5) If (pos > 0) Then '** there is a </lotusscript> tag s1 = Mid(a1(i), pos + Len(LS_END)) 'text after the ending tag s2 = Left(a1(i), pos - 1) 'text before the ending tag Else '** no stop tag - get rest of text s1 = "" s2 = a1(i) End If '** convert s2 using lotusscript2html s2 = ConvertStringEx(s2, style, False) '** add to s4 s4 = s4 &amp; s2 &amp; s1 End If Next s3 = s4 '** a few additional fixes s3 = fixAmp(s3) s3 = fixRelativeLinks(s3) '** put back any "safe" HTML that was fixed s3 = allowSafeHTML(s3) '** convert linefeeds to <p> or <br> s3 = parseParas(s3) wikiFormat = s3 End Function

How I love objects…

When combining OOP with the basis design patterns from the GoF book your code really becomes better. It should be obvious but sometimes it takes a success to fully realize and appreciate it.

I just spent some time extending a framework I am developing in LotusScript with some new functionality. Because I used the Factory and Template Method pattern I was able to add the functionality in mere 20 minutes. My initial guess was 2 hours!!

Quite a difference.

Now that I’m ranting about OOP in Notes I am really surprised how difficult it is to get Notes developers to adopt OOP in LotusScript. Maybe because Lotus doesn’t push it harder by providing a decent IDE supporting the task. Maybe it is because everything else in Lotus Notes is so easy that the learning curve is too steep. OOP is hard to learn and use properly, but once you get there you reap the reward. Big time.

Loving the Tomcat Domino redirector

The Tomcat Domino Redirector is a DSAPI filter written by Andy Armstrong of Tagish. DSAPI is a plug-in infrastructure that allows you to write plug-ins that runs under the Domino HTTP stack and allows you to process HTTP requests before they reach the Domino HTTP stack. For those familiar with ISAPI, DSAPI is the same but for the Domino server.

The filter has recently been moved to be a official part of the Tomcat Connectors instead of being a separate project. The connector now also supports the JK2 protocol for those interested in such details. JK2 is the same protocol you use when you setup Tomcat being the Apache HTTP server using the mod_jk module.

To setup the DSAPI connector I simply followed the steps in a howto document I found on Google. I had to get the binary Tomcat 5.5.9 distribution from the Jakarta site since I couldn’t find the workers2.properties file anywhere else. Furthermore – the Registry file provided from the page didn’t set the “serverRoot” key for some reason so I had to create that key manually afterwards.

Other than that the whole process was painless and now JIRA runs happily behind Domino configured using Internet Sites documents without any issues and the users didn’t even notice. Nice.

Johan Känngård LGPL’ed his LotusScript Collection classes – nice… :-)

Some time back Johan chose to change the license of his very nice LotusScript collection classes from no license to GPL. This was a problem for me since we use the classes in a wide range of applications. GPL doesn’t allow the code to be included in a non-GPL application.

I wrote Johan and asked whether he really wanted this or whether he would consider changing the license to LGPL instead (LGPL allows you to incorporate the code in closed-source applications). Johan agreed that LGPL would be better so he will change the license when he get around to it.

Very nice. Thank you Johan.

Single-Sign-On (LtpaToken) login problem from Domino servlet solved with the help of Lotus support

We have been using the NotesFactory.createSession(null, String) method to create Session objects from Java servlets for a long time but for some reason it didn’t work under Domino 6.0.x when running Internet Sites so we gave it up and continued using Web Configuration where it worked flawlessly. Until now that is since we really needed some of the Internet Sites functionality so I gave it another try under 6.5.4 but without any success. I broke down and called Lotus Support.

Lotus support came back to me promptly with a solution. The solution was to use another method to create the Session objects. Instead of manually getting the LtpaToken cookie from the request and passing it to the createSession-method as mentioned above you should pass the HttpServletRequest to the method like NotesFactory.createSession(null, javax.servlet.HttpServletRequest).

Perfect!