Portlet Integration

Last modified by Marius Dumitru Florea on 2010/06/16 15:31

Overview of the Portlet Specification 2.0 (JSR286)

Portlets provide a componentized user interface for services. In a Service Oriented Architecture one does not write monolithic applications, but separate services that can be orchestrated together into applications. This service orchestration requires componentized UIs for the services, monolithic web UIs based on servlets are no longer sufficient. The Java Portlet Specification allows coordination on the UI layer with different means, such as events, application sessions, and public render parameters, in order to provide a deep and seamless integration between the different services.

Portlet Concepts

portalPageCreation.png

  • a portal is a web based application that commonly provides personalization, authentication, content aggregation from different sources and hosts the presentation layer of information systems
  • a portlet is an application that provides a specific piece of content (information or service) to be included as part of a portal page
    • web clients interact with portlets via a request/response paradigm implemented by the portal
  • a portlet container runs portlets and provides them with the required runtime environment
    • manages the life cycle of portlets
    • provides persistent storage for portlet preferences

elementsOfAPortalPage.png

  • a portlet mode indicates the function a portlet is performing in the render method
    • standard portlet modes are: view, edit and help
    • view: generate markup reflecting the current state of the portlet
    • edit: customize the behavior of the portlet
    • help: provide help information about the portlet
  • a portlet window is the visual component used to display the content generated by a portlet within portal pages
  • a window state is an indicator of the amount of portal page space that will be assigned to the content generated by a portlet via the render method
    • possible window states are: normal, maximized and minimized

Portlet Life Cycle

The life cycle of a portlet is expressed through the init, processAction, render and destroy methods of the Portlet interface. Optionally, portlets can implement the ResourceServingPortlet interface to gain an additional phase to their life cycle: serveResource.

requestHandlingSequence.png

processAction(ActionRequest, ActionResponse)

  • triggered only by an action URL (e.g. when a form is submitted)
  • doesn't have access to the response output stream and writer
  • doesn't have access to the request URL
  • can't create portlet URLs
  • can issue a response redirect
  • can access the action request parameters (i.e. submitted data)
  • can set render request parameters (e.g. pass action request parameters to the render phase)
  • can dispatch the action request to a servlet but the servlet inherits the restrictions, e.g. request URL is null and all content written to the response output stream is ignored

render(RenderRequest, RenderResponse)

  • triggered by a render URL or by an action URL if there was no response redirect issued during the process action phase
  • has access to the response output stream and writer but it must output only HTML/WML markup fragments
  • doesn't have access to the request URL
  • can create action/render/resource portlet URLs
  • can't issue a response redirect
  • doesn't have access to the action request parameters (i.e. submitted data); if required, they need to be passed as render request parameters during the process action phase
  • can access render request parameters
  • can dispatch the render request to a servlet but the servlet inherits the restrictions, e.g. request URL is null and response redirects are ignored

serveResource(ResourceRequest, ResourceResponse)

  • triggered only by a resource URL
  • has access to the response output stream and writer and can output any content type
  • doesn't have access to the request URL
  • can create action/render/resource portlet URLs
  • can't issue a response redirect
  • can access resource request parameters (i.e. parameters set on the resource portlet URL)
  • can dispatch the resource request to a servlet but the servlet inherits the restrictions, e.g. request URL is null and response redirects are ignored

resourceRequestHandlingSequence.png

Portlet URLs

  • URLs that reference a portlet
  • the string representation may not be a well formed URL but a special token at the time the portlet is generating its content
    • may even be an ECMA script method that may generate the URL at the time the user clicks on the link
    • the portlet container is responsible for resolving tokens into real URLs
  • support application specific parameters
    • parameters can be set only using a dedicated API
    • the portlet container decides how to encode the parameters in the final URL
    • parameters are usually aggregated and encoded as a single query string parameter
  • hold information about the portlet mode and window state
  • can be created only during render and serveResource phases (i.e. not during the processAction phase)
  • missing API for setting the fragment identifier
  • action URLs
    • to be used within HTML forms
    • action parameters are available only to the action request, within the processAction method of the targeted portlet
  • render URLs
    • all the parameters set when constructing a render URL become render parameters of the subsequent render requests for the portlet
    • should be accessed via HTTP method GET as they should not change any state on the server
    • shouldn't be used within HTML forms
    • doesn't trigger processAction method of the targeted portlet
  • resource URLs
    • triggers only the serveResource method of the targeted portlet
    • when rendering resources the portlet has full control over the output stream and can render binary markup

Portlet Constraints

  • enforced separation between request processing and response generation
  • the markup fragment generated by a portlet may be not the only markup returned in the document to the client thus the portlet markup needs to co-exist with whatever other markup the portal produces
    • HTML ids must be namespaced to prevent conflicts with ids of elements generated by other portlets within the same portal page
    • CSS must affect only the content generated by the portlet
    • JavaScript code must be namespaced to prevent overwriting functions or variables defined by other portlets within the same portal page
  • the same portlet can be included multiple times on the same portal page, possibly without sharing the runtime state
    • make sure JavaScript objects aren't shared between instances of the same portlet
  • portlet URLs can be modified only through a specialized API (e.g. can't append query string parameters to the URL string representation)
  • when creating a portlet URL we must know how it will be used: form action requires an action URL, resource URL for AJAX requests and render URL for links between different pages
  • it is desirable to use/integrate with the authentication/authorization mechanism provided by the portal application
  • render method is triggered on a different HTTP request than processAction in the reference implementation of the portlet specification, i.e. render and processAction methods can be executed in different threads (the portlet container issues a response redirect using a render URL after the process action phase)

Overview of the Current Implementation in XWiki Core

  • http://svn.xwiki.org/svnroot/xwiki/platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/web/
  • based on Java Portlet Specification 1.0 (JSR168)
  • tightly-coupled with xwiki-core
  • XWiki request is both a servlet request and a portlet request
    • interface XWikiRequest extends HttpServletRequest, RenderRequest, ActionRequest
  • XWiki response is both a servlet response and a portlet response
    • interface XWikiResponse extends HttpServletResponse, RenderResponse, ActionResponse
  • XWikiPortlet tries to act like the action servlet passing the control to the appropriate XWiki action
    • the list of known XWiki actions is hard-coded
  • XWikiPortlet duplicates code from XWikiAction
    • XWiki context initialization
    • calling action and render methods of the appropriate XWiki action and handling the returned template name
  • processAction and render portlet methods execute almost the same code
    • the code was written so that XWikiAction#action is called during processAction phase of the portlet and XWikiAction#render is called during render phase, but currently XWikiAction#render is called during both phases and XWikiAction#action is never called
  • XWikiPortletURLFactory determines the type of portlet URL to create only based on the XWiki action parameter
    • the mapping between XWiki action names and portlet URL types is hard-coded
    • doesn't create resource URLs (resource handling was added in JSR286)
    • behaves as if portlet URLs are well formed URLs
  • XWikiContext#getMode() is used to distinguish between servlet mode and portlet mode
    • there are many places in xwiki-core where context mode is checked in order to execute a different code in portlet mode

Integration Solutions

Tightly-Coupled

Loosely-Coupled

  • http://svn.xwiki.org/svnroot/xwiki/contrib/sandbox/xwiki-portlet/
  • idea:
    • set a dispatchURL parameter on all portlet URLs
    • the portlet reads the dispatch URL from the request and forwards the request and response
    • rewrite URLs in the response if content type is HTML
  • process action logic
    extract initial dispatch URL from request
    do {
       wrap request and response
       forward wrapped request and response to the current dispatch URL
       if (response was redirected) {
           transform redirect URL in dispatch URL and update the current dispatch URL
        } else {
           store response data on session
           store the session key and the last dispatch URL as render parameters
           break
        }
    } while (true)
  • render logic
    extract response data key from request
    if (key found) {
       extract response data from session and remove the key
    } else {
       extract dispatch URL from request
       wrap request and response
       forward wrapped request and response to the dispatch URL
       extract response data from wrapped response
    }
    rewrite URLs in response data
    render modified response data
  • serve resource logic
    extract dispatch URL from request
    wrap request and response
    forward wrapped request and response to the dispatch URL
    if (content type is HTML) {
       rewrite URLs in response data
    }
    output (modified) response data
  • limitation: the servlet application where the request and response are forwarded must reside on the same server and must use a single entry point servlet
  • URL rewrite logic
    • use an XML SAX filter
    • use a configurable (Portlet URL type, XWiki URL) mapping
      action=
      /bin/save/
      /bin/cancel/
      /bin/upload/

      resource=
      /bin/download/
      /bin/export/
      /bin/get/
      /resources/
      ?xpage=plain&outputSyntax=plain
    • rewrite anchor URLs
      • determine portlet URL type based on the mapping
      • extract dispatch URL from the href attribute
    • rewrite form URLs
      • use action portlet URL
      • extract dispatch URL from the action attribute
    • rewrite URLs in JavaScript code (TODO)
      • use resource portlet URLs for AJAX requests
  • inform the servlet application that it runs in portlet mode
Tags:
   

Get Connected