+

Search Tips   |   Advanced Search

Preference layers and portlet modes


Get an overview of portlet configuration preference layers and portlet modes to best implement the different layers on which preferences for portlet views can be configured.


Overview of portlet configuration preference layers and portlet modes

Portlets that are written to comply with the Standard Portlet API access their configuration using the PortletPreferences interface from the standard portlet API. Internally, WebSphere Portal keeps multiple levels of portlet configuration that are aggregated to form the representation of the portlets for the users:

Type of configuration Description Portlet mode
Deployment descriptor preferences They are associated with a deployed portlet, represented by a <portlet> tag in portlet.xml. They apply to all occurrences on that portlet on all pages for all users.  
Administrator preferences They are associated with a portlet definitions that is a particular copy of a portlet. They apply to all occurrences on that portlet definition on all pages for all users. The administration portlets allow us to create multiple copies of the same portlet with different configurations on the administrator level. config
Shared preferences They are associated with a particular occurrence of a portlet definition on a page and apply to all users who view the portlet on that page edit_defaults
Personalized preferences They are associated with a single user and apply only to that particular user who views the portlet on the page. edit, view, help

For details about the tag for the edit_defaults mode refer to <portal-skin/> tags under the tag <portal-skin:portletEditDefaults/>.


Access preferences

WebSphere Portal merges the different preference keys and valuedefined on these levels into a single PortletPreferences object. When the same preference key is defined on multiple levels with different values, the most specific value, takes precedence and values on more general levels are not available. This allows us to set up general default values for preferences that can then be customized by individual users. Preference values can be locked for user customization by declaring them read-only in the deployment descriptors. Read-only values can only be modified on the administrator level but can never be overridden in lower levels. An example:

  1. Administrator A configures a database viewer portlet so that it displays the Fish view in the Animals database and shows 10 lines per page. The database setting is locked (read-only) so that users may customize the portlet but cannot use it to view a different database.

  2. Editor E places the portlet on a page and decidethat the Mammals view is a more interesting default.

  3. User U1 personalizes the portlet to display the Birds view with 20 lines per page instead of the defaults given by the administrator and the editor.

  4. User U2 personalizes only the number of displayed lines with a value of 55, so user U2 still sees the Mammals view.

  5. Other users who view the same page will still see the Mammals view with 10 lines per page as set by the administrator and the editor.

  6. Editor E now changes the default view to Reptiles. This does not affect U1, but only U2 and other users that have not personalizethat particular preference key.

  7. Finally, U1 resets the personalization of the database view. As a result, the shared default, which is now Reptiles, is shown again. The number of displayed lines still remains at the personalized value of 20.


Modify preferences

A preference is modified using setValue. This normally occurs at the personalized layer and therefore affects only the current user. WebSphere Portal uses two special custom modes from the set of predefined custom modes in the Java Portlet Specification to allow setting up the more general preference levels:

Portlet mode Layer to which preference changes are written
config Administrator preferences
edit_defaults Shared preferences
All other modes: edit, view, help Personalized preferences

If a portlet wants to use these custom modes, they must be declared with <custom-portlet-mode> tags in the deployment descriptors. Entering one of these modes requires special access permissions. For details about access permissions refer to the appropriate sections. Portlets can enter these modes using the standard APIs for setting a portlet mode. These APIs are ActionResponse.setPortletMode and PortletURL.setPortletMode. However, normally the portlets do not need to do so, because the portal normally provides buttons in the portlet skin that allow to switch to these modes, if they are supported by the portlet. The administrator level of preferences for a particular portlet can also be modified without actually invoking the portlet itself using the portlet management portlet.

Each call to PortletPreferences.store persists those values at the current preference levethat were set using setValue. Even if the value that is being set is identical to the currently applicable value, which has been set by the more general level, the new value is now stored at the current level and never inherited. That means, to make use of the preferences hierarchy, so that later changes on a more general level are available (“shine through”) to the more specific levels, you must take care to set and store only those preferences that should not be inherited from the more general levels. Resetting of preferences as on the previous example is done programmatically using the reset method. This means that the value of the preference kethat is reset will now be read from the next more general preference layer.

  1. The reset of a preference is fundamentally different from setValue(null): the latter will hide any default value that was set on a more general level.

  2. If a preference is reset at all levels and has no value defined in portlet.xml, the default value passed to the getValue call will be returned.


Programming recommendations

The separation of preferences into different layers is mostly transparent to the portlet programmer. In the code, you access the aggregated preferences using the PortletPreferences object. The portal will automatically select the appropriate values for the current user and portlet mode. The only place where the distinction of the preference layers becomes visible in a portlet is in the configuration viewso that is in the portlet modes edit, edit_defaults, and config. The different preferences and the different modes in which they are presented determine which part of the portlet behavior can be customized by users and which part can only customized by editors or administrators.

In practice, it is often difficult for the programmer to anticipate how a portlet will be used in a particular environment. In many cases it should rather be decided by an administrator which of the preferences can be customized and at which level they should be customized. Therefore, program the portlets in such a way that these decisions are not determined by the code but, as far as possible, by the deployment descriptors. This makes it easier for the administrator later to determine to which extent and on which levels preferences can be customized.

This can often be achieved using the same code (and JSPs) for implementing all three configuration views, edit, edit_defaults, and config, and simply deactivating or hiding those configuration settings that cannot be modified in the current mode. Settings that can only be modified by administrators (config mode) can be determined by the read-only state defined in portlet.xml. There is no standard APused to indicate which preferences should only be modified in the shared configuration and which preferences should be locked for users. If this is required, we recommend to keep a special (invisible) preference locked-pref-keys that holds a list of those preference keys that can only be modified in edit_defaults or config mode.

Code examples:

  1. Define the preference names that should be locked for the user in the portlet.xml:
    <preference>
        <name>locked-pref-keys</name>
        <value>allowed-folders</value>
        <value>folder</value>
    </preference>     
    

  2. Verify the preference is writable before allowing the user to change a preference value:
    public boolean isWritable(String prefName) {
        PortletMode mode = request.getPortletMode();
        if (mode.equals(CONFIG_MODE)) 
            return true;
    
        PortletPreferences prefs = request.getPreferences();
        if (prefs.isReadOnly(prefName))
            return false;
    
        if (! mode.equals(EDIT_DEFAULTS_MODE)) {
            String[] lockedKeys = prefs.getValues("locked-pref-keys", null);
            if (lockedKeys != null && Arrays.asList(lockedKeys).contains
              (prefName))
                return false;
            }
            
        return true;
        }
    

As previously mentioned, for the normal display of your portlet, you do not need to distinguish whether a particular preference value is an administrator or a user setting. The portal will automatically select the appropriate values for the current user and portlet mode. Nevertheless, you need to consider the merging behavior for the different preference levels particularly in two scenarios:

There are multiple options to resolve the second problem; it depends on the logic of the portlet which of them is most appropriate:

  1. We can always set all the dependent preference keys in a single operation by setting all of them explicitly before the same call to store.

  2. We can even merge the dependent preference keys into a single string value. This is what you should do for combined values, for example x-y coordinates. This implies that no merging of preference levels can take place, therefore we cannot use this approach to support a use case scenario in which administrator changes can be partially overridden by users.

  3. In other cases, it is more appropriate to accept the possibility of invalid preference combinations and just provide suitable error handling; for the previous example, the portlet should simply be prepared to handle the face that the specified database view may be invalid and resethat preference key to go back to a - hopefully valid - defaulthat was set on a more general level.

  4. Another option to resolve this problem is the use of a PreferenceValidater to make sure that only valid preference combinations are available to the portlet. The following section Preference Validaters describes how to do this.


Preference Validaters

The Java Portlet Specification defines how a preference validatar is defined in a portlet. If it is present, tools can use it to make sure that only valid preference combinations are saved for a portlet. WebSphere Portal uses a preference validatar not only to validate preferences stored, but also to make sure that a change on a more general level has not invalidated the current view. Whenever a portlet retrieves its preferences in a particular context, the available combination of preference levels is validated, if necessary, and preference levels that have become invalid in combination with more general levels are ignored: they are not available to the portlet but are retained in the database. Therefore they can become available again when the conflicting preferences on the more general level are updated to be compatible again. This way we can isolate the validation checking and let the portal take care of providing the display logic with valid data. To verify whether the selective hiding of preference levels works as expected, we can enable traces for the following trace string:

    com.ibm.wps.pe.pc.std.core.impl.WPPreferencesHierarchyImpl=low=enabled

This will generate trace logs for validation exceptione that occur during preference reads.

Keep the following restrictions in mind when implementing a preference validatar:

  1. A failed validation on preference access causes the complete conflicting level to be hidden. To be more selective about how preferences are made consistent, you need to use the following approach with self-contained preference validatars.

  2. Preference validatars are intended to be used also by standalone tools. Therefore they should be self-contained and not require a portal run time environment, network, or back end access etc. This means that a preference validatar would not be suitable for the previous examples that is for checkinthat the specified document really exists in the document database.


Compatibility with portlets that do not support the edit_defaults portlet mode

The Standard Portlet API supports the standard portlet modes edit, view, and help. Generic portlets that are written to comply with the Standard Portlet API support those portlet modes. But as they are not aware of the preference hierarchy implemented in WebSphere Portal, they usually do not support the custom portlet mode edit_defaults. Instead, they only support the standard portlet mode edit for customization. The same applies to portlets that were written to comply with the Standard Portlet API for a previous version of WebSphere Portal, in which the edit_defaults mode was not yet supported. Preference valueset in any of the standard portlet modes are never shared between users, in accordance with the behavior assumed by the Java Portlet Specification, because they are always stored at the personalized preference level. Unfortunately, this behavior precludes even the required use case where an Editor wants to set up a read-only page for all users with the appropriate shared portlet configuration. Normally this would be done in the edit_defaults mode, but as the portlet does not support that mode, this is not possible.

To enable editing of shared preferences on such portlets, WebSphere Portal provides a special compatibility mode, the edit_defaults_compatibility portlet mode. Like any other custom portlet mode, this mode must be explicitly enabled in the portlet deployment descriptors, but other thas that, the portlet does not require any special coding. To the portlet, the compatibility mode will just appear as the standard edit mode that it already supports, but the API implementation will read and store the shared preference level instead. As the portlet code does not know about the compatibility mode, entering that mode is only possible from the icon or pull-down menu selection option that is provided on the portlet title bar. As the compatibility mode is mapped to edit mode for the portlet, a portlet that supports this mode must also support edit mode for the same content types in the portlet deployment descriptors. As an example, consider the following code snippet:

<supports>
     <mime-type>text/html</mime-type>
     <portlet-mode>edit</portlet-mode>
     <portlet-mode>edit_defaults_compatibility</portlet-mode>

      . . . . . 
</supports>

In the standard portlet modes, such as edit, a portlet that supports the compatibility mode will still read and store personalized preferences only, and changes are not visible to other users. There is, however, a slight difference to the normal aggregation of preference layers: When a user personalizes the portlet, the preferences are stored in a private copy and not on a personalized layer. No merging takes place between shared and personalized preferences, and any subsequent changes on the shared preferences are not visible to a user who has personalized the portlet, no matter which preference keys are affected. This arrangement as been made to avoid issues with inconsistencies between dependent preference values, as portlet code might not be prepared to handle unexpected combinations of preference values resulting from the merging of shared and personalized levels (as described under Access preferences).

As an example, assume that the database viewer portlet mentioned under Access preferences was written without support for config and edit_defaults modes, and allows us to customize all settings in the edit mode only. To set up the portlet on a shared page without requiring each user to customize it, its deployment descriptors has been modified to support the edit_defaults_compatibility mode. Editor E sets up the portlet on a shared page using the compatibility mode to display the Mammals view from the Animals database with 10 lines per page. User U personalizes the portlet in edit mode to show 20 lines instead. At this point, a private copy of all preference keys is created, so if editor E changes the shared preferences to display the Reptiles view instead, U will continue to see the Mammals view when viewing the page.

This behavior is almost identical to Version 5.1 of WebSphere Portal, where the explicit distinction between shared and personalized preference levels, along with the support for the edit_defaults mode, did not yet exist. The only difference is that E must now explicitly enable and use the edit_defaults_compatibility mode for changing shared preferences, while in Version 5.1 the same behavior was implicitly chosen in edit mode, because E has the necessary access permissions to change the shared configuration visible to all users.

The modes edit_defaults and edit_defaults_compatibility mode are mutually exclusive. A portlet can support only one of them at a time.


Related


Parent: Understand the basics