Liferay 7/Liferay DXP Screen Name Validator

screen-name-validator


Screen Name in Liferay is very important which is unique in the Portal. While creating user the Screen Name is mandatory field and Screen Name represents the actual user in the portal. Sometimes its necessary to validate the screen name entered by the user at the time of creation of users. In this article we will explain how to write Custom Screen Name Validator in the form of OSGI Module. We can validate screen name both in client side and server side. At the end of this article we will be able to define our own reserved words in the Liferay control panel and those reserved words can’t be used while crating users in the portal. 


Key Points:

  • Write Configuration Interface for reserved words
  • Implement ConfigurationBeanDeclaration
  • Implement ScreenNameValidator

Step 1 : Create one OSGI Module

You can create one OSGI module using maven archetypes. Open the command prompt and type 

mvn archetype:generate -Dfilter=liferay

mvc-template

We can select below from the above list

com.liferay:com.liferay.project.templates.mvc.portlet (Liferay Project Templates MVC Portlet)

Note :

We are not creating any portlet here. But still we can use MVC Portlet archetype to create the project structure. Once directory structure is created we can delete portlet related class. At the end, the final artifact should be OSGI Module.

Step 2: The Configuration Interface

Here we will define the Reserved words in the form of java interface. Below is the interface

package com.proliferay.config;

import aQute.bnd.annotation.metatype.Meta;

import com.liferay.portal.configuration.metatype.annotations.ExtendedObjectClassDefinition;

/**
 * Give attention to scope = ExtendedObjectClassDefinition.Scope.COMPANY
 * By category =  "Pro Liferay", we are telling to Liferay where our configuration 
 * will be avaiable in the Liferay Control Panel.In this case the configuration would
 * be available under Pro Liferay Category. You can navigate to 
 * Control Panel->Configuration->System Settings->Pro Liferay 
 */
@ExtendedObjectClassDefinition( 
    category =  "Pro Liferay", scope = ExtendedObjectClassDefinition.Scope.COMPANY
)
@Meta.OCD( 
    id = "com.proliferay.config.ReservedWordsConfiguration",
    localization = "content/Language", name = "custom.screen.name"
)
/**
 * This interface actually holds the reserved words 
 * 
 * @author hamidul.islam
 *
 */
public interface ReservedWordsConfiguration {
    //Define default values
    @Meta.AD(deflt = "admin|user", required = false)
    public String[] reservedWords();

}

In the above step we have created the default reserved words as admin and user. You can navigate Control Panel->Configuration->System Settings->Pro Liferay to save the reserved words. 

reserved-words

Step 3 : Bean Declaration

In this step we will register our above configuration interface with the framework so that our configuration can be easily retrieved from ConfigurationProvider

package com.proliferay.declaration;


import com.liferay.portal.kernel.settings.definition.ConfigurationBeanDeclaration;

import com.proliferay.config.ReservedWordsConfiguration;

import org.osgi.service.component.annotations.Component;

/**
 * By this class we are registering our configuration file to Configuration Framework 
 * 
 * Later on from ConfigurationProvider we can retrieve DemoScreenNameConfiguration instance 
 * 
 * @author hamidul.islam
 *
 */
@Component
public class BeanDeclaration
    implements ConfigurationBeanDeclaration {

    @Override
    public Class<?> getConfigurationBeanClass() {
        return ReservedWordsConfiguration.class;
    }

}

Step 4: Implement Liferay ScreenNameValidator

package com.proliferay.validator;

import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.Company;
import com.liferay.portal.kernel.module.configuration.ConfigurationException;
import com.liferay.portal.kernel.module.configuration.ConfigurationProvider;
import com.liferay.portal.kernel.security.auth.ScreenNameValidator;
import com.liferay.portal.kernel.service.CompanyLocalService;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.ResourceBundleUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.proliferay.config.ReservedWordsConfiguration;

import java.util.Locale;
import java.util.ResourceBundle;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
 * service = ScreenNameValidator.class must be available 
 * 
 * There can be multiple implementations of the same service. We can assign higher ranking so that liferay
 * can pick our service implementation instead of the existing implementation. This is done by
 * service.ranking:Integer=100
 * 
 * 
 * @author hamidul.islam
 *
 */

@Component(
    configurationPid = "com.proliferay.config.ReservedWordsConfiguration",
    immediate = true, property = {"service.ranking:Integer=100"},
    service = ScreenNameValidator.class
)
public class MyScreenNameValidator implements ScreenNameValidator {

    /**
     * 
     * Client Side Validation
     * 
     * Provides the JavaScript validations for the UI 
     */
    @Override
    public String getAUIValidatorJS() {
        _log.info("######Calling getAUIValidatorJS()####");
        StringBuilder javascript = new StringBuilder();

        try {
            Company company = _companyLocalService.getCompanyByWebId(
                PropsUtil.get(PropsKeys.COMPANY_DEFAULT_WEB_ID));

            long companyId = company.getCompanyId();
            _log.info("########companyId###########"+companyId);

            String[] reservedWords = getReservedWords(companyId);

            javascript.append("function(val) { return !(");

            for (int i = 0; i < reservedWords.length; i++) {
                javascript.append(
                    "val.indexOf(\"" + reservedWords[i] + "\") !== -1");

                if ((reservedWords.length > 1) &&
                    (i < (reservedWords.length - 1))) {

                    javascript.append(" || ");
                }
            }

            javascript.append(")}");
        }
        catch (PortalException portalException) { 
            _log.error(portalException);
        }catch (Exception e) {
            _log.error(e);
        }
        
        return javascript.toString();
    }

    /**
     * This method display the actual error message in the UI
     * This can be localized 
     * Use Resource Bundle to display the error message. However this is optional 
     */
    @Override
    public String getDescription(Locale locale) {
        _log.info("######Calling getDescription()####");
        
        ResourceBundle resourceBundle = ResourceBundleUtil.getBundle("content.Language", locale, getClass());
        
        //Look the key error.description in properties file
        String description = ResourceBundleUtil.getString(resourceBundle, "error.description");
        
        return  description;
    }

    /**
     * Server Side Validations 
     * 
     * Validate the screen name provided by the user against the reserved words 
     * which are set in the control panel 
     * 
     * If the screen name entered contains reserved words return false, otherwise return true
     */
    @Override
    public boolean validate(long companyId, String screenName) {
        _log.info("######Calling validate()####");
        String[] reservedWords = getReservedWords(companyId);
        
        String lowerCaseScreenName = StringUtil.toLowerCase(screenName); 
        for (String word : reservedWords) {
            if (lowerCaseScreenName.contains(StringUtil.toLowerCase(word))) {
                return false;
            }
        }

        return true;
    }
    
    private String[] getReservedWords(long companyId) {
        ReservedWordsConfiguration reservedWordsConfiguration = null; 
        try {
            //Retrieve the compnay specific Configuration 
            reservedWordsConfiguration = _configurationProvider.getCompanyConfiguration(ReservedWordsConfiguration.class, companyId);
        } catch (ConfigurationException e) {
            _log.error(e);
        }catch (Exception e) {
            _log.error(e);
        }

        if (reservedWordsConfiguration != null) {
            return reservedWordsConfiguration.reservedWords();
        }

        return new String[0];
    }

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

    @Reference
    private volatile CompanyLocalService _companyLocalService;

    /**
     * _configurationProvider will be auto injected by the framework 
     * 
     * Later on from _configurationProvider we can retrieve DemoScreenNameConfiguration instance 
     */
    @Reference
    private volatile ConfigurationProvider _configurationProvider;

}

Step 5: Include meta type in BND file

Add below in the bnd.bnd file

-metatype: *

This will include meta types (defined in Step 2) in the final OSGI JAR

TODO:

After deployment of this OSGI Module try to create user with screen name, admin or user. You should get error message with message that are set in Language.properties file. 

Download:

custom-screen-validator

About The Author

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top
%d