Developing JSR-168 Portlets 
by Ted O'Connor and Martin Snyder


Listing One 

package com.docway.publishedfolder.portlet;
import java.io.IOException;
import javax.portlet.*;
 
/** Main portlet class. Handles render requests from portal framework. */
public class PublishedFolder extends GenericPortlet
{
    public void doView(RenderRequest request, RenderResponse response)
            throws PortletException, IOException
    {
        response.setContentType("text/html");
        final PortletContext context = getPortletContext();
        final PortletRequestDispatcher rd = context
                .getRequestDispatcher("/view.jsp");
        rd.include(request, response);
    }
}


Listing Two 

<%@ page import="com.docway.publishedfolder.content.ContentSource,
            com.docway.publishedfolder.content.ContentDocument, 
            com.docway.publishedfolder.HTMLRenderer" %>
<%
String html;
try
{
//retrieve document listing from content source
final ContentSource source = ContentSource.getContentSource();
    final ContentDocument[] documents = source.getContentList();
    //convert the results to HTML
    html = HTMLRenderer.render(documents);
}
catch(Throwable t)
{
//convert the exception or error to HTML
html = HTMLRenderer.render(t);
}
//display the HTML
out.println(html);
%>


Listing Three 

package com.docway.publishedfolder.content;
import com.docway.publishedfolder.content.impl.*;

/** Class used to retrieve ContentDocuments and abstract the source
 * specific functionality and packages. */
public abstract class ContentSource {
    /** Gets subclass that implements any content source specific functions.
     * @return ContentSource implementation */
    public static ContentSource getContentSource() {
        // For now this just returns Documentum implementation. This method
        // could be easily modified to determine implementation to use based
        // on the properties file or some other mechanism.
        return new DocumentumSource();
    }
    /** Retrieves an array of all documents that are located in location in
     * the repository that was set in the application's resource bundle. This
     * should only be used to display the list of documents and their
     * attributes. Since document contents are not streamed at this point the
     * ContentDocuments that are returned may not have that property populated
     * even though content might exist.
     * @return Array of ContentDocuments that are contained in the repository
     *         location or null if none found.
     * @throws Exception
     */
    public abstract ContentDocument[] getContentList() throws Exception;
    /** Retrieves an individual document by ID that is located in location in
     * the repository that was set in the application's resource bundle. This
     * should only be used to retrieve document contents. Since attributes are
     * not streamed the ContentDocument that is returned may not have its
     * attribute map populated even though additional attributes might exist.
     * @param contentID
     *            Unique ID of document to retrieve.
     * @return ContentDocument with requested ID or null if not found.
     * @throws Exception
     */
    public abstract ContentDocument getContentDocument(String contentID)
            throws Exception;
}


Listing Four 

package com.docway.publishedfolder.content;
import java.io.InputStream;
import java.util.*;

/** Class represents a document returned from a ContentSource. There are
 * several standard properties like id, name, content, and size. Any other
 * custom attributes can be stored in the attributes ArrayList.
 */
public class ContentDocument {
    private String id;
    private String name;
    private InputStream content;
    private long size;
    private ArrayList attributes = new ArrayList();
    /** @param id
     *  @param name */
    public ContentDocument(String id, String name) {
        this(id, name, null, -1);
    }
    /* @param id
     * @param name
     * @param content
     * @param size */
    public ContentDocument(String id, String name, InputStream content, 
        long size) {
        super();
        this.id = id;
        this.name = name;
        this.content = content;
        this.size = size;
    }
    public void addAttribute(String key, String value) {
        attributes.add( new Attribute(key, value));
    }
    public Attribute[] getAttributes() {
        return (Attribute[]) attributes
        .toArray(new Attribute[attributes.size()]);
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public long getSize() {
        return size;
    }
    public void setSize(long size) {
        this.size = size;
    }
    public InputStream getContent() {
        return content;
    }
    public void setContent(InputStream content) {
        this.content = content;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public static class Attribute
    {
        private String name;
        private String value;
        public Attribute(String name, String value) {
            this.name = name;
            this.value = value;
        }
        public String getName() {
            return name;
        }
        public String getValue() {
            return value;
        }
    }
}


Listing Five 

package com.docway.publishedfolder.content;
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;

public class ContentServlet extends HttpServlet {
   private static final long serialVersionUID = 1L;
   private static final int CHUNK_SIZE = 2048;
   public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            final String contentID = request.getParameter("content_id");
            final ContentSource source = ContentSource.getContentSource();
            final ContentDocument document = source
                    .getContentDocument(contentID);
            response.setStatus(200);
            response.setHeader("Content-Length", Long.toString(document
                    .getSize()));
            response.setHeader("Content-Disposition","attachment; filename=\""
                    + document.getName() + "\"");
            copyStream(document.getContent(), response.getOutputStream());
        } catch (Exception e) {
            throw new ServletException(e);
        }
    }
    /** Copies an InputSteam to an OutputStream.
     * @param input
     * @param output
     * @throws IOException */
    private static void copyStream(final InputStream input,
            final OutputStream output) throws IOException {
        final byte[] chunk = new byte[CHUNK_SIZE];
        while (true) {
            final int i = input.read(chunk);
            if (i < 0) // eof
            {
                break;
            }
            output.write(chunk, 0, i);
        }
        output.flush();
    }
}

Listing Six 

### Sample Properties file for DocWay Published Folder portlet
### The domain property is optional.  All other properties are required
username=johndoe
password=jsr168rules
#domain=
repository=MyDocbase
location=0c00000180000112





1


