How to create data transfer object(DTO), Converter and populator, Facade?

In this blog, we will explain the process of creating a data transfer object(DTO), Converter and populator, facade. We will show you the process of calling facade from the controller class and defining spring bean and its properties. We will create one model attribute and populate it. We will modify the UI by making a change in the tag file.

We take one example and this example explains how to show cart subtotal without taxes. Remember that there are many other ways by which we can show cart subtotal without taxes but we took the following approach to explain the above points.

Show cart subtotal without taxes/How to show cart subtotal without taxes?

Currently in SAP Hybris Commerce Accelerator when we add products to the cart then it shows cart subtotal with taxes. You can observe this in below image where we added one product to the cart in the apparel storefront that shows cart subtotal with taxes.

cart subtotal with taxes

Now here our goal is to show cart subtotal without including taxes. To achieve this goal we do not make any changes in OOB(out of the box) files but we use them from our created custom files to achieve this goal. We need to follow the following steps to achieve this goal.

  1. Create data transfer object(DTO)
  2. Create converter and populator
  3. Create facade and populate the data
  4. Call the facade from CartPageController/ Modify CartPageController
  5. Modify the cartTotal.tag file

1. Create data transfer object(DTO)

Now we will create one DTO(data transfer object) class named as SubTotalWithOutTax and it contains one property called as a sub of PriceData type. This sub property will hold the value of order subtotal without taxes.

Steps to create SubTotalWithOutTax DTO class

  1. Navigate to yacceleratorfacades->resources and open yacceleratorfacades-beans.xml.
  2. Add the following lines of code to yacceleratorfacades-beans.xml file.
    SubTotalWithOutTax DTO class
    Note: This entry must be between <beans> </beans> tag.
  3. Build the hybris system by running ant clean all.
    After successful build we can check our SubTotalWithOutTax DTO(data transfer object) class at the specified package and the file will look like this.

    SubTotalWithOutTax.java
    SubTotalWithOutTax.java

     

2. Create converter and populator

Before learning how to create converter and populator we need to know why we need converters and populators?

Now we will create a converter and populator for our SubTotalWithOutTax DTO(data transfer object) class. We need to follow the following steps to create a converter and populator.

  1. Now we create SubTotalWithOutTaxPopulator to fill the data in SubTotalWithOutTax DTO(data transfer object) class as you can see in the below image. SubTotalWithOutTaxPopulator implements the Populator interface.
    SubTotalWithOutTaxPopulator.java
    SubTotalWithOutTaxPopulator.java

     

  2. Navigate to yacceleratorfacades->resources and open yacceleratorfacades-spring.xml. Now we define a spring bean for the new SubTotalWithOutTaxPopulator and SubTotalWithOutTaxConverter as shown in below image.
    yacceleratorfacades-spring.xml
    yacceleratorfacades-spring.xml

     

  3. Build the hybris system by running ant clean all.

3. Create facade and populate the data

Generally, facade classes are created to call the services and to fill the data in DTO(data transfer object) class using converters and populators.

In our case, we create one DefaultBitbyteCartFacade class that implements BitbyteCartFacade interface. Through this class, we make a call to CartService and populate the data in SubTotalWithOutTax DTO class using converter and populator.

We need to follow the following steps to create BitbyteCartFacade

  1. Navigate to yacceleratorfacades->src and create an interface named as BitbyteCartFacade. as you can see in the below image

    BitbyteCartFacade.java
    BitbyteCartFacade.java
  2. Now we provide the implementation for the BibyteCartFacade interface in DefaultBitbyteCartFacade class.

    DefaultBitbyteCartFacade.java
    DefaultBitbyteCartFacade.java
  3. Navigate to yacceleratorfacades/resources and open yacceleratorfacades-spring.xml. Now we define a spring bean for the new DefaultBitbyteCartFacade as shown in below image.

    Spring Bean for Facade
    yacceleratorfacades-spring.xml
  4. Build the hybris system by running ant clean all.

4. Call the facade from CartPageController/Modify CartPageController

CartPageController is permitted to use annotation-based declaration so we inject BitbyteCartFacade as shown below in CartPageController.

BitbyteCartFacade bean Injection
CartPageController.java

Now add following lines of code inside prepareDataForPage method

Setting Model Attribute
CartPageController.java

Build the hybris system by running ant clean all.

5. Modify the cartTotal.tag file

Navigate to yacceleratorstorefront->web->webroot->WEB-INF->tags->cart and open cartTotal.tag file.

Replace the following lines of code with line number 14 and 15 to this file as shown in the image.

cartTotals.tag
cartTotals.tag

After saving this file, refresh apparel storefront and you can clearly observe that subtotal of the cart does not include taxes.

Cart Subtotal Without Taxes

Interceptor in SAP Hybris Commerce

Interceptor

An interceptor addresses a particular step in the life cycle of a model. When the life cycle reaches a certain step, you can activate a corresponding interceptor. An interceptor can modify the model, raise an exception to interrupt the current step or publish an event if the model matches certain criteria. For example, you could check that an attribute contains certain values before saving the model.

In easy words, we can say that anything that intercepts something else is called an interceptor. We can take one example to explain interceptor concept in a real-life scenario. We take one example where a person wants to watch a movie in the cinema hall. Now we will see how an interceptor is used in this scenario.

Interceptor Example

In the above diagram, we can see that one person went to the cinema hall and his journey intercepted at the ticket checking counter. Here Diamond(Has ticket) works as an interceptor. If a person has a ticket then he is permitted to watch a movie. If he doesn’t have a ticket then he is redirected to buy a ticket at the ticket counter.

What is the model’s life cycle?

This question is asked in hybris interviews. Here I am trying to explain this so it can help you in cracking hybris interview.

A model represents a state in the database. The representation is not live, that means that modified model values are not written to the database automatically. Instead, when you modify a model, you must explicitly save it to the database to have its state reflected there.

Model Life cycle
Model Life Cycle

Phases in the Model’s life cycle

There are four phases in the model’s life cycle.

  1. Instantiating the model
  2. Modifying model values
  3. Saving Model Values
  4. Removing the model

 

1. Instantiating the model

This can be done by either creating a new Model instance or by loading a Model from the database.

  1. Creating a model instance:- Visit link Model service create method vs new operator.
  2. Loading an existing model from the database is possible either by using pk or by using a query expression.
    Example:- UserModel user = modelService.get(pk);    [loading using primary key]

2. Modifying model values

We can modify the properties of the model if required.

3. Saving model values

If a model is created or modified. We save back the model to update the database. If we have used a new model, a new record is inserted/created in the database, otherwise, the existing record is updated.

4. Removing the model

If the model is no longer needed, the database record is deleted.

We can use interceptors to hook into the model’s life cycle.

Types of interceptors

  1. Load interceptor

    The load interceptor is called whenever a model is loaded from the database. You may want to use this interceptor if you want to change the values of the model after load. An exception raised during execution prevents the model from being loaded. To use this interceptor we must implement LoadInterceptor interface.

  2. InitDefaults Interceptor

    The InitDefaults interceptor is called when a model is filled with its default values. This happens either when it is created via the modelService.create method or when the modelService.initDefaults method is called. You can use this interceptor to fill the model with additional default values defined in the items.xml. To use this interceptor we must implement InitDefaultsInterceptor interface.

  3. Prepare interceptor

    The Prepare interceptor is called before a model is saved to the database before it is validated by Validate interceptors. Use this to add values to the model or modify existing ones before they are saved. An exception is raised during execution prevents the model from being saved. Prepare interceptor is called before the Impex translators. To use this interceptor we must implement PrepareInterceptor.

  4.  Validate interceptor

    The Validate interceptor is called before a model is saved to the database after is been prepared by the Prepare interceptors. We can use Validate interceptor to validate values of the model and raise an InterceptorException if any values are not valid. To use this interceptor we must implement ValidateInterceptor.

  5.  Remove Interceptor

    The Remove interceptor is called before a model is removed from the database. We can use this interceptor to prevent the removal of the model by raising an InterceptorException. To use this interceptor we must implement RemoveInterceptor.

How to register an interceptor?

After implementing an interceptor, we need to register it as a spring bean. The steps involved in registering an interceptor as followed:-

  1. Navigate to  customExtension->resources and open customExtension-spring.xml. Add the following line of code to this file.
    Custom Interceptor Bean
  2. In this step, we will do Interceptor mapping as shown in below image.
    Interceptor Mapping

Backoffice Customization

What is Backoffice Framework?

Backoffice Framework is new SAP Hybris Backoffice Framework designed to facilitate the creation of business tools and user interfaces in an easy and consistent way. It is shipped with SAP Hybris Commerce in the backoffice extension. It makes it possible to create a variety of components that can be reused later on in all kinds of applications. These components are standalone and deployable widgets can be easily modified without touching the code base.

In this tutorial, we will show you, how to create a custom widget using the Backoffice Framework. Our custom widget will have one input and one submit button. Suppose we enter some input and press the button, If the entered value is an integer then one pop up appears and it contains a message that Input value is an integer otherwise it will display an error that entered input is not an integer.

Steps to create a custom widget

  1. Create a custom  backoffice extension

  2. Create a widget definition

  3. Creating a widget view

  4. Create a service for widget/Use existing service for a widget

  5. Create a controller for the widget

  6. Build and start the server

  7. Deploy the widget

1. Create a custom  backoffice extension

Here we will create one custom backoffice extension named hybrisdiary using the BackOffice template extension. In this custom backoffice extension (hybrisdiary) we can create our custom widgets. To create custom backoffice extension(hybrisdiary) follow the following steps:-

  1. Open the command prompt and navigate to  <%HYBRIS_HOME_DIR%>/hybris/bin/platform directory and run the setantenv.bat file as shown in below image.setantenv.bat
  2. Now run ant extgen command.ant extgen
    Extgen prompts you to specify values for the technical aspects of an extension. Extgen comes with default values for all these technical aspects.
    These default values are defined in the project.properties file in the extgen directory. The default value is displayed in brackets ([ and ])
  3. Now we enter ybackoffice as shown in below image.ybackoffice
  4. Now enter extension name hybrisdiary as shown in below image.
    hybrisdiary custom backoffice name
  5. Now enter the package name(de.hybris.hybridiary) as shown in below  image
    package name
  6. If you want to register  SASS support for your extension then press enter otherwise type false and then press enter. Here we are using default value so we will press enter.
  7. If you want to create sample widget then press enter otherwise type false and then press enter. Here we are creating sample widget so will press enter.
  8. If you want to create a sample style sheet then type true and then press enter. If you do not want to create a sample style sheet then simply press enter.
    SASS extension sample widget sample style sheet
  9. Navigate to <%HYBRIS_HOME_DIR%>/config and open local.properties file and specify the following entry and save it.
    backoffice.sass.enabled=true
  10. Now run ant sasscompile from the platform.
    ant sasscompile
  11. Now we will add our custom backoffice extension(hybrisdiary) to localextensions.xml
    localextensions.xml
  12. Now we will do ant clean all.
    ant clean all

If the build successful then your custom backoffice extension successfully generated. If you are using eclipse then import your custom backoffice extension in to eclipse.

2. Create a widget definition

To create a widget definition, we must keep in mind that widget-definition id must be unique. If your widget-definition id matches with existing widget-definition id then your new widget will not appear on the list of widgets in the choose widget wizard. Now do the following steps to create the widget definition:-

  1. Navigate to hybrisdiary->backoffice->Resources->widgets and create a new folder called as mycustominput
    mycustominput folder location
  2. Now create a definition.xml file inside the newly created folder(mycustominput).
  3. Now add the following lines of code to the file(definition.xml).

    definition.xml
    definition.xml

3.Creating a widget view

The view of our widget will be defined in the ZUL file and the name of the file must match with last part of the widget ID as defined in the definition.xml file. The last part of widget ID is mycustominput so the view file name will be mycustominput.zul. In mycustominput.zul file, we will define all frontend component. To check whether the entered input is an integer or not we need one textbox for input and one button to submit. So we will define one textbox and one button in mycustominput.zul file. Now follow the following steps to create the widget view:-

  1. Now create a mycustominput.zul file inside the mycustominput folder.
  2. Now add the following lines of code to the mycustominput.zul file.
    mycustominput.zul
    mycustominput.zul

     

4.Create a service for widget/ Use existing service for a widget

For our example, we need some service to do some action. Either we can create our custom service to do some logic or we can use existing services. In our example, we will create a custom service that will check that the entered input is an integer or not. To create a service for our custom widget, we need to follow the following steps:-

  1. Navigate to hybrisdiary->src folder and create MyCustomInputService.java file in de.hybris.hybrisdiary.mycustominput package.
  2. Add the following lines of code to the MyCustomInputService.java file.

    MyCustomInputService.java file
    MyCustomInputService.java
  3. Navigate to hybrisdiary->resources and open hybrisdiary-backoffice-spring.xml file and define the bean for MyCustomInputService as shown in below image.
    mycustominputservice bean
    mycustominputservice bean

     

5. Create a controller for the widget

Here we have not defined any action for submit button so when we click on the button nothing will happen. To do some action we need to define a controller for the widget. To create a controller for the custom widget we need to follow the following steps:-

  1. Navigate to hybrisdiary->backoffice/src and create MyCustomInputController.java in de.hybris.hybrisdiary.widgets.mycustominput package.
  2. Add the following lines of code to the file.

    MyCustomInputController
    MyCustomInputController.java
  3. Navigate to hybrisdiary->backoffice->Resouces->widgets->mycustominput and open definition.xml file and we add a controller class to this file as shown in the image.

    definition.xml
    definition.xml

6.Build and start the server

Now we will build the system by running ant clean all and we start the server by running the hybrisserver.bat file.

7.Deploy the widget

Now we will deploy our custom widget. To deploy the custom widget do the following steps:-

  1. Open the internet browser.
  2. Enter https://localhost:9002/backoffice  in the browser’s address bar.
  3. Enter your credentials and log in.
    backoffice login
  4. Press F4 to enter into Application Orchestrator mode and click on the symbol(+ symbol inside an orange circle) to add the new widget as shown in below image.
    Application Orchestrator mode
    Application Orchestrator mode

    The choose widget appears, which contain all the available widgets and choose My Custom Input widget. You can easily learn the process of adding a widget to backoffice by observing the image.
    add widget process

  5. Now press F4 to enter into normal mode and you will see the newly added widget in backoffice.
    new widget in backoffice
  6. Now we enter 54 in the input box and which is an integer and we press the submit button. Now message box will appear which show us that “input value is an integer“.
    working widget

Navigation management in SAP Hybris Commerce

Navigation management through impex

When we create a website based on an existing content catalog, a default navigation structure is created for our content catalog. If we create a website based on a new content catalog, we must build navigation structure for our new content catalog. So we will learn here how to create navigation nodes using impexes.

Create new navigation node using impex

To explain this we will create one new custom navigation node in apparel storefront. In apparel storefront, there are 5 navigation nodes as shown in the image and we will add another navigation node at the end of navigation nodes.

Apparel Store
Apparel Storefront

Steps to create a new navigation node

Step-1

Create a new CMSNavigationNode. Like created in below image.

CMSNavigationNode

Step-2

Create a new CMSNavigationEntry for CMSNavigationNode. Like created in below image.

CMSNavigationEntry

Step-3

Create a new CMSLinkComponent. Like created in below image.

CMSLinkComponent

Step-4

In this step, we do localization of CMSNavigationNode and CMSLinkComponent as shown in the image

Localiztion

The complete impex will look like this.

create_navigation_node
new_navigation_node.impex

Here we assume that your server has started already. Now run the above impex(new_navigation_node.impex) in HAC(Hybris Administration Console) and synchronize the content catalog(apparel-ukContentCatalog).

Now access the apparel storefront and you can clearly observe newly created navigation node. In below image, you can see new custom navigation node.

Apparel store with new node
Apparel store with new navigation node

Create Children nodes of Custom navigation nodes

Now we will create children of above-created navigation node. To create children of above-created navigation node, we need to follow the following steps

Step-1

Create a new CMSNavigationNode. Like created in below image.

ChildrenCMSNavigationNode

Custom Brands Nav Node is a child of Custom Nav Node and Custom Brands Nav Node is the parent of bitbyte Link and hybrisdiary Link.

Navigation tree structure

Step-2

Create a new CMSNavigationEntry for children nodes. Like created in below image.

CMSNavigationEntry For Children

Step-3

Create a new CMSLinkComponent. Like created in below image.

CMSLinkComponentForChildren

Step-4

In this step, we do localization of CMSNavigationNode and CMSLinkComponent as shown in the image.

Children's localization

The complete impex will look like this.

Complete impex for children node
new_navigation_children_node.impex

Here we assume that your server has started already. Now run the above impex(new_navigation_children_node.impex) in HAC(Hybris Administration Console) and synchronize the content catalog(apparel-ukContentCatalog).

Now access the apparel storefront and Hover on custom navigation node and you can clearly observe newly created children(HYBRISDIARY and BITBYTE) of custom navigation node. In the below image you can observe.

Apparel store with Childrens
Apparel store with new navigation node and with its children

Hot Deployment – Hybris

Introduction

In this tutorial I will be covering the configuration of JRebel with Hybris. With JRebel configured you will be able to modify java source classes and compile them on the fly.

“No need to build and start the server again and again”

The configuration is very simple, just 3 steps and you are good to go!

Step 1

  • Download JRebel: Archive can be downloaded from the below link http://zeroturnaround.com/software/jrebel/download/prev-releases/
  • Extract the zip file at a location of your preference, for eg: C:/jrebel
    unzip
  • Active JRebel:
    – Go inside bin folder of JRebel.
    – Start the activation utility by running “activate-gui.cmd” file.
    – It will open a Jrebel activation window. The window will contain 2 tabs:
    Try JRebel    for free and I already have a license.Choose Try JRebel for FREE and fill the basic information.

jrebelfreeform
OR
Buy a license and fill the information in the I already have a license section.

Step 2

  • Add the below given property in local.properties file
    tomcat.javaoptions=-agentpath:C:/jrebel/lib/jrebel64.dll
    ** change the version of the jrebel[XX].dll according to the machine specifications.

 Creation of rebel.xml file:
– You will be required to add the rebel.xml file in the resource folder of each extension.

rebel.png

– Create a new rebel.xml class and copy/paste the below given content into the file:

<?xml version=”1.0″ encoding=”UTF-8″?>
<application xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns=”http://www.zeroturnaround.com&#8221; xsi:schemaLocation=”http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_1.xsd”&gt;
<classpath>
<!– Make sure to replace Absolute_Path with your concrete values –>
    <dir name=”{Absolute_Path}/classes”/>
</classpath>
</application>

**   The absolute path should be the complete path to the classes folder.
Example: C:/hybris/bin/custom/demo/demofacades/classes

***The classes folder is the compiled source folder of Hybris and not IDE’s(eclipse).

Step 3

  • Change the IDE(eclipse) compile output path in “.classpath” file of the extension.classpath.png
    TO
    classpath1.png
    Path structure:
    path.png
    All the configurations are completed.You just need to recompile the code from IDE(eclipse) after making the changes in the Java source file.For Eclipse you need to do the below mentioned step:

    • Just go to Project -> Clean
    • Select “Clean projects selected below” option and select the extensions which contains the modified java source classes.
    • Select “Start build immediately”.
    • Select “Build only the selected projects”.
    • Press OK and you are done!

Understanding Spring Events in Hybris

We humans are known to celebrate certain milestones in our life journey. We do celebrate birth, tying knots etc. Similarly, in the buying journey of a customer, there are few milestones which are worth celebrating or react to. Order placement, registration of a customer is few of them. The reaction could be about sending a welcome email, or sending the order data to a third party system for fulfillment.

Further, let’s say, a customer registered on a web site, and wants to start browsing the cool products. But the lousy code of sending a fancy welcome email with a promotional voucher in it, took around one minute. He will regret his decision to register, and will walk away.

spring-listener.jpg

Spring based events, provides the exact same infrastructure. So now we know, whenever we have a situation where some lousy code is to be executed after some thing happens (an event), we will rely on events.

 First we need to create an Event class, that will hold the necessary data to pass to the listener.

protected AbstractCommerceUserEvent initializeEvent(final AbstractCommerceUserEvent event, final CustomerModel customerModel)
{
event.setBaseStore(getBaseStoreService().getCurrentBaseStore());
event.setSite(getBaseSiteService().getCurrentBaseSite());
event.setCustomer(customerModel);
event.setLanguage(getCommonI18NService().getCurrentLanguage());
event.setCurrency(getCommonI18NService().getCurrentCurrency());
return event;
}

Spring provides a way to publish an event.

getEventService().publishEvent(initializeEvent(new RegisterEvent(), customerModel));

There are dedicated listeners lying around, who listens to these wishes, and reacts the way, they are programmed.

Listeners can be bonded to publishing services via common event object.

public class RegisterEventListener extends AbstractEventListener
{
   @Override
   protected void onEvent(final AbstractEvent event)
   {
      if (event instanceof RegisteEvent)
      {
          // Do whatever you want. send email/voucher or whatever
      }
   }
}

Please note that since, listener code starts in a new thread, it will not hamper customer journey on your site. The listener code will execute as a back end process.

Adding a new attribute to edit view area in Product Cockpit.

I was working on a Project and there was a requirement to add a new attribute in edit view area In Product Cockpit.

I followed these few step to do this task.

1.Create a new Model e.g MyProduct that extends ProductModel in Items.xml, add attribute in this model e.g:

“<itemtype code=”MyProduct” extends=”Product”>
<description>my product that contains additional attributes.</description>
<attributes>
<attribute qualifier=”attribute1″ type=”localized:java.lang.String”>
<description>example for product cockpit</description>
</attribute>
</attributes>
</itemtype>”

after this,Build the project and start the server, do Update running system from Hac.

Add some product in your “Myproduct” Model.

2.Create  a editorArea_MyProduct.xml file in your Cockpit extension and add key for new attribute in xml file

editorArea_MyProduct

3. Localized the key name in  ProjetcNamecockpits-locales_en.properties and i3-label.properties file.

ProjetcNamecockpits-locales_en

 

4.Restart the server and do update from HAC. Open ProductCockpit in url “http://localhost:9001/productcockpit&#8221; and search your product which you added in “MyProduct” model .

5.Open that product and in left side you will find your new attribute in Editor_area.

Capture1

Hybris Mobile and Desktop Site

Most people face problem in understanding the difference between Desktop site and Mobile site in Hybris and how do we setup the Mobile site and what parameters control the switching of Desktop and Mobile site. Also, how does a responsive site differ from both Desktop and Mobile site?

Technical Difference in terms of UI

First of all, the mobile site differs from the desktop site generally in terms of the UI. The back end code mostly remains the same for both the mobile and desktop sites.

The UI change is controlled by CSS, JS and images.

Also, the UI, which is defined using Hybris WCMS, need to define different Page Template, ContentSlot, ContentPage, ProductPage and the relationship between them for Mobile site and Desktop site.

Technical Difference in terms of Java code

For accessing the UI of either the Mobile site or the Desktop site, we need set the UiExperienceLevel to corresponding device type for which we need to first of all detect the device from which request is coming. This is done using an interceptor i.e. DeviceDetectionBeforeControllerHandler using class DefaultDeviceDetectionFacade and more specifically in SpringMobileRequestDeviceDataPopulator.

After device detection, the detected device needs to be mapped to a UiExperienceLevel (i.e whether it is desktop, tablet, mobile), which is done in class DeviceDataUiExperiencePopulator.

After this the detected UiExperienceLevel is compared with the supported UiExperienceLevel and if matched then DetectedUiExperienceLevel is set to this value.

Parameters controling switching of Desktop and Mobile site

UiExperienceLevel is configured in your properties file using the property “uiexperience.level.supported”.

Please note the correct format of specifying the value for “uiexperience.level.supported” is comma separated Camel Case names like Mobile,Desktop or Desktop,Mobile for the functionality to work correctly.

There is one more interceptor SetUiExperienceBeforeControllerHandler called before the request reaches the controller. This interceptor checks for the parameter “uiel” (like ?uiel=Mobile) in the request and if set its value is used to override all previous UiExperienceLevel.

Based on the UiExperienceLevel set, the corresponding CSS, JS and images are set and we see either the Mobile site or the Desktop site.

Responsive

When we have constructed our website for Responsive UI then the UI automatically adjusts itself according to the device type and this is done because of the responsive JS used. Hybris has made the desktop site responsive hence eliminating the need for separate Desktop and Mobile sites.

Different Views for Electronics Site:

MobileSite
Mobile Site – Non Responsive
ResponsiveSite-MobileView
Mobile Site – Responsive

 

 

 

 

 

 

 

 

 

ResponsiveSite-DesktopView

Desktop Site – Responsive

ResponsiveSite-TabView

Tab Site – Responsive

 

Understanding Cronjobs

A Cronjob is a scheduler where we can schedule a particular Job to be performed at a specified time or over a period of time.

The 3 parts of a Cronjob are:

  1. CronJob
  2. Job
  3. Trigger

For understanding each of these clearly I would take an example:

1. CronJob:

First of all you need to identify what task you CronJob need to do.

In this case lets say that your cronjob needs to send NewsletterEmail periodically with a personalized message.

You would create a NewsletterEmailCronJob item in your items.xml file having attributes for storing a personalizedMessage

<itemtype code=”NewsletterEmailCronJob” autocreate=”true” generate=”true” extends=”CronJob”
jaloclass=”com.email.jalo.NewsletterEmailCronJob”>
<description>Cronjob for sending Newsletter Email</description>
<attribute qualifier=”personalizedMessage” type=”java.lang.String”>
<persistence type=”property”/>
</attribute>
</itemtype>

Now the above code would create the required Model class when you save it and run Ant Build script.

2. Job:

Job is where your business logic goes and it uses the CronJob Model you created as part of CronJob above.

Here you would create a class say NewsletterEmailJob which would extend AbstractJobPerformable and would work on NewsletterEmailCronJobModel.

You would override the perform method to write the business logic in it.

Code Snippet:

public class NewsletterEmailJob extends AbstractJobPerformable<NewsletterEmailCronJobModel>
{

@Override
public PerformResult perform(final NewsletterEmailCronJobModel cronJob)
{

….. Logic for sending News letter Email with Personalized Message ….

}

}

Also, you would define a bean for the above class in your spring.xml file as follows:

<bean id=”newsletterEmailJob” class=”com.email.NewsletterEmailJob”
parent=”abstractJobPerformable” >
</bean>

3. Trigger

Trigger defines the time event when the Job would be executed.

The trigger is linked to the Job via CronJob. You would first create a CronJob item and associate the bean id of the Job to it. Then you would create a Trigger item which contains the CronJob item reference and the time schedule for execution. The time schedule expression is written using Quartz Job Scheduler which can found at http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger

INSERT_UPDATE NewsletterEmailCronJob; code[unique=true];job(code);
 ;newsletterEmailCronJob;newsletterEmailJob;
INSERT_UPDATE Trigger;cronJob(code)[unique=true];active;year;month;day;hour;minute;second;maxAcceptableDelay;relative;weekInterval;daysOfWeek
 ;newsletterEmailCronJob;true;-1;-1;-1;-1;10;-1;1;true;

What is role of jalosession?

The Jalo layer in hybris is depreacted, not the jalosession.

Whenever a request is made to hybris server, it may need current user details, currency, language, timezone etc to serve that request efficiently. Since HttpSession does not hold all these details, hybris came up with the concept of JaloSession.

Whenever a request comes to Hybris, the filter HybrisInitFilter creates an object of JaloSession. Every JaloSession object is associated with a SessionContext object, which has current user, language, currency etc and the current httpSession object.

  • Cron jobs also run in a JaloSession.
  • Each JaloSession is bound to a tenant. This cannot be changed, after the instance of JaloSession is created.
  • JaloSession is never made persistent in database.

What are ModelAttributes?

Some time it is necessary to get few data in many JSPs, and we don’t want to pass them as a part of DTO (data objects). For example, the titles (Mr and Mrs etc). They can be used in many JSPs and tags file, like registration, delivery address etc.

In such cases, what we do is, create a convenient method in Abstract controllers, and use model attribute annotation for them. In this way they are available from all JSPs directly  using model attribute.

modelAttributes

These can be accessed directly in JSPs or even tag files. like

Current Language : ${currentLanguage}

Data model of Hybris

The hybris data model is made up of type systems.

A type system is defined as a collection of different itemtypes declared in items.xml. Each item type is consist of a Java class which gives access to different members through getter methods and set the values in them through setter methods. In addition to that, each item type has a database entity (table) associated with it.

Item type = Table + Java class

Like any other data model defining entity, item types gives us the flexibility of defining various data structures including primitive one. An data model may consist of integers, Strings or an complex data structure, with a mixture of everything.

For example, let’s take the example of a Student table, having name and roll number.

Student
Roll number Name
123 Ram
456 Shyam

The above data structure of Student can be simply defined as a Java class called Student and two member variable roll number and name.

Student

The above class will give us utility method to access Student object. This class also defines the data types of its member variables. The same is also necessary to define, while creating the database table Student.

So essentially, we can say that a java class and a database entity is something very basic, to create a world, where a java program interacts with a database entity.

Hybris data model collaborated these two and made us write a single xml file declaratively. This gives us freedom from writing create statements in database and also keeps us free from writing monotonous pojo classes.

In real world, the data structures are not as simple, as depicted in above example, rather they are very complex involving floats, double, integers, Strings, collections, enums and nested objects to name a few.

Hybris data model also support each one of them, and we can define every possible data structure in our items.xml.

Atomic types: The item types which are primitive in java, are called atomic itemtypes. For example, integer, float, double, boolean, Strings etc. They are defined in items.xml as follows.

<atomictype class=“java.lang.String” extends=“java.lang.Object” autocreate=“true” generate=“false”/>

Collection type: They are analogue of generic types in Java. A collection is a group of similiar type item types. Like a group of language used for a particular application could be stored as LanguageList.

<collectiontype code=”LanguageSet” elementtype=”Language” autocreate=”true” generate=”true” type=”set”/>

 

 

Enum types: The group of fixed constants are defined as enums, like any other language.

<enumtype code=“ExportStatus” autocreate=“true” generate=“true”>

<value code=“NOTEXPORTED”/>

<value code=“EXPORTED”/>

</enumtype>

To define a general data structure, like that of Student from above example, we need to define a new item type.

<itemtype code=“Student” extends=“GenericItem”

autocreate=“true” generate=“true”                                      jaloclass=“com.blog.hybrisdiary.core.jalo.Student”>

<attributes>

<attribute qualifier=“name” type=“localized:java.lang.String”>                                                                                                            <modifiers/>

<persistence type=“property”/>

</attribute>

</attributes>

</itemtype>

Here we defined an new item type extending Generic item, which is parent of all item type. This item type has only one attribute, name.

The jalo class, is the class which creates the item Student. This class is auto generated.

Each of the characteristics of an item type is defined as attribute of item type. The attibute itself could be of any type, i.e an atomic type like here (String) or another item type.

Suppose, we have to handle student’s address as well. Now it is not advisable to keep addresses as simple Strings. Since address itself, may consist of house number, street number, town, city, country, and mobile number etc. So we should have a separate entity managing the addresses.

<itemtype code=“Address” extends=“GenericItem”

autocreate=“true” generate=“true”

jaloclass=“com.blog.hybrisdiary.core.jalo.Address”>

<attributes>

<attribute qualifier=“town” type=“localized:java.lang.String”

>

<persistence type=“property”/>

</attribute>

<attribute qualifier=“country” type=“Counry”

>

<persistence type=“property”/>

</attribute>

</attributes>

</itemtype>

Here the attribute country of Address is again of type Country. Since Country can have name, isocodes and regions etc. So we used type as Country for qualifier country.

Now we can modify our Student itemtype to accommodate address as well.

<itemtype code=“Student” extends=“GenericItem”

autocreate=“true” generate=“true”                                      jaloclass=“com.blog.hybrisdiary.core.jalo.Student”>

<attributes>

<attribute qualifier=“name” type=“localized:java.lang.String”>                                                                                                            <modifiers/>

<persistence type=“property”/>

</attribute>

<attribute qualifier=“address” type=“Address”>                                                                                                        <modifiers/>

<persistence type=“property”/>

</attribute>

</attributes>

</itemtype>

Items.xml

The data model of hybris is defined declaratively in items.xml. This file is like the nervous system of Hybris project. Every data definition starts from here. This file can be used to define any data structure used in project.

Below are few important points about items.xml

  • The item type in itself, is of type Item.
  • The instance of item type are stored is item type table, but the item type defination is stored in composedType. For example,for the Student item type, the instances of Student will be stored in Student table, but the definition of Student will be stored in composedType table.
  • Any extension can have a items.xml file to define data model used in extension. But this file is not mandatory to have.
  • The order in which the types are declared is very important. The order in which types are defined must conform to below
  • Atomic types
  • collection types
  • enum types
  • map types
  • relation types
  • item types
  • GenericItem is the default parent of each item type.
  • We can extend one item type using keyword

 

      <itemtype code=”ApparelProduct” extends=”Product”>

                          

                           ********

</itemtype>

 

Here ApparalProduct is extending the Product. This is similar to java inheritance concept. The subclass will have all properties of super class. In our case, all the attribute of super class are available for sub class.

  • Ideally we can define an our custom item type, in any extension. But we should define it in relevant extension only.
  • During build of hybris, the extensions are build with taking care of dependency, it makes sure that the parent item type is available.
  • We can control the access to an attribute using modifiers.

<attribute autocreate=“true” qualifier=“code”                     type=“java.lang.String”>

<persistence type=“cmp”             qualifier=“internalCode”/>

<modifiers read=“true” write=“false”   search=“true” initial=“true” optional=“false”            unique=“true”/>

</attribute>

Here the code attribute, is readable, but not writable. It means it’s value cannot be changed, after it is set once.

read – If false, we cannot access it from our java program.

write – If false, we cannot modify the value.

optional– if false, it is mandatory to initialize this attribute. Since it is not optional.

unique– if true, the attribute must hold a unique value. Similar to unique constraints in DBMS.

search – if true, the attribute is searchable through queries.

  • We can control, how the tables are created for an item type. The default table for each item type is genericitem. The table is called as deployment in hybris. So GenericItem is the default deployment.

<deployment table=“UserRights” typecode=“29”/>

Here the table name will be UserRights. The type code is used internally by hybris to generate primary keys. We can give any positive integer for typecode, barring few reserved integers.

  • If we do not give a deployment tag for a item type, the instances of that item type will get start to store in Generic item table. This will cause generic item table to expand drastically, which is a not good for database performance. So we should always give deployment, if our item type is extending generic item directly.
  • Persistence is one of the property of item type attribute. if this property is set to property, it means that attribute will be stored in database. If it is set to dynamic, the attribute will not be part of database table. It is just calculated at run time. This is similar to calculated column in DBMS.

Extensions in Hybris

Hybris suite is a package of number of business functionalities, like a storefront to checkout products, a platform to provide spring features, a service layer to provide persistence and lot others.

Each of these functionality is available as an isolated java project, which has it’s own data model (if required), its own spring configurations ans properties etc. This grouping of similar functionality into one java project is termed as extension. Below is a snapshot for commerceservices extension from hybris.

ext1

An extension may or may not have a web interface. It may depend on other extensions to fulfill it’s purpose. This information is defined in extensioninfo.xml

The data model of extension is defined in <extension-name>-items.xml file.

The spring configuration for an extension is defined in <extension-name>-springs.xml. It has all bean definitions, dependency injections etc.

Each active extension of your hybris project must find a place in localextension.xml

How to set up a svn environment for hybris projects?

Maintaining a version system for any project is one of the most crucial aspect. Hybris projects are not special in this regard. They also do have the same life cycle in terms of development. We need to maintain different environments like SIT, UAT etc. To provide a local development environment is also equally important.

Since the size of OOB Hybris is huge, it is difficult to put everything in SVN (or GIT). Also it is not advisable. The hybris is improvising every day. A new release should not give us pain in terms of development.

The best practice for versioning a hybris project could be:

  • Put only custom folder, containing customized extensions to versioning software.
  • Pass latest local.properties, localextensions locally to each developers.
  • Maintain copy of latest local.properties, localextensions in each of servers like development and SIT, UAT etc.
  • Hybris software is wrapped around custom folder on each environment.
  • Media folder could possibly in SVN or can be passed locally like property files.

2

  • production environment, normally is not connected to SVN. Rather we take the most stable copy from UAT and deploy it using some deployment tool like , bamboo.

Logs are printed twice in console

Hybris comes with bundled Log4J logger. This is used for every logging activity in hybris.

We can define log levels for each extension and even each package. So if we have defined logger level for sub package, then it will execute twice. For eg;

log4j.com.package.name = debug,appconsole

log4j.com.package.name.subpackage = debug,appconsole

So every logging  activity for subpackage will be run twice, once for parent package and one for sub package.

We can disable it via:

log4j.additivity.com.package.name.subpackage=false 

What is omni-commerce?

I have heard of omnipotent. Alright, that is God, or a mobile now a days. But what the hack is this omni-commerce?

As the word suggest, a commerce which is present every where.

Just look around you and get a life. When did you last ordered a dress or ring for your wife (ok ..girlfriend)?

  1. You went to a local store, select it from hundred of it shown by salesperson, and after some negotiation, you bought it.  You are old school. You are so single channel person.
  2. You browsed through tanishq website. Select a design. Note down the SKU of ring. Then you go to a nearby Tanishq and buy the same ring at the same price. You need not to go through that staring look of sales person. Bravo. You have gone multi channel.
  3. You went to Amazon, download their pamphlet for rings, pass it to your girlfriend, she selects one, you called their call center, and ordered one. They deliver it to your sweetheart’s home. You have moved to next class of cross channel (select from print, ordered online).

From above, you see how a simple process of buying a ring could be modified, and how being shopping experience is boosted up now a days.

Now think of a more moderate approach. When you think of buying a ring. You start your action via a research on web. You want to see same kind of result all over. Be it mobile, web or physical shop. Same experience. Same price. Same discount. You want to use your makemytrip voucher in ebay retail. And you want to redeem it at all places, mobile , web, physical store or a kiosk at railway station. you want to modify delivery address. you want to have multiple option for payments. You want a seamless return and refund process.

Such kind of agile and dynamic behavior is served by omni commerce. Here customer centric application are made instead of channel specific.

Hybris is one of the leader in omni commerce technologies.