It's been a while since the last post. And the main reason is that I have been waiting for version 6.1.0 of Liferay bacause a got stuck in a point that I thought It would be resolved in last release but it is not. Well, actually it is not very likely to be a Liferay bug but my fault. And this is what this post will talk about. It is something like an S.O.S. call.
As it can be read in previous posts, I managed to obtain, from Android device, a user in Liferay via REST (getUserById , getUserByEmailAddress ...). So, every thing look fine and I started to implement the rest of the client-side methods that invoke the exposed service. (UserService in this case)
Functionally talking, next isteresting method was addUser. Basically, the idea was to create a basic sign-in and register dummy app having Liferay as backOffice. So, I needed to implement the ability to add a user via REST. And here is were the problem came.
UserServiceUtil has two addUser methods, and I chose the one with less parameters, just for simplicity. And this is the spec:
public static com.liferay.portal.model.User addUser(long companyId,
boolean autoPassword, java.lang.String password1,
java.lang.String password2, boolean autoScreenName,
java.lang.String screenName, java.lang.String emailAddress,
long facebookId, java.lang.String openId, java.util.Locale locale,
java.lang.String firstName, java.lang.String middleName,
java.lang.String lastName, int prefixId, int suffixId, boolean male,
int birthdayMonth, int birthdayDay, int birthdayYear,
java.lang.String jobTitle, long[] groupIds, long[] organizationIds,
long[] roleIds, long[] userGroupIds, boolean sendEmail,
com.liferay.portal.service.ServiceContext serviceContext)
throws com.liferay.portal.kernel.exception.PortalException,
com.liferay.portal.kernel.exception.SystemException;
First of all, before implementing the call in Lifedroid's UserManager I tried to invoke the service via web browser manually. With something like that making a GET call:
http://localhost:8080/tunnel-web/secure/json
?serviceClassName=com.liferay.portal.service.UserServiceUtil
&serviceMethodName=addUser
&serviceParameters=[companyId,autoPassword,password1,password2,autoScreenName,screenName,
emailAddress,facebookId,openId,locale,firstName,middleName,lastName,prefixId,suffixId,
male,birthdayMonth,birthdayDay,birthdayYear,jobTitle,groupIds,organizationIds,roleIds,
userGroupIds,sendEmail,serviceContext]
&serviceParameterTypes=[long,boolean,java.lang.String,java.lang.String,boolean,java.lang.String,java.lang.String,
long,java.lang.String,java.util.Locale,java.lang.String,java.lang.String,java.lang.String,int,
int,boolean,int,int,int,java.lang.String,long,long,long,long,boolean,com.liferay.portal.service.ServiceContext]
&companyId=10160
&autoPassword=true
&password1=aritz
&password2=aritz
&autoScreenName=true
&screenName=aritz
&emailAddress=aritz@mail.com
&facebookId=1
&openId=2
&locale={}
&firstName=aritz
&middleName=galdos
&lastName=otermin
&prefixId=1
&suffixId=1
&male=true
&birthdayMonth=2
&birthdayDay=2
&birthdayYear=2000
&jobTitle=1
&groupIds=1
&organizationIds=1
&roleIds={}
&userGroupIds={}
&sendEmail=false
&serviceContext={}
There is no problem with the firts marameters, as they are primitive types or Strings until we reach the locale parameter. D'oh! (Would Homer say)
I attached the source code of 6.1.0 b3 to Eclise and I started to debug/trace the code trying to figure out how to pass a locale object as parameter.
As I could read in a James Falkner's post called Yet Another Liferay JSON Service Example he passes the parameter serviceContext as "{}" and similarly I tryed it with locale.
The execution goes to JSONServiceAction class, method getArgValue. This method, in the begining, get the typeNameOrClassDescriptor for the param being evaluated, and returns the convenient class instance with the value passed as String.
The problem is that the Locale class is not contemplated and in this case and the method returns:
return JSONFactoryUtil.looseDeserialize(value);
Where value equal {}
Which should deserialize the value to an instance of Locale class.
So at this point, I think that what I have to do is to work out how to pass a locale correctly serialiced, to be deserialiced to Locale.
In case you have any clue or tip that could help me work this out, please, spot me some light via twitter @aritzg or @LifedroidNet. Or in the contact form.
Thanks for reading.