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.

Saturday, 24 October 2009

My new GPS: to Garmin or not to Garmin

My trusty old GPS device, a Magellan SporTrak Color, that I use for Geocaching, recently started going a bit haywire. After being turned on it would start to go randomly into on-off cycles, making it very difficult to use. I've had this device for about 4 to 5 years now and was pretty satisfied with it. It had all the necessary functions for geocaching such as an electronic compass and map support, but it was starting to show its age a bit, most of all in satellite acquisition speed and accuracy.

So I decided to look for a new device that had to satisfy certain requirements:
  • Electronic compass
  • Map support (commercial and open source if possible)
  • Mac compatible (Magellan has little to no support)
  • USB (my SporTrak only supports serial ports, a USB to serial cable helps, but transfer speed is still slow)
  • Newest generation GPS chip with WAAS/EGNOS support
  • Extendable memory (my SporTrak only had a fixed 32Mb internal memory)
  • Run on standard AA size batteries (I bloody hate battery packs)
  • Color screen (my SporTrak also had this, but it's just a nice to have)
So I started looking around and came across the newer generation Magellan and Garmin devices. After checking out some tests and reviews for the Magellan Trition series and the Garmin Colorado/Oregon/Dakota series, it seemed like these devices are promising, but still have some teething problems. So I decided to go for the tried and tested Garmin GPSMAP 60CSx as it seems to be the preferred device among geocachers according to the usage numbers and reviews on the geocaching site.
The GPSMAP 60CSx fits all the requirements I'd set, but has one small problem: a recommended selling price of 400 euro. So like I usually do when I don't want to pay full price: I started looking around online. After some searching I found a promising eBay shop: SATNAV24. Here I could buy the device I wanted, including an additional 2Gb MicroSD card and get it shipped to me for only 275 euro.

After ordering it and paying for it via PayPal on sunday evening, it was delivered at work on friday, You've got to love those online retailers. With those prices and service I'm wondering why anybody still buys their stuff in regular shops where they never have what you want, treat you as crap, overcharge you or just plainly annoy you (e.g. pushy sales people).

After receiving the new device and testing it out a bit, I've come to the following preliminary conclusions:
  • Startup time and satellite acquisition are really fast
  • Position accuracy is much better than my old SporTrak
  • Mac support in general is good, but MapSource maps still need to be converted on a Windows PC first before they can be used
  • Lots of advanced functionalities (maybe even just a bit too much)
  • Certain tasks, such as entering a waypoint are not as easy, clear and quick as on my old SporTrak
  • The electronic compass is not as simple to use as the one on my old SporTrak
So we'll have to see what the future brings. After some jiggling around with the battery connectors on my old SporTrak it seems to be working a bit better again. The GPSMAP 60CSx will become my new primary GPS device because I don't want to be geocaching somewhere far away from civilisation and have my GPS die on me, but I'll keep the SporTrak as a backup in case I drop the Garmin off a cliff.

Tuesday, 13 October 2009

Barbie pink network cable

What's wrong with this picture of the network cable that's currently plugged in to my Mac at a customers' offices?


It's pink! Not a soft pastel pink or even hot pink, bloody Barbie pink. While I do understand the value of color coding network/patch cables so you don't get lost in your own racks, Barbie pink ones are one step too far. And after seeing these cables I think all hope is lost.