Monday 2 November 2009

Change Liferay Chat Portlet Buddy List Strategy

Some time ago I had to check out the possibilities of the Liferay Chat portlet together with a colleague to see if it could be used in our current project or not. Installing it was easily done via the recently introduced Liferay Control Panel. After some quick tests it seemed that for the most part the portlet would be useable if we could find some way to configure who gets to chat to who.

Some clicking around in the control panel and checking out the portlet preferences didn't provide any clues as to how this could be done. So we started looking at the Chat portlet source code and discovered something promising: ChatUtil.getBuddies(long userId).

public class ChatUtil {

public static final int MAX_ENTRIES = 50;

public static final long MAX_POLL_LATENCY = Time.SECOND * 15;

public static final long ONLINE_DELTA = Time.MINUTE;

public static List<Object[]> getBuddies(long userId)
throws SystemException {

long modifiedDate = System.currentTimeMillis() - ONLINE_DELTA;

List<Object[]> buddies = null;

if (PortletPropsValues.BUDDY_LIST_STRATEGY.equals("all")) {
buddies = StatusLocalServiceUtil.getAllStatuses(
userId, modifiedDate, 0, SearchContainer.DEFAULT_DELTA);
}
else if (PortletPropsValues.BUDDY_LIST_STRATEGY.equals("communities")) {
buddies = StatusLocalServiceUtil.getGroupStatuses(
userId, modifiedDate, 0, SearchContainer.DEFAULT_DELTA);
}
else if (PortletPropsValues.BUDDY_LIST_STRATEGY.equals("friends")) {
buddies = StatusLocalServiceUtil.getSocialStatuses(
userId, SocialRelationConstants.TYPE_BI_FRIEND,
modifiedDate, 0, SearchContainer.DEFAULT_DELTA);
}
else if (PortletPropsValues.BUDDY_LIST_STRATEGY.equals(
"communities,friends")) {

List<Object[]> groupBuddies =
StatusLocalServiceUtil.getGroupStatuses(
userId, modifiedDate, 0, SearchContainer.DEFAULT_DELTA);
List<Object[]> socialBuddies =
StatusLocalServiceUtil.getSocialStatuses(
userId, SocialRelationConstants.TYPE_BI_FRIEND,
modifiedDate, 0, SearchContainer.DEFAULT_DELTA);

buddies = new ArrayList<Object[]>(
groupBuddies.size() + socialBuddies.size());

buddies.addAll(groupBuddies);

BuddyComparator buddyComparator = new BuddyComparator(true);

for (Object[] socialBuddy : socialBuddies) {
if (Collections.binarySearch(
groupBuddies, socialBuddy, buddyComparator) < 0) {

buddies.add(socialBuddy);
}
}

Collections.sort(buddies, buddyComparator);
}
else {
buddies = new ArrayList<Object[]>();
}

return buddies;
}

}
This code seems to suggest that there are 4 different ways in which the list of people you can chat to is constructed:
  • all
  • communities
  • friends
  • communities,friends (this looks like something that will have to be refactored someday...)
It seems from the code that all is the default strategy. As almost everything in Liferay can be configured by extending the default portal.properties file, by making and deploying a portal-ext.properties file containing a set of diffs against the original properties file. So we tried to change the strategy to communities by adding 'buddy.list.strategy=communities' to our portal-ext.properties file, using the key as suggested by the code in the PortletPropsValues class:
public class PortletPropsValues {

public static final String BUDDY_LIST_STRATEGY = GetterUtil.getString(
PortletProps.get("buddy.list.strategy"));

}

After restarting the portal and testing, it seemed as if nothing had changed. We still got the see the same people in our respective buddy list. We tried changing the organisations and communities our different users belonged to, but nothing seemed to have the desired effect. Where did we go wrong...? Some Googling pointed us to a forum post that reinforced our feeling that we were indeed looking in the right direction. But why didn't it work then?

While I had to start working on something else, my colleague continued to look into the problem and ultimately found the solution. While we did indeed find the correct configuration key/value pair, we had put it in the wrong file, portal-ext.properties, as the Chat portlet, by means of the portlet.properties file, is configured to override even this file:

include-and-override=portlet-ext.properties

buddy.list.strategy=all
#buddy.list.strategy=communities
#buddy.list.strategy=friends
#buddy.list.strategy=communities,friends
So setting the buddy list strategy in the portal-ext.properties file doesn't have any effect since it will be overridden by the value in portlet.properties because of the include-and-override setting. So when you change the value directly in the portlet everything starts to make a whole lot more sense.

And now I'm gonna have me some object-oriented toast.

No comments:

Post a Comment