VariableResolvers: Handle With Care
I’ve blogged before about VariableResolvers and the more I dig into them, the more powerful they are. Performance-wise, I’ve already blogged they’re as rapid as you can get, the perfect place for regularly-accessed bits of code. Anyone at UKLUG will have seen that I extended that particular performance table to show that a VariableResolver in an OSGi plugin is virtually as quick.
But there is a caveat I’ve found. Amusingly, I’d made the link that examines the caveat on another blog post, about Expression Language. I said:
Expression Language is parsed quickly. I suspect it’s using something like a VariableResolver and PropertyResolver, to quickly access the datasource and call a getValue() method.
Well that’s exactly what happens. Expression Language queries the VariableResolver for what’s left of the dot notation, then queries the PropertyResolver for what’s to the right of the dot notation. Some objects are loaded as variables whenever XPages runs on a database, without you doing anything – session, database, sessionAsSigner, context etc. Behind the scenes these string names are mapped to the current NotesSession, the current NotesDatabase etc.
Other objects are loaded as variables through components you drop onto the XPage. When you create a dominoDocument datasource, you specify a var name to refer to it. var is short for variable, and this is the string name that is parsed by the VariableResolver to refer to the dominoDocument datasource. The same happens for repeating controls – View Panels, Repeat Controls, Data Views etc.
Other objects are loaded as variables in the faces-config.xml. That’s what you’re doing when you register beans, Java validators etc. You’re saying “When you come across this name, look to this Java class”.
Finally, you can define variables specifically in the VariableResolver.
And if you think about it, that’s where the huge caveat comes in. Whenever you refer to any of those objects, whether in Expression Language or SSJS, the code will route to your VariableResolver. If the VariableResolver is coded efficiently, the overhead is minimal. If it’s not, the overhead becomes significant. I only realised this when I added a print statement into a VariableResolver to print out the variable name and saw “context”, “document1″, “database”, “rowEnt” and any other variable name defined or used on my XPage.
So VariableResolvers are still immensely powerful, but they do need to be coded particularly carefully.