Super Useful Set of LotusScript Wrapper Classes
I know LotusScript is a "legacy" language, but, some of us still use it on all-too-regular basis (myself included) to think of it that way.
Recently I devised a set of core LotusScript "wrapper" classes that help with some of the more mundane aspects of writing web apps built with LotusScript.
A lot of the LotusScript I've written over the years has been along the lines of something like this:
Dim coll as NotesDocumentCollection Dim view as NotesView Dim doc as NotesDocument set view = database.GetView("InvoicesByUserName") Set coll = view.GetAllDocumentsByKey("jake howlett", True) Set doc = coll.GetFirstDocument() Print "content-type: application/json" Print "[" While not doc is Nothing Print |{"Title":"|+doc.getItemValue("Title")(0)+|", "Value": |+_
Cstr(doc.GetItemValue("Value")(0))+|},|
Set doc = coll.GetNextDocument(doc) Wend Print "]"
Nothing wrong with the code above (apart from one problem I've left in for the eagle eyed ÔÇô top marks to anybody who spots it!), per se, but imagine you could write it like this instead:
Dim factory As New InvoiceFactory() Dim invoices As InvoiceCollection Set invoices = factory.getAllInvociesForUser("jake howlett") Print "content-type: application/json" Call factory.PrintToWebAsJSONArray(invoices)
Well, now you can!
Not only that, but you can write code like this:
Dim factory As New InvoiceFactory Dim invoices As InvoiceCollection Dim invoice As Invoice Set invoices = factory.GetAllInvoices() If invoices.Count > 0 Then Set invoice = invoices.getFirst() While Not invoice Is Nothing Print "<h1>" + invoice.Title + "</h1><p>" + invoice.ValueFormattedAsString + "</p>" Print "<h4>As JSON</h4>" Print "<p><code>" + invoice.AsJSON + "</code></p>" Print "<h3>Customer</h3>" Print "<p>Customer's name is " + invoice.Customer.FullNameReversed +_ " ("+ invoice.CustomerID + "), who has " +_ CStr(invoice.Customer.Invoices.Count) + " invoices in total.</p>" Print "<h4>As JSON</h4>" Print "<p><code>" + invoice.Customer.AsJSON + "</code></p>" Print "<hr>" Set invoice = invoices.getNext() Wend End If
The custom classes in use above are InvoiceFactory, InvoiceCollection and Invoice. They are based, respectfully, on the base classes DocumentFactory, DocumentCollection and DocumentWrapper.
These three base classes can be used to represent each type of business object in the database. Roughly speaking, there's one set of classes per Form used. The above three classes are for the Invoice form. Each Invoice is linked to a customer, which has a Customer form and can be represented using the CustomerFactory, CustomerCollection and Customer classes.
All the code involved is available here.
The benefits of using classes to represent objects should go without saying. It just makes things so much simpler. Not only to maintain, but also to code. Instead of typing: document.getItemValue("DidICallTheTitleFieldTitle?")(0) you just type invoice.Title (Domino Designer even suggests this for you as you type!).
You no longer need to litter your LotusScript agents with field names and logic. I know field names rarely change, but you never know! The benefits of class-based logic stretch way further than that.
Using this approach requires quite a bit of upfront work to set the classes up, but it's worth it. If not just for that warm fuzzy feeling of seeing your classes and properties appear while type-ahead coding. No? That's just me then is it?
All a bit late in the day really. I so wish I'd come up with this approach 10 years ago....
Is there any interest in this? I'm guessing not, but if there is I can put together a demo download.
Those are really good examples of Lotus script classes. IBM developer works had a similar article, but all of the examples were in java.
Coming up with these classes requires a deep knowledge of the language AND a good understanding of the business domain and work flow. Those don't come overnight and IBM haven't been forthcoming with an abundance of examples so thanks to your experience we get to reap the benefits.
Thank you.
Reply
Thanks Wayne! I wrote this blog post late last night, posted it and went inside the house with a sinking feeling of pointlessness about what I'd just "wasted" an hour of my life doing.
It's good to know it's not in vain.
Reply
Did you leave a trailing comma in your JSON?
Reply
Yes. Gold star! Although, the comma is meant to be there, to separate each object in the array, but the loop doesn't cater for the fact the last one in the loop, which doesn't need one. Not all browsers complain. But some do, so it's best avoided. The "printtowebasjsonarray" method of the documentfactory class shows how to get round it.
I just noticed another error in the code! The CStr( is missing a closing ) !!
Reply
Why would you think we are not interested?
Reply
I guess I believe the hype. The hype being that XPages is the future and everything else is legacy. Which is so far from the truth for me. I still have no idea what my future is but I'd be amazed (worried!) if it were XPages.
It's hard to gauge interest levels on a blog and I honestly just thought that there would be little to no interest in this topic whatsoever.
Reply
Show the rest of this thread
This could have been the basis for a session at IBM Connect 2013.
The dev track was pretty much all XPages all the time. Meanwhile most of the developers I talked to told me that the bulk (if not all) of their day-to-day work is still traditional Notes client/web dev. So for them, the sessions offered nothing they could use when they got back to work today.
On the other hand I can use this post NOW. So thanks (and please don't stop).
Reply
Lotussphere is just marketing. Come to codestore.net for your real world solutions ;-)
I've given quite a bit of thought over recent months (years even) about quitting blogging. I just can't seem to though.
Thanks, by the way. Feedback like yours is what keeps me from stopping. I just need to know it's worthwhile.
Reply
Very useful set of classes and a good place to take advantage of code templates in LS for the getters.
Even though the sessions I give are on XPages, I still do a lot of LotusScript. An added benefit of this approach is that the same kind of wrapper can be used for Java in XPages in a managed bean, for example. If you're already familiar with the LotusScript it makes the transition easier. It also makes support across XPages and LotusScript more standardised. Many Domino apps will still be at core LotusScript and traditional Notes Client for some time yet.
Reply
Thanks Paul. No disrespect to the others above but it means a lot coming from somebody who is obviously respected as knowing what they're talking about.
Do you have any examples of LS code templates in getters that you mentioned? I'm not sure what you mean.
Reply
Show the rest of this thread
Jake,
Keep up the good work. XPages is what IBM pushing because it can be use to bridge us to Connections. We still do most of our stuff using Lotusscript. There is a little bit of XPages but the core is Lotusscript and heaven for bit C/C++. To customers, it does not matter what it is in for us.
Reply
Not quite 10 years, but this might help:
http://www.slideshare.net/billbucha.. ..01-advanced-object-oriented-programming-for-lotusscript
;)
There's a lot more Lotuscript stuff up there if you're keen.
Cheers,
---* Bill
Reply
Hi Bill,
If only I'd read that 10 years ago. The trouble is I probably wouldn't have done (no offence), as, personally, I don't learn that way. Reading the virtues of a methodology and seeing a high-level abstracted demo rarely makes me think how I could best apply it. It's only when I have a moment and think "hey, a class would help here" that it clicks.
I'm hoping that providing a "real world" demo (and soon a download) of the classes above will help others who learn best by example....
Reply
Great stuff, as usual. Thanks, Jake!
Also, in your first code sample, you never instantiated your database object before calling "set view = database.GetView("InvoicesByUserName")"
Reply
Good design pattern use, Jake. You can legitimately put "LotusScript Master" on your CV now. :-)
"Thumbs up" for real world examples that are useful and work and kindly given up for the price of reading through an article.
Reply
+1, Jake.
These are definitely cool things, and I use this all the time. It's always worth the initial investment, because you don't have to debug for hours somewhere down the line because you've made a typo with a field name.
Reply
The only disadvantage I have found with additional layers of OO Logic is that it can be a pain debugging, with the stone-age Debugger. Unless, of course, there are special tips about using the debugger that I am unaware of.
Reply
Nope. The debugger is awful. However, writing OO code in classes means far more code re-use, and far more focused, shorter code sequences to debug in future.
So you tend to debug more. We have tons of run-time diagnostic stuff too (as our product is meant to be used in secure environments) meaning that since we have more state information during every single cycle, debugging is far easier.
(or so we've found. The 160,000+ lines of Lotuscript in FirM are over 10 years old, OO based and - I'm rather proud to say - still working)
---* Bill
Reply
Not only did you not waste an hour of your life on this post, you have just saved me hours of starting from scratch this coming Monday.
I was just kind of poking around the Web on a bunch of different subjects and was looking for what your latest musings on .NET might be when I stumbled on the latest post of your update to this subject. Well, as it turns out, I'm currently working on a horrid project that has to go through all the documents in a set of NSFs and, for each one where a field has 1 specific value, search all the other DBs for any document where that field has any one of 3 values and an timestamp within a specific range. I've wrestled the past week on different ways to restructure it and was bemoaning the fact that I can't use C# at work but then I saw your latest update, read it, caught up in reverse order on the postings about this and it all clicked. Monday morning, I'll be wrapping those docs and this little project is in the bag.
And, yes, this is all LotusScript. I'll believe IBM has made Java king of Notes dev when I can write a Java agent in the Designer, set a breakpoint in NotesMain and click the Eclipse Debug\As Java button. And define my view columns in Groovy or Jython.
Reply
Hi Ted. I now think of it as an hour well-spent!
Reply