Monday, May 13, 2013

Java Reflection API: Constructing Objects


Moving forward from my previous article: Java Reflection API: Introduction

Using Java Reflection API, you can instantiate objects at runtime and invoke class constructors.
Getting Constructor
To get the list of all public constructors declared use the below code:
Constructor[]
constructors = mClass.getConstructors();

Here Constructor[] is an array of type java.lang.reflect.Constructor. However If you have the precise parameter types of the constructor you want to access, you can do so rather than obtain the array all constructors. Below example returns the public constructor of the given class which takes String as parameter:
Constructor constructor
= mClass.getConstructor(new Class[]{String.class});

Further to read all the input parameters of a constructor, do like this:
Class[] parameterTypes =
constructor.getParameterTypes();

Do the below to create an object using Java Reflection:
Constructor constructor = mClass.getConstructor(String.class);
Object mObject = constructor.newInstance("argument-1");
Next post in the series is Java Reflection API: Calling Methods

Java Reflection API: Introduction

Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine.  It enable applications to perform operations which would otherwise be impossible. An application may make use of external, user-defined classes by creating instances of extensibility objects using their fully-qualified names.
Thus Java Reflection makes it possible to inspect classes, interfaces, fields and methods at runtime, without knowing the names of the classes, methods etc. at compile time. It is also possible to instantiate new objects, invoke methods and get/set field values using reflection.

The Drawbacks of reflection are:

  • Performance overhead
  • Security restrictions
  • Exposure of internals
Creating a Class Object when you don't know the class name at runtime:
String className = ??? //get fully qualified classname at runtime
Class mClass = Class.forName(className);
The Class.forName() method may throw a ClassNotFoundException if the class cannot be found on the at runtime.

You can access the modifiers ("public", "private", "static" etc.) of a class via the Class object. 

int modi = mClass.getModifiers();
Now using java.lang.reflect.Modifier , you can check the modifier info, for example:
Modifier.isAbstract(modi);

You can access the constructors of a class like this: 
Constructor[] constructors = mClass.getConstructors();
You can access the methods of a class like this:
Method[] methods = mClass.getMethods();
You can access the fields of a class like this:
 Field[] fields = mClass.getFields();
Next post in the series is Java Reflection API: Constructing Objects

Tuesday, April 23, 2013

Liferay: using DynamicQuery in a velocity template.

Consider a scenario if you have 1000 records in a Dynamic Data List (DDL) record set. You need to show only 20 latest records. One ways is to bring all the records and use a loop to show the records and break when a counter is greater then 20, this will cause slowness in page as you are bringing the complete record set.

To overcome this consider if you bring only latest 20 records from database something like at most list screens in liferay where pagination is used. Below is the set of lines that will allow you to achieve this;



#set ($ddlRecordSet = $serviceLocator.findService('com.liferay.portlet.dynamicdatalists.service.DDLRecordSetLocalService'))
#set ($ddlLocalService = $serviceLocator.findService('com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalService'))

#set ($recordSetId = $getterUtil.getLong($reserved_record_set_id.data, 0))
#set ($DDLrecordClass = $portal.getClass().forName("com.liferay.portlet.dynamicdatalists.model.DDLRecord"))
#set ($dqfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil"))
#set ($ofu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.OrderFactoryUtil"))
#set ($rfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil"))
#set ($q = $dqfu.forClass($DDLrecordClass))
#set ($V = $q.add($rfu.eq("recordSetId", $getterUtil.getLong($recordSetId))))
#set ($V = $q.addOrder($ofu.desc("modifiedDate")))
#set ($records = $ddlLocalService.dynamicQuery($q,0,20))
#set ($recordTitle = $ddlRecordSet.getRecordSet($recordSetId))
#set ($title = $recordTitle.getName())

You can modify the dynamic query as per your needs to order data on different columns.

Thursday, December 06, 2012

Why Liferay ?


So why is Liferay Portal the best portal product in our opinion?
  1. Liferay has the lowest Total Cost of Ownership (TCO) compared to its competitors starting with its licensing and getting it up and running through development costs, operational costs, and training/support costs (from the perspective of infrastructure, developers, administrators, and end users).
  2. Second-to-none rich out-of-the-box (OOTB) functionality around core portal, content management, collaboration, social, mobile, security and more; check out http://www.liferay.com/products/liferay-portal/features/portal for more information.
  3. All portal products typically need extensions and/or additions to deliver requisite functionality – with Liferay you can simply do more within a specific budget.
  4. Product innovation – leader in introducing new capabilities whether it be AJAX or friendly URLs or mobile or social
  5. Improved business agility – it is lightweight in nature; you can quickly get it up and running, and it is easier to develop on/manage.
  6. A mature Enterprise Open Source (fully supported) product – 24x7x365 platinum support with 1 hour response time SLA; this includes access to all service packs, hot fixes, notifications of security alerts, phone and web based support.
  7. Liferay’s open architecture and its open source nature help you avoid lock-in to a single proprietary vendor.
  8. Liferay’s hook and extension plugin model allows you to tailor product behavior to your needs without rewriting from scratch and without creating upgrade hell.
  9. Liferay offers opportunities for product feature sponsorship to enable contributions back into the core product for key customizations – this allows you to offload responsibility of maintaining and enhancing your custom features back to Liferay.
  10. Liferay offers you a full choice of application servers, databases, and operating systems to run on, thereby allowing you to leverage your infrastructure and skills investment.
References:




Wednesday, December 05, 2012

Part 3: Custom Liferay Plugin JSON Web Services

Go to Previous post Part 2: Custom Liferay Plugin JSON Web Services
Below is the step by step setup to expose and consume a plugin portlet service as JSON web service.

Step 1: Create a liferay plugin portlet

Step 2: Create a custom service

Using Liferay Service builder create a service. For example

The service.xml will look like below:
<service-builder package-path="com.rdg.api">
 <author>rishidev.gupta</author>
 <namespace>ServiceAPI</namespace>

 <entity name="Bridge" remote-service = "true" local-service="true" human-name="Bridge">
  <reference package-path="com.liferay.counter" entity="Counter"></reference>
  <reference package-path="com.liferay.portal" entity="User"></reference>
  <reference package-path="com.liferay.portlet.journal" entity="JournalArticle"></reference>
 </entity>
</service-builder>

Step 3: Build the service using liferay service builder 

Step 4: Writing a custom method to be exposed

public class BridgeLocalServiceImpl extends BridgeLocalServiceBaseImpl {

 public String getBridge(String str) throws PortalException {
  System.out.println("You have successfully requested for: " + str);
  return "You have successfully requested for: " + str;

 }
}
public class BridgeServiceImpl extends BridgeServiceBaseImpl {
 public String getBridge(String str) throws PortalException {
  return bridgeLocalService.getBridge(str);
 }
}
Now rebuild the service.

Step 5: Configuring web.xml 

To make sure that your custom portlets can be scanned, and their service can become part of the JSON API. For this you must add the following in portlets web.xml:


     <servlet>
        <servlet-name>JSON Web Service Servlet</servlet-name>
        <servlet-class>com.liferay.portal.kernel.servlet.PortalClassLoaderServlet</servlet-class>
        <init-param>
            <param-name>servlet-class</param-name>
            <param-value>com.liferay.portal.jsonwebservice.JSONWebServiceServlet</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>JSON Web Service Servlet</servlet-name>
        <url-pattern>/api/jsonws/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>JSON Web Service Servlet</servlet-name>
        <url-pattern>/api/secure/jsonws/*</url-pattern>
    </servlet-mapping>

This enables the servlet that is responsible for scanning JSON web services configuration. Now deploy the plugin portlet in a running tomcat server.

Step 6: Consuming JSON Web Service

 To list registered services on portlet, 
http://localhost:8080/<portlet-context>/api/jsonws
 
To access service using browser
http://localhost:8080//service-api-portlet/api/jsonws/bridge/get-bridge?&str=rishidev.gupta