Tuesday, 22 March 2016

How to Create a Liferay Application Startup Event Hook

How to Create a Liferay Application Startup Event Hook

Many a times I have seen that application needs to have a lot of configuration, doing all such configuration manually is time consuming job at the same time its tedious too. Fortunately Liferay provides a way to get configuration done grammatically and get rid of manual configuration. Application Startup Event Hook is useful for writing a configuration logic related to configuration of the system.

Here are the simple steps for creating the Application Startup Event Hook
1    Create a Hook "{startupaction}"
2    Create a custom class / action to be executed for configuration
3    Create a properties file for a Hook
4    Map properties file entry with "liferay-hook.xml"
5    Deploy "{startupaction}" hook
6    Test functionality

Here are the steps in detail
1    Create a Hook "{startupaction}"

    To create a hook from command prompt follow below commands:
    i)    Go to your liferay plugin sdk / hooks
    ii)    Fire a command on command propmpt called e:/lifera.../hook>create startupaction "startupaction"

2    Create a custom class / action to be executed for configuration

    Custom Action class which we create will be executed (run method) at the time of deploying our {startupaction} hook
    Lets say we create a Class/Action called "MyStartUpAction" which is used to create a custom field of an organization called "orgType".
    Here is the sample code for

        package com.startup.action;

        import java.util.List;

        import com.liferay.portal.kernel.events.ActionException;
        import com.liferay.portal.kernel.events.SimpleAction;
        import com.liferay.portal.kernel.exception.PortalException;
        import com.liferay.portal.kernel.exception.SystemException;
        import com.liferay.portal.kernel.util.UnicodeProperties;
        import com.liferay.portal.model.Company;
        import com.liferay.portal.model.Role;
        import com.liferay.portal.model.User;
        import com.liferay.portal.security.auth.PrincipalThreadLocal;
        import com.liferay.portal.security.permission.PermissionChecker;
        import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
        import com.liferay.portal.security.permission.PermissionThreadLocal;
        import com.liferay.portal.service.CompanyLocalServiceUtil;
        import com.liferay.portal.service.RoleLocalServiceUtil;
        import com.liferay.portal.service.UserLocalServiceUtil;
        import com.liferay.portlet.expando.model.ExpandoBridge;
        import com.liferay.portlet.expando.model.ExpandoColumnConstants;
        import com.liferay.portlet.expando.util.ExpandoBridgeFactoryUtil;

        public class MyStartupAction extends SimpleAction {
            /*
             * (non-Java-doc)
             *
             * @see com.liferay.portal.kernel.events.SimpleAction#SimpleAction()
             */
            public MyStartupAction() {
                super();
            }

            /*
             * (non-Java-doc)
             *
             * @see com.liferay.portal.kernel.events.SimpleAction#run(String[] arg0)
             */
            public void run(String[] companyId) throws ActionException {
                // TODO Auto-generated method stub

                System.out.println("Length of arguments " + companyId.length + " value is " + companyId[0]);
                System.out.println("My Startup Action Method has been called..... !!!");
               
                //We like to create a custom field for the resourceType as "organization".
                String modelResource = "com.liferay.portal.model.Organization";
                long resourcePrimKey = 0;
                String name = "orgType";

                ExpandoBridge expandoBridge = ExpandoBridgeFactoryUtil
                        .getExpandoBridge(Long.parseLong(companyId[0]), modelResource,
                                resourcePrimKey);

                UnicodeProperties properties = null;
                try {
                    properties = expandoBridge.getAttributeProperties(name);
                } catch (Exception e) {
                    properties = new UnicodeProperties();
                }

                //Creating a default property for the "orgType" custom field
                int type = ExpandoColumnConstants.STRING;
                properties.setProperty(ExpandoColumnConstants.PROPERTY_HEIGHT, "105");
                properties.setProperty(ExpandoColumnConstants.PROPERTY_WIDTH, "450");

                //This is a mimic to set a custom permission checker. If we dont set this then while adding a new attribute in expando will create a permission checker error. Piece of code from DoAsUserThread class
                setPermissionChecker(companyId);

                try {
                    expandoBridge.addAttribute(name, type);
                } catch (PortalException e) {
                }
                expandoBridge.setAttributeProperties(name, properties);
            }
           
            /*
                Setting up the custom permission checker object
            */
            private void setPermissionChecker(String[] companyId) {
                Company companyqq = null;
                try {
                    companyqq = CompanyLocalServiceUtil.getCompanyById(Long.parseLong(companyId[0]));
                } catch (PortalException | SystemException e1) {
                }
                Role adminRole = null;
                try {
                    adminRole = RoleLocalServiceUtil.getRole(companyqq.getCompanyId(),"Administrator");
                } catch (PortalException | SystemException e1) {
                }
                List<User> adminUsers = null;
                try {
                    adminUsers = UserLocalServiceUtil.getRoleUsers(adminRole.getRoleId());
                } catch (SystemException e1) {
                }

                PrincipalThreadLocal.setName(adminUsers.get(0).getUserId());
                PermissionChecker permissionChecker = null;
                try {
                    permissionChecker = PermissionCheckerFactoryUtil.create(
                            adminUsers.get(0), true);
                } catch (Exception e1) {
                }
                PermissionThreadLocal.setPermissionChecker(permissionChecker);
            }
        }

   
3    Create a properties file for a Hook

    Create a properties file lets say "portal.properties" in our case on the location   
    liferay-plugins-sdk-6.2\hooks\{startupaction}-hook\docroot\WEB-INF\src\portal.properties
   
    Inside the "portal.properties" file add an entry as below of our custom class / action i.e. MyStartupAction in our case
    application.startup.events=com.startup.action.MyStartupAction

   
4    Map properties file entry with "liferay-hook.xml"

    We need to specify the name of the property file inside the "liferay-hook.xml" file. This is the file which Liferay hook will read for all the overridden properties
   
    Here is the sample entry of "liferay-hook.xml"
    <?xml version="1.0"?>
    <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd">

    <hook>
        <portal-properties>portal.properties</portal-properties>
    </hook>

   
5    Deploy "{startupaction}" hook
   
    Alright Then! We are done with our coding / changes for application startup action hook. Just deploy our hook via below command

    i)    Open command Prompt and go to the location of your plugin sdk and hit "ant"
    ii)    e:\...\liferay-plugins-sdk-6.2\hooks\{startupaction}-hook>ant
   
6    Test functionality

Once we deploy our {startupaction} hook in the console we can see below entries which is the proof that our hook is invoked and our custom
field will be created called "orgType" under "organization".







Console Output is:
Length of arguments 1 value is 20155
My Startup Action Method has been called..... !!!


To verify from the Admin console follow below steps

1)    Go to "Admin" -> "Control Panel"
2)    Go to "Configuration" -> "Custom Fields"
3)    Go to "Organization" -> "Edit"
4)    See our newly created custom field called "orgType" is created and available in listing

Great! We are done!

Cheers!
Henal Saraiya

No comments:

Post a Comment