Bridging the Gap – The File Upload saga continues…

Last week on LOST….
What’s the issue with a File Upload control in a WebSphere Portlet (and please, if you’ve done something like this and know an easier way, I’m all ears)?

WebSphere portlets aren’t keen (they don’t listen for) forms that use multi-part encoding. The portlet action gets ignored, your file delivered to the heavens and your customer left feeling blue (IBM Blue?).

So the first part of the two part problem is getting the file up to the server. The second involves what to do with it once it arrives. The image files needs to be persisted to the user’s Member record inside LDAP.

Portal provides a nice facade for dealing with Members. It’s called WMM (WebSphere Member Manager). WMM masks things like attribute mapping and LDAP syntax, it’s just the gate keeper. Works nicely…provided you’re within the Portal context (making a Portlet request).

Let me try tying the two issues together with the solution I devised.

The Portlet now calls an external (from the Portal context) Servlet to grab and parse the file (using Apache’s wonderful FileUpload library from their Commons project).

So now I have the file…how do I get it into a valid WMM context (knowing the receipt of the file came via HTTPServletRequest rather than Portlet Request)?

Here’s a little pattern I tried, using Observer. I call it the PhotoBooth/PhotoLab pattern.

When the portlet’s Session bean instantiates from the Portlet, I create an Envelope. The Envelope contains the user’s unique id and a property to house the image (byte[]). The Envelope is then ‘dropped off’ at the PhotoLab, a singleton with a Map of Envelopes. The Map’s key is the unique ID. So the empty envelope has been left at the PhotoLab. When the FileUploadServlet receives and parses the file, it asks the PhotoLab for the envelope (the key was a parameter passed to the FileUpload servlet). The photo gets placed into the envelope and then guess what happens?

Yep, the trusty old Observer pattern kicks in. When the image setter is called on the envelope, the state gets changed (calling setChanged(); ) and then Observers are notified: The Session bean’s update() method gets called and the envelope is dropped of.

The Portlet now has the photo and can use WMM to persist it when the user clicks ‘Save Profile’ (via PortletRequest)

I’m happy with how it works, I just need to clean up the implementation a little bit. Ted O’Grady did a great job of defining the code’s current state as the Speculative Solution…time to clean that speculation up a bit and get the Durable code in place.

File Upload, Portal, JSF and not being surprised…

I’m writing a portlet that allows a user to modify certain LDAP attributes.  It’s a nice little solution (if I do say so myself), wrapping IBM’s PUMA framework with something a little more durable, a little more generic and a lot less IBM.

The customer would like the user to upload their own picture.

“Yeah, shouldn’t be a problem…” I say, recalling the File Upload control on Rational Application Developer’s JSF palette…famous last thoughts.

IBM, in their wisdom and glory, have shipped some JSF components that don’t work with their Portal solution.  They’re available for use in a Portal project, they just don’t work… (bonus points to me for looking it up in the documentation rather than bugging the local IBM on-site consultant).  I guess that makes sense…

This means a trip to Apache and a chance to try the Commons File Upload component (apparently it works with Portal…I won’t get into why I find this entire thing so hilarious).

EJPPG0003E: ServletContext lookup for /.CreditCounterPartyReviewLog returned the portal context. It has to be a different one.

I’m working on a Portlet project right now. It helps a group over at TransAlta keep their financial obligations and exposures in check. I like the application…it has great business value, terrific customer participation…a great project.

A second developer was introduced to the project recently. He brought the portlets down from CVS and tried running them on his workstation. The received the following error:

2006.08.23 13:37:49.064 E getServletContext
EJPPG0003E: ServletContext lookup for /.CreditCounterPartyReviewLog returned the portal context. It has to be a different one.

hmmm, what does that mean? He created an EAR file to associate the project with…ahh, but wait! When Rational Application Developer associates Web Modules with an EAR, it doesn’t give it a context root. It tries using the context root for the Portal itself (uh oh) and then throws the exception found above. Fixing it, as my good friend from IBM Thomas Young discovered, is quite simple. Open the EAR, find the module reference and click ‘Refesh’ located beside the Context Root field.

ReDeploy and run…Right Side, not cropped