« Back

kaleo configuration for custom portlet in liferay 6.0 EE.

General Blogs July 10, 2013 By priti parmar

Step1 : Add following reference and column to your service.xml (service in which you would like add workflow),out of these some of fields must be there which will help in mapping between workflow tables and your custom table.

<column name="resourcePrimKey" type="long"></column>

<column name="title" type="String"></column>

<column name="status" type="int"></column>

<column name="statusByUserId" type="long"></column>

<column name="statusByUserName" type="String"></column>

<column name="statusDate" type="Date"></column>

<!-- Finder methods -->

<finder name="R_S" return-type="Collection">

<finder-column name="resourcePrimKey"></finder-column>

<finder-column name="status"></finder-column>


<reference package-path="com.liferay.portal" entity="WorkflowInstanceLink"></reference>

<reference package-path="com.liferay.portlet.asset" entity="AssetEntry"></reference>

<reference package-path="com.liferay.portlet.social" entity="SocialActivity"></reference>


Step 2 :Build service to make sure there is no compile time error.


Step 3: Once you Confirm with service just add following line in liferay-portlet.xml <portlet> tag on which you wish to apply workflow.





- path : This is path of your own workflow handler class and your own

AssetRendererFactory handler class

- Note : This tag should before initialize of portlet.








Step 4: You need to extend com.liferay.portal.kernel.workflow.BaseWorkflowHandler class and override four abstract method.


  • String getClassName()
  • String getType(Locale locale)
  • Object updateStatus(int status,Map workflowContext)
  • String getIconPath(ThemeDisplay themeDisplay)


public class ArticleWorkflowHandler extends BaseWorkflowHandler






Note : Here one thing is very important updateStatus() method called another method which you gonna developed in Step5.



public Object updateStatus(int status, Map<String, Serializable> workflowContext)


return DemoLocalServiceUtil.updateStatus(userId, resourcePrimKey, status,      serviceContext);



Step 5: Now you need to implement one method called updateStatus() in you LocalServiceImpl class. which will return object of your model class.



public class DemoLocalServiceImpl extends DemoLocalServiceBaseImpl


public Demo updateStatus(long userId, long resourcePrimKey, int status,ServiceContext serviceContext)


User user = userPersistence.findByPrimaryKey(userId);

Date now = new Date();

// Article

Demo dempObj = null;





demoPersistence.update(dempObj, false);

if (status != WorkflowConstants.STATUS_APPROVED)


return dempObj;


return dempObj;




Step6: You need to extend com.liferay.portlet.asset.model.BaseAssetRendererFactory class and override abstract method.


  • String getClassName()
  • String getType(Locale locale)
  • Object getAssetRenderer(long classPK, int type)


public class ArticleAssetRendererFactory extends BaseAssetRendererFactory




public static final String CLASS_NAME = Article.class.getName();

public static final String TYPE = "article";


public AssetRenderer getAssetRenderer(long classPK, int type)

throws PortalException, SystemException {

// TODO Auto-generated method stub

int status = WorkflowConstants.STATUS_ANY;


status = WorkflowConstants.STATUS_APPROVED;


Article article = ArticleLocalServiceUtil.getLatestArticle(

classPK, status);

return new ArticleAssetRenderer(article);



Note : Here one thing is ArticleAssetRenderer Class which you gonna developed in Step7.


Step7: Now you need to create one class called ArticleAssetRenderer and extends BaseAssetRenderer and override 7 abstract method.


  • long getClassPK()
  • long getGroupId()
  • String getSummary()
  • String getTitle()
  • long getUserId()
  • String render(RenderRequest renderRequest,
  • RenderResponse renderResponse, String template)


public class ArticleAssetRenderer extends BaseAssetRenderer





public String render(

RenderRequest renderRequest, RenderResponse renderResponse,

String template) throws Exception {

if (template.equals(TEMPLATE_FULL_CONTENT)) {

   return "/admin/asset/fullcontent.jsp";

}else {

return null;







Step8: Now Deploy service and portlet you will find out your asset in control panel as showing below .now you can apply any definition on that.



Step9: Start workflow

  • Now you need to start Workflow at the time of add content there.
  • You have to write following method in your addContent() and updateContent() in your ***LocalServiceImpl class.


  • assetEntryLocalService.updateEntry(

userId, article.getGroupId(), Article.class.getName(),

article.getClassPK(), article.getUuid(), assetCategoryIds,

assetTagNames, article.isApproved(), null, null, null, null,

ContentTypes.TEXT_HTML, article.getTitle(),

article.getDescription(), null, null, 0, 0, null, false);

  •  WorkflowHandlerRegistryUtil.startWorkflowInstance(

     user.getCompanyId(), groupId, userId, Demo.class.getName(),

     resourcePrimKey, article, serviceContext);


public class ArticleLocalServiceImpl extends ArticleLocalServiceBaseImpl{

   public Article addArticle(long userId, long parentResourcePrimKey, String title,String content, String description, int priority, String dirName, ServiceContext serviceContext)

    throws PortalException, SystemException      


User user = userPersistence.findByPrimaryKey(userId);

long groupId = serviceContext.getScopeGroupId();

long articleId = counterLocalService.increment();

long resourcePrimKey = counterLocalService.increment();

Article article = articlePersistence.create(articleId);

articlePersistence.update(article, false);

    // Asset


     userId, article, serviceContext.getAssetCategoryIds(),


    // Workflow


     user.getCompanyId(), groupId, userId, Article.class.getName(),

     resourcePrimKey, article, serviceContext);

return article;


public void updateAsset(long userId, Article article, long[] assetCategoryIds,String[] assetTagNames)throws PortalException, SystemException {

   assetEntryLocalService.updateEntry(userId, article.getGroupId(), Article.class.getName(),article.getClassPK(), article.getUuid(), assetCategoryIds,assetTagNames, article.isApproved(), null, null, null, null,ContentTypes.TEXT_HTML, article.getTitle(), article.getDescription(), null, null, 0, 0, null, false);



Threaded Replies Author Date
Great article Priti, thanks for the contribution! Scott Lee July 10, 2013 9:34 AM
Hi Priti, good Article, i thought about asking... Ramkumar Chandran July 11, 2013 3:47 AM
Hi Ram, I am sorry , I dont get a chance to... priti parmar July 11, 2013 3:50 AM
Hi Priti, Thanx for this great post. Actually i... BabuNandan Biswal November 3, 2013 11:28 PM
Hi I have a confusion that the method... Mahesh Narke November 26, 2013 10:25 PM
i get an exception because there is no... Mahesh Narke November 26, 2013 11:09 PM
[...] Piyush Shukla: Hi all, would you please... Anonymous December 21, 2015 5:28 AM

Great article Priti, thanks for the contribution!
Posted on 7/10/13 9:34 AM.
Hi Priti,
good Article, i thought about asking a question in forum for long time... i find it this as a right time.....

i am looking for some article regarding liferay api on workflow... which i can build built on my custom plugin. for example instead of kaleo workflow, if i want to any other like jbpm or activi or any other workflow to integrated what are basic steps and api i should use... some kind of steps must be there.....

Hope u understand my question.
Posted on 7/11/13 3:47 AM.
Hi Ram,

I am sorry , I dont get a chance to work with jbpm or activity workflow .
Posted on 7/11/13 3:50 AM in reply to Ramkumar Chandran.
Hi Priti,
Thanx for this great post.
Actually i had some issue regarding this.
a)I am getting an error while adding <finder> tag in service.xml
b)I was unable to define the abstact method in ArticleWorkflowHandler class, so this will be a great help if you post a dummy code for this so that i can get an idea.

and if possible please mail me.

Thank You
Babu Nandan Biswal
Posted on 11/3/13 11:28 PM.
I have a confusion that the method updateStatus is implemented in Impl class while accessed in handler using LocalServiceUtil.updateStatus() . How will it work?
Posted on 11/26/13 10:25 PM.
i get an exception because there is no parameterized constructor in AssetRenderer while we are calling it in the AssetRendererFactory.
Also where is "/admin/asset/fullcontent.jsp"?? We need to create it?
Posted on 11/26/13 11:09 PM.
[...] Piyush Shukla: Hi all, would you please share with me , regarding this workflow what is workflow? why we go for workflow? with an live example. workflow with custom portlet. plese give me a brief... [...] Read More
Posted on 12/21/15 5:28 AM.