Oracle9iAS Portal Developer Kit
Implementing Session Storage in PL/SQL Portlets

Oracle9iAS Portal provides a set of APIs for storing and manipulating temporary data for the session the user is currently running.  The session store is implemented as an object which contains information about the object itself and session elements, the information stored in the session object.  For an introductory overview of Session Storage Services, please refer to the Primer on Session Storage

The persistency of the data stored in the session store is the same as the persistency of the portal session.  When the session ends, the data stored in the session store for that session is lost.  For example, when you close all instances of your current browser, the current portal session ends and the session information in the session store is gone.

Session storage services are available through the  wwsto_api_session  package.

This article describes how the session storage services are implemented using the Services Example.  It provides a guideline for adding the session storage service to your portlet functionality.   

Assumptions

How to Use Session Storage

The general model for working with the session store can be described as follows:

  1. Load the session object, with an appropriate domain and sub-domain combination, using the load_session method.
  2. Manipulate the contents of the object using the set_attribute methods, or just access it's contents using the get_attribute methods.
  3. Force these changes to be saved, using the save_session method.  This is needed only if any changes have been made to the session object using the set_attribute methods.

IMPLEMENTING SESSION STORAGE

This section describes how the session storage service is implemented using the Service Example in PDK.  In the Services Example, the objective is to achieve the following functionality:

Note: You may have NLS requirements of your session store functionality.  Like in the Services Example, you would first want to load the required NLS strings to the database.  The document on Implementing NLS Services describes how string definitions are loaded into the database.

Implementation

This section describes how the session storage service is implemented for the Services Example.
  1. From the downloaded Services Example, review the services_portlet.pkb file which is the package body for this portlet.  An excerpt is provided below.
  2. The domain, and sub-domain definitions for your session object are provided aliases at the start.  These are used later on while loading the session object.  This code segment is highlighted below.  You may choose your own domain and sub-domain names too instead.
  3. Scroll to the section that contains the procedure clear_count.  Your portlet needs to clear the display counter whenever user chooses to reset the counter. 
  4. First  it makes a call to wwsto_api_session.load_session for loading the session object as shown below.  Then it calls wwsto_api_session.set_attribute for setting the counter to zero. Finally it saves the session object by calling the save_session API.  This code segment is highlighted below. 
     

    CREATE OR REPLACE

    package body SERVICES_PORTLET

    is

           --   Constants  --

        DOMAIN constant varchar2(30) := 'provider';

        SUBDOMAIN constant varchar2(32) := 'services';    

        ...

        procedure clear_count

        (

            p_action in varchar2,

            p_back_url in varchar2,

            p_reference_path in varchar2,

        )

        is

           session_parms &&1..wwsto_api_session;

           ex_counter integer;

        begin

            if (p_action = 'clear') then

                  /*

            Clear the display counter.

            */

                      /*

               Load the session object that contains the display counter.

              */

                session_parms := &&1..wwsto_api_session.load_session(DOMAIN,SUBDOMAIN);

                ex_counter := session_parms.get_attribute_as_number(

                                      'ex_counter' || p_reference_path);

        

                      /*

                Reset the display counter.

              */

              ex_counter := 0;

              session_parms.set_attribute(

                          'ex_counter' || p_reference_path, ex_counter);

              /*

              Save the changes to the database immediately to avoid any

              data consistency problems with the data stored in the

              session object.

              */

              session_parms.save_session;

     

           end if;

           owa_util.redirect_url(curl=>p_back_url);

        end clear_count; 

        ...

    end SERVICES_PORTLET;

    /

  5. In the show details mode, the show procedure calls the show_details procedure where it shows the button for clearing the counter.  Whenever user presses this button, it calls the clear_count procedure explained above.
  6. Similarly in the show mode, it retrieves the session object to display the number of times user has rendered the portlet.  It retrieves the counter value using the get_attribute_as_number API call.  It increments the counter for every invocation of this procedure.
     

    CREATE OR REPLACE

    package body SERVICES_PORTLET

    is

     

        procedure show

        (

            p_portlet_record wwpro_api_provider.portlet_runtime_record

        )

        is

           session_parms &&1..wwsto_api_session;

           ex_counter integer;

           l_portlet wwpro_api_provider.portlet_record;

           ...

        begin

           ...

           if (p_portlet_record.exec_mode = wwpro_api_provider.MODE_SHOW) then

               /*

               In this mode a session counter is used to indicate

               the number of invocations of this portlet during the

               current session. The counter is stored in the session

               store.

               */

               session_parms := &&1..wwsto_api_session.load_session(DOMAIN,SUBDOMAIN);

               ex_counter := session_parms.get_attribute_as_number(

                                  'ex_counter' || p_portlet_record.reference_path);

               if (ex_counter is null) then -- first invocation

                   session_parms.set_attribute(

                           'ex_counter' || p_portlet_record.reference_path,1);

                   ex_counter := session_parms.get_attribute_as_number(

                                      'ex_counter' || p_portlet_record.reference_path);

               else -- on every invocation increase by 1

                   ex_counter := ex_counter + 1;

                   session_parms.set_attribute(

                           'ex_counter' || p_portlet_record.reference_path, ex_counter);

               end if;

               session_parms.save_session;

           ...

           elsif (p_portlet_record.exec_mode = wwpro_api_provider.MODE_PREVIEW) then

           ...

        end show;

        ...

     end SERVICES_PORTLET;

    /

You can implement session store in a similar fashion but based on your functional requirements. 

VIEW PORTLET FUNCTIONALITY

  1. Create a page and add the Services portlet to your page.  Refresh the page a few times and notice the displayed text change.  Take note of how the counter value is stored and retrieved from the session store.  Then click on the 'Details' link and press the 'Clear' button to restart the counter.  Again view your portlet to see how the counter starts from zero again. 


Revision History