05 June, 2012

zk-zul integration with liferay

Hi liferay Rockers,

I really feel nice to write this blog because i am also new to zk-zul framework.
I just started hands on this framework and i want to integrate with  liferay.
So finally i have created very simple portlet using zk framework and 
Steps are given below :

  1. Create simple MVC portlet (if you are new to create portlet, just check http://www.liferaysolution.com/2012/05/create-simple-plugin-portlet-liferay.html)
  2. Now you may need to include necessary zk-zul libraries in portlet lib folder. ZK libraries can be downloaded from ZK Download and then save it to a proper location.
  3. Unzip zk-bin-x.x.x.zip (the x.x.x is the latest version)  
  4. Copy JAR files under following list to zk-test-portlet\docroot\WEB-INF\lib
  5. Now create web.xml file under zk-test-portlet\docroot\WEB-INF directory and put below code in web.xml:
  6. 
      ZK-Learning-Portlet
       
       Used to cleanup when a session is destroyed
      ZK Session cleaner
      org.zkoss.zk.ui.http.HttpSessionListener
     
     
      The ZK loader for ZUML pages
      zkLoader
      org.zkoss.zk.ui.http.DHtmlLayoutServlet
      
       update-uri/zkau
      1
     
     
      The asynchronous update engine for ZK
      auEngine
      org.zkoss.zk.au.http.DHtmlUpdateServlet
     
     
      zkLoader
      *.zul
     
     
      zkLoader
      *.zhtml
     
     
      auEngine
      /zkau/*
     
      
       
        http://java.sun.com/portlet_2_0
        
         /WEB-INF/tld/liferay-portlet.tld
        
       
      
    
    
  7. Now open liferay-portlet.xml file and put below code :
  8. 
     
      zk-test
      /icon.png
      true
      /css/main.css
      /zkau/web/js/zk.wpd
      /js/main.js
      zk-test-portlet
     
     
      administrator
      Administrator
     
     
      guest
      Guest
     
     
      power-user
      Power User
     
     
      user
      User
     
    
    
  9. Now create hello.zul file under zk-test-portlet\docroot\zul folder :
  10. 
       Hello World!
         
    
    
  11. Now open portlet.xml and put below code :
  12. 
     
      zk-test
      zk-test
      com.cignexdatamatics.zktest.zk.MainPortletController
      
       view-jsp
       /zul/hello.zul
      
      0
      
       text/html
      
      
       zk-test
       zk-test
       zk-test
      
      
       administrator
      
      
       guest
      
      
       power-user
      
      
       user
      
     
    
    
  13. Now create MainPortletController class as shown below :
  14. package com.cignexdatamatics.zktest.zk;
    
    import java.io.IOException;
    
    import javax.portlet.PortletException;
    import javax.portlet.PortletRequest;
    import javax.portlet.PortletRequestDispatcher;
    import javax.portlet.PortletResponse;
    import javax.portlet.RenderRequest;
    import javax.portlet.RenderResponse;
    
    import org.zkoss.zk.ui.Session;
    import org.zkoss.zk.ui.http.DHtmlLayoutPortlet;
    
    import com.liferay.portal.kernel.log.Log;
    import com.liferay.portal.kernel.log.LogFactoryUtil;
    import com.liferay.portal.kernel.util.GetterUtil;
    import com.liferay.portal.kernel.util.StringPool;
    import com.liferay.portal.kernel.util.Validator;
    import com.liferay.portal.util.PortalUtil;
    
    public class MainPortletController extends DHtmlLayoutPortlet{
     
     
     @Override
     public void init() throws PortletException {
      // TODO Auto-generated method stub
      _log.info("init called.............");
      super.init();
      jspPath = getInitParameter("jsp-path");
    
      if (Validator.isNull(jspPath)) {
       jspPath = StringPool.SLASH;
      }
      else if (jspPath.contains(StringPool.BACK_SLASH) ||
         jspPath.contains(StringPool.DOUBLE_SLASH) ||
         jspPath.contains(StringPool.PERIOD) ||
         jspPath.contains(StringPool.SPACE)) {
    
       throw new PortletException(
        "jsp-path " + jspPath + " has invalid characters");
      }
      else if (!jspPath.startsWith(StringPool.SLASH) ||
         !jspPath.endsWith(StringPool.SLASH)) {
    
       throw new PortletException(
        "jsp-path " + jspPath + " must start and end with a /");
      }
    
      aboutJSP = getInitParameter("about-jsp");
      configJSP = getInitParameter("config-jsp");
      editJSP = getInitParameter("edit-jsp");
      editDefaultsJSP = getInitParameter("edit-defaults-jsp");
      editGuestJSP = getInitParameter("edit-guest-jsp");
      helpJSP = getInitParameter("help-jsp");
      previewJSP = getInitParameter("preview-jsp");
      printJSP = getInitParameter("print-jsp");
      viewJSP = getInitParameter("view-jsp");
    
      clearRequestParameters = GetterUtil.getBoolean(
       getInitParameter("clear-request-parameters"));
      copyRequestParameters = GetterUtil.getBoolean(
       getInitParameter("copy-request-parameters"));
    
      
     }
     
     @Override
     protected void doView(RenderRequest renderRequest, RenderResponse renderResponse)
       throws PortletException, IOException {
      // TODO Auto-generated method stub
      _log.info("doView called.............");
      
      include(viewJSP, renderRequest, renderResponse);
      
      super.doView(renderRequest, renderResponse);
     }
     
     @Override
     protected boolean process(Session sess, RenderRequest renderRequest,
       RenderResponse renderResponse, String path, boolean flag)
       throws PortletException, IOException {
      // TODO Auto-generated method stub
      _log.info("process called.............");
      return super.process(sess, renderRequest, renderResponse, path, flag);
     }
     
     protected void include(
       String path, RenderRequest renderRequest,
       RenderResponse renderResponse)
      throws IOException, PortletException {
    
      include(
       path, renderRequest, renderResponse, PortletRequest.RENDER_PHASE);
     }
     
     protected void include(
       String path, PortletRequest portletRequest,
       PortletResponse portletResponse, String lifecycle)
      throws IOException, PortletException {
    
      PortletRequestDispatcher portletRequestDispatcher =
       getPortletContext().getRequestDispatcher(path);
    
      if (portletRequestDispatcher == null) {
       _log.error(path + " is not a valid include");
      }
      else {
       checkJSPPath(path);
    
       portletRequestDispatcher.include(portletRequest, portletResponse);
      }
    
      if (clearRequestParameters) {
       if (lifecycle.equals(PortletRequest.RENDER_PHASE)) {
        portletResponse.setProperty("clear-request-parameters", "true");
       }
      }
     }
     
     protected void checkJSPPath(String path) throws PortletException {
      if (!path.startsWith(jspPath) ||
       path.contains(StringPool.DOUBLE_PERIOD) ||
       !PortalUtil.isValidResourceId(path)) {
    
       throw new PortletException(
        "Path " + path + " is not accessible by this portlet");
      }
     }
     
     protected String aboutJSP;
     protected boolean clearRequestParameters;
     protected String configJSP;
     protected boolean copyRequestParameters;
     protected String editDefaultsJSP;
     protected String editGuestJSP;
     protected String editJSP;
     protected String helpJSP;
     protected String jspPath;
     protected String previewJSP;
     protected String printJSP;
     protected String viewJSP;
     
    
     private static Log _log = LogFactoryUtil.getLog(MainPortletController.class);
    
    }
    
    
  15. Now deploy your portlet and see the magic of zk framework.(See below screenshot)

Rate Me:

Create Servlet Project as Module

You would have seen that many times we are writing out own servlet in Liferay portal to achieve some specific use case. In DXP, You can st...