« Back to Expando

Adding Custom Attributes to Communities

(Redirected from Adding an custom attribute to a Community)

Introduction #

This is an example of adding an Expando attribute called "title" on a com.liferay.portal.model.Group (a community).

Creating the Attribute #

void createAttribute(long companyId)
	ExpandoBridgeImpl expandoBridge = new ExpandoBridgeImpl(com.liferay.portal.model.Group.class.getName());
	if (expandoBridge.hasAttribute("title")) {
		log.debug("attribute title already exists");
	}
	else {
		log.info("adding title attribute");
		expandoBridge.addAttribute("title");
	}
}


Setting Permissions for Community Members #

void setPermissions(long companyId) {
	ExpandoBridgeImpl expandoBridge = new ExpandoBridgeImpl(com.liferay.portal.model.Group.class.getName());
	Role guest = RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST);
	Role member = RoleLocalServiceUtil.getRole(companyId, RoleConstants.COMMUNITY_MEMBER);
	ExpandoColumn column = ExpandoColumnLocalServiceUtil.getColumn(
		expandoBridge.getClassName(),
		ExpandoTableConstants.DEFAULT_TABLE_NAME,
		"title");
	String[] actionsRO = new String[] { ActionKeys.VIEW };
	String[] actionsRW = new String[] { ActionKeys.VIEW, ActionKeys.UPDATE };
	// make sure the resource exists
	Resource resource = ResourceLocalServiceUtil.addResource(
		companyId,
		ExpandoColumn.class.getName(),
		ResourceConstants.SCOPE_INDIVIDUAL,
		String.valueOf(column.getColumnId()));

	PermissionLocalServiceUtil.setRolePermissions(guest.getRoleId(), actionsRO, resource.getResourceId());
	PermissionLocalServiceUtil.setRolePermissions(member.getRoleId(), actionsRW, resource.getResourceId());
}


Using the Attribute #

Java #

void updateTitle(Group group, String title) {
	group.getExpandoBridge().setAttribute("title", title);
	log.info("updated group " + group.getName() +
		      ", set title = " + twinspace.getExpandoBridge().getAttribute(""));
}

Velocity #

Use the community (=Group) title in the theme, for ex. in portal_normal.vm

#set ($community_title = $themeDisplay.getScopeGroup().getExpandoBridge().getAttribute("title"))


Troubleshooting #

Permissions Error #

  1. Instead of using the ExpandoBridge you can use ExpandoTableLocalServiceUtil and ExpandoColumnLocalServiceUtil. These services don't use permission checking. This is a bit more code.
  2. You can temporarily set a permissionChecker with PermissionThreadLocal.setPermissionChecker(pc). Don't forget to reset it to the original one after you are done.
0 Attachments
89947 Views
Average (2 Votes)
The average rating is 5.0 stars out of 5.
Comments
Threaded Replies Author Date
When creating the custom attribute inside a... Peter Mesotten September 28, 2009 1:59 AM
Hi Peter, did you solve your this problem? I'm... Sven Ehlert October 9, 2009 6:21 AM
There are two solutions around this problem: 1.... Martin Goldhahn October 19, 2009 7:47 AM
He Peter, In Liferay 6.2 you can use the method... Rami MASMOUDI July 7, 2014 5:24 AM
Rami, Thanks for your reply. It worked. Anil T August 17, 2015 1:42 AM
How do i know / find out required role(s) for... Scott Langeberg May 5, 2010 5:53 PM
There are methods like addAttribute(String... Hiran Chaudhuri August 18, 2011 2:53 PM
I am in the same boat as Scott. How do you... Rob Chan August 31, 2011 10:31 AM
addAttribute int type definition is listed in... Jens Straube April 19, 2012 3:42 AM
Deprecated. Use the methods that receive... Christopher Jimenez July 17, 2013 7:54 AM

When creating the custom attribute inside a startup hook I get the following permission exception. I probably need to set the according permission to add an expando column for the user. But which user do I have to address here? And how should I set the permissions? I really want to avoid using ExpandoXXXLocalServiceUtil methods. Is this possible in startup hooks?

com.liferay.portal.security.auth.PrincipalException: PermissionChecker not initialized
at com.liferay.portal.service.base.PrincipalBean.getPermissionChecker(PrincipalBean­.java:77)
at com.liferay.portlet.expando.service.impl.ExpandoColumnServiceImpl.addColumn(Expa­ndoColumnServiceImpl.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.jav­a:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils­.java:307)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(Ref­lectiveMethodInvocation.java:182)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveM­ethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(Transa­ctionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveM­ethodInvocation.java:171)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInv­ocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveM­ethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.j­ava:204)
at $Proxy95.addColumn(Unknown Source)
at com.liferay.portlet.expando.service.ExpandoColumnServiceUtil.addColumn(ExpandoCo­lumnServiceUtil.java:60)
at com.liferay.portlet.expando.model.impl.ExpandoBridgeImpl.addAttribute(ExpandoBri­dgeImpl.java:98)
at be.aca.liferay.samples.expando.ExampleStartupHook.createAttribute(ExampleStartup­Hook.java:39)
at be.aca.liferay.samples.expando.ExampleStartupHook.doRun(ExampleStartupHook.java:­29)
at be.aca.liferay.samples.expando.ExampleStartupHook.run(ExampleStartupHook.java:21­)
at com.liferay.portal.kernel.events.InvokerSimpleAction.run(InvokerSimpleAction.jav­a:52)
at com.liferay.portal.deploy.hot.HookHotDeployListener.initEvent(HookHotDeployListe­ner.java:582)
at com.liferay.portal.deploy.hot.HookHotDeployListener.initEvents(HookHotDeployList­ener.java:643)
at com.liferay.portal.deploy.hot.HookHotDeployListener.doInvokeDeploy(HookHotDeploy­Listener.java:237)
at com.liferay.portal.deploy.hot.HookHotDeployListener.invokeDeploy(HookHotDeployLi­stener.java:98)
at com.liferay.portal.kernel.deploy.hot.HotDeployUtil._doFireDeployEvent(HotDeployU­til.java:108)
at com.liferay.portal.kernel.deploy.hot.HotDeployUtil._fireDeployEvent(HotDeployUti­l.java:153)
at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(HotDeployUtil­.java:43)
at com.liferay.portal.kernel.servlet.PortletContextListener.portalInit(PortletConte­xtListener.java:113)
at com.liferay.portal.kernel.util.PortalInitableUtil.init(PortalInitableUtil.java:4­8)
at com.liferay.portal.kernel.servlet.PortletContextListener.contextInitialized(Port­letContextListener.java:109)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843­)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:926)
at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:889)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1217)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:293)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.ja­va:117)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1337­)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChild­ren(ContainerBase.java:1601)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChild­ren(ContainerBase.java:1610)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(Containe­rBase.java:1590)
at java.lang.Thread.run(Thread.java:595)
Posted on 9/28/09 1:59 AM.
Hi Peter, did you solve your this problem? I'm having the exact same issue.
Posted on 10/9/09 6:21 AM in reply to Peter Mesotten.
There are two solutions around this problem:
1. Instead of using the ExpandoBridge you can use ExpandoTableLocalServiceUtil and ExpandoColumnLocalServiceUtil. These services don't use permission checking. This is a bit more code.
2. You can temporarily set a permissionChecker with PermissionThreadLocal.setPermissionChecker(pc). Don't forget to reset it to the original one after you are done.
Posted on 10/19/09 7:47 AM in reply to Peter Mesotten.
How do i know / find out required role(s) for user to have, when updating Group Expando (such as group.getExpandoBridge().setAttribute("title", title);)?

That is, in some situations, my user can setAttribute() on the group expando. However, I have other user(s) / environments / roles, whereby the user is getting the error below.

I've tried giving the user full owner / admin rights, but still getting error. If there is related documentation, i'd greatly appreciate a link!:

2010-05-05 16:57:49,432 INFO (http-172.19.20.203-8080-3) 16:57:49,417 ERROR [ExpandoBridgeImpl:280] com.liferay.portal.security.auth.PrincipalException
com.liferay.portal.security.a­uth.PrincipalException
at com.liferay.portlet.expando.service.permission.ExpandoColumnPermission.check(Exp­andoColumnPermission.java:67)
at com.liferay.portlet.expando.service.impl.ExpandoValueServiceImpl.addValue(Expand­oValueServiceImpl.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.jav­a:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils­.java:307)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(Ref­lectiveMethodInvocation.java:182)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveM­ethodInvocation.java:149)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(Meth­odInvocationProceedingJoinPoint.java:77)
at com.liferay.portal.spring.aop.ServiceHookAdvice.invoke(ServiceHookAdvice.java:90­)
at sun.reflect.GeneratedMethodAccessor318.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.jav­a:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGive­nArgs(AbstractAspectJAdvice.java:627)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(Abstrac­tAspectJAdvice.java:616)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.j­ava:64)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveM­ethodInvocation.java:171)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(Transa­ctionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveM­ethodInvocation.java:171)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInv­ocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveM­ethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.j­ava:204)
at $Proxy219.addValue(Unknown Source)
at com.liferay.portlet.expando.service.ExpandoValueServiceUtil.addValue(ExpandoValu­eServiceUtil.java:52)
at com.liferay.portlet.expando.model.impl.ExpandoBridgeImpl.setAttribute(ExpandoBri­dgeImpl.java:275)
Posted on 5/5/10 5:53 PM.
There are methods like
addAttribute(String name)
addAttribute(String name, int type)
addAttribute(String name, int type, Serializable default)

How do you know what type to use for e.g. Date fields?
Posted on 8/18/11 2:53 PM.
I am in the same boat as Scott. How do you explicitly give users permissions to use ExpandoBridge?
Posted on 8/31/11 10:31 AM in reply to Hiran Chaudhuri.
addAttribute int type definition is listed in com.liferay.portlet.expando.model.ExpandoColumnConstants
Posted on 4/19/12 3:42 AM in reply to Rob Chan.
Deprecated.
Use the methods that receive 'companyId'
Posted on 7/17/13 7:54 AM in reply to Hiran Chaudhuri.
He Peter,
In Liferay 6.2 you can use the method addAttribute(String name, boolean secure)
with secure=false to escape the permission exception emoticon
Posted on 7/7/14 5:24 AM in reply to Peter Mesotten.
Rami, Thanks for your reply. It worked.
Posted on 8/17/15 1:42 AM in reply to Rami MASMOUDI.