Easy Access to Sub-Collections of the DocumentWrapper Class
My favourite feature of the Wrapper Classes I keep going on about is the ready access they can give to any given class's related sub-classes.
For example, let's say you have an object based on the Customer class and you want to find all their Invoices. Wouldn't it be nice to write code like this in a WQO agent:
Dim customer As Customer, invoice As Invoice Set customer = New Customer(web.document) If customer.Invoices.Count > 0 Then Set invoice = customer.Invoices.getFirst() While Not invoice Is Nothing 'Do what you like here Set invoice = customer.Invoices.getNext() Wend End If
When you start using code like this in your day-to-day LotusScripting that's when it all starts to gel and there's no going back.
Imagine also that you wanted to know how many other invoices the customer for any given invoice has. You can do it like this:
Print "This invoice's customer has " + Cstr(invoice.Customer.Invoices.Count - 1) + " other invoices"
Cool, no?
Adding Collection Properties
But how do we add this "Invoices" property? Easy. Just do something like this in the Invoice class:
Class Customer as DocumentWrapper Private Invoices_ As InvoiceCollection Private Factory_ As InvoiceFactory Property Get Invoices As InvoiceCollection 'lazy load the invoices! If Invoices_ Is Nothing Then Set Factory_ = new InvoiceFactory() Set Invoices_ = Factory_.GetInvoicesForCustomer(Me) End If Invoices = Invoices_ End Property End Class
Noticed we've defined a class-level InvoiceCollection and InvoiceFactory (we need to do this so they stay in scope). We then "lazy load" them the InvoiceCollection when it's first requested.
Here we're only going one level of sub-class deep. But you could go as many levels deep as you needed.
In the example above I've called a method called GetInvoicesForCustomer(). How this works depends on how your data is structured. Maybe the invoices are child documents of the Customer. Maybe they're just tied together by an "id" field. Either way, it doesn't really matter.
Definitely easier for someone inheriting that code to see the business logic than direct calls to item values and view lookups.
Java has a handy notion called "Iterable": any class that claims to implement that feature can use a very terse looping syntax. So if you were writing these same classes in Java, and InvoiceCollection implemented Iterable, then this syntax:
if (customer.getInvoices().getCount() > 0) {
invoice = customer.getInvoices().getFirst();
while (invoice != null) {
// Do what you like here
invoice = customer.getInvoices().getNext();
}
}
...can be shortened all the way to:
for (Invoice invoice : customer.getInvoices()) {
// Do what you like here
}
It's like Forall in LotusScript without all the messy Variant side effects. :)
Reply
Hi Jack,
I'm a long time reader of your blog, keep on writing !
Nice posts. I did a lot of writing of classes in lotusscript. I can give you some advices.
1. Convention : create a lotusscript library by notes document. Use a naming convention. The idea is that this script lib is the central point to access the document. The idea is also that the document is a serialized version of an object.
Ex. Form = invoice -> lib script name -> app.doc.docInvoice
the typical squeleton of a document wrapper will be :
class docInvoice
Public Sub New(docp As NotesDocument, pApp As myApp)
End Sub
Reply
Here the end of my post...
2. Use this squeleton for your doc wrapper
class docInvoice
private doc as notesdocument
sub new (pdoc as notesdocument)
set doc = pdoc
end sub
end class
3. Use lotusscript.doc to documente your project.
Some tricks I learned :
1. Lotusscript OOP at large scale goes evil.
2. Lotusscript is not usable easily in xPages... you should rewrite in SSJS
One question. Why a skillful developer like you is going back to lotuscript ?
Greetings.
Reply
"Why a skillful developer like you is going back to lotuscript ?"
The alternative being Xpages? Or pure Java Agents?
Xpages has just never been an option for me. Using purely Java agents never felt like the right thing to do. Coding in LotusScript is horrible, but it feels like the right option in most cases. It's fast and reliable.
Reply