Social Equity in Liferay

Social Equity is a brand new feature in Liferay version 6. It is based on the white paper and calculations of Peter Reiser from SUN Microsystems.

The objective is to build a dynamic social capital system by measuring the contribution and participation of a user and the information value of an asset. A person can gain such equity through certain activities performed in communities.
 
The activities that award equities include
  •  adding contributions (wikis, blogs)
  •  rating, commenting
  •  viewing content
  •  searching and tagging (not implemented yet)
The main values used to describe engagement in communities are the following:
 
Information Equity (IQ)
This equity shows the importance and quality (measured by popularity) of the information contained in an asset. It is calculated through social activities related to the information.
 
Contribution Equity (CQ)
The contribution equity measures the contribution of a person to the community. This value is calculated from the information equity of the contributed assets.
 
Participation Equity (PQ)
This equity measures the active participation of a person. It is calculated by measuring the feedback a person has provided to other community contributions (assets). Viewing a contribution can be translated as feedback as well.
 
Personal Equity (PEQ)
The ultimate result, that describes a person's achievements and participation in the community. This value is the sum of a person's contribution and participation equities.
 
Configuration
By default the social equity feature is disabled and can be turned on by setting the "social.equity.equity.log.enabled" property in portal.properties. The social equity system works by evaluating and maintaining equity rewards that are the results of certain activities in the system. The social equity service doesn't know the meaning of these actions, these are configured in and by the contributing portlets. Naturally there is an administration portlet - accessible from the control panel - that allows administrators to change predefined values and store them into the database. There are two value sets that can be defined for an activity - information equity and participation equity. The first set contains values for calculating the reward for the information equity of the corresponding asset, while the latter is used to calculate participation equity rewards for the acting user.
 
All information has its usefulness only for a period of time. That period is determined by active downloads, comments, ratings or views of the information. So any information that is not rated, commented or viewed can be counted as stale information that lost its importance. Likewise, when a user is inactive for a certain period of time, his or her usefulness to the community diminishes or ceases all together.  In order to model this deterioration, the equity rewards are aging and thus are linearly converging to zero over a certain time period.
 
The above mentioned configuration value sets consist of two main values: the reward and its lifespan that is the time period in days over which the reward degrades to zero. There is also a daily limit value that simply sets how many times a day the corresponding equity reward can be used. The purpose of this limit is to slow down the development of a person's participation equity or an asset's information equity.
 
Ranking and daily maintenance
The main time unit for the social equity system is one day. Equity rewards degrade on a daily basis, and personal equity rankings are also calculated once a day. 
 
Top Users portlet
There is a portlet similar to friends that is capable of displaying the top ranked users and their equity values. It only displays users that have a rank greater than zero, so it is possible that a user has already accumulated some social equity but as the ranking process runs only once a day, his or her ranking might have not been updated yet, which results in the user not appearing in the list at all.
 
Contributing portlets
Currently there are three portlets that use the social equity service. These are Wiki, Blogs and Message Boards. The activities and their default values are configured in the resource actions xml.
 
Wiki
Configured activities are: ADD_PAGE, VIEW, ADD_DISCUSSION
 
Blogs
Configured activities are: ADD_ENTRY, VIEW, ADD_DISCUSSION
 
Message Boards
Configured activities are: ADD_MESSAGE, ADD_VOTE, REPLY_MESSAGE, VIEW
 
Blogs
A really super cool feature that was actually kind of asked for as late as today in discussions with a customer of ours. It will be interesting to see how this develops, like integration with Web Content, Asset Publisher (rating, commenting, etc) and stuff like that.

Nice work!
Can anyone share screenshots of what this looks like in Liferay 6.0?
I wrote a wiki about it too with some screenshots:

http://www.liferay.com/community/wiki/-/wiki/Main/Social+Equity+Admin
http://www.liferay.com/community/wiki/-/wiki/Main/Top+Users+portlet
Pretty cool stuf.
My question is, how can we customize this in other portlets? For example, imagine you want to consider contribution score when users write on each other's wall, upload an image, etc.
Or even non-liferay portlets. If you have a portlet, e.g. to share news or add meetings etc., what should you set in these portlets so that they can communicate with Social Equity portlet?
Is this possible at all, or are we only limited to the three portlets mentioned above?
Expanding "social equity" beyond existing portlets could create a powerful tool for collaborative negotiation. Think of a global registry where every asset, contributed to any web site or application, is associated with a universal value. Like virtual money, this would creative greater incentives and social rewards for people who share anyway.

The ideal system would require good connectivity and an RSS–like standard that associates each published asset with usage and ranking in a global registry. The standard would allow a publisher, coder or service provider to easily register any article, working application, or even a shared piece of code. Each time an asset is used or ranked, its properties would change.

It would be great if Liferay would start such a registry for its own assets. This could later be expanded into an open global registry. I've been thinking about this idea for a while, and described it in one of my patents (“Distributed Active Knowledge and Process”) about ten years ago, but as far as I know this has never been implemented. I’ll be glad to help Liferay or anyone who plans to implement it. I'm not looking for any payment or fees. I would just like to see it happen and think it could be a valuable addition to the Open Internet.
Hey Puj,

For the internal portlets we are probably going to integrate most of them though I can't give you any details about which ones and when. Custom portlets can register actions and use the social equity service to trigger those actions. In this regard, social equity is more like a service. There is a Top Users portlet that shows a competition style ranking for users based on their personal equities.

I hope this helps. Cheers!
Hi Zsolt,

thanks for the info!
You said: "Custom portlets can register actions and use the social equity service to trigger those actions."

Could you please give me a brief sample-code for that? Imagin I have a portlet with form in it, so that users enter some info. For this portlet I already have
<portlet:actionURL var="updateUnits" windowState="normal" name="<%=Constants.ADD_UNITS_ACTION%>" />
to enter the data into database.

What I would like to implement is that each time a user enters new info (updateUnits action is called), his contribution-score would also increase.

If you can give me the sample code (or the standard how to do it), then I don't have to implement an isolated scoring system and then merge it with scores from social equity later.
Many thanks!
Hi Puj,

Please take a look at the wiki page about integrating custom portlets into the social equity system:

http://www.liferay.com/community/wiki/-/wiki/Main/Using+Liferay%27s+Social+Equity+System
Hi Zsolt, thanks. This is one of cool features in Liferay 6.

Questions:
1) can it be extended for other core portlets like Journal (Web Content)?
2) can it be extended for custom portlets like Knowledge Base?
3) can this be done by tag like social activity?

<social-activity-interpreter-class>com.liferay.knowledgebase.admin.social.AdminActivityInterpreter</social-activity-interpreter-class>
Hey Jonas,

We are currently working on some additional core features, that's why social equity has not been extended to other core portlets like Web Content. But we are planning to. As to your questions:

1-2. Absolutely. The framework is portlet agnostic. It operates on assets and uses action keys defined in resource-actions xmls. Service calls need to be added to the respective services (Journal, Knowledge Base, etc.)

3. What exactly is it that you want to achieve here?

I hope I could help.

Cheers.
Hi Zsolt, thanks.

I got the answer for the question 3). I am going to write a blogs to explain how to add social equity services on custom assets in plugins.

http://www.liferay.com/c/blogs/find_entry?entryId=5981482

social equity is really nice feature in Liferay portal 6.1. Thank you again, Zsolt.
Hi, Zsolt, thanks for the valuable information.

I have 2 questions:

1. How to map the activities to the relevant social equity? May I say that "adding contributions" is for Contribution Equity, while "rating, commenting, viewing" are translated into Participation Equity?

I saw your screenshot of the Social Equity Admin in the wiki. What I'm not clear is how it can be translated into the IQ, CQ, PO and PEQ respectively?

2. I created a community using Liferay. In the community portal, I saw Contribution Score and Participation Score. How are they calcualted and how are they linked to the social equity (IQ, CQ, PQ and PEQ)?

Thanks in advance for the reply.
Hi Azalea,

1. You can map activities to social equity however you want. It is totally up to you what you configure for those actions. If you want, you can say that creating a Wiki Page should only count for a member's participation. The tricky but also exciting thing is how you configure your community.

Generally you would probably want to set some participation values for each action because even creating an article or wiki page counts as participation. It's a big question whether you should set information values for those actions or not. You really don't know the quality and value of the asset at creation time. Therefore I would probably put more emphasis on setting some information values on actions that other users make on this asset such as "view" and especially "vote". Of course these actions also should have some participation values assigned, otherwise people would loose interest in voting or viewing wikis or blogs or whatever. (Of course I know that social equity is not the main reason why people view pages or blogs on communities or vote for them, but you know what I mean...)

A very important thing to remember and to understand regarding social equity. The information value you set for a certain action is added to the asset's IQ (and as a consequence to the owner's CQ) and the participation value is added to the executing user's PQ. This basically mean that if you set both values for the VIEW action, you assign some points to the asset's IQ, which in turn will increase user A's CQ and at the same time you add some points to user B's PQ. So we are sometimes changing scores for two different users with a single action...

2. score = equity. It's just probably a more friendlier or common term. XXX Equity is basically a score, because we are accumulating points...

I hope I could help.
Hi, Zsolt,

Thank you very much for the quick and detailed reply. It's very useful.

I plan to use the CQ and PQ as one of the contributing factors for a professional certification. Currently there is a scheme to score the members physical activities, e.g. 50 points for attending a training course, 80 points for publishing a conference paper, etc. I would like to add CQ and PQ as an additional evaluation criteria. It is a mechanism to encourage members contribution and participation online.
Hi Zsolt,

If you are not tired of responding to all these question, I have two more questions. ^^

1- is there a standard way of mapping the Equity/score to roles in liferay? For example, to define, when the equity of a users is more than 10.000 he or she is automatically receives publisher role.
2- The same question is for users' status. Has liferay a standard way of doing the transactions that can be used in pluggins to map one user's equity to its status (like Padawan, Jedi Master, etc. in Liferay)? I have not seen any -status management- portlet or mechanism to date. Have I missed something or there is none?

Thanks for your time! emoticon
Hi,

while trying to add socialEquity to my custom portlet, I cannot see my action in social-equity list of available partlet actions.

I read somewhere that after adding resources one should put the line below in the portal-ext.properties so that liferay adds the resources to its current resources. In that case, the .xml file in the resource-actions folder is the same name as the portlet:

resource.actions.configs=resource-actions/portletName.xml

The question is, when this file is called default (as mentioned in the totorial) should we put
resource.actions.configs=resource-actions/default.xml
in portal-ext.properties? If yes, then I assume some problems would arise if two separate portlets deine resource-actions at the same time in their default.xml, right?
Am I missing something? Or does liferay merges all theses "default.xml"s?
Any hints would reduce my increasing headache and gray hairs! emoticon
Hi Puj,

First, you can name your resource actions xml anything as long as you set resource.actions.configs.

As for the place for this settings, it's in portlet.properties, not in portal-ext.properties. You pack your resource actions xml file with your portlet and that's how you can have more than one default.xml for example...

I hope I could help.

Cheers,
Zsolt
Hi Zsolt,

Thanks a lot! It works now. I had to take a look at sample-permission-portlet to grasp the whole idea behind key-actions and permissions.
I also wrote the explanation under your wiki post here:
http://www.liferay.com/community/wiki/-/wiki/Main/Using+Liferay%27s+Social+Equity+System

The only thing that is now missing is that I couldn't find a tag to set the daily-limit. Is it only possible to set it in the social-equity-admin page or is there a way to also set the corresponding value in the default.xml?

Cheers,
Puj
Hi Zsolt,

Sorry to bother you again. I am trying to give users rankings according to their social equity. For this, I used this method to get the scores in my jsp:
<%@ page import="com.liferay.portlet.social.service.SocialEquityUserLocalServiceUtil" %>
<%=SocialEquityUserLocalServiceUtil.getParticipationEquity(PortalUtil.getUserId(request)).getValue()%>
and
<%=SocialEquityUserLocalServiceUtil.getContributionEquity(PortalUtil.getUserId(request)).getValue()%>

But it throws NullPointerException at this line when trying to use the dynamic query to get the projectionList:

DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass( SocialEquityUser.class);

The Exception:

15:03:35,406 ERROR [jsp:154] java.lang.NullPointerException
at org.hibernate.criterion.DetachedCriteria.forClass(DetachedCriteria.java:88)
at com.liferay.portal.dao.orm.hibernate.DynamicQueryFactoryImpl.forClass(DynamicQueryFactoryImpl.java:35)
at com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil.forClass(DynamicQueryFactoryUtil.java:23)
at com.liferay.portlet.social.service.impl.SocialEquityUserLocalServiceImpl.getEquityValue(SocialEquityUserLocal
ServiceImpl.java:75)

Am I missing anything? Should I set something somewhere beforehand?
The socialEquityLog is active and the top user portlet shows my user with c-score 10 and p-score 5 already (I checked socialEquityLog table and there are two actions added for this user too).

Is there any other way to request the c-score and p-score of a specific user?

Thanks for your time in advance
Hi Puj,

As Social Equity is still an experimental feature, this one somehow slipped past and is in fact broken. I'm going to create an LPS for this as I have already fixed it. I hope it can get to the next release. If not, you can always create a service hook for that service method and fix it. The only thing it needs is a second parameter for the class loader, which you can get by PortalClassloaderUtil.getClassLoader().

I hope this helps,
Zsolt
Hi Jonas, Hi Zsolt

From the forum and wiki searches I guess i am the only one trying to user social equity in custom plug-ins! Anyway, I pave way for other! ;) I hope Zsolt and Jonas could provide some help.

I have a plug-in, with some resource-actions, that also appear on the social equity page of the community. For some actions, I use the
addEquityLogs(long userId, String className, long classPK, String actionId)
method in my action methods (or sometimes right in the ServiceImpl methods) to give users some point for that action.
No errors is received, however, the score of the user does not change at all.
When I check the socialEquityLog table, I only see the standard actions (like VIEW) and not my custom actions.
Has anyone tested this feature yet? I am using liferay 6EE and the feature is supposed to work.
Anything I might have missed?
Hi Puj,

As for the score not changing, there can be a number of reasons. Make sure, you don't run into some of the restrictions, such as the duplicate check or the invisible asset check, or the one that checks if you want to add points to yourself.

If you give me some more info maybe I can check it...

Best,
Zsolt
Hi Zsolt,

Thanks for your response! Social equity is an awesome feature in liferay 6 and you have done a great job! I will further test the features and let you know if I see any other problems/bugs.
As for the first issue, I have already submitted it, so you don't have to create a new one:
http://issues.liferay.com/browse/LPS-14157

For the second one, I found out that no asset was assigned to the entitiy we were trying to assign equity to and I saw in the code that when no asset is available, it just returns:
public void addEquityLogs(
long userId, String className, long classPK, String actionId)
throws PortalException, SystemException {

if (!PropsValues.SOCIAL_EQUITY_EQUITY_LOG_ENABLED) {
return;
}

AssetEntry assetEntry = null;

try {
assetEntry = assetEntryLocalService.getEntry(
className, classPK);
}
catch (NoSuchEntryException nsee) {
return;
}

I guess in the documentation it is worth mentioning that an asset should have been created for the custom entity before, otherwise it will not work. When I finally implement it successfully, I will extend your wiki or write a new one with all the details.

And if your patch didn't make it to the next Liferay 6EE release, I appreciate it if you can give me some hints on what to change in the service (in a hook of course). Thanks!
Hi,

I've managed to register a new Social Equity Entity, by adding:

- WEB-INF/classes/portlet.properties
- WEB-INF/classes/resource-actions/default.xml

This was enough to see my class (Poll.java) appearing in the Social Equity admin view.

Now, from my Portlet I'd like to do something like:

long classPK = 12000;
long userId = 10876;
SocialEquityLogLocalServiceUtil.addEquityLogs(userId,classPK,"SEND_INVITATION");
OR
SocialEquityLogLocalServiceUtil.addEquityLogs(userId,"com.....Poll.java",classPK,"SEND_INVITATION");

but in both cases, I do not understand where/how I should register "classPK".

I have tried few things, but no success:

1. Define the Poll.java class as follows:

public class Poll extends SocialEquityLogImpl {
....
@Override
public long getPrimaryKey() {
return 12000;
}
}

2. Invoke the following code in my Portlet, right before adding equity logs:

AssetEntry entry = AssetEntryLocalServiceUtil.createAssetEntry(classPK);
entry.setPrimaryKey(classPK);
entry.setClassPK(classPK);
entry.setClassUuid("com.....Poll");
AssetEntryLocalServiceUtil.addAssetEntry(entry);

How can I register my Asset so that it can be used by Social Equity? What exactly is the classPK and how should be handled?

Thanks in advance!

Maurizio
Hi Maurizio,

First of all, don't extend SocialEquityLogImpl. That is an internal class and has nothing to do with extending social equity.

The classPK is the primary key of your Poll object in the database. In case you don't want to store it in any table other than AssetEntry, you just create a new primary key. What is important is that the combination of the className (or rather classNamId) and the classPK must be unique.

So if you're storing your object in your own poll table, just use the primary key, you've generated for it, otherwise just call the CounterService (CounterLocalServiceUtil.increment()) to get a new unique key.

As for the classNameId, you can register it with the portal transparently by using PortalUtil.getClassNameId("com....Poll"). This will return the classNameId that you can use when creating the asset. There is no need to set the UUID, set the classNameId to the return value of that method.

I hope I could help.

Cheers,

Zsolt.
Hi Zsolt,
thanks a lot for your support! Will get back to you as soon as I can apply your advises.

Looking forward to contribute back some snippets and documentation!

mau
Hi Zsolt, it works!

What I did:

INSERT INTO ASSETENTRY VALUES(11315,10493,1,11020,'Michelle Writer','2011-02-28 12:09:27.356000000','2011-02-28 12:01:42.595000000',11607,11901,'84d083df-c766-4102-9bae-6021be1f5d23',TRUE,NULL,NULL,NULL,NULL,'text/html','DUDES Poll','','','',0,0,0.0E0,0)

where...
11315 = the entryId, set as a higher value of the previous table row entryId (11308)
10493 = the groupId
11020 = the userId
11901 = classPK, a long which was randomly chosen; would be safer to generate it via CounterLocalServiceUtil.increment()
11607 = classNameId, generated invoking PortalUtil.getClassNameId(Poll.class)

All other values are not relevant (at least for the SocialEquity voting feature)

Into my Portlet code, I did the following:

1) Send 2 logs to the same action, using the different method signatures

SocialEquityLogLocalServiceUtil.addEquityLogs(11020,Poll.class.getName(),11901,"SEND_INVITATION");
SocialEquityLogLocalServiceUtil.addEquityLogs(11020,11315,"SEND_INVITATION");

2) Check the logs to see if the 2 created logs are registered

List<SocialEquityLog> logs = SocialEquityLogLocalServiceUtil.getSocialEquityLogs(0, SocialEquityLogLocalServiceUtil.getSocialEquityLogsCount());
for(SocialEquityLog log : logs) {
System.out.println("-- Social Equity Log --");
System.out.println(
"actionID: "+ log.getActionId() +
"; assetEntryID: " + log.getAssetEntryId() +
"; equityLogID:"+log.getEquityLogId() +
"; primaryKey:"+log.getPrimaryKey() +
"; primaryKeyObj:"+log.getPrimaryKeyObj());
System.out.println("-- END Social Equity Log --");
}

Thanks again for your support and for contributing such a cool feature, I really love Social Equity support in Liferay.

mau
Hi Zsolt,

This feature looks great and I am exploring it and would like to recommend it. However, I have seen on SUN/Oracle site (http://blogs.sun.com/peterreiser/entry/community_equity_specification) that they have filed a patent on Community Equity on which this feature is based.
Will this patent have any practical (e.g. financial) implication for Liferay users?
I really like this Social Equity feature! I am curious though, is there a way to get rid of the information lifetime, so that points that a user earns don't deteriorate over time?

I suppose I could set the information-lifetime setting really high, but I'd prefer to just remove it if I can. I tried setting the information-lifetime to '0', but that only resulted in not giving a user points when they performed an action.
i want to develop one social equity small application how to develop give some idea.. and give code for that..
Hi ,

I have a requirement to add my custom portlet to the SocialActivity in the Configuration, as we have the Blogs Entry,MessageBoards ,Wiki Page .

I have tried to override the view.jsp under social_activity and also tried extending the Action class . But I couldnt achieve it .

What all are the steps needed to be followed to add a custom portlet to the Social Activity in the Configuration .
Can anyone please help me to achieve the above task .

Thanks,
Hi ,

I have a requirement to add my custom portlet to the SocialActivity in the Configuration, as we have the Blogs Entry,MessageBoards ,Wiki Page .

I have tried to override the view.jsp under social_activity and also tried extending the Action class . But I couldnt achieve it .

What all are the steps needed to be followed to add a custom portlet to the Social Activity in the Configuration .
Can anyone please help me to achieve the above task .

Thanks,