April 10, 2020
Estimated Post Reading Time ~

Dueling with Java Use API

Today, we are going to look into a more popular way of dealing with server-side logic using Java Use API.
We will be creating a simple text component (similar to the one in the previous post) and will use Java backend logic to do our task.

What on earth is WCMUsePojo?

You must have heard about the WCMUsePojo term while developing with AEM. What is it? Actually, it is a class that enables us to talk to the front end of our component. It is similar to the JavaScript Use API in usage. 

Since we likely need a way to provide back-end logic to components in AEM’s component development mechanism, we write Use API logic

We also know that HTL is a limited template language that allows doing only small basic operations, and the heavy lifting logic should be done inside a Java class or a server-side JS.

This provides better decoupling of the business logic and so your code will be more easily maintainable and also easier to debug. All of this is achieved by extending WCMUsePojo in our custom class which provides us with the capability to deal with JCR.

Example

After understanding the purpose and usage of the API, it's time to see the concepts in action.
  • Create a new AEM project using AEM Multimodule Project and deploy in your AEM instance.
  • Go to CRXDE and under your project in /apps create a new component with the following configuration
Create a component
  • After creating the component node, create a cq:dialog underneath and configure it as follows -
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:primaryType="nt:unstructured"
    jcr:title="Text Component 2.0"
    sling:resourceType="cq/gui/components/authoring/dialog">
    <content
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/foundation/container">
        <layout
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/foundation/layouts/tabs"
            type="nav"/>
        <items jcr:primaryType="nt:unstructured">
            <tab
                jcr:primaryType="nt:unstructured"
                jcr:title="Properties"
                sling:resourceType="granite/ui/components/foundation/container">
                <layout
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
                <items jcr:primaryType="nt:unstructured">
                    <columns
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/foundation/container">
                        <items jcr:primaryType="nt:unstructured">
                            <title
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/foundation/form/textfield"
                                class="field-whitespace"
                                fieldDescription="Enter the title"
                                fieldLabel="Title"
                                name="./title"/>
                            <description
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/foundation/form/textarea"
                                class="field-whitespace"
                                fieldDescription="Enter the description"
                                fieldLabel="Description"
                                name="./description"/>
                        </items>
                    </columns>
                </items>
            </tab>
        </items>
    </content>
</jcr:root>
  • Now go to the eclipse in the core child project and create a class named TextComponent2.java and paste the following code in it
package org.redquark.demo.core.cqcomponents;

import javax.jcr.Node;

import org.redquark.demo.core.models.TextComponent2Model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adobe.cq.sightly.WCMUsePojo;

/**
 * @author Anirudh Sharma
 * 
 * This class has the back-end logic for the Text Component 2.0
 */
public class TextComponent2 extends WCMUsePojo {

 /**
  * Logger
  */
 private static final Logger log = LoggerFactory.getLogger(TextComponent2.class);

 /**
  * Model object
  */
 private TextComponent2Model model;

 /**
  * Overridden activate method
  */
 @Override
 public void activate() throws Exception {

  try {

   log.info("Text Component 2.0 backend logic starts");

   /**
    * Initializing the model object to set the values
    */
   model = new TextComponent2Model();

   /**
    * Getting the current node from the resource object which is available in Use
    * API
    */
   Node node = getResource().adaptTo(Node.class);

   /**
    * Check if the node has title property
    */
   if (node.hasProperty("title")) {

    /**
     * Reading the title property from the string
     */
    String title = node.getProperty("title").getString();

    /**
     * Setting the value entered by the user in the model object
     */
    model.setTitle(title);

   }

   /**
    * Check if the node has description property
    */
   if (node.hasProperty("description")) {

    /**
     * Reading the title property from the string
     */
    String description = node.getProperty("description").getString();

    /**
     * Setting the value entered by the user in the model object
     */
    model.setDescription(description);

   }

  } catch (Exception e) {

   log.error(e.getMessage(), e);
  }
 }

 /**
  * This method is wrapper to return the model object
  * 
  * @return {@link TextComponent2Model}
  */
 public TextComponent2Model getModel() {
  return model;
 }
}
    This class requires a model class to save the values in memory. For this, I created one simple model class with two properties - title and description (we mimicked the edit dialog properties). Now, create a model class TextComponent2Model.java and paste the following code in it.
  • Let's look at the class TextComponent2.java and understand its code. First, we have extended the class WCMsePojo to make use of Java Use API
  • Now, in the overridden activate() method, we will write the logic. We are getting the adapted Node object from the getResource() method which is available due to the use of WCMUsePojo class. We then are checking the existence and getting the properties from the JCR using javax.jcr.Node API. After getting the properties, we are setting them in the model object.
  • Now, rename text2.jsp to text2.html and paste the following code in it
Text Component 2.0 - Showcases Java Use API

<div data-sly-use.text2="org.redquark.demo.core.cqcomponents.TextComponent2">
<h1>Title: ${text2.model.title}</h1>
<p>Description: ${text2.model.description}</p>
</div>
  • Here, we are using data-sly-use to include the Java file (TextComponent2.java), then we are accessing the values via the model object.
  • Now drag and drop the component on the page and configure it using the edit dialog. You will see the passed values on your page.


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.