Using the ODA Design API for File-Resource Manipulation

Nov 19, 2014, 6:25 PM

Tags: oda design-api

As is characteristic of his blog, Sven Hasselbach recently posted two interesting posts on using the NAPI classes in the XPages runtime to manipulate files in the WebContent folder. If you haven't read the posts, I suggest you do so now, because it's knowledge that is very good to have. The NAPI classes are chock full of cheating sorcery.

But the point of this post here is a bit of me-too-ism. Which is to say: the OpenNTF Domino API has you covered on this front. The API's Design package (org.openntf.domino.design.*) contains classes that, among other things, let you retrieve, create, and modify both "normal" and these extra file resources.

The starting point is the getDesign() method on an ODA database object. Using this DatabaseDesign object, you can get access to files. For example:

Database database = FrameworkUtils.getDatabase();

DatabaseDesign design = database.getDesign();

for(FileResource res : design.getFileResources()) {
	// do stuff
}

FileResource newResource = design.createFileResource();
newResource.setName("some file.txt");
newResource.setFileData("some content".getBytes());
newResource.save();

FileResource existing = design.getAnyFileResource("existing-file.txt");
String existingContent = new String(existing.getFileData());
existing.setFileData((existingContent + " new stuff").getBytes());
existing.save();

Created file resources show up in the File Resources section currently (you can call setHideFromDesignList(true), which removes them from there, but puts them at the root of the VFS... that works, but it'd be better for them to show up in WebContent (putting "WebContent/" in the name LOOKS like it works, but doesn't)). The getAnyFileResource method will search for any "file" type element with the given name - normal file resources, WebContent files, XPages, and Java source/class files. There are better classes for manipulating the latter two, but they show up because that's how they're implemented.

One note: the Design API uses DXL, not the NAPI classes, which means it gains freedom from an XSP dependency at the cost of memory efficiency. To do its thing, it must export the file as DXL, which will be larger in memory than the file size, and then convert that BASE64 representaiton to bytes, meaning the memory cost is more than double the size of the file. For most files, that's fine, but be wary of dealing with, say, 200MB video files. That sort of thing totally works (I tested), but only if you have the memory to spare and your JVM configured to use it. Maybe one day the API will have direct access to the notes.

Okay, a second note: it's important to make sure that the max Internet access level is Designer or above for this to work, at least with the normal session object.

If you haven't taken a look at the Design API before, it may be worth at least glancing over the DatabaseDesign interface to get a feel for what it currently allows. Maybe attention on it will coax me into finding free time to finish all the other aspects I plan to get to.

Commenter Photo

Mark Barton - Dec 15, 2014, 11:06 AM

Jesse is there a Jar for the Domino API I can  use in a Java agent?

I want to use your code to replace file resources either from a HTTP stream or a file - this means we could use a very old hack to have Server Side includes for Domino - where the static HTML is generated on alternative platforms (thinking handlebars + node).

I started to dig through the source and it seems daft to extract the different classes from your API when you have done all of the hard work.

I am ok with Java but not brilliant  and it would be great it you could point me in the direction of a Jar file?

Thanks

Mark

Commenter Photo

Mark Barton - Dec 16, 2014, 4:28 AM

Many thanks Jesse - I will let you know how it goes.

Mark

Commenter Photo

Mark Barton - Dec 16, 2014, 6:00 AM

Got a bit bogged down trying to get from louts.domino.Database to ODA Database - do you have the FrameworkUtils class handy?

Mark

Commenter Photo

Jesse Gallagher - Dec 16, 2014, 6:02 AM

If you're in an agent, the quickest way to switch is to just change the "import lotus.domino.*" line to import "org.openntf.domino.*". That contains a JavaAgent class that provides a pre-wrapped Session class (assuming it's still working, that is).

Commenter Photo

Mark Barton - Dec 16, 2014, 6:47 AM

Jesse - it was initially looking for the Notes.ini under the framework directory - so I have copied my ini there.

Getting a class not found now for org.openntf.formula.DateTime.

Mark

New Comment