Categories
bdg Plumtree • BEA AquaLogic Interaction • Oracle WebCenter Interaction

Ruby IDK 5.3 development has begun

We’ve laid down the basic architecture for the Ruby IDK 5.3 and written most of IPortletContext and IPortletRequest. We also now have a test bed application built in Rails, the output of which checks for CSP-Gateway-Type == 'Plumtree', displays your HTTP environment (dumps all the headers) and then proceeds to call each IDK method in IPortletRequest.

This is our first adventure in Ruby and I must say, it’s easy breezy. What a great language! And don’t get me started on how easy it is to prototype a web application with Rails using scaffolding. Makes J2EE seem almost neolithic.

Categories
dev2dev Plumtree • BEA AquaLogic Interaction • Oracle WebCenter Interaction

ALUI Portlet Pagination Cookbook

A coworker asked me how to write Plumtree portlet pagination (i.e. showing records in a UI and allowing the user to move from page to page, n records at a time) the other day and the ensuing discussion made me rethink how I’ve always done this and consider some new options. In this post, I attempt to shed some light on a very simple concept that turns out to be quite interesting in terms of implementation.

First, let’s consider some of the ways developers typically add pagination to standard web applications, forgetting about portals and portlets for a moment. Let’s call n your page size, i your page number and t the total number of records. On the first page, you might see n records laid out with alternating row colors and a 1-n of t marker to show you were you are, e.g. Now Showing Records 1-5 of 45. There’s probably also a next button and a back button (grayed out for now), a first page button (also grayed out), a last page button and maybe even a “fast-forward” button to move forward several pages at a time.

A very easy way to implement this in a standard (non-portal) MVC Java/J2EE Web application would be to carry some state, say i (the page index), on the querystring. For example, say you have a record viewer servlet called “RecordView” running on a Java-enabled Web application container such as Tomcat. You could have something like http://bdg-plumtree:8080/bdg-plumtree-context/RecordView as your URL. Your servlet code snippet might look something like this:

import javax.servlet.*;
import javax.servlet.http.*;

...

private Model model;

protected void doPost(HttpServletRequest request,
                      HttpServletResponse response)
                        throws IOException {

    //if you didn’t specify a page argument, display the
    //first page (pageIndex = 0)
    int pageIndex = request.getParameter("i") == null ? 0 :
      Integer.parseInt((String)request.getParameter("i"));

    //make a call into the data model to get the i-th page
    //and put the results in the request
    request.setAttribute("results", model.getResults(pageIndex));

    //forward to your view (JSP)
    request.getRequestDispatcher("view.jsp").forward(request, response);
}

In the view, you would simply print out the results, line-by-line, perhaps alternating row colors to make it easier to read. Then you need to display the little marker that tells you what page you’re on and the buttons to get next/back/to the end/etc. The logic to figure out what buttons to display and which buttons to gray out is a little involved, but it’s mundane enough that I don’t think I need to cover it here. The important part for this discussion is what’s in the links that actually take you forward and (soon) back. The answer there is simple enough — just create links that append the appropriate querystring and you’re all set. Here’s an example:

<a href="http://bdg-plumtree:8080/bdg-plumtree-context/RecordView?i=<%=i + n%>">Next</a>

So far so good.

The problem is that when you try to do this in an ALUI portlet, you don’t have direct access to the querystring, so you can’t use this approach. You need to store the variable i using some kind of state mechanism. Here are your options:

  1. The HTTP session
  2. A portlet setting
  3. A session setting (G6 and up only)

There are tradeoffs between #1 and #2 but #3 offers a good compromise. Let me explain.

If you use the HTTP session, your users’ page setting (i), will only persist for the life of the session, which is probably desirable. But, if you’re using the Plumtree caching model for portlets (such as expires or last-modified/etag caching), you can’t cache this portlet at all, which is definitely not desirable. The reason is that every page, regardless of the value of i, will have the same cache key.

To implement session-based pagination, you only need to change two lines of code:

request.getParameter("i")
becomes request.getSession().getAttribute("i") and your anchors that control the moving from page to page now need to point to a different controller servlet. (Remember, you don’t have control over the query string any more in portletland).

<a href="http://bdg-plumtree:8080/bdg-plumtree-context/ChangePage?i=<%=i%>">Next</a>

The ChangePage servlet simply sets the session attribute and then calls return to portal as shown here:

request.getSession().setAttribute("i",
    request.getParameter("i"));
PortletContextFactory.createPortletContext(request,
    response).getResponse().returnToPortal();

The only way to unique-ify the cache key, therefore caching your portlet appropriately, is to go with approach #2, the portlet setting. Now, when users advance i, they will be creating a new cache entry for each value of i (since settings are always part of the cache key). The drawback is that the users’ page settings (i) will persist longer than the life of the session. In other words, they could be browsing page 5, then they could leave the portal for several days, come back, and still be on page 5!

For your view:

PortletContextFactory.createPortletContext(request,
  response).getRequest().getSettingValue(SettingType.Portlet, "i");

And for your ChangePage servlet:

PortletContextFactory.createPortletContext(request,
  response).getResponse().setSettingValue(SettingType.Portlet, "i", request.getParameter("i"));
PortletContextFactory.createPortletContext(request, response).getResponse().returnToPortal();

G6 offers a nice compromise: the session setting. (If I had to guess, I would say the session setting was designed expressly for pagination.) With a session setting, you get the best of both worlds: a page setting that lasts only for the duration of the session but also a unique cache key so that you can effectively cache your portlet.

For your view:

PortletContextFactory.createPortletContext(request,
  response).getRequest().getSettingValue(SettingType.Session, "i");

And finally, for your ChangePage servlet:

PortletContextFactory.createPortletContext(request,
  response).getResponse().setSettingValue(SettingType.Session, "i", request.getParameter("i"));
PortletContextFactory.createPortletContext(request,response).getResponse().returnToPortal();

All of these methods have one drawback — they refresh the entire page on every portlet pagination click. So . . . stay tuned for an upcoming post on AJAX-based portlet pagination.

Comments

dev2dev comments are listed in date ascending order (oldest first)

  • This is a good start for everyone on Java. If you are like me and are a .NET developer at heart, you will be glad to know the .NET Web Control Consumer supports the use of a MS data grid control. All that is needed is for the developer to drag one of these objects onto the form, hook it up to a data source, and presto, you get pagination, storability, edit, and any other thing you always wanted from a table.

    Andrew Morris – [email protected]

    Posted by: drews_94580 on August 15, 2006 at 2:03 PM

  • It’s true — in many ways, .NET is way ahead of Java. I have only a little experience with the .NET Web Controls and the Control Consumer, but from what I’ve seen, there’s a lot of power and flexibility there. My post was making the “I want to roll my own pagination in Java” assumption. 🙂

    Posted by: bucchere on August 16, 2006 at 8:30 PM

Categories
bdg dev2dev Plumtree • BEA AquaLogic Interaction • Oracle WebCenter Interaction

Mingle & the PHP EDK moved to dev2dev’s CodeShare

Just in case you’re looking for our two opensource projects that were once accessible via the Plumtree Portal, you can now find them on BEA dev2dev’s CodeShare. Here are the links:

Mingle: https://mingle.projects.dev2dev.bea.com
PHP EDK: https://plumtree-php-edk.projects.dev2dev.bea.com

Enjoy!

Categories
Plumtree • BEA AquaLogic Interaction • Oracle WebCenter Interaction

Plumtree releases G6

Late yesterday, Plumtree announced the release of their G6 line of products. They have made everything generally available for download for partners and customers at portal.plumtree.com.

A couple things have been renamed. The Portal has become the “Foundation,” Content Server has become “Publisher,” Authentication Web Services have become “Identity Services,” Crawler Web Services have become “Content Services,” the .NET Web Controls have had the word “Consumer” tacked on the end, and the EDK (once known as the GDK), is now contained within something called the PDK. Not sure what happened to the WSRP container, but the JSR 168 container has been updated for G6 as well.

The major difference is that the Foundation product and many of the services are now entirely Java-based or entirely C#-based. This means some interesting things, including the fact that although Plumtree is only officially supporting RedHat Linux 3 ES Update 3 right now, there’s a good chance that the Java version will run (and run well) on other versions of Linux and even on Solaris or even Solaris X86.

On Windows, the support matrix includes IIS 6.0 and SQL Server 2000 SP3a.

For the non-Microsofties, Oracle 9i and Oracle 10G (with or without RAC) are supported along with Tomcat 5.0.28, IBM WebSphere 6.0.1 and of course BEA 8.1 SP4.

If you’re just silly like that, you can also run any of those configurations on Windows, but I’d have to ask you “why?!?” if you did. 😉

Major feature differences include a re-tooled (and now web-based) object migration, enhanced subportals (now called user experiences), improved user syncrhonization, enhanced Snapshot Queries and Best Best, and improved tools for integrating existing web applications into the portal.

Everyone at bdg is excited about this release and we look forward to helping our customers upgrade to the latest and greatest, starting whenever they’re ready.