19 July, 2017

REST Client OSGi Bundle

Hello Friends,

If you are planing to create HTTP REST client using OSGi, Just follow the steps.

1) Create bundle project of type API using IDE
2) Write one Class called RestClient.java
package sample.rest.client.api;

import com.liferay.portal.kernel.configuration.Configuration;
import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;

import java.io.IOException;

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

/**
 * @author jignesh.vachhani
 */
public class RestClient {
 /* public static void main(String[] args) throws Exception {
  RestClient obj = new RestClient();
  String response = obj.getResponse();
  System.out.println(response);
 }*/
  public String getResponse() throws ClientProtocolException, IOException{
    String responseFromService;
   CredentialsProvider credsProvider = new BasicCredentialsProvider();
   credsProvider.setCredentials(new AuthScope(_configuration.get("rest.url.host"), AuthScope.ANY_PORT),new UsernamePasswordCredentials(_configuration.get("rest.username"), _configuration.get("rest.password")));
   CloseableHttpClient httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
   try {
    HttpGet httpget = new HttpGet(_configuration.get("rest.url.protocol")+"://"+_configuration.get("rest.url.host")+"/basic-auth/user/passwd");
    System.out.println("Executing request " + httpget.getRequestLine());
    CloseableHttpResponse response = httpclient.execute(httpget);
    try {
     System.out.println("----------------------------------------");
     System.out.println(response.getStatusLine());
      responseFromService = EntityUtils.toString(response.getEntity());
    } finally {
     response.close();
    
    }
   } finally {
    httpclient.close();
   
   }
   return responseFromService;
  }
  private static final Configuration _configuration = ConfigurationFactoryUtil.getConfiguration(RestClient.class.getClassLoader(), "portlet");
}


3) define below dependencies in build.gradle
dependencies {
    compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "2.0.0"
    compileOnly group: "com.liferay.portal", name: "com.liferay.util.taglib", version: "2.0.0"
    compileOnly group: "javax.portlet", name: "portlet-api", version: "2.0"
    compileOnly group: "javax.servlet", name: "javax.servlet-api", version: "3.0.1"
    compileOnly group: "jstl", name: "jstl", version: "1.2"
    compileOnly group: "org.osgi", name: "osgi.cmpn", version: "6.0.0"
    compile group: 'commons-codec', name: 'commons-codec', version: '1.9'
    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5'
    compile group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.4.1'

}
4) In bnd.bnd
Bundle-Name: sample-rest-client
Bundle-SymbolicName: sample.rest.client
Bundle-Version: 1.0.0
Export-Package: \
    sample.rest.client.constants,\
    sample.rest.client.api
 Include-Resource:\
@httpclient-4.5.jar,\
@httpcore-4.4.1.jar,\
@commons-codec-1.9.jar 


Just deploy and you are done. Its simple  interesting isn't it ?

13 June, 2017

Captcha & reCaptcha with Liferay 7

If you are planning to integrate captcha in you liferay custom portlet then use below stuff


view.jsp:
<%@taglib uri="http://liferay.com/tld/captcha" prefix="liferay-captcha" %>
<portlet:resourceURL id="/login/captcha" var="captchaURL"/>
<liferay-captcha:captcha url="<%=captchaURL%>" />


Write CaptchaMVCResourceCommand.java :

@Component(
    property = {
        "javax.portlet.name=test_portlet",
        "mvc.command.name=/login/captcha"
    },
    service = MVCResourceCommand.class
)
public class CaptchaMVCResourceCommand extends BaseMVCResourceCommand {

    @Override
    public boolean serveResource(
        ResourceRequest resourceRequest, ResourceResponse resourceResponse) {

        try {
            CaptchaUtil.serveImage(resourceRequest, resourceResponse);
            return false;
        }
        catch (Exception e) {
            _log.error(e, e);

            return true;
        }
    }

And you are done...

Make sure you use <liferay-captcha:captcha url="<%=captchaURL%>" />  instead of <liferay-ui:captcha url="<%=captchaURL%>" /> as its not support in custom module somehow.

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