An Extended Document Data Source To Support MIMEBean

Wed Aug 22 20:02:00 EDT 2012

Tags: mime xpages java

Ever since I personally came up with the idea of storing serialized Java objects in Notes documents via MIME, I've been trying to use the technique all over the place, since it's basically the best thing since sliced bread.

My latest notion was that the pattern would be all the cooler if the serialized Java objects could be referenced directly in EL, so you could do something like #{doc.LineItems[3].cost}, pulling directly from a more-or-less normal Domino document. I decided to give implementing this a shot, since it would also have the side benefit of introducing me to writing JSF components/complex types.

The path I took sure feels like the long route (lots of manual doubling up of property definitions and proxying methods), but it seems to work: I have a "mimeDominoDocument" data source that acts just like a normal document source except it transparently serializes and deserializes Java objects. It's not exactly a perfect implementation (the setValue() method has a rather naive method of guessing which objects should be serialized and which shouldn't, and I didn't handle the case of setting a value to an object and then using, say, getItemValueString()), but it should be fine for demo and basic purposes.

I set up an example database with pages for the appropriate code here: /tests/mime.nsf.

Starting With Java Classes First

Mon Aug 20 21:06:00 EDT 2012

Tags: xpages java

Every time I make a new XPages app, I start by using the normal xp:dominoView and xp:dominoDocument data sources, on the theory that building with the standard set of components will keep things clean while I build on top of that. However, with each successive app, the time before I get annoyed at how messy the code has to be and start writing Java wrapper and management classes gets shorter and shorter.

For example, in my Forms 'n' Views mini-Designer app, I have the sidebar list of databases, which is just pointing to a view and showing those entries. That works pretty well, since the values I need are in the view itself. However, now I want to show the database icons, but also want to check to make sure the DBs are on the current server, allow the current user to access them, and are accessible via HTTP (I'm just pointing the image to /whatever.nsf/$Icon). Doing that with just the view entries will get messy, requiring a bunch of Server JavaScript to be crammed into my xp:image object. It'd work, but it'll only be a matter of time before I want to add more smarts, such as if I make it so that you can grant enhanced access to certain design elements to a certain user. The best way to handle this will be to make a "DatabaseEntry" class and give it methods to determine the icon and design-element visibility.

I don't think I really saved myself any time by delaying this - it's pretty rare that I DON'T have this sort of calculation eventually, so I'm just adding a bit of time doing things the "dirty" way first before cleaning them up. I'm not really familiar with "vanilla" JSF, but I get the impression that it doesn't really let you put as much business logic into the view portion as XPages do (I think JSF tends to stick to EL normally). Certainly, when you write a Rails app, you start with the models and controllers cleanly before putting the data on the page. The XPage architecture doesn't make that as easy, with its lack of reasonably-modifiable controllers, but adding Java classes and using collection classes in xp:dataContexts or as managed beans work great.

I've toyed with the idea of expanding the classes I use in my forums app to work smoothly with any view/document, picking up the columns by name and storing them in Map representing the entry/document. The problem with that is that the data source and needs tend to be just different enough per app that it's not generic enough (for example, in this one, I'm getting databases for the "add DB" picker via DbDirectory, not a view). In the mean time, I think I'll just start with the access classes first and see what I do most commonly.

I Started Another Side Project

Thu Aug 09 09:26:00 EDT 2012

While working on the view indexer thing (which seems to be taking the form of "yet another SQL exporter for Domino", but with some advantages), I started thinking about how I often want a nice, quick way to edit some views, forms, or stylesheets without having to launch Windows and Designer. The Mac client is there for views, but the experience still leaves something to be desired. In addition, I do very little lately that's intended to be seen directly in the Notes client - most views are set up as data structures to be used in XPages, yet the default editor dedicates about half of its real estate to actions and a completely unreliable visual preview area and only lets you work with one column's settings at a time (other than position and width). Same goes for forms - many of them lately are just the equivalent of schemas, with the client appearance being almost irrelevant.

So, to scratch my itch, I've started making myself another XPages app:

Forms 'n' Views

This has the side benefit of giving me an opportunity to make a UI entirely composed of Dojo layout widgets - I've used them frequently, but not exclusively in a site. The dynamic tabbed panel stuff is pretty cool.

I'm trying to be careful about how the editing happens. Rather than building an object structure from the DXL and then writing out a new DXL document to import - risking deleting any additional attributes that I don't care about - each design element wrapper class works directly on a DOM version of the DXL document, so that anything that it doesn't touch remains when it's imported again. That should allow me to edit existing forms without worrying about destroying the layout - any new fields can just get tacked on to the end, or maybe in a generic table structure, while the rest of the layout remains the same.

I don't know how crazy I want to get with it (I could, for example, make it so that you can allow non-Designers access to modify specific design elements per-DB), but it's a fun little project nonetheless.

This View Indexer Thing Might Be Worth Some Time

Sun Aug 05 16:51:00 EDT 2012

Tags: java views crazy
  1. I Went Crazy and Made a Small View Indexer
  2. This View Indexer Thing Might Be Worth Some Time

I've put a little more time into my small view indexer from the other day, and it seems even more promising now. The editor I made for it might give you some idea of the potential:

Fancy View Builder

Since the view building is all being done in Java, I decided to toss in the list of available JSR-223-compliant scripting languages currently available. The scripting context is given a variable "doc" that's a DocumentWrapper class I wrote that implements Map to make its use a bit easier. For added fun, I baked in knowledge of serialized Java objects stored in the document's items:

Fancy View Objects

Normally, the wrapper just returns the value of getItemValue(...), but when it encounters a MIME entity of type "application/x-java-serialized-object", it deserializes it and returns that instead, allowing for real structured data access.

I also realized that I don't have any reason to stick to only objects available in the stock JDK for index storage. Since using this will require extra Java code anyway, I may as well make my life easier and write my own "view entry" class. Once I get that sorted out, I can work on keeping the indexes updated with a server task, dealing with reader fields, and physical storage.

Hmm, maybe I should make myself an editor for normal views that looks like this one. It'd probably be a lot less hassle to deal with than the legacy one.

I Went Crazy and Made a Small View Indexer

Sat Aug 04 11:45:00 EDT 2012

Tags: java views crazy
  1. I Went Crazy and Made a Small View Indexer
  2. This View Indexer Thing Might Be Worth Some Time

Warning: this post is almost entirely pie-in-the-sky nonsense, untethered from reality. Probably.

So yesterday, for some reason, I got to thinking about Domino's view indexing and whether or not it can be readily done better. The current view indexer does its intended task with aplomb (most of the time), but it has its problems. For one, iterating over view indexes in Java (read: everything you should do in Domino today) is dog slow. More theoretically, since it deals only with summary data for performance reasons, its ability to deal with structured data is limited - you can't deal with rich text or, for example, store any sort of Map in a Domino document and deal with it in a view (realistically).

I had the notion that it may be faster, at least in some cases, to do your own indexing: make a Java collection of your "view" data and serialize the result into a note. I decided to try a little test: take a view that consists only of a sorted column of 100k documents' UNIDs and compare it to a TreeSet of the same. My initial results were promising: iterating over the collection of documents (via getNextDocument() and a forall with getDocumentByUNID(), respectively) was about twice as fast with the Java version and was stored in about 17% the space, presumably thanks to document compression.

To be fair, that was really stacking the deck in favor of Java: I didn't care about reader fields or any entry metadata like position, and fetching every document in a large view is possibly the most expensive way to use it. Presumably, fetching just the first entry would make the view version much faster. Still, it shows that it might be useful in some cases, so I decided to try something a bit more complicated.

I made another view with 15k documents (task requests) and two columns: the date of the request, sorted, and the summary line. I matched that up with a TreeSet containing Lists of Maps and iterated over both to fetch and print the entry data. Again, the Java version ended up way faster, taking about 25% of the time.

Now it has me wondering about whether it'd be worth investigating further. It's fair to assume that Java can be treated as the new "native" language of Domino, so serialization is potentially a legitimate mechanism. Furthermore, a real implementation of an alternative view index wouldn't have to be as hopelessly naive as the one I put together: the basic java.util.* collections are almost definitely not the best storage mechanisms for a database index, and, better still, this is well-trodden territory. Since normal views would still exist in this magic future world, these fancy views could eschew a lot of the UI and build-performance requirements of the normal ones in favor of fancy tricks like native knowledge of serialized data structures. Imagine storing structured data like a table of line items in a MIME entity but then being able to query that in a "view". Reader fields could be handled by storing the applicable names in the "entry" and then comparing that two the user's names list at runtime, presumably like standard views do. A server task could handle monitoring document changes and making incremental changes (like happens now, really).

So it's theoretically possible. Would it be worth it? I'm not sure - maybe. It's fun to think about, in any event.