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>
</finder>
<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.
<workflow-handler>path</workflow-handler>
<asset-renderer-factory>path</asset-renderer-factory>
- path : This is path of your own workflow handler class and your own
AssetRendererFactory handler class
- Note : This tag should before initialize of portlet.
E.x
<asset-renderer-actory>
com.liferay.admin.asset.ArticleAssetRendererFactory
</asset-renderer-factory>
<workflow-handler>com.liferay.workflow.ArticleWorkflowHandler</workflow-handler>
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.
E.x
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.
E.x
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;
dempObj.setStatus(status);
dempObj.setStatusByUserId(user.getUserId());
dempObj.setStatusByUserName(user.getFullName());
dempObj.setStatusDate(serviceContext.getModifiedDate(now));
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)
E.x
public class ArticleAssetRendererFactory extends BaseAssetRendererFactory
{
----------
--------
public static final String CLASS_NAME = Article.class.getName();
public static final String TYPE = "article";
@Override
public AssetRenderer getAssetRenderer(long classPK, int type)
throws PortalException, SystemException {
// TODO Auto-generated method stub
int status = WorkflowConstants.STATUS_ANY;
if (type == TYPE_LATEST_APPROVED) {
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)
E.x.
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);
-E.x
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
updateAsset(
userId, article, serviceContext.getAssetCategoryIds(),
serviceContext.getAssetTagNames());
// Workflow
WorkflowHandlerRegistryUtil.startWorkflowInstance(
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);
}
}

