Display Profile and Portlets

We have problems getting collection properties from the display profile in a portlet.

Scenario:

- We have a JSR-168 portlet that realizes a news channel.

- The news channel has many news categories.

- We would like to make available, pre-select and force certain categories to certain roles.

- It would be ideal to use the role system, and attach this category info to the "atomic" roles and then have the portal construct the display profile with resultant category info.

Example fragment of the DP for the news channel for a certain role:

<Collection name="available_news_category" merge="fuse">

<String value="public_news"/>

<String value="student_news"/>

</Collection>

The problem is, that I can't get the values for this collection property in the portlet with request.getPreferences(). The portal server doesn't seem to be able to map a collection property to a multivalued portlet preference.

I noticed that Portal Server 6 stores portlet preferences defined in portlet.xml with underscores for example:

<String name="__Portlet__test" value="TESTSTRING"/>

And for multivalued preferences it stores the values as pipe delimited characters:

<String name="__Portlet__available_news_category" value="|public_news|other_news"/>

In other words, it stores multiple values to one String, and the display profile cannot fuse new values to it!

So the question is, is it possible to get values from a collection property in a portlet?

Thanks,

Juhani

[1608 byte] By [Juhani] at [2007-11-26 8:46:42]
# 1
You need to use the JSR-168 API calls to retrieve these preferences.PortletRequest.getPreferences() returns a PortletPreferences object. From there, you can retrieve and even change these values.- Jim
jimfaut at 2007-7-6 22:32:36 > top of Java-index,Web & Directory Servers,Portal Servers...
# 2

PortletRequest.getPreferences() only returns properties

when you first describe them as a pref in portlet.xml and then specify

them in the DP with __Portlet__ prefix.

Here's what I did to verify this:

I added...

<Collection name="available_category_test">

<String value="foobar1"/>

<String value="foobar2"/>

</Collection>

...to the DP for a role that all users belong to. Just to test, I also added a

property:

<String name="__Portlet__test" value="TESTSTRING"/>

I added code to the portlet so that it outputs all preferences and

values that are made available to it using getPreferences().

I couldn't see any output for these properties so i described them in

the portlet.xml:

<preference>

<name>test</name>

<value>foobar</value>

</preference>

<preference>

<name>available_category_test</name>

<value>default</value>

</preference>

After redepolying I correctly got "TESTSTRING" as the value for property

"test" (the dp had correctly overwritten the default in portlet.xml)

but for "available_category_test" I got "default". So the collection

didn't work out.

I then tried renaming

<Collection name="available_category_test">

to

<Collection name="__Portlet__available_category_test">

After this modification I couldn't get any values for the property - not

even the default value described in portlet.xml. So I guess the Portal

Server doesn't know how to map a collection property to a multivalued

portlet preference?

Any ideas? We really need to get this working.

Juhani at 2007-7-6 22:32:36 > top of Java-index,Web & Directory Servers,Portal Servers...
# 3
Collections are not accessible from the portlet api.
jimfaut at 2007-7-6 22:32:36 > top of Java-index,Web & Directory Servers,Portal Servers...
# 4

An alternative solution would be to have separate portlet preferences for each role. For example:

Role1_Category = "Category1"

Role2_Category="Category2"

Then you can test the user's role membership using the isUserInRole() API. Get the list of categories that correspond to the user's role membership and construct the list manually in your portlet.

- Jim

jimfaut at 2007-7-6 22:32:36 > top of Java-index,Web & Directory Servers,Portal Servers...
# 5

I would recommend to follow these two steps :

1. Add multivalued collection in portlet.xml as follows :

<preference>

<name>available_news_category</name>

<value>public_news</value>

<value>student_news</value>

</preference>

2. Deploy the portlet.

3. check out the dp at the dn where you deployed the portlet . The portlet fragment should have the following :

<String name="__Portlet__available_news_category" value="|public_news|student_news"/>

4. Now in your code , use pref = req.getPortletPreferences() pref.getValues("available_news_category",null)to get the string array values associated with this key.

ruchigoel at 2007-7-6 22:32:36 > top of Java-index,Web & Directory Servers,Portal Servers...
# 6

<String name="__Portlet__available_news_category" value="|public_news|student_news"/>

That works but the problem is that we need to merge the display profile. That can't be done with normal String properties as far as I know.

For example, we could have three roles:

all:

<String name="__Portlet__available_news_category" value="|public_news|student_news"/>

staff:

<String name="__Portlet__available_news_category" value="|staff_news"/>

foo:

<String name="__Portlet__available_news_category" value="|foo_news|bar_news"/>

So if a user belongs to roles all and staff, he would end up with:

<String name="__Portlet__available_news_category" value="|public_news|student_news|staff_news"/>

It's really sad that this great feature (merging display profile) can't be used with portlets.

Anybody know does portal server 7 or future versions support this?

Juhani at 2007-7-6 22:32:36 > top of Java-index,Web & Directory Servers,Portal Servers...
# 7

Portal 7 does not implement a collection in this manner either. The functionality is the same between Portal 6 & 7.

I understand the problem, and I agree that it would have been more useful for them to have implemented this feature using a Collection property. However, the JSR-168 specification does not mention any merge functionality when it comes to roles and preferences. That type of merging is something that is particular to the Sun Portal.

There are methods available to obtain a user's role membership. Therefore, you can have separate properties for each role and then merge them manually in your portlet code.

I will file an RFE for this enhancement.

- Jim

jimfaut at 2007-7-6 22:32:36 > top of Java-index,Web & Directory Servers,Portal Servers...
# 8

Thanks for your help,

I'll probably name the properties like

<String name="__Portlet__available_news_category_all" value="|public_news|student_news"/>

<String name="__Portlet__available_news_category_staff" value="|staff"/>

Then use PortletPreferences.getNames() and collect all the values for properties containing "available_news_category". I don't have to bother finding out users roles in this case.

-Juhani

Juhani at 2007-7-6 22:32:36 > top of Java-index,Web & Directory Servers,Portal Servers...