Xpages Xtreme
I was lamenting today that I haven't done
much technical blogging in the last year or so. It's a bit of a personal
disappointment to not be publishing as much, but it's not without reason.
I've worked for both service- and product-oriented companies over
the last 17 years, and the pattern is always consistent: working in services
means sharing more technical tips. In October I went from working
for a services company that dabbled in products to a product company that
acquired a services team. Of course, that was less of a sea change
that you might assume, as the Lotus 911 development team had been working
on a product-focused solution for 6 months at that point in the form of
Bones.
So, as you might imagine, my job responsibilities have included a
lot more trade secrets than they have in the past. This is good for
my personal progression; while not so good for my publication results.
I'm sure every developer reading this can relate to that constant
tension.
We did get to show off some results at Lotusphere, although truthfully the Atlanta dev team was uncharacteristically coy about the whole thing. I think we showed some exciting direction, but we really didn't talk about what we did behind the scenes. And while I can't really describe things in detail, as I look around the blogosphere and see long time yellowbleeders really starting to understand the power of Xpages, I thought I'd take a minute and stretch the boundaries of my nondisclosure, and at least talk about what we know is in the realm of the possible.
Click through for more...
We did get to show off some results at Lotusphere, although truthfully the Atlanta dev team was uncharacteristically coy about the whole thing. I think we showed some exciting direction, but we really didn't talk about what we did behind the scenes. And while I can't really describe things in detail, as I look around the blogosphere and see long time yellowbleeders really starting to understand the power of Xpages, I thought I'd take a minute and stretch the boundaries of my nondisclosure, and at least talk about what we know is in the realm of the possible.
Click through for more...
1) Scoped variables can be transcendent.
If you've read the doc, you know about Request, View, Session and
Application-scope variables. What may not be obvious is that because
all Xpages applications run in the same JVM on the server, it's possible
to share information even between Applications. And perhaps even
more amazingly, because there's now a single JVM instance on Domino 8.5.1,
you can actually share in-memory information between Xpages, Agents and
Web Services. We have a handy little server JAR to do this.
2) XSP components can simply be generated. Whether you're in server-side javascript, or a native Java bean, once you get a specific UI root, you can drop in your own custom controls declaratively, whether you've included them on your .xsp or not. Think of this like being able to run a WebQueryOpen agent and declaratively inject a subform or embedded view at runtime. With the proper motivation, you can basically make the Designer visual IDE unnecessary.
3) EL resolution is seriously dynamic. You can write your own Expression Language resolver, which means you can effectively design your own language syntax inside Xpages. Once you start with your own managed bean, there's straight forward syntactical rules to follow to resolve expressions of any length. When combined with item 2 above, this means you can dynamically inject UI elements with extremely complex EL bindings. We regularly work with runtime-generated Xpages that include edit control bindings like #{innova.module['Expenses'].record['1234567812345678'].wire['Project>Company>BillingContact>EmailAddress'].value} Generic Xpages would have no idea what that means, but throw something in your faces-config.xml settings, and suddenly that's valid syntax that can be a symmetric binding for normalized data.
4) Datasources are scoped internally in the component tree. This means that if you have a component inside, say, a repeat control, it can include datasources that bind dynamically according to what they repeat over. Define the right kind of datasource, and all your item-level bindings become symmetric -- you can write back to them just as readily as you can read. This is extremely handy. A custom control included in a panel that's in a repeat control can write back information to documents in a view with ease.
5) Repeat controls are far more flexible than folders or views. The very first thing I ever wrote about Xpages was the ability to perform a column-based JOIN of information from a foreign view inside a View custom control. While that's all well and good, the truth is that there is far more flexibility than people realize here. For instance, you can grab a repeat component and give it some arbitrary DocumentCollection as new data. Think of this like being able to change the collection in a folder on the fly, except without the disk-write penalty. Play your cards right, and you can even create some specific behavior inside that Collection, like being able to sort it on any arbitrary criteria, including foreign values as in the Tigerstyle demo.
6) Yes Virginia, there is a Santa Claus. After the last 10 weeks of struggling with some very advanced Xpages development, my team got some breathing room in the post-Lotusphere euphoria. We spent it on designing better ways to debug XSPs. When you have Tim on your team, that works to your advantage, and I would describe his approach as "exceedingly clever." The result is that we have a Firebug plugin that reveals the whole Xpages component tree, along with a per-user console output from executable code. We're trying now to figure out a way to make this available to the Lotus community at large.
Of course, as long as we still have motivated and talented engineers, the innovation never stops. We're exploring topics now like transactional boundaries and rollbacks, and normalized security controls. As we prepare to bring our vision of next generation Domino apps to market, we'll continue to reveal new solutions that break the boundaries of what people think of as Notes & Domino. And as always, we're trying to find ways to balance the everyday business need to generate return on investment against the eternal desire to share as much as we can.
Hopefully, you'll stay tuned.
2) XSP components can simply be generated. Whether you're in server-side javascript, or a native Java bean, once you get a specific UI root, you can drop in your own custom controls declaratively, whether you've included them on your .xsp or not. Think of this like being able to run a WebQueryOpen agent and declaratively inject a subform or embedded view at runtime. With the proper motivation, you can basically make the Designer visual IDE unnecessary.
3) EL resolution is seriously dynamic. You can write your own Expression Language resolver, which means you can effectively design your own language syntax inside Xpages. Once you start with your own managed bean, there's straight forward syntactical rules to follow to resolve expressions of any length. When combined with item 2 above, this means you can dynamically inject UI elements with extremely complex EL bindings. We regularly work with runtime-generated Xpages that include edit control bindings like #{innova.module['Expenses'].record['1234567812345678'].wire['Project>Company>BillingContact>EmailAddress'].value} Generic Xpages would have no idea what that means, but throw something in your faces-config.xml settings, and suddenly that's valid syntax that can be a symmetric binding for normalized data.
4) Datasources are scoped internally in the component tree. This means that if you have a component inside, say, a repeat control, it can include datasources that bind dynamically according to what they repeat over. Define the right kind of datasource, and all your item-level bindings become symmetric -- you can write back to them just as readily as you can read. This is extremely handy. A custom control included in a panel that's in a repeat control can write back information to documents in a view with ease.
5) Repeat controls are far more flexible than folders or views. The very first thing I ever wrote about Xpages was the ability to perform a column-based JOIN of information from a foreign view inside a View custom control. While that's all well and good, the truth is that there is far more flexibility than people realize here. For instance, you can grab a repeat component and give it some arbitrary DocumentCollection as new data. Think of this like being able to change the collection in a folder on the fly, except without the disk-write penalty. Play your cards right, and you can even create some specific behavior inside that Collection, like being able to sort it on any arbitrary criteria, including foreign values as in the Tigerstyle demo.
6) Yes Virginia, there is a Santa Claus. After the last 10 weeks of struggling with some very advanced Xpages development, my team got some breathing room in the post-Lotusphere euphoria. We spent it on designing better ways to debug XSPs. When you have Tim on your team, that works to your advantage, and I would describe his approach as "exceedingly clever." The result is that we have a Firebug plugin that reveals the whole Xpages component tree, along with a per-user console output from executable code. We're trying now to figure out a way to make this available to the Lotus community at large.
Of course, as long as we still have motivated and talented engineers, the innovation never stops. We're exploring topics now like transactional boundaries and rollbacks, and normalized security controls. As we prepare to bring our vision of next generation Domino apps to market, we'll continue to reveal new solutions that break the boundaries of what people think of as Notes & Domino. And as always, we're trying to find ways to balance the everyday business need to generate return on investment against the eternal desire to share as much as we can.
Hopefully, you'll stay tuned.




Comments
...than reading your blog on the iPhone!
Please fix that; on the iPhone, you only read the teaser text, but the link "Please click through for more..." does not work and there is no "Permalink" link in the iPhone blog layout. What a pain, especially for this article.
Sounds all pretty cool. I guess you also have a fancy UI to configure that stuff and let users add their own UI elements (or even complete applications) without the need to dive into Domino Designer.
I could add two things to the list:
7) Why do you only bind repeat controls to a list of data objects? Think about binding it to a java object structure that describes your user interface instead (hey, when does the first one develop a CMS based on this?!).
and
8) If all this Java, bean, repeater stuff sounds like rocket science to you and you like rocket science, visit the "XPages" category of our blog. There is a series that helps to get started with your own advanced XPages development.
Posted by Karsten Lehmann At 02:38:37 AM On 02/03/2010 | - Website - |
Glad to hear that this technique still works with XPages.
Posted by Julian Buss At 03:05:39 AM On 02/03/2010 | - Website - |
Posted by Fredrik Stöckel At 05:23:05 AM On 02/03/2010 | - Website - |
Great stuff! Sounds like you're having fun.
-John
Posted by John Mackey At 08:34:44 AM On 02/03/2010 | - Website - |
Leveraging the Expression Language resolver is definitely awesome - I've got a multi-contextual @Formula evaluator I wrote a few years ago and it tickled me pink when I realized I could just drop it in to the EL with full entity awareness. I've been meaning to expand it in a manner syntactically similar to what you've done since it's slightly more elegant when formulas aren't involved.
Do tell me you've shown Tiger Style (great name, by the way) off on Design Partner calls and screamed "NSF indexing needs to be able to do this stuff!"
#6 sounds particularly sweet.
Posted by Erik Brooks At 08:43:40 AM On 02/03/2010 | - Website - |
The trick for 2) is probably, that the UIComponents of XPages return a mutable Java List when you call UIComponent.getChildren(). That means that you can call childList.add(UIComponent) to add your own children, as long as you find out how to create new instances of the XPages UIComponents or create a copy of existing ones.
BTW, a Java best practise is to not return the actual instance of lists and array, but only return a copy of it to prevent others to hack into the system
Regarding 3), that offers a lot of possibilities, but I think you may get some problems in DDE (in case you don't create the complete UI in code like Nathan's team does, but in DDE). Don't know how good DDE supports custom EL expressions. At least DDE 8.5 liked to overwrite such things in the XPage's source code. 8.5.1 got a bit better, haven't checked 8.5.2.
But there is different approach if you understand how the standard EL parser resolves the expressions. I expained it in article #5 of our series ( { Link } ). You could for example create your own implementation of the java.util.Map interface and declare it as a managed Java bean, e.g. "MyMap".
An expression like #{MyMap["@Text(@Now))"]} would then make the JSF framework call MyMap.get("@Text(@Now))"). In your get method implementation, you can then evaluate that expression and return a string, or even a java object (e.g. a Java List that could be used in a repeater).
Posted by Karsten Lehmann At 09:22:04 AM On 02/03/2010 | - Website - |
Karsten's series on managed beans was invaluable when we started getting serious about XSP deep-diving 6 months ago, and using beans is really the reason why only 1 person out of 4 was really spending any time in Designer for the last 10 weeks. We owe him a debt of gratitude.
@2 - I don't know why I never bothered to think about the commonality of the JVM before. This was just something we encountered when we wanted to design Server-scoped variables for read-through-write-behind caching. (which is again implemented as a bean in any given app.)
@4 - @6 is correct. There's are some hard-learned lessons about sequencing, though. No debugger and no documentation make the experience like a blind man solving a Rubik's cube.
@5 - I assure you that the right people at IBM have seen the Tigerstyle demo and understand the importance of that functionality set. That's really all I can say about it.
@6 - Designer 8.5.1 seems to handle our custom EL syntax just fine. That's how we smoke test the expression resolver in the first place.
Returning Maps for the EL resolver works, and we do it quite frequently. There are some other ways to approach this as well that give a bit more flexibility, and take into account some of the automatic behavior of the renderkit. For instance, an Edit Box which is bound to a field on a document that the user only has Read access to will be rendered as HTML text, instead of an <INPUT> tag. There are ways to do something similar in your own EL resolvers, but I don't know whether IBM is ready to make those interfaces public yet.
It's funny... out of all this other stuff, I left out a really cool and useful thing we did, which was tap into the Typeahead control behavior so we could do keyword aliasing. That proved rather useful, and took a surprising amount of work to get right.
Posted by Nathan T. Freeman At 09:50:42 AM On 02/03/2010 | - Website - |
Posted by Peter Presnell At 09:51:39 AM On 02/03/2010 | - Website - |
Posted by Jo Grant At 01:02:50 PM On 02/03/2010 | - Website - |
Can you pl. tell me how to integrate apatna plugin with in domino designer 8.5.1.
thanks,
haran
Posted by Haran At 01:25:28 PM On 02/22/2010 | - Website - |