![]() Operating systems: i5/OS, Linux,Windows |
This topic gives an overview of portlet configuration preference layers and portlet modes. It describes how you best implement the different layers on which preferences for portlet views can be configured.
Portlets that are written to comply with the Standard Portlet API access their configuration by using the PortletPreferences interface from the standard portlet API. Internally, WebSphere Portal Express 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 |
---|---|---|
Administrator preferences | They are associated with a portlet definition, that is a particular copy of a portlet. They apply to all occurrences of that portlet definition on all pages for all users. The administration portlets allow you 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/>.
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 descriptor. 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 by using the portlet management portlet.
Each call to PortletPreferences.store persists those values at the current preference level that were set by 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, if you want 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, 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 example above is done programmatically by using the reset method. This means that the value of the preference key that is reset will now be read from the next more general preference layer.
Notes:
The separation of preferences into different layers is mostly transparent to the portlet programmer. In the code, you access the aggregated preferences by 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 views, 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 end 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 your portlets in such a way that these decisions are not determined by the code but, as far as possible, by the deployment descriptor. This makes it easier for the administrator later to determine to which extent and on which levels preferences can be customized.
Note: This can often be achieved by 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 that is defined in portlet.xml. There is no standard API that can be used to indicate which preferences should only be modified in the shared configuration and which preferences should be locked for end-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:<preference> <name>locked-pref-keys</name> <value>allowed-folders</value> <value>folder</value> </preference>
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 mentioned above, 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:
Example: If you want to implement a scenario where, for example, an administrator defines a part of a bookmark list that all users must see, and users can personalize the list by adding or removing their own entries, you need to use separate keys for administrator and user preferences and merge the values explicitly in the code.
There are multiple options to resolve the second problem; it depends on the logic of your portlet which of them is most appropriate:
The Java Portlet Specification defines how a preference validator 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 Express uses a preference validator not only to validate preferences that are 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 you can isolate your 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, you 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 exceptions that occur during preference reads.
Note: Keep the following restrictions in mind when implementing a preference validator:
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 Express, 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 Express, in which the edit_defaults mode was not yet supported. Preference values that are set 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 Express 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 descriptor, but other than 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 descriptor. 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 Accessing preferences).
As an example, assume that the database viewer portlet mentioned under Accessing preferences was written without support for config and edit_defaults modes, and allows you 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 descriptor has been modified to support the edit_defaults_compatibility mode. Editor E sets up the portlet on a shared page by 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.
Note: The modes edit_defaults and edit_defaults_compatibility mode are mutually exclusive. A portlet can support only one of them at a time.