Storing user settings


This topic describes how user settings can be stored and retrieved in JSR 168 compliant and IBM portlets. Both examples in this topic build off of the HelloJSP samples described in Generating output. All sample portlets are available from the portlet catalog by searching for navcode 1WP10004N. See Sample portlets for more information.

In JSR 168, user settings are stored, set, and retrieved using the PortletPreferences object, which represents name/value pairs in <preference/> elements of the portlet deployment descriptor. Preferences can be marked read-only, in which case they can only be modified by someone with administrative privileges, typically using a configure mode. Otherwise, the portlets can be modified in any portlet mode.

In the following example, the userName preference is provided, but set to a null value. This preference is not marked read-only, so it can be changed by any user with edit access to the portlet.


      <portlet-preferences>
            <preference>
                <name>userName</name>
                <value></value>
            </preference>
      </portlet-preferences>           

The portlet retrieves a reference to an instance of PortletPreferences by calling the getPreferences() method of the PortletRequest object. The store() method saves the information PortletData. The JSR 168 specification allows the portlet to define a preference validator in the portlet deployment descriptor. If one is defined, then the validator is called before the store operation is performed.

The following example from jsrHelloUser.war builds on the jsrHelloJSP.war sample by adding the doEdit() and processAction() methods to allow the user to edit preferences. The getValue() method allows the portlet developer to designate a default value if the preference has not been set.

Example: Java source for Hello User portlet (JSR 168)


package com.ibm.wps.samples.jsr;

import javax.portlet.*;
import java.io.*;

public class HelloUser extends GenericPortlet {
 
   public void init PortletConfig(portletConfig) throws UnavailableException, PortletException
   {
     super.init(portletConfig); 
     // The default user name is obtained from the portlet configuration parameters
   }

  public void doView(RenderRequest request, RenderResponse response)
                                   throws PortletException, IOException {
    // set return content type
    response.setContentType("text/html");

 // Get the user's preferred name to display from preferences
 // If no value is available, set it to "User"
    String displayName = request.getPreferences().getValue("userName", "User");

 // Add the display string to the portlet request to make it accessible by the view JSP
 request.setAttribute("username", displayName);

    PortletContext context = getPortletContext();
    context.getRequestDispatcher("/jsp/View.jsp").include( request, response);
  }

  public void doEdit(RenderRequest request, RenderResponse response)
     throws PortletException, IOException{

    response.setContentType("text/html");

    // Create the return URL for the cancel link of the edit page
    PortletURL cancelUrl = response.createRenderURL();
    cancelUrl.setPortletMode(PortletMode.VIEW);
    // Preserve the Cancel URL in the request to make it accessible by the edit JSP
    request.setAttribute("cancelUrl",cancelUrl.toString());

 // For the "Save" button the return URI must include the "Save" action
    PortletURL saveUrl = response.createActionURL();
    saveUrl.setPortletMode(PortletMode.VIEW);
    saveUrl.setParameter("save","save");
 // Preserve the Save URL in the request to make it accessible by the edit JSP
    request.setAttribute("saveUrl",saveUrl.toString());

 String displayName = request.getPreferences().getValue("userName", "User");
 request.setAttribute("username", displayName);

    String jspName = getPortletConfig().getInitParameter("jspEdit");
    PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher("/jsp/Edit.jsp");
    rd.include(request,response);

  }

  public void processAction(ActionRequest request, ActionResponse response)
    throws PortletException, IOException{

  PortletContext context = getPortletContext();

  try{
    String save = request.getParameter("save");
    if (save != null){
   PortletPreferences prefs = request.getPreferences();
   prefs.setValue("userName",request.getParameter("username"));
   prefs.store();
    }
  }
  catch ( IOException ioe ){
     context.log("An IO error occurred when trying to save the name.");    
  }
  catch ( PortletException pe ) {
     context.log("A portlet exception was thrown when trying to save the name.");    
  }    

  }

}

Using the IBM Portlet API, user settings are saved, retrieved, or deleted using the PortletData object. Portlets can store values in the PortletData object only when the portlet is in edit mode. If the portlet is on a group page, then information saved in PortletData is available to all users of the portlet. The portlet retrieves a reference to an instance of PortletData by calling the getData() method of the PortletRequest object. The store() method saves the information PortletData. Only data of the Java String type can be saved in the PortletData object.

PortletData is used in the ibmHelloUser.war sample to allow users to edit and save their names in which they are addressed in the greeting. This sample builds on the ibmHelloJSP sample by adding the doEdit() and the actionPerformed() methods, thus allowing users to edit the greeting and save their preferences.

  • The default greeting to display is obtained from the portlet deployment descriptor . The following example shows the portion of this descriptor with the configuration parameter defaultUserName set to "User".

    Example: Portlet deployment descriptor for ibmHelloUser

    
       <config-param>
          <param-name>defaultUserName</param-name>
          <param-value>User</param-value>
       </config-param>               
    
    

    Configuration data that is set by the <init-param> tags are read-only and maintained for all users and every concrete portlet derived from the portlet. To allow different configurations for each concrete portlet, then the data should be set in the <concrete-portlet> tag of the portlet deployment descriptor.

  • The doView() method receives control prior to the standard display for this portlet. The PortletData object is accessed to obtain the string to display. If the user has not yet specified a string to display, the default string will be used. The string is stored in the PortletRequest object to make it available to the JSP that generates the view markup for this portlet (viewJSP).
  • The doEdit() method receives control prior to the display of the edit page for this portlet. A return URI is created and passed to the JSP for edit mode using the PortletRequest object. The save action is included in the return URI using the addAction() method. The portal passes control to the ActionListener upon processing the save action. The ActionListener can preserve the user entered "edit" information in the persistent storage. See Action events for more information about ActionListener and portlet actions.

Example: Java source for Hello User portlet (IBM)


package com.ibm.wps.samples;

import org.apache.jetspeed.portlet.*;
import org.apache.jetspeed.portlet.event.*;
import java.io.*;

public class HelloUser extends PortletAdapter implements ActionListener{

  private String defaultString;
  private String displayName;

  public void doView PortletRequest(request, PortletResponse response) 
                                    throws PortletException, IOException 
  {
    //Get the user's name to display from persistent storage
    displayName = (String) request.getData().getAttribute("userName");
    defaultString = request.getPortletSettings().getAttribute("defaultUserName");

    // If user's preferred name is not found, display the default
    if (displayName == null) {
        displayName = defaultString;    // set default string
    }

    // Add the display string to the portlet request to make it accessible by the view JSP
    request.setAttribute("userName", displayName);

    getPortletConfig().getContext().include("/jsp/View.jsp", request, response);
  }

  public void doEdit PortletRequest(request, PortletResponse response) 
                                    throws PortletException, IOException 
  {

    // Create the return URI for the cancel link of the edit page
    PortletURI cancelURI = response.createReturnURI();

    // Preserve the Cancel URI in the request to make it accessible by the edit JSP
    request.setAttribute("cancelURI", cancelURI.toString());

    // For the "Save" button the return URI must include the "Save" action
    // so the Action Listener for this portlet will be invoked
    PortletURI saveURI = response.createReturnURI();
    saveURI.addAction("save");
    // Preserve the Save URI in the request to make it accessible by the edit JSP
    request.setAttribute("saveURI", saveURI.toString());

    //Get the user's name to display from persistent storage
    displayName = (String) request.getData().getAttribute("userName");
    defaultString = request.getPortletSettings().getAttribute("defaultUserName");
    // If user's preferred name is not found, display the default
    if (displayName == null) {
       displayName = defaultString;    // none found, set default string
    }
    // Add the display string to the request to make it accessible by the edit JSP
    // as an initial value of the input field on the edit form
    request.setAttribute("userName", displayName);

    getPortletConfig().getContext().include("/jsp/Edit.jsp", request, response);

  }

  public void actionPerformed(ActionEvent event) 
  {

    String action = event.getActionString();
    PortletLog log = getPortletLog();

    // If this is a save action, then see if the user specified a name
    if ( action!=null ) {
      if ( action.equals("save") ) {
        PortletRequest request = event.getRequest();
        PortletData portData = request.getData();
        String userName = request.getParameter("userName");
        try {
          // Save the name specified by the user
          if ( userName != null ) {
            portData.setAttribute("userName", userName);
            portData.store();
          }
        } catch ( AccessDeniedException ade ) {
        } catch ( IOException ioe ) {
          log.error( "<i><b>Couldn't write the user data to " );
          log.error( "persistence because an I/O Error occurred.</b></i>" );
        }
      }
    }
  } 

}

As mentioned previously, an ActionListener is implemented by HelloUser to process the save action. The user enters a name on the edit page and the actionPerformed() method of the ActionListener obtains the user-specified string from the PortletRequest object for storing in the user's persistent storage. The ActionListener is invoked prior to returning to the doView() method of the portlet, thus if the user failed to enter a name, the ActionListener can force the portlet to remain in edit mode, waiting for input from the user.

 

See also

Home |

 

WebSphere is a trademark of the IBM Corporation in the United States, other countries, or both.

 

IBM is a trademark of the IBM Corporation in the United States, other countries, or both.