![]() ![]() ![]() ![]() ![]() ![]() |
WebLogic Portal enables user profile information to be passed from consumers to producers. This feature allows many of the Personalization features available in WebLogic Portal to function in a federated portal. This chapter explains how to work with user profile information in a federated portal. Before a federated portal can use user profile information, some configuration is required in both the consumer and producer applications.
This chapter includes the following topics:
This section summarizes the purpose of user profile propagation and how WebLogic Portal propagates user profile data in a federated environment.
A user profile is a collection of property sets that contain user-specific information. WebLogic Portal provides many features that rely on user profiles. For example, the WebLogic Portal Personalization features rely on user profiles to deliver customized content to specific types of users.
For example, you could create a property set in Workshop for WebLogic called human resources that contains properties such as gender, hire date, and email address. This information can be used to personalize the user’s experience in your portal. When users log into a portal, the portal can access the property values and target them with personalized content, e-mails, pre-populated forms, and discounts based on the Personalization rules you set up.
See the Interaction Guide for more information on personalization. For detailed information on creating user profiles, see User Management Guide.
For a WebLogic Portal producer to return personalized content to a consumer, user information must be conveyed from the consumer to the producer. The basic requirements for using user profile information in a federated portal include:
Tip: | Once retrieved, the list of the properties required for a specific portlet is stored in the consumer database for future access. |
As shown in Figure 11-1, after a consumer first contacts a producer, the producer responds with a list of the portlets it offers and with a request for the user information that each portlet requires.
If a portlet requires user information, the consumer will attempt to supply that information as part of the getMarkupRequest()
to the producer before the portlet can be rendered, as illustrated in Figure 11-2. WebLogic Portal uses the P13N API, typically in conjunction with a mapping file, to retrieve the requested user properties on the consumer.
The WSRP protocol specifies a standard format for storing and exchanging user information. This format, called Platform for Privacy Preferences (P3P), is an internet standard. You can configure WebLogic Portal applications to accept user information presented in this format as well as in the WebLogic Portal user profile format.
See P3P Examples for more information. The P3P specification is available on the W3C website, www.w3.org/TR/P3P.
Use this feature if the user properties defined on the producer and consumer do not match. When exactly the same user properties exist on the consumer and producer, you do not need to use this feature.
Tip: | In a production environment, the best practice is to specify a property set and property name for each user property you want to propagate. Retrieving all properties is inefficient when only a small subset of properties is needed. |
To use user profile information in a federated portal, you need to declare on the producer which user properties are required by the portlets deployed on the producer. The declared properties are marshalled in a response to the consumer and returned to the consumer application, which must then return the requested user property values when registering the producer.
The procedures for configuring portlets deployed in a producer to use user profile information differs depending on whether you are configuring Java portlets or non-Java portlets.
This section includes the following topics:
The Java Portlet Specification specifies how Java portlets access user attributes such as the name, email address, phone number, and other attributes of the user. This section explains how to specify user attributes for Java portlets deployed in a producer application, and how Java portlets retrieve user information.
Tip: | For detailed information on how user information is accessed by Java portlets, refer to the User Information section of the Java Portlet Specification. |
The Java Portlet Specification defines the <user-attribute>
element for specifying user attributes required by a deployed Java portlet. Figure 11-1 shows an excerpt of a portlet.xml
file with user properties specified. The <name>
elements specify user attribute names.
<portlet-app>
...
<user-attribute>
<name>Employee/Language</name>
</user-attribute>
<user-attribute>
<name>Employee/Role</name>
</user-attribute>
...
</portlet-app>
The Java Portlet Specification also specifies how Java portlets retrieve user information from the portal environment in which they are deployed. The portlet can retrieve a Map object that contains the user attributes of the user who initiated the request. You can retrieve this Map object from the request using the PortletRequest.USER_INFO
constant.
The example code in Listing 11-2 shows how a Map of user information is retrieved from the request in a JSP associated with a Java portlet. User property values are retrieved from the Map using the user property names as keys.
...
Map<String, Object> props;
PortletRequest portletRequest = (PortletRequest)
request.getAttribute("javax.portlet.request");
if (portletRequest != null) {
props = (Map<String, Object>)
portletRequest.getAttribute(PortletRequest.USER_INFO) ;
} else {
props = null ;
}
if (props == null) {%>
<p>Empty Profile</p>
<%} else {%>
<p><%= props.get("Employee/Language") %></p>
<p><%= props.get("Employee/Role") %></p>
<%}%>
...
If the user properties on the consumer and producer do not match, you can create a mapping file on the consumer. In addition, all requested P3P properties must be specified in the mapping file. A mapping file allows the consumer to retrieve user properties that map to the properties requested by the producer. For detailed information on mapping user properties, see Configuring the Consumer.
This section explains how to specify user attributes for non-Java portlets deployed in a producer application.
For non-Java portlets, you specify required user properties in the descriptor file wsrp-producer-config.xml
. This file is located in the WEB-INF
directory of your producer web application. Listing 11-3 shows a sample wsrp-producer-config.xml
file. The <requiredUserProperties>
element specifies the required user properties for portlets deployed in the producer web application (shown in bold type). In the example, the value All
specifies that consumer must supply all available user profile information to the producer. Other possible values are discussed in this section.
<?xml version="1.0" encoding="UTF-8"?>
<wsrp-producer-config
xmlns="http://www.bea.com/servers/weblogic/wsrp-producer-config/9.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:uddi="urn:uddi-org:api_v2"
xsi:schemaLocation="http://www.bea.com/servers/weblogic/wsrp-producer-config/9.0 wsrp-producer-config.xsd">
<description></description>
<service-config>
<registration required="true" secure="false"/>
<service-description secure="false" supports-method-get="true"/>
<markup secure="false" rewrite-urls="true" transport="string"/>
<portlet-management required="true" secure="false"/>
</service-config>
<supported-locales>
<locale>en</locale>
<locale>en-US</locale>
</supported-locales>
<requiredUserProperties properties="All">
</wsrp-producer-config>
</requiredUserProperties>
The <requiredUserProperties>
element contains one attribute, called properties
, which takes one of these three values:
All
– Instructs the consumer to send all user profile information. For example:
<requiredUserProperties properties="All">
None
– Instructs the consumer to send no user profile information. For example:
<requiredUserProperties properties="None">
Specified
– Instructs the consumer to send only specified user profile information. Use the <specifiedProperties>
sub-element to list the user information required by the portlet. For example:
<requiredUserProperties properties="specified">
<description>These are required properties</description>
<specifiedProperty name="Employee/name"/>
<specifiedProperty name="Employee/gender"/>
<specifiedProperty name="Employee/number"/>
</requiredUserProperties>
The value given for the name
property can take one of these forms:
propertySet
/
propertyName
– The name of a property set defined on the producer and the name of a property in that property set. For example:
<requiredUserProperties properties="specified">
<specifiedProperty name="Employee/gender"/>
</requiredUserProperties>
propertySet
/
* – The name of a property set defined on the producer and an asterisk (*), which specifies that all properties in that property set are required. For example:
<requiredUserProperties properties="specified">
<specifiedProperty name="Employee/*"/>
</requiredUserProperties>
p3pName
– Specify P3P user properties. For example:
<requiredUserProperties properties="specified">
<specifiedProperty name="name/given"/>
<specifiedProperty name="gender"/>
</requiredUserProperties>
If no user information is specified in wsrp-producer-config.xml
, the behavior is the same as if a value of None
were specified in <requiredUserProperties>
.
Retrieving User Information in a Portlet
The code excerpt in Listing 11-4 shows how user properties are retrieved in a portlet’s JSP file using the P13N tag <profile:getProperty>
.
...
<%
if (request.getUserPrincipal() != null) {
%>
<profile:getProfile profileKey="<%= request.getUserPrincipal().getName() %>" />
<%
} else { %>
<profile:getProfile profileKey="anonymous" groupOnly="true" />
<%
}
%>
<tr>
<td>Name</td>
<td id="wsrp_date"><profile:getProperty propertySet=
"Employee" propertyName="name"/></td>
</tr>
<tr>
<td>Gender</td>
<td id="wsrp_int_code"><profile:getProperty propertySet=
"Employee" propertyName="gender"/></td>
</tr>
<tr>
...
If a WebLogic Portal or non-WebLogic Portal consumer sends extended P3P user profile information, the portlet can retrieve the extensions as a List object obtained from the <profile:getProperty>
tag. Listing 11-5 shows example code that extracts a List containing telephone extensions. In this case, the property homeInfo/postal/extensions
is an extended WSRP user property.
<profile:getProperty propertySet="<%= UserProperty.P3P_PROPERTY_SET_NAME %>" propertyName="homeInfo/postal/extensions" id="postalExtsObj"/>
<%
List<Element> teleExts = (List<Element>) postalExtsObj;
if (teleExts != null) {
for (int i = 0 ; i < teleExts.size() ; i++) {
String extStr = teleExts.get(i)
%>
<tr> <td>Postal Extension[<%= i %>]</td>
<td colspan="2"
id="postal_extensions[<%=i%>]"><%= extStr %></td> </tr>
<% }
}%>
Consumers may map the user properties requested by producers to properties that exist on the consumer. For detailed information on mapping user properties, see Configuring the Consumer.
In many cases, the user property set and property names that exist on a producer do not match those on the consumer. Therefore, WebLogic Portal allows you to map these names appropriately. This section explains how to map property set and property names using a configuration file or programatically with a mapping class.
This section includes these topics:
Specify user profile mappings in the wsrp-user-property-config.xml
file. This file is located in the WEB-INF
directory of the consumer web application.
As shown in Listing 11-6, the element <wsrp-user-property-map-bean>
is the top-level element that can appear in this configuration file. The elements that can fall under <wsrp-user-property-map-bean>
are shown in bold type and include:
<user-property-map>
– Creates a producer to consumer mapping that applies to all producers registered with the consumer. <producer-user-property-map>
– Creates a mapping tied to a specific producer, indicated with the <producer-handle>
element. <mapper-class-name>
– Lets you supply a class that peforms mappings programatically. You must specify the fully qualified classname of the mapping class. For more information on creating a mapping class, see Using a Mapping Class.
As shown in Listing 11-6, the <producer-user-property-map>
element can be used to create producer-specific mappings directly or with a mapping class.
<?xml version="1.0" encoding="UTF-8"?>
<wsrp-user-property-map-bean xmlns="http://www.bea.com/ns/portal/90/wsrp-user-property-config">
<!-- Maps ldap/name -> Employee/name for all registered producers -->
<user-property-map>
<producer-property-name>Employee/name</producer-property-name>
<consumer-property>ldap/name</consumer-property>
</user-property-map><!-- Specifies a mapper class to apply to all registered producers -->
<mapper-class-name>myClasses.MyUserPropertyMapper1</mapper-class-name>
<!-- User Property Map for specific producer -->
<producer-user-property-map>
<producer-handle>complexProducer</producer-handle>
<user-property-map>
<producer-property-name>Employee/number</producer-property-name>
<consumer-property>"xxxxxx"</consumer-property>
</user-property-map>
</producer-user-property-map>
<!-- Specifies a mapper class for specific producer -->
<producer-user-property-map>
<producer-handle>complexProducer2</producer-handle>
<mapper-class-name>myClasses.MyUserPropertyMapper2</mapper-class-name>
</producer-user-property-map>
</wsrp-user-property-map-bean>
The <producer-property-name>
sub-element of <user-property-map>
specifies the propertySet
/propertyName
pair of the requested producer property, and the <consumer-property>
sub-element specifies the equivalent pair that exists on the consumer.
The <producer-property-name>
and <consumer-property>
pairs can take the following forms:
propertySetName/propertyName
– The name of a property set and the name of a property in that property set. For example:<producer-property-name>propertySetName-A/propertyName-A</producer-property-name>
<consumer-property>propertySetName-B/propertyName-B</consumer-property>
propertySetName/*
– The asterisk (*) specifies that all properties in that property set are mapped. This pattern assumes that the same property names exists in the mapped property sets on the consumer and the producer.
For example, the following lines map all properties in propertySetName-A
on the producer to propertySetName-B
on the consumer.
<producer-property-name>propertySetName-A/*</producer-property-name>
<consumer-property>propertySetName-B/*</consumer-property>
propertyValue
– Maps a property name from the producer to a constant value. For example, the following lines map the property called propertyName-A
from the producer to an arbitrary string constant. In addition to strings, you can specify other types of constants. For more information, see Mapping Constants. <producer-property-name>propertySetName-A/propertyName-A
</producer-property-name>
<consumer-property>”aStringValue”</consumer-property>
In addition to using a mapping file to map requested producer properties to consumer properties, you can create a mapping class to programmatically map and set user property values on the consumer. To use a mapping class, you need to do the following:
To create a mapping class, do the following:
getProducerProperties
method to implement the mapping functions that you want to create. For detailed information on this method, refer to the
Javadoc. The mapper class example in Listing 11-7 sets the gender property for a user based on the user’s name. Note: | Extending DefaultUserPropertyMapper and overriding getProducerProperties is the simplest and best practice, although it is not required. You can also extend its abstract base class if you want to. |
wsrp-user-property-config.xml
file. To do this, add lines to wsrp-user-property-config.xml
that follow the pattern shown in Listing 11-7, where producerHandle
is the unique name that identifies the producer on the consumer, and myClasses.MyMapperClass
is the full classname of the mapper class. package com.bea.portlet.qa.wsrp.userprops;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.bea.p13n.property.EntityPropertyCache;
import com.bea.wsrp.consumer.userproperty.DefaultUserPropertyMapper;
import com.bea.wsrp.consumer.userproperty.RequiredUserProperties;
import com.bea.wsrp.consumer.userproperty.UserProperty;
public class TestUserPropertyMapper extends DefaultUserPropertyMapper {
private final static Set<String> MALE_NAMES = new HashSet<String>() ;
private final static Set<String> FEMALE_NAMES = new HashSet<String>() ;
static {
final String[] maleNames = {"Nate","Nathan","Eric","Subbu","Scott"};
MALE_NAMES.addAll(Arrays.asList(maleNames)) ;
final String[] femaleNames = {"Mandy","Geeta","Jenn","Jen","Jenny"} ;
FEMALE_NAMES.addAll(Arrays.asList(maleNames)) ;
}
/**
* Map set the user's gender if user.name.given is set
* @param requiredProperties the properties requested by the producer
* @param map A map where the key is the producer's name and
* the value is the consumer's name
* @param profile the User's profile on the consumer
* @return the properties mapped to the producer
*/
public Collection<UserProperty> getProducerProperties(
RequiredUserProperties requiredProperties,
Map<String, String> map,
EntityPropertyCache profile) {
final Collection<UserProperty> properties =
super.getProducerProperties(requiredProperties, map, profile) ;
if (requiredProperties.isPropertyRequired("HR", "gender")) {
final String givenName = (String) getProperty(profile, "HR", "name.given") ;
if (MALE_NAMES.contains(givenName)) {
addUserProperty(properties, "HR", "gender", "M") ;
} else if (FEMALE_NAMES.contains(givenName)) {
addUserProperty(properties, "HR", "gender", "F") ;
}
}
return properties ;
}
}
You need to declare mapping classes in the wsrp-user-properties-config.xml
file. To do this, use the <mapper-class-name>
element. This element takes a fully qualified classname as its property, as shown in the following example:
<mapper-class-name>myClasses.MyMapperClass
</mapper-class-name>
You can place this element directly under the <wsrp-user-property-map-bean>
element or the <producer-user-property-map>
element. For detailed information on the configuration file, see Using a Mapping File.
In addition to mapping user properties to user properties, you can map user properties to constant values. You can map to constants in the configuration file or in a mapper class. Listing 11-8 shows part of a wsrp-user-properties-config.xml
file where a property called long
is mapped to a constant of type long, which is enclosed in /L
delimiters.
...
<user-property-map>
<producer-property-name>map/long</producer-property-name>
<consumer-property>/L42/L</consumer-property>
</user-property-map>
...
Table 11-1 includes the full set of constant delimiters.
If you create a mapping class, you can specify constants using the delimiters shown in Table 11-1 or use the constants defined in the com.bea.wsrp.consumer.userproperty.UserProperty
interface. For details on this interface, refer to the
Javadoc.
This section recasts some of the examples given previously in this chapter to show how to use P3P attributes instead of WebLogic Portal user attributes. This section includes the following examples:
This section includes these examples:
The portlet.xml file is a standard deployment descriptor for Java portlets. Listing 11-9 shows a portlet.xml
file that includes P3P attributes. For more information on this file, see Configuring Java Portlets.
P3P attribute names always begin with the prefix user
, and by convention, a dot (.) separator is used to separate elements of a name (for example: user.name.given
). For a complete set of names used by Java portlets, refer to the Java Portlet Specification.
<portlet-app>
…
<user-attribute>
<description>User Given Name</description>
<name>user.name.given</name>
</user-attribute>
<user-attribute>
<description>User Last Name</description>
<name>user.name.family</name>
</user-attribute>
<user-attribute>
<description>User eMail</description>
<name>user.home-info.online.email</name>
</user-attribute>
<user-attribute>
<description>Company Organization</description>
<name>user.business-info.postal.organization</name>
</user-attribute>
...
</portlet-app>
The example code in Listing 11-10 shows how a Map of user information is retrieved from the request in a JSP associated with a Java portlet. Note that standard P3P user property names, such as user.bdate
, are used in the file.
...
Map<String, Object> props;
PortletRequest portletRequest = (PortletRequest) request.getAttribute("javax.portlet.request");
if (portletRequest != null) {
props = (Map<String, Object>) portletRequest.getAttribute(PortletRequest.USER_INFO) ;
} else {
props = null ;
}
if (props == null) {%>
<p>Empty Profile</p>
<%} else {%>
<p><%= props.get("user.bdate
") %></p>
<p><%= props.get("user.business-info.telecom.telephone.intcode
") %></p>
<%}%>
...
The code excerpt in Listing 11-11 shows how P3P properties are retrieved in a portlet’s JSP file using the P13N tag <profile:getProperty>
. WebLogic Portal recognizes the constant com.bea.wsrp.consumer.userproperty.UserProperty.P3P_PROPERTY_SET_NAME
to be the set of standard P3P user properties.
<%@ page import = "com.bea.wsrp.consumer.userproperty.UserProperty" %>
...
<%
if (request.getUserPrincipal() != null) {
%>
<profile:getProfile profileKey="<%= request.getUserPrincipal().getName() %>"
/>
<%
} else { %>
<profile:getProfile profileKey="anonymous" groupOnly="true" />
<%
}
%>
<tr>
<td>Date</td>
<td id="wsrp_date"><profile:getProperty propertySet=
"<%= UserProperty.P3P_PROPERTY_SET_NAME %>" propertyName="bdate"/></td>
</tr>
<tr>
<td>Int Code</td>
<td id="wsrp_int_code"><profile:getProperty propertySet=
"<%= UserProperty.P3P_PROPERTY_SET_NAME %>" propertyName=
"businessInfo/telecom/telephone/intcode"/></td>
</tr>
...
![]() ![]() ![]() |