Monday 18 January 2016

Enable and Disabled Log in Liferay

In our development time and in production we need to debug the functionality for resolve the issue.

Liferay gives OOTB logging functionality. Say I have ABController.java and  I want to get log of this class then create one static log variable in Java class.  

private static Log _log = LogFactoryUtil.getLog(ABController.class);

You have below option to log the value.

1. _log.debug() method  :  This log only can see when the debug option is selected for this class in control panel (we will see where you can change it)
2. _log.error() method : To display error message.
3. _log.info() method : This will always display log message.
4. _log.fatal() method : This will display fatal error message.
5. _log.warn() method : This message will display warnings.

You can enabled and disabled the log level of Class in Control panel. Go to  Control panel -> Server Administration -> Log Levels.   First search you class with full package in Update category tab and if you find the class then you can change log level from log level options. But if you don't find the Class then you can create your own category by click on Add category and add  your class with full specified path and select log level you want to select.

In production, more logs may create performance issue so generally We will use _log.debug() method. When we need to test on production then enable debug log level for this class and after completion of debugging reset it to Off.

Useful links:
 https://www.liferay.com/community/wiki/-/wiki/Main/How+to+configure+the+logs+in+Liferay

Saturday 9 January 2016

Run Script of code in Liferay

Hi All,

In our development time, some times we need check output of some methods of Util class or service class. Say I want to view all documents of group in Lifray then Liferay provides you run your lines of code in control panel.

Go to Control Panel -> Server Administration -> Script  and select Groovy for Java code.

Paste below lines of code to get all documents of group.

java.util.List<DLFileEntry>  dlFileEntryList =       com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil.getGroupFileEntries(10167, -1, -1);

   for(com.liferay.portlet.documentlibrary.model.DLFileEntry fileEntry : dlFileEntryList){

                          out.println(fileEntry.getTitle());
                    }

Here 10167 is static value of group Id but you can get it the same way as above script.  

Click on Execute button and it will run above code and it will show all document title in page.


Same way you can run and check the out put of any code but make sure to use Class or Object with full specified path like  for DLFileEntry object I have used com.liferay.portlet.documentlibrary.model.DLFileEntry.

Tuesday 11 August 2015

Liferay DWR Integration

What is DWR?
DWR is a Java library that enables Java on the server and JavaScript in a browser to interact and call each other as simply as possible. DWR is develop on top of AJAX.

DWR will generate the JavaScript to allow web browsers to securely call into Java code almost as if it was running locally. It can marshal virtually any data including collections, POJOs, XML and binary data like images and PDF files.
In Reverse Ajax, DWR allows Java code running on a server to use client side APIs to publish updates to arbitrary groups of browsers. This allows interaction 2 ways - browser calling server and server calling browser. DWR supports Comet, Polling and Piggyback (sending data in with normal requests) as ways to publish to browsers.

Here we are going to integrate DWR with Liferay Spring MVC Portlet and we will call server method from Javascript.

Before start, I have assumed that you have created Liferay Spring MVC portlet and you need below additional steps.

Step-1 : Add below code in web.xml file

                <servlet>
                <servlet-name>DwrServlet</servlet-name>
                <servlet-class>org.directwebremoting.spring.DwrSpringServlet</servlet-class>
                                <init-param>
                                    <param-name>crossDomainSessionSecurity</param-name>
                                    <param-value>false</param-value>
                                </init-param>
                </servlet>
                <servlet-mapping>
                                <servlet-name>DwrServlet</servlet-name>
                                <url-pattern>/dwr/*</url-pattern>
                </servlet-mapping>

Step-2 : Add below code in  Spring Application context xml file

  • Add/Update below line in <beans> tag in this file.

               (Update) :  xsi:schemaLocation="http://www.springframework.org/schema/beans
                                                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd       
                                                http://www.directwebremoting.org/schema/spring-dwr
                                                http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd"
               
  • Add below tag in this file.

                <dwr:configuration/>
                <dwr:controller id="dwrController" debug="true" />
                <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                                <property value="true" name="alwaysUseFullPath"></property>
                                <property name="mappings">
                                <props>
                                                <prop key="/dwr/**/*">dwrController</prop>
                                </props>
                                </property>
                               
                </bean>
                <bean id="SampleMVCDWR" class="com.sample.dwr.controller.SampleMVCDwrController">
                    <dwr:remote javascript="SampleMVCDWR">
                                   <dwr:include method="getDataFromDWRMethod" />
                    </dwr:remote>
      </bean>

Here SampleMVCDwrController is my controller class and getDataFromDWRMethod is method in controller class which will call from JavaScript.

Step -3 : Controller Class

@Controller
@RequestMapping("VIEW")
public class SampleMVCDwrController {
               
                private static final Log log = LogFactoryUtil.getLog(SampleMVCDwrController.class);
  
                @RenderMapping
                public String defaultViewMethod(Locale locale, Model model) {
                                log.info("iniside default view method");
                                return "view";
                }
                public String getDataFromDWRMethod(String str) {
                                log.info("iniside DWR sample method");
                     return str + " + modified in server response";
                }
}

Step - 4 : Changes in JSP file

Add below script in view.jsp file.
<script type='text/javascript' src='/sample-dwr-mvc-portlet/dwr/engine.js'></script>
<script type='text/javascript' src='/sample-dwr-mvc-portlet/dwr/util.js'></script>
<script type='text/javascript' src='/sample-dwr-mvc-portlet/dwr/interface/SampleMVCDWR.js'></script>

here "sample-dwr-mvc-portlet" is my portlet name and SampleMVCDWR.js name must be match with  bean in define in Spring application context file.

Below is the Script to call controller method from JavaScript.

<script>
                function getDataFromServer() {
                                var inputStr =$("#inpurStr").val();
                                SampleMVCDWR.getDataFromDWRMethod(inputStr,{
                                                 callback: getDataFromServerCallBack
                     });
                }
                                               
                function getDataFromServerCallBack(dataFromServer) {
                                alert(dataFromServer);
    }
                               
</script>
<input type="text" id="inpurStr" name="str"/>               
<input type="button" value="GET DATA" onclick="getDataFromServer(); return false;">             

Here in this our example I have taken one input field and one button. on click of button JavaScript function getDataFromServer() will call and it will call JAVA class method getDataFromDWRMethod() and get response from  in callback function.

SampleMVCDWR.js file is created by DWR which include your controller class’s method compatible with JavaScript and engine.js and engine.js are supporting file for DWR.

You can get more information about DWR here in below link.

Difference between DWR and AJAX:

If you have any question or want any more information then let me know.

Wednesday 5 August 2015

Dynamic Roles/User assignment in Liferay Kaleo workflow

What is Kaleo Workflow ?

 Liferay Portal includes a workflow engine called Kaleo. Kaleo workflow allows a user to define any number of simple to complex business processes/workflows, deploy them, and manage them through a portal interface. Those processes have knowledge of users, groups, and roles without writing a single line of code—it only requires the creation of a single XML document.
 You can get all information about kaleo workflow here.
Link:

In kaleo defination xml file you can have <task> tag to define task which have <actions> tag to perform action on workflow, <notification> tag to notify when any action occurs, <assignments> tag to assign workflow to user/role, <transitions> tag to forward workflow to next step. In this blog we are going to discuss about <assignments> tag and  how you can assign workflow task to Role dynamically.

Generally, In <assignments> we give some <role> and <user> tag to assign the workflow task respective to Liferay Role and User. The example as below.
<assignments>
              <roles>
                         <role>
                                     <role-type>organizatiaon</role-type>
                                     <name>Organization Approver</name>
                          </role>
                           <role>
                                     <role-type>regular </role-type>
                                     <name>Portal Content Reviewer</name>
                            </role>
                </roles>
</assignments>

Here Role assignment is static but if you want to make it dynamic or programmatically then how to do?  For that Liferay support Groovy script to assign task dynamically. We are going to understand by taking practical use case.

Use case : Our user case is such that one user create web content and assign some categories to this web content. Now When User will publish this web content then the Role which map to web content categories should have assign this web content for review. Please note that here the mapping between Role and web content as Role name will be Category name + " " + "Approver". So for example if user assign category as "HR" then the web content only assign to Users which have "HR Approver" Role. If user does not assign any category to web content then the default Role is "HR Home Page Reviewer".
 The groovy script for above use cases is as below.
 <assignments>
    <scripted-assignment>
                <script>
                                <![CDATA[
                                     import com.liferay.portal.kernel.util.GetterUtil;
                                     import com.liferay.portal.kernel.workflow.WorkflowConstants;
                                     import com.liferay.portal.model.Role;
                                     import com.liferay.portal.service.ServiceContext;
                                     import com.liferay.portal.service.RoleLocalServiceUtil;
                                     import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
                                     import com.liferay.portlet.asset.model.AssetCategory;
                                                                                                               
                                     long companyId = GetterUtil.getLong((String)workflowContext.get(WorkflowConstants.CONTEXT_COMPANY_ID));
                                     long groupId = GetterUtil.getLong((String)workflowContext.get(WorkflowConstants.CONTEXT_GROUP_ID));
                                     roles = new ArrayList<Role>();
                                     ServiceContext serviceContext = (ServiceContext) workflowContext.get(WorkflowConstants.CONTEXT_SERVICE_CONTEXT);
                                     long[] categoryIds = serviceContext.getAssetCategoryIds();
                                     if(categoryIds.length>0){
                                             for(int i=0; i< categoryIds.length;i++){
                                                       try{
                                                                AssetCategory category = AssetCategoryLocalServiceUtil.getCategory(categoryIds[i]);
                                                               Role category_role = RoleLocalServiceUtil.getRole(companyId,category.getName()+" "+"Approver");
                                                                         if(category_role != null){
                                                                                roles.add(category_role);
                                                                        }
                                                                }catch(Exception e){
                                                                }
                                                }
                                     }
                                     if(roles.isEmpty()){
                                            try{
                                                    Role defaultRole = RoleLocalServiceUtil.getRole(companyId, "HR Home Page Reviewer");
                                                    if(defaultRole != null){
                                                            roles.add(defaultRole);
                                                    }
                                             }catch(Exception e){
                                            }
                                     }
                                   user = null;      
                            ]]>
                </script>
                <script-language>groovy</script-language>
    </scripted-assignment>
</assignments>  

Here our use case is to get Role name from web content category name but here in this Groovy script we can write any dynamic code to get Roles and Users.
Please let me know if  you need any more information on this.

Friday 11 April 2014

Delete page in staging in liferay

Hi All Lifeay folks,

Today i am writing about How to delete page in staging environment in Liferay. Staging is good functionality given by Liferay to view page before publish to live. We create page on staging site and make it publish to live. we can modify our page content in staging site and it will not reflected to live page until we will publish it.

In some scenario we want to delete live page then what to do ?? Here are some basic steps.

Step-1  : Navigate to your staging page (ex.. /web/guest-staging/pagename) then hover on Staging in doc bar and then click to Publish to  Live.
Step-2: It will open one dialog box as below image.



Step-3: Click on Publish Button and it will delete your live page.
Step-4: Delete your staging page from control panel as normal way.

This the strait forward way to Delete staging and live page. but sometime we directly delete page from control panel at that time we can not delete live page above way.

So I am giving you some below steps for delete live page in staging environment  when we have delete staging page from control panel.

Step-1 : Go to Control panel and navigate to staging site.
Step-2 :  Click on "Copy From Live" button.


Step-3 : It will open one dialog box and click on "Change Selection" button.
Step-4: It will list all pages with check box. check page name which we want to copy from live.





Step-5:  Click on "Publish" button. It will  copy live page to  staging page(which was deleted).

Step-6:  Now if you want to delete live page then follow above Steps 1,2,3 starting of this blog.


Thats ALL !!!!!

Keep Playing with Liferay..

Regards,
Sandip Patel
+91 9510645454