Using the "exclusive" Window State in uPortal

holdorph's picture

I have just finished creating a sample application to allow a portlet to transmit binary data to end users. For this particular sample I wanted to take advantage of the uPortal custom Window State called "exclusive". I am happy to report I have this application working.

I started this project with a vanilla uPortal 2.5.3 GA download. I did run into one problem that required obtaining a new version of the pluto jar file. The version I ended up using came from the head of the 2.5 branch, so will be included in a future uPortal 2.5.4 release. (The same jar will also appear in a future uPortal 2.6.0 release as well)

There are 3 things you need to accomplish file downloading in a Portlet with uPortal's exclusive window state.

  • Create a PortletURL with the exclusive Window State
  • Specify any additional content types your Portlet will use in the portlet.xml file
  • In the Portlet code, detect the exclusive Window State, set the appropriate content type and write the binary data to the Portlet OutputStream

To create a PortletURL in your Portlet code for the exclusive Window State follow you can code like this.


PortletURL url = response.createRenderURL();
url.setWindowState(new WindowState("exclusive"));

When you edit your portlet.xml, you must include one additional supports section per content type. The following portlet.xml supports GIF images in addition to the HTML a portlet must normally support for uPortal.


<?xml version="1.0" encoding="UTF-8"?>

<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
    version="1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd
    http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">

    <portlet>
        <description xml:lang="en">This portlet will show an image when the user
 clicks on the link</description>
        <portlet-name>ShowImagePortlet</portlet-name>
        <display-name xml:lang="en">Show Image Portlet</display-name>
        <portlet-class>sample.showimage.ShowImagePortlet</portlet-class>
        <expiration-cache>60</expiration-cache>
        <supports>
            <mime-type>text/html</mime-type>
            <portlet-mode>VIEW</portlet-mode>
        </supports>
        <supports>
            <mime-type>image/gif</mime-type>
            <portlet-mode>VIEW</portlet-mode>
        </supports>
        <supported-locale>en</supported-locale>
        <portlet-info>
            <title>Show Image Portlet</title>
            <short-title>Show Image</short-title>
            <keywords>portlet, sample, image</keywords>
        </portlet-info>
    </portlet>

</portlet-app>

As long as you're editing the portlet.xml file, you might want to add the following section as well. uPortal does not currently require this section, however the JSR 168 portlet specification says it should be included whenever a custom Window State is used.


    <custom-window-state>
        <description>The portlet controls the entire response</description>
        <window-state>exclusive</window-state>
    </custom-window-state>

Finally you're ready to actually respond to the exclusive Window State. Below I show the entire doView method for my sample application. It incorporates very simple HTML output to display a PortletURL to our sample binary resource. If you use the code below don't forget to change the filename and/or copy a valid GIF image to the filename location you specify.


    public void doView(RenderRequest request, RenderResponse response)
    	throws PortletException, IOException
    {
        final WindowState EXCLUSIVE = new WindowState("exclusive");

        WindowState state = request.getWindowState();

        if (!state.equals(EXCLUSIVE)) {
            PortletURL url = response.createRenderURL();
            url.setWindowState(EXCLUSIVE);

            response.setContentType("text/html");
            PrintWriter out = response.getWriter();

            out.println("<b>Hello World!</b>");
            out.print("<br/><a href=\"");
            out.print(url);
            out.println("\">Show me an Image!</a>");
            out.flush();
        }

        else {
            String filename = "/tmp/mainlogo.gif";
            PortletContext context = getPortletContext();
            response.setContentType(context.getMimeType(filename));

            OutputStream os = response.getPortletOutputStream();
            byte b[]=new byte[1024];
            InputStream is = new FileInputStream(filename);

            int numRead=0;
            while ((numRead=is.read(b)) > 0) {
                os.write(b, 0, numRead);
            }

            os.flush();    		
        }
    }

I have attached the complete sample application to this blog post. Feel free to download and try it out. Just remember to replace your pluto jar file. Also, I believe with this research we can close out to uPortal JIRA issues UP-1427 and UP-1407.

In a future article I will explain other options for doing file downloading from portlets.

---- Cris J H

AttachmentSize
ShowImagePortletExample.zip113.13 KB