23 November, 2016

Spring MVC Portlet Migration - DXP

Friends,

Do you want to migrate your Spring MVC portlet into DXP ? yooo here are the steps you will have to follow to get it migrate.

Before we jump into steps, let me light up regarding spring mvc. Actually Spring MVC is purely used for web project architect and there is no any specific intention to get it convert into OSGi module jar. So here we may not be able to convert it into module jar but  such kind of portlets will get deployed as a war file only and Liferay container will convert into OSGi compatible WAB (Web Application Bundle) project by  Liferay WAB Generator.

Follow below steps to get it convert


22 November, 2016

Custom portlet configuration - DXP

Hello Folks,

Here I have tried to put all the possible steps which we would required to introduce custom portlet configuration.


1) Create new Liferay module using mvcportlet template
2) Define below highlighted property in your controller class:
@Component(
        immediate = true,
        property = {
                "javax.portlet.name=SamplePortlet",
                "javax.portlet.supports.mime-type=text/html",
                "javax.portlet.display-name=SamplePortlet",
                "javax.portlet.init-param.template-path=/",
                "javax.portlet.init-param.view-template=/html/view.jsp",
                "javax.portlet.init-param.config-template=/html/config.jsp",

                "javax.portlet.portlet-info.title=SamplePortlet",
                "javax.portlet.portlet-info.short-title=SamplePortlet",
                "javax.portlet.portlet-info.keywords=SamplePortlet",
                "javax.portlet.resource-bundle=content.Language",
                "javax.portlet.security-role-ref=administrator,guest,power-user,user",
                "com.liferay.portlet.display-category=SamplePortlet",
                "com.liferay.portlet.instanceable=false",
                "com.liferay.portlet.header-portlet-css=/css/main.css",
                "com.liferay.portlet.footer-portlet-javascript=/js/main.js"
        },
        service = Portlet.class
    )
public class SamplePortletextends MVCPortlet {
 
}

3) Introduce custom interface for models with unique id as highlighted

@Meta.OCD(
            id = "com.sample.action.SamplePortletConfig "        )
        public interface SamplePortletConfig {
 @Meta.AD(
        deflt = "blue",
        required = false
    )
    public String favoriteColor();

    @Meta.AD(
       deflt = "red|green|blue",
       required = false
    )
    public String[] validLanguages();

    @Meta.AD(required = false)
    public int itemsPerPage();

}
Note :
  1. Meta.OCD: Registers this class as a configuration with a specific id. You can choose any string you want, but make sure it’s unique. A common pattern is to use the fully qualified class name.
  2. Meta.AD: Specifies the default value of a configuration field as well as whether it’s required or not. Note that if you set a field as required and don’t specify a default value, the system administrator must specify a value in order for your application to work properly. Use the deflt property to specify a default value.

4) Create custom config action class

@Component(
        configurationPid = "com.sample.action.SamplePortletConfig",
        configurationPolicy = ConfigurationPolicy.OPTIONAL, immediate = true,
        property = {
                "javax.portlet.name=SamplePortlet"
        },
        service = ConfigurationAction.class
    )
public class SamplePortletConfigAction extends DefaultConfigurationAction {

// processaction,render and include methods
}

5) Add below property in module bnd file
-metatype: *
  
 6) Introduce config.jsp with all possible fields which you want to configure

 Now check your configuration icon and see if custom configuration is available or not for that specific portlet.


Interesting right !!!!!!!  Enjoy Learning Osgi :)

Overriding classes and properties using OSGi - DXP

Hello Friends,

Here i have published all possible ways to override Liferay classes and properties for which we were using hook in older Liferay version.

 

1) Create Custom portlet data handler

 @Component(
        property = {
            "javax.portlet.name=com.sample.portlet"
        },
        service = PortletDataHandler.class
    )
public class SamplePortletDataHandler extends BasePortletDataHandler
{
// Override methods which you required to override
}

2) Create Custom Model Listner

 @Component(
        immediate = true,
        service = ModelListener.class
    )
public class LayoutModelListener extends BaseModelListener<Layout>
{
 // Override methods which you required
}

3) Create Custom workflow handler

 @Component(
        property = {"model.class.name=com.sample.model.SampleEntity"},
        service = WorkflowHandler.class
    )
public abstract class SampleWorkflowHandler extends BaseWorkflowHandler
{
 // Override methods which you required
}

4) Custom Action

@Component(
        property = {
            "javax.portlet.name=" + PollsPortletKeys.POLLS,
            "javax.portlet.name=" + PollsPortletKeys.POLLS_DISPLAY,
            "mvc.command.name=/polls/edit_question"
        },
        service = MVCActionCommand.class
    )
public class CustomMVCActionCommand  extends BaseMVCActionCommand
{
 // Override methods which you required
}

5) Custom Render

@Component(
        property = {
            "javax.portlet.name=" + PollsPortletKeys.POLLS_DISPLAY,
            "mvc.command.name=/polls_display/view"
        },
        service = MVCRenderCommand.class
)
public class CustomActionMVCRenderCommand implements MVCRenderCommand
{
 // Override methods which you required
}

6) Override Liferay Language Properties

@Component(
        property = { "language.id=en_US" },
        service = ResourceBundle.class
    )
public class ENResourceBundleComponent  extends ResourceBundle {

    @Override
    protected Object handleGetObject(String key) {
        return _resourceBundle.getObject(key);
    }

    @Override
    public Enumeration<String> getKeys() {
        return _resourceBundle.getKeys();
    }

    private final ResourceBundle _resourceBundle = ResourceBundle.getBundle(
        "content.Language", UTF8Control.INSTANCE);
}

7) Override Liferay Module Language Properties

@Component(
    immediate = true,
    property = {
        "bundle.symbolic.name=com.liferay.polls.web",
        "resource.bundle.base.name=content.Language",
        "servlet.context.name=polls-web"
    }
)
public class ResourceBundleLoaderComponent  implements ResourceBundleLoader {

    @Override
    public ResourceBundle loadResourceBundle(String languageId) {
        return _resourceBundleLoader.loadResourceBundle(languageId);
    }

    @Reference(target = "(bundle.symbolic.name=com.liferay.polls.web)")
    public void setResourceBundleLoader(
        ResourceBundleLoader resourceBundleLoader) {

        _resourceBundleLoader = new AggregateResourceBundleLoader(
            new CacheResourceBundleLoader(
                new ClassResourceBundleLoader(
                    "content.Language",
                    ResourceBundleLoaderComponent.class.getClassLoader())),
            resourceBundleLoader);
    }

    private AggregateResourceBundleLoader _resourceBundleLoader;

}

8) Override Liferay services

@Component(service = ServiceWrapper.class)
public class CustomUserLocalService extends UserLocalServiceWrapper {
// Override methods which you require   
}


Note:
Portal-ext.prioperties cannot be override through OSGi and you will have to manually update portal-ext.properties which we are keeping inside WEB-INF/classes




Liferay MVC Portlet with Service Builder - DXP

Friends,

Here you will see how you can create Liferay MVC portlet with best practice.

If you remember, we were creating portlets in 6.X by selecting specific portlet type from IDE and choosing weather we have to use service builder or not. So there it was creating only one single portlet including service layer.

Now in DXP, you will have to separately create service layer and web portlet layer .
Now here we will have to keep 2 things in our mind.
1) Portlet specific service layer
2) Generic service layer (Which can be used across all the modules)

Identically both are same and the way of accessing the service also would be the same only difference is, if service is portlet specific then you can keep service and web layer altogether in single module project which will help for CI and build whole project.

1) Now here first step would be create new Liferay module by selecting servicebuilder as template and create.

You can also create this portlet using blade-cli tool as well.
You can use below command to create if you have install blade-cli in your local.

11 November, 2016

Issues During 6.X to DXP migration

There are couple of common problem which we might facing during migration or upgration from 6.X to Liferay DXP.

We will discuss all possible items over here.