Monday 11 December 2017

Converters and populators in hybris


In this blog post, I’m going to share about Converters and Populators with practical scenarios.
In Hybris Converters and Populators are very important to populate data.
This article will help you to get a clear picture.

Converters:-

=>Converters create new instances of Data objects and call Populators to populate data.


=>It converts data from source to target using Populators.

=>Contains a list of populators.

Ex:- converter configuration






<alias name="acceleratorGenderConverter" alias="genderConverter"/> 
<bean id="acceleratorGenderConverter" parent="abstractPopulatingConverter">
<property name="targetClass" value="co.hybrisinstructive.facades.product.data.GenderData"/>
<property name="populators">
<list>
<ref bean="genderDataPopulator"/>
</list>
</property>
</bean>


=>Inject the bean in class and call convert() method by passing GenderModel. Like below,


GenderData  data=getGenderConverter().convert(gender);



Populator:- 

=>Populator fill the data object by getting the data from the model.

=>All conversion logic exists in populators.

=> Populator shouldn't be called directly in code.[Not recomended]

Ex:-Populator



<alias name="defaultGenderDataPopulator" alias="genderDataPopulator"/>
<bean id="defaultGenderDataPopulator" class="co.hybrisinstructive.facades.populators.GenderDataPopulator" >
 <property name="typeService" ref="typeService"/>
</bean>


->Converters and populators are used in facade layer to convert the model to data.
->In facade layer we call converter method by injecting the converter bean. We call converter methods to convert the model to data.
->Converter having list of populators. We can add the list of populators.
->Actual logic is written in populators and that logic is excecuting by calling converter methods. Converter internally calls the list of populators.
->We can directly call populators to convert 
  Below are some tasks on converters and populators





Task 1. Converting Model By Using Converter.convertAll() method:-

* In Facade layer we convert the model to Data by using Converter.convert() method we can convert the model to Data.

For thiswe need to configure that converter and populator in xxxfacade-spring.xml


Step 1:-  Create populator for our data class like below





public class NewProductPopulator2 implements Populator<ElectronicProductsModel, productData>
{
private static final Logger LOG = Logger.getLogger(BajajCustomerFullNamePopulator.class);
/*
* (non-Javadoc)
*
* @see de.hybris.platform.converters.Populator#populate(java.lang.Object, java.lang.Object)
*/
@Override
public void populate(final ElectronicProductsModel sourcefinal ProductData targetthrows ConversionException
{
LOG.info("####################### Electrnic product populator");
target.setProductPrice(source.getProductPrice());
target.setProductName(source.getProductName());
target.setDiscount(source.getDiscount());
}
}

Step 2:-

           write methods in all the layers like controller, facade, service, and DAO for retrieving that model


In Controller:-



@RequestMapping(value = "/getProductData", method = RequestMethod.GET)
public String getProductData(final Model model)
{

final List<ProductData> productDetails = bajajProductFacade.getProductData();
model.addAttribute(ProductDetails_Attr, productDetails);
return ControllerConstants.Views.Pages.Bajaj.productresult;

}

In FacadeImpl:-


@Override
public List<ProductData> getProductData()
{
final List<ElectronicProductsModel> electronicProductModel = bajajProductService.getProductData();

final List<ProductData> ProductData = mobilesConverter.convertAll(electronicProductModel);
return ProductData;

}



In ServiceImpl:-


@Override
public List<ElectronicProductsModel> getProductData()
{
return bajajProductDao.getProductData();
}

In DaoImpl:-

@Override
public List<ElectronicProductsModel> getProductData()
{

final String query = "select {pk} from {ElectronicProducts}";
final SearchResult<ElectronicProductsModel> result = getFlexibleSearchService().search(query);
return result.getResult();
}




Step 3:-

     we need configure that converter and populator in xxxfacade-spring.xml like the following.

<!-- For bajaj product conveter and populator -->

<bean id="bajajProductConverter" parent="abstractPopulatingConverter">
<property name="targetClass"
value="com.org.training.facades.product.data.ProductData" />
<property name="populators">
<list>
<ref bean="bajajProductPopulator" />

</list>
</property>
</bean>
<bean id="bajajProductPopulator"
class="com.org.bajaj.facades.newuser.populator.CustomUserFullNameDataPopulator" />



Task 2:Converting Model By  Using Converter.convert() Method


Step 1:-
              write method for retrieving data from database like the following





In FacadeImpl:

@Override
public ProductData getProductDataWithConvert(final int discount)
{
final ElectronicProductsModel electronicProductModel = bajajProductService.getProductDataWithPopulator(discount);

final ProductData ProductData = mobilesConverter.convert(electronicProductModel);
return ProductData;
}




Step 2:-

we need configure that converter and populator in xxxfacade-spring.xml like the following

<bean id="bajajProductConverter" parent="abstractPopulatingConverter">

<property name="targetClass"
value="de.hybris.platform.commercefacades.user.data.ProductData" />

<property name="populators">
<!--adding list of populators to converter -->
<list>
<ref bean="customProductDataPopulator" />
<ref bean="customProductDataPopulator2" />
</list>
</property>
</bean>

<bean id="bajajProductPopulator"
class="com.org.bajaj.facades.newuser.populator.BajajProductDataPopulator" />

<bean id="bajajProductPopulator"
class="com.bajaj.facades.mobiles.populator.NewProductPopulator" />


Step 3:-  we will get output like the following.



Task 3:- Converting Model By Using Populator.populate() Method.



Step 1:-

              When we retrieving a single model object then we can use Populator.populate() like the following

@Override
public ProductData getProductDataWithPopulator(final int discount)
{

final ElectronicProductsModel electronicProductModel = bajajProductService.getProductDataWithPopulator(discount);

final ProductData ProductData = new ProductData();
bajajProductPopulator.populate(electronicProductModel, ProductData);
return ProductData;

}



Step2:-
write one populator for your data class like the following




public class BajajProductPopulator implements Populator<ElectronicProductModel, ProductData>
{

@Override
public void populate(final ElectronicProductsModel source, final ProductData target) throws ConversionException
{
target.setProductPrice(source.getProductPrice());
target.setProductName(source.getProductName());
target.setDiscount(source.getDiscount());

}
}

Step 3:-

          we need to configure that populator in xxxfacade-spring.xml like the following


<bean id="bajajProductPopulator"
class="com.bajaj.facades.mobiles.populator.BajajProductPopulator" />
<bean id="newProductPopulator2"
class="com.bajaj.facades.mobiles.populator.BajajProductPopulator2" />


Step 4:-

     we will get output like the following


Task 4:- Adding the list of Populators to the converter


Step1:-

   Here we adding the list of populators to one converter for this create many populators for populate and add those list of populators to converter like the following then we will get output like the above figure.


<!-- For CustomProduct conveter and populator -->
<bean id="bajajProductConverter" parent="abstractPopulatingConverter">
  <property name="targetClass"
      value="de.hybris.platform.commercefacades.user.data.ProductData" />
 <property name="populators">
<!--adding list of populators to converter -->
    <list>
        <ref bean="bajajProductPopulator" />
        <ref bean="newProductPopulator2" />
     </list>
    </property>
</bean>


Step 2:-

we will get output like the following



Task 5:-Adding a populator through modifyPopulatorList

Step 1:-

         Here we add one converter and populator for modifyPopulatorList like the following in xxxfacade-spring.xml then we will get output like above figure


<!-- Adding a populator through modifypopulatorlist -->

<bean parent="modifyPopulatorList">
     <property name="list" ref="bajajProductConverter" />
      <property name="add" ref="bajajProductPopulator2" />
</bean>



Task 6:- Overriding ootb populators &7.Adding a populator to existing converter

Step 1:-

Here we are creating one populator for our requirement and extends that to OOTB populator like the following


public class extends AddressPopulator
{
@Override
public void populate(final ElectronicProductModel source, final NewProductData target)
{
super.populate(source, target);

target.setFirstName("suresh");
target.setLastName("naresh");
target.setEmail("suresh@GMAIL.COM");
target.setCompanyName("GOOGLE");

}
}


Step2:-  In xxxfacade-spring.xml like the following



<bean id="bajajProductPopulator3"
class="com.bajaj.facades.mobiles.populator.BajajProductPopulator3" parent="defaultAddressPopulator"></b<bean>





Step 3:-  we will get output like the following