Wednesday, April 29, 2009

Linked!!!

DominoPower Magazine picked up my post on Creating PDFs in a Java Agent using Apache FOP.


(Something to tell the grand kids someday.)

Tuesday, April 28, 2009

Creating PDFs Using Notes Java Agent

A new project hit my desk a few weeks ago. The project involves the enhancement of an existing Notes workflow application, adding on processes to the start and finish of the workflow process. One of the requirements is to create a PDF for archival as the final step. In order to save some money and learn some new techniques, I chose to look into using the Apache FOP project.

I learned a few things while building a proof of concept and wanted to share what I learned. At a high level, this approach will require some knowledge of Java agents and a little knowledge of XSL-FO. So if you're not already up to speed on these two areas, you might want to spend a little time with the following:

  • Java agents and the Notes Java back-end classes. The notes help has a pretty good reference, and if you know the LotusScript back-end classes, you pretty much already know the Java classes. Also note that Java is pretty version specific and the Apache FOP project requires 1.4.x or later. That means this solution only works on Lotus Domino 7 or newer.
  • You'll probably want to learn how to use Eclipse in your Java agent development. Although not necessary, it provides a lot of help organizing and importing your packages, and assisting with your coding so your method signatures are correct, etc.
  • Depending on how intricate your PDF formatting will be, you'll want to familiarize yourself with XSL-FO. Also, download the Apache FOP zipped source files and look at the example FO files for ideas.
  • Download and set up OpenLog from OpenNTF.org to help in your debugging and error handling. As always, you can use the Java Debug Console or system.out to the console and log.nsf, but OpenLog gives you a few more options such as including a document link to the document being worked on at the time of the log event or error event. (You can even debug from Eclipse if you know what you're doing.)

My original approach was to import the Jar files into the agent or a script library, but I ran into a few problems with this approach: even if you get your base directory lined up correctly for your classes to access the META-INF path, the Jars are too big to include and will throw a out of memory error. Although not ideal, you will need to put all the Jar files in the jvm/lib/ext directory of your Domino directory (or Notes directory if you're testing locally).

The rest is pretty straightforward:

  • My agent (download the sample NSF here) will access a Notes document and construct the FO as a string. The string is constructed from various fields in the document and formatted to conform to the XSL-FO standards. When complete, the string is passed into a transformer class. (If the XSL-FO is quite large or elaborate, you will probably want to use a StringBuffer: use the append method to build the XSL-FO; use the toString method to pass the resulting XSL-FO into the transformer.)
  • Use the example in the Basic Usage Pattern to write the FOP components of your Java agent.
  • The results are saved to a file on disk, which you will eventually want to deal with. In my case I'll save directly to the file system of another server using a UNC path. In the example you will see a file path in which you can specify where the resulting PDF is to be saved. If you would like to add the PDF as an attachment to a document use the embedObject method of the RichTextItem class. Depending on what you end up doing with these PDFs, you might find yourself with a pile of files. Cleaning up these files can be done with another LotusScript agent or with the java.io.File class delete() method in the same Java agent.
  • Because the agent is writing to the file system you will need to give it a runtime security level of 2, allowing restricted operations.

Regarding setup, for testing you can run it locally on your workstation. Download the FOP binaries at the Apache site and extract the jar files to your notes/jvm/lib/ext directory. Sign the database and give that ID manager access and double-check that ID can run unrestricted agents. Right-click the ApacheFOP agent and select Run. If everything goes well and you haven’t changed anything, there should be a file in your C:\Temp directory called myfile.pdf. Once you know its working, go ahead and start customizing things to suit your needs.

Note: The code uses the UNID of the Simple.fo document that is inside the nsf, so you can open that document up in your Notes client and modify the XSL to make it custom for you.

There's alot of different things you can do within the FO, different approaches with Notes to build the FO, and different ways to process the resulting PDF (attaching, emailing, etc.). Hopefully this open source solution gives you some new options when it comes to incorporating PDFs into your Notes applications.

Thursday, April 16, 2009

LCTY Minneapolis

Just a couple quick thoughts on yesterday's Lotusphere Comes To You Minneapolis. The one thing that really stood out for me was the number of new faces. Typically, these events draw alot of the Lotus faithful, but I noticed quite a bit more new faces in the crowd. Granted, this is a very unscientific analysis, but I do have another supporting piece of information to back this up. At my lunch table I spoke with two gentlemen who were either brand new to Notes or whose employer is a new Lotus customer. This is a good sign that the Lotus Software climate is not only alive, but growing. There is excitement about the new Notes and Sametime clients and the accompanying new technologies in the 8.x releases.

I think to round things out, the message needs to penetrate upper management of existing customers, both at the I.T. level and at general corporate level. The new customers (my lunch mates yesterday came from a position of not having a good email solution and evaluating the product market from scratch) are finding value, having not known much about Lotus Notes. Does upper management know what these new customers have found out?

After new customers get it, and upper management gets it, the last piece for all of them to be enlightened on is the value Notes and Domino brings as an application development platform. With new tools in our toolbox--composite applications, XPages--we developers can reignite interest in using Notes and Domino to provide excellent solutions to meet business demands.

Keep up the great work everyone!

Tuesday, April 14, 2009

Microsoft BizSpark

Got a LinkedIn invitation to join Microsoft BizSpark, so I started the sign-up process. Looks like an interesting deal: get access to developer tools and resources for free. I'm interested for two reasons.
  1. I'm interested in extending the capabilities of the Notes client by scripting into the Microsoft Office Suite. (On the same note I'm also interested in extending the capabilities of Notes by scripting into Lotus Symphony and OpenOffice.)
  2. As a newly minted small business owner, I'm interested in what big corporations are offering little guys like me. I'll keep an eye on things and perhaps let IBM know what's going on inside BizSpark.
I shall keep you all posted when I find out more.

Monday, April 6, 2009

No Ordinary Small Business I.T. Solution

Why settle for an ordinary I.T. solution? Make your small business extraordinary!



Does your current I.T. solution facilitate

COLLABORATION

inside and outside the office? Help with

INNOVATION

in delivering your product to your customers? Provide

BUSINESS AGILITY

in responding to change? Facilitate

SUPERIOR CUSTOMER SERVICE

? Allow you to leverage

SOCIAL SOFTWARE

? Provide

INSIGHT

into your operation and your market? Help seek out a new

OPPORTUNITY

? Would your potential I.T. solution help with

COST REDUCTION

? Does it give you

FREEDOM OF CHOICE

? How about

FLEXIBILITY

?

IBM Lotus offers you all of these.

Want to know more? Contact me.

Saturday, April 4, 2009

Does your job give you enough satisfaction?

Joel Spolsky writes a column for Inc. Magazine in which he discusses how to structure salaries in such a way that things can be equitable and transparent.

A couple paragraphs resonated with me, as I've been that miserable employee:

At the same time, if you hear a lot of griping about salaries, you shouldn't look just at your system for paying people. One thing I've learned from experience is that happy, motivated employees who are doing work they love and feel they are being treated as adults don't gripe about money unless their pay is egregiously unfair. If you hear a lot of complaints about salaries, I suspect that's probably a manifestation of a much bigger disease: Your employees aren't deriving enough personal satisfaction from their work, or they are miserable for other reasons.

It takes a lot of salary to make up for a cruel boss or a prisonlike workplace. And rather than adjusting pay, you might choose to focus on some nonmonetary ways to make employees happy. Happy employees make better products and provide better customer service and will make your company successful and profitable. And success allows you to pay workers better. It's a virtuous circle, and it has worked for Fog Creek.

I've always said that people will work for much less, provided they're happy and they feel like they're a productive, contributing member of the team.

Friday, April 3, 2009

Small Business IT Services

Following up on a post from January, I wanted to expand on point #2: Develop a Strong Marketing Message and Hook. I really believe IBM Lotus is offering an outstanding value to small and medium size businesses. So the message is...

The lineup is extensive:
The technology's reliability and scalability has been proven in the enterprise. The administration of these products has been refined over many years and they practically run themselves. Their "fit and finish" are on par with all the Web 2.0 offerings presently in the market. They offer out-of-the-box functionality for mobile access as well as provide tools to combine your Notes applications with external data (aka Mashups). Third party solutions to layer on top of these platforms are abundant and talented independent systems integrators (Me!) are ready to help put these products to productive and profitable use.

The hook? Why go with the unproven upstart or the default choice just because you didn't dig a little deeper to find a really great value? With Express licensing, small and medium size business can get these enterprise-grade technologies at a very affordable price.

Thursday, April 2, 2009

Document was deleted from this collection

In LotusScript, you might encounter the error number 4434 and/or the error description "Document was deleted from this collection" when looping through a NotesDocumentCollection object and calling the DeleteDocument method.

I'm a big fan of OpenLog, which has shaved off a ton of development time when coding back-end objects that are difficult to debug with the LS debugger. Most recently, it helped detect a bug in my code that might never have been caught. The error wasn't fatal, but it revealed that my code just wasn't doing what I thought it should be doing.

Anyway, since Google is our friend when we run into issues like this, I thought I'd post it to benefit any future searchers. Notes help is fairly useless for troubleshooting error numbers and in this particular case the example code only retrieves the first document in the collection.

Credit for helping me solve this problem goes to Domino Power and Mick Moignard. The article is about folders, but the relevant piece has to do with utilizing a temporary NotesDocument object and setting it to your current NotesDocument object so you can use that object as the parameter in the DeleteDocument method. This allows you to use your current NotesDocument as the parameter in the GetNextDocument method at the end of your loop. Without it, the GetNextDocument has no reference point to refer to in the collection.

Here's an example where you want to remove a document from a collection based on some criteria (SomeFlag = 1) and maybe do something with the collection later on, such as StampAll.

'Assume I have already built the NotesDocumentCollection called docCol
'and I have dimensioned two NotesDocument objects, curDoc & tmpDoc
Set curDoc = docCol.GetFirstDocument
For i = 1 to docCol.Count
        If curDoc.SomeFlag(0) = 1 Then
                Set tmpDoc = curDoc
                Call docCol.DeleteDocument(tmpDoc)
        End If
        Set curDoc = docCol.GetNextDocument(curDoc)
Next

Using the temporary document allows you to not lose your reference to the current document in your collection.

This should help spur things along

Accounting board poised to give companies more leeway in asset values. Looks like the market likes it: