Set the profile selection handler
In the Select Handler editor of the Profile Manager, we can set the profile selection handler class to use for the current profile set. You can also declare a value selector class that dynamically assigns data to the profile values in the profile set.
Key Terms
The following terms are important to understand in the description of profile selection handlers:
Segment - A categorization that you associate with a profile. Common segment types include J2EE Roles and LDAP groups. We can create your own segment types by implementing the com.bowstreet.profiles.SegmentList interface.
The profile selection handler matches a request with a segment and returns the profile associated with that segment. If the request corresponds with more than one segment, the profile selection handler returns the "most-derived" profile.
Profile - A collection of profile entry values that determine the values for profiled builder call inputs. We can associate a profile with a segment when you create or edit the profile. We can also create a Profile Selection Handler to implement your own segment/profile associations.
Setting the Profile Selection Handler for the Profile Set
The Factory includes the following profile selection handlers:
- Explicit Handler - Associates the request with the default profile in the current profile set. Typically used during development so that we can preview models with different profiles applied.
- File Segment Handler - Associates a hard-coded user with a profile based on the user/profile mappings in an XML file.
- J2EE Role Handler - Associates the user with a J2EE Role and returns the profile associated with that role.
- LDAP Group Based Selection Handler - Associates the user with an LDAP Group segment and queries the profile set to return the profile associated with the given LDAP Group.
- Locale Selection Handler - Associates the user with a language locale segment and returns the profile associated with the locale name. This handler can be used with a WebSphere portlet or with a standalone web application.
- WPS Execution Mode Handler - Associates the request with a profile associated with a "standalone" mode or "running within a portal" mode. We can use this selection handler to execute different code based on the execution mode. See Profiling Based on Execution Mode for more information.
- WPS Group Segment Handler - Associates the request with the WebSphere Group to which the user belongs and returns the profile associated with that group. See Profiling WebSphere Portlets for more information.
If the user belongs to more than one segment, a profile selection handler returns the most-derived (least-privileged) profile.
We can create your own profile selection handlers.
To set the profile selection handler for the profile set:
In the Select Handler tab of the Profile Manager, choose one of the profile selection handlers from the Profile Selection Handler select box.
If you do not select a Profile Selection Handler, the Factory servlet uses the default Profile Selection Handler, which is set by the bowstreet.profiles.default.selection.handler property in the WEB-INF/config/cluster.properties file.
Specifying a Value Setter for the Profile Set
We can specify a Java class that assigns values to entries in the profile set. This Java class is known as a profile entry value setter, and can be used to set profile entry values according to logic executed during generation.
To specify a profile entry value setter for a profile set:
In the Select Handler tab of the Profile Manager, enter the fully-qualified class name in the Value Setter text input.
See below for more information about creating a profile entry value setter class.
Localization and the Profile Custom Value Class
The Profile Custom Value class can be used as a value setter to determine the Users Locale settings from WPS. its name is: com.bowstreet.ibmportal.profiles.WPSLocaleProfileValue. This class is located in the portlet_adapter.jar.
This class expects the profile entry names to match the Locale bean style access method names (i.e. country, displayCountry, language, displayLanguage).
The Following rules are used to determine the Locale:
- The class will first check the users WPS preferred language setting.
- If no preferred language is set for the user, the preferred locale that the client will accept content in, based on the Accept-Language header will be used (using HttpServletRequest getLocale()).
- If the client request doesn't provide an Accept-Language header, then the default locale for the server will be used.
Also included is a Profile Set named wps.locale.value.pset that has its Profile Value Setter class set to com.bowstreet.ibmportal.profiles.WPSLocaleProfileValue, and contains entries for "country" and "language".
The Combination of the WPSLocaleProfileValue class and its associated wps.locale.value.pset ProfileSet is useful when using the Localized Resource Builder and you want to determine the Language, and Country based on individual users preferences. In place of selecting the Language, and Country in the builders inputs we can instead profile the Language, and Country inputs using the wps.locale.value.pset Profile Set and selecting the proper profile entry name.
Create Profile Selection Handlers
Profile selection handlers are defined by the following:
- Handler definition file - This XML file lists the Java classes used to implement the profile selection handler and any properties of the profile selection handler. See the next section for complete information about the handler definition file.
- (optional) SegmentList implementation - This Java class determines and returns a list of segments to be used by the Profile Manager when customizing profile entries.
- BaseSelectionHandler extension - This Java class associates the request with one or more segments and returns a profile according to the least-privileged segment.
Create a Handler Definition
We can create a new handler definition by copying an existing handler definition file and saving it with a different name.
To create a new handler definition:
- Copy one of the existing handler definitions in the Factory's WEB-INF/config/selection_handlers directory.
- Save the copied file with a new name, such as account_type_handler.xml.
- Set the values of the following elements:
- Handler - This is the name of the handler, which will be used as the display name in the Profile Manager to allow the user to select a handler for their profile set.
- Description - A short description that specifies the functionality of the handler.
- Selection - Set the class attribute to the name of the class that extends the BaseSelectionHandler class. Include the full package name (for example, com.acme.AccountTypeSelectionHandler).
- Properties - (optional) These are name/value pair properties that will be passed as a Map to the init(..) method of your ProfileSelection and SegmentList implementation classes.
- SegmentList class - (optional) Set the class attribute to the name of the class that implements the SegmentList interface. The Profile Manager uses this class to get the list of segments for this handler. Include the full package name (for example, com.acme.AccountSegmentList).
The following code sample is the handler definition file for the File Segment Handler:
<Handler name="File Segment Handler">
<Description>Handler that maps users to a segment using mapping data
from a simple xml file.</Description>
<Selection class="com.bowstreet.profiles.FileSegmentSelectionHandler">
<Properties>
<Property name="file">factory/profile_segment_data/segments.xml</Property>
</Properties>
</Selection>
<SegmentList class="com.bowstreet.profiles.FileSegmentSelectionHandler" />
</Handler>
As is the case with the FileSegmentSelectionHandler class, we can implement the ProfileSelection and SegmentList interfaces in the same class and specify that class as both the Selection class and SegmentList class.
Extending the SelectionHandlerBase Class
The SelectionHandlerBase base class includes the following methods that facilitate the development of profile selection handlers:
- The getProfileBySegment() method returns the most-derived (least-privileged) profile given one or more segments.
- Handling explicit profile validation. The explicit profile validation checks:
- Whether the profile exists
- Whether the user's segments match one of the segments in the specified profile.
If the profile does not have any segments specified then it can be selected without a user segment match.
- The getUser() method returns the user ID associated with the request
The SelectionHandler class implements the ProfileSelection interface, which provides
- init() - Performs any initialization before the selectProfile() method executes.
- selectProfile() - Selects a Profile from the specified ProfileSet that is passed in and returns its name. The Factory servlet generates a new instance of the WebApp according the profile entry values specified by the returned profile name.
See the Javadoc for the SelectionBaseHandler class for a complete list of available methods.
Sample Profile Selection Handler
The following code is an example of a simple profile selection handler that associates a request with a profile according to the day of the week:
import com.bowstreet.webapp.ModelInstanceCreator;
import com.bowstreet.profiles.*;
import com.bowstreet. model .IProfileSelection
import javax.servlet.http.*;
import java.util.Map;
public class SampleProfileSelection extends SelectionHandlerBase
{
public String selectProfile(HttpServletRequest request, ProfileSet profileSet,
String modelName, String explicitProfile,
ModelInstanceCreator modelInstanceCreator)
{
// Get the day of the week
Calendar calendar = new GregorianCalendar();
int day = calendar.get(Calendar.DAY_OF_WEEK);
// if it's Monday then get the Monday Profile
if(day == Calendar.MONDAY)
{
return profileSet.getProfile("Monday").getName();
}
else
{
return profileSet.DEFAULT;
}
}
}
About Profile Names
To support the ability to query a ProfileSet for its hierarchy without having to filter out possible thousands of leaf nodes we are adding the concept of a container node flag. This flag is a boolean on each Profile that can specify that it is a container. The hierarchy should be fairly limited in size compared to the number of leaf nodes, which in theory can be thousands or hundreds of thousands. By default, all new Profiles created will be containers and therefore manually set its container flag to false if you intend it to not be a container. This flag is also exposed as a Profile property in the Profile Manager.
Implementing the SegmentList Interface
We can create your own SegmentList implementation so that we can associate profiles with segments of your own type in the Profile Manager.
The Factory includes sample implementations of the following alternate segment types:
- File-based User/Profile Association - Used with the File Segment List
- J2EERole - Used with the J2EE Role Selection Handler
- LDAP Group - Used with the LDAP Group Handler
All SegmentList implementations return an Iterator to a list of available segments. When you open the Advanced pull-down menu on the New Profile or Edit Profile dialog, it displays the list of available segments.
See the getSegments() methods in the source code for the FileSegmentSelectionHandler and the LDAPGroupHandler classes. We can find the Java source for these classes in the WEB-INF/work/selectionhandlers.zip file.
Replacing the Default Profile Selection Handler
We can declare one of your own profile selection handlers as the default handler for the Factory servlet to use if a profile set does not specify a profile selection handler to use.
To replace the default profile selection handler:
Set a bowstreet.profiles.default.selection.handler property in the cluster.properties to the name of the handler specified in the handler definition file. For example, you would set the property to "File Segment Handler" if the Handler element looks like: <Handler name = "File Segment Handler">
The following example is from the cluster.properties file:
# This property specifies the handler to use for a factory wide default profile selection for WebApp Models.
bowstreet.profiles.default.selection.handler=File Segment Handler
Create Profile Entry Value Setters
To assign the values for profile entries at generation time, we can do so in a Java class that implements the com.bowstreet.profiles.ProfileUpdateValue interface.
Implementing the ProfileUpdateValue Interface
The following code example sets a profile entry value to the user name associated with the request:
import com.bowstreet.webapp.ModelInstanceCreator;
import com.bowstreet.profiles.*;
import javax.servlet.http.*;
import java.util.Map;
public class SampleTestProfileUpdateValue implements ProfileUpdateValue
{
public void updateProfileValues(HttpServletRequest request, Profile profile,
String modelName, String explicitProfile,
ModelInstanceCreator modelInstanceCreator)
{
// Get the value for the "UserName" and replace it with the current users name.
ProfileValue profileValue = profile.getValue("UserName");
if(profileValue != null && request != null)
{
// assume user is authenticated
String strUserName = request.getUserPrincipal().getName();
// now replace it
profileValue.setData(strUserName);
}
}
}
}