« Zurück zu Expando

Adding Custom Attributes to Communities

(Umgeleitet von 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 Anhänge
89929 Angesehen
Durchschnitt (2 Stimmen)
Die durchschnittliche Bewertung ist 5.0 von max. 5 Sternen.
Kommentare
Antworten im Thread Autor Datum
When creating the custom attribute inside a... Peter Mesotten 28. September 2009 01:59
Hi Peter, did you solve your this problem? I'm... Sven Ehlert 9. Oktober 2009 06:21
There are two solutions around this problem: 1.... Martin Goldhahn 19. Oktober 2009 07:47
He Peter, In Liferay 6.2 you can use the method... Rami MASMOUDI 7. Juli 2014 05:24
Rami, Thanks for your reply. It worked. Anil T 17. August 2015 01:42
How do i know / find out required role(s) for... Scott Langeberg 5. Mai 2010 17:53
There are methods like addAttribute(String... Hiran Chaudhuri 18. August 2011 14:53
I am in the same boat as Scott. How do you... Rob Chan 31. August 2011 10:31
addAttribute int type definition is listed in... Jens Straube 19. April 2012 03:42
Deprecated. Use the methods that receive... Christopher Jimenez 17. Juli 2013 07:54

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)
Gepostet am 28.09.09 01:59.
Hi Peter, did you solve your this problem? I'm having the exact same issue.
Gepostet am 09.10.09 06:21 als Antwort auf 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.
Gepostet am 19.10.09 07:47 als Antwort auf 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)
Gepostet am 05.05.10 17:53.
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?
Gepostet am 18.08.11 14:53.
I am in the same boat as Scott. How do you explicitly give users permissions to use ExpandoBridge?
Gepostet am 31.08.11 10:31 als Antwort auf Hiran Chaudhuri.
addAttribute int type definition is listed in com.liferay.portlet.expando.model.ExpandoColumnConstants
Gepostet am 19.04.12 03:42 als Antwort auf Rob Chan.
Deprecated.
Use the methods that receive 'companyId'
Gepostet am 17.07.13 07:54 als Antwort auf 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
Gepostet am 07.07.14 05:24 als Antwort auf Peter Mesotten.
Rami, Thanks for your reply. It worked.
Gepostet am 17.08.15 01:42 als Antwort auf Rami MASMOUDI.