Monday, November 9, 2020

Accessing AEM jcr pragmatically

 
Accessing AEM jcr pragmatically
 
To use the JCR API, add “jackrabbit-standalone-2.4.0.jar” file to your Java application as external jar file from URL: https://archive.apache.org/dist/jackrabbit/2.4.0/
We can modify nodes and properties located within the AEM repository from a standalone java program.
Here we used the JCR API to perform operations on content located within the AEM repository.
We have created following methods that can:
1)  insertNode - Add Node at any given location
2)  deleteNode - Delete node from any location
3)  addProperties - Add property to any node
4)  readProperty - Read property from any node
5)  readProperties Read All properties of a node
6)  readChildNodes - Read child nodes.
7)  readPageData -  Read page data from /content/
8)  readFileData  - Read file data from local file
9)  readcomponentsData – Reads Components under given project
10) readStylesData – Read client library data
 
 
Step 1: Creating a Connection
We have to connect to a repository and establish a connection, here we have used a method “getRepository” that belongs to “org.apache.jackrabbit.commons.JcrUtils” class.
This method takes a string parameter that represents the URL of the AEM server.
The “getRepository” method returns a Repository instance.
 
// Create a connection to the AEM repository running on local host
Repository repository = JcrUtils.getRepository("http://localhost:4502/crx/server");
 
 Step 2: Creating a Session
Now we used the Repository instance to establish a session with the repository.
To create a session, invoke the Repository instance’s login method and pass “javax.jcr.SimpleCredentials” as object.
Pass the Username and Password of AEM Instance as parameters
 
// Create a Session
javax.jcr.Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
 
Step 3: Creating a Node instance
Now we used a Session instance to create a “javax.jcr.Node” instance.
A Node instance perform node operations.
To create a node that represents the root node, invoke the Session instance's “getRootNode” method:
// Create a node that represents the root node
   Node root = session.getRootNode();
 
Step 4: Creating methods to access JCR Nodes
 
1)    Method To Insert Node
 
public static void insertNode(Node root, String existingNodePath, String newNodeName) {
       try {
              if (root.hasNode(existingNodePath)) {
                     if (root.hasNode(existingNodePath + "/" + newNodeName)) {
                           System.out.println("Warning! Can't ADD new node as node with same name already exists");
                     } else {
                           Node node = root.getNode(existingNodePath);
                           node.addNode(newNodeName);
                           System.out.println("New Node Inserted as " + existingNodePath + "/" + newNodeName);
                     }
              } else {
                     System.out.println("Warning! Can't ADD new node as node doesn't exists");
              }
       } catch (Exception e) {
              e.printStackTrace();
       }
}
 
2)    Method To Delete Node
 
private static void deleteNode(Node root, String deleteNodePath) {
       try {
              if (root.hasNode(deleteNodePath)) {
                     Node node = root.getNode(deleteNodePath);
                     node.remove();
                     System.out.println("Node " + deleteNodePath + " removed");
              } else {
                     System.out.println("Warning! Can't DELETE as node doesn't exists");
              }
       } catch (Exception e) {
              e.printStackTrace();
       }
}
 
3)    Method To Add Properties To Node
 
private static void addProperties(Node root, String addPropNodePath) {
       try {
              if (root.hasNode(addPropNodePath)) {
                     Node node = root.getNode(addPropNodePath);
                     node.setProperty("jcr:data", 6269);
                     node.setProperty("jcr:mimeType", "image/png");
                     System.out.println("Properties added for node: " + addPropNodePath);
              } else {
                     System.out.println("Warning! Can't ADD Properties as node doesn't exists");
              }
       } catch (Exception e) {
              e.printStackTrace();
       }
}
  
  
4)    Method To Read Property From Node
 
private static void readProperty(Node root, String readPropNodePath) {
       try {
              if (root.hasNode(readPropNodePath)) {
                     Node node = root.getNode(readPropNodePath);
                     System.out.println("jcr:created:::" + node.getProperty("jcr:created").getString());
              } else {
                     System.out.println("Warning! Can't READ Properties as node doesn't exists");
              }
       } catch (Exception e) {
              e.printStackTrace();
       }
}     
 
5)    Method To Read All Properties From Node
 
private static void readProperties(Node root, String nodePath) {
       try {
              if (root.hasNode(nodePath)) {
                     Node node = root.getNode(nodePath);
                     PropertyIterator iter = node.getProperties();
                     while (iter.hasNext()) {
                           Property nextProp = iter.nextProperty();
                           String propertyName = nextProp.getName();
                           System.out.print(propertyName + " : ");
                           Property property = node.getProperty(propertyName);
                           if (!property.isMultiple()) {
                                  String propertyValue = node.getProperty(propertyName).getString();
                                  System.out.println(propertyValue);
                           } else {
                                  Value[] value = property.getValues();
                                  int len = value.length;
                                  for (int i = 0; i < len; i++)
                                         System.out.println(value[i].getString());
                           }
                     }
              } else {
                     System.out.println("Warning! Can't READ properties as path doesn't exists");
              }
       } catch (Exception e) {
              e.printStackTrace();
       }
}
 
 
JCR Properties:
 


Eclipse Output:



6)    Method to Read Child Nodes
private static void readChildNodes(Node root, String nodePath) {
       try {
              if (root.hasNode(nodePath)) {
                     Node node = root.getNode(nodePath);
                     NodeIterator iter = node.getNodes();
                     while (iter.hasNext()) {
                           Node nextNode = iter.nextNode();
                           String absPath = nextNode.getPath();
                           System.out.println(absPath);
                     }
              } else {
                     System.out.println("Warning! Can't READ child nodes as path doesn't exists");
              }
       } catch (Exception e) {
              e.printStackTrace();
       }
}
 
Eclipse Output:
 


7)    Method to Read Page Data from crx in external file

private static void readPageData(Node root, String nodePath, QueryManager queryManager) {
              try {
                     // Creating a object of FileWriter class and defining file path
                     FileWriter fileWriter = new FileWriter("c:/temp/samplefile2.html");
 
                     // Using AEM Query Manager API to query Nodes
                     String sqlStatement = "SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE([" + nodePath + "])";
                     Query query = queryManager.createQuery(sqlStatement, "JCR-SQL2");
 
                     // Execute the query and get the results ...
                     QueryResult result = query.execute();
 
                     // Iterate over the nodes in the results ...
                     NodeIterator nodeIter = result.getNodes();
                     fileWriter.append("<html><body>\n");
                     while (nodeIter.hasNext()) {
                           Node node1 = nodeIter.nextNode();
                           NodeIterator iter1 = node1.getNodes();
                           while (iter1.hasNext()) {
                                  Node nextNode = iter1.nextNode();
                                  String absPath = nextNode.getPath();
 
                                  // System.out.println(absPath);
                                  String modifiedPath = absPath.substring(1);
 
                                  // Code to read node properties
                                  if (root.hasNode(modifiedPath)) {
                                         Node node = root.getNode(modifiedPath);
                                         PropertyIterator iter = node.getProperties();
                                         String childDepth = "childDepth", panelTitle = "cq:panelTitle", fileReference = "fileReference",
                                                       description = "jcr:description", title = "jcr:title", link = "link",
                                                       linkURL = "linkURL", listFrom = "listFrom", navigationRoot = "navigationRoot",
                                                       parentPage = "parentPage", sortOrder = "sortOrder", startLevel = "startLevel",
                                                       structureDepth = "structureDepth", text = "text", type = "type";
                                         while (iter.hasNext()) {
                                                Property nextProp = iter.nextProperty();
                                                String propertyName = nextProp.getName();
                                                if (propertyName.equals(childDepth) || propertyName.equals(panelTitle)
                                                             || propertyName.equals(fileReference) || propertyName.equals(description)
                                                              || propertyName.equals(title) || propertyName.equals(link)
                                                              || propertyName.equals(linkURL) || propertyName.equals(listFrom)
                                                              || propertyName.equals(navigationRoot) || propertyName.equals(parentPage)
                                                              || propertyName.equals(sortOrder) || propertyName.equals(startLevel)
                                                              || propertyName.equals(structureDepth) || propertyName.equals(text)
                                                              || propertyName.equals(type)) {
                                                       System.out.print(propertyName + " : ");
                                                       Property property = node.getProperty(propertyName);
                                                       if (!property.isMultiple()) {
                                                              String propertyValue = node.getProperty(propertyName).getString();
                                                              if (propertyName.equals(fileReference)) {
                                                                     System.out.println("http://localhost:4502" + propertyValue);
                                                                     String test = "http://localhost:4502" + propertyValue;
                                                                     fileWriter.append("<img src=\"");
                                                                     fileWriter.append(test);
                                                                     test = "\" height= \"500\" style=\"width: fit-content\"";
                                                                     fileWriter.append(test);
                                                                     fileWriter.append(">\n");
                                                              } else {
                                                                     System.out.println(propertyValue);
                                                                     fileWriter.append(propertyValue);
                                                                     fileWriter.write(System.getProperty("line.separator"));
                                                              }
                                                       } else {
                                                              Value[] value = property.getValues();
                                                              int len = value.length;
                                                              for (int i = 0; i < len; i++) {
                                                                     System.out.println(value[i].getString());
                                                                     fileWriter.append(value[i].getString());
                                                              }
                                                       }
                                                }
                                         }
                                  } else {
                                         System.out.println("Warning! Can't READ properties as path doesn't exists");
                                  }
                           }
                     }
                     fileWriter.append("</body></html>");
                     fileWriter.close();
              } catch (Exception e) {
                     e.printStackTrace();
              }
}
CRX Node Tree:
 http://localhost:4502/crx/de/index.jsp#/content/we-retail/language-masters/en/about-us
 

Eclipse Console output:



Page Screenshot:




File Output (c:/temp/samplefile2.html):
 
<html><body>
<img src="http://localhost:4502/content/dam/we-retail/en/activities/hiking-camping/trekker-ama-dablam.jpg" height= "500" style="width: fit-content">
Our Stores
h2
Tab 1
New York
Tab 2
San Francisco
San Jose
Store Location WeRetail San Francisco Address 601 Townsend St, San Francisco, CA 94103 Description San Francisco, in northern California, is a hilly city on the tip of a peninsula surrounded by the Pacific Ocean and San Francisco Bay. It's known for its year-round fog, iconic Golden Gate Bridge, cable cars and colorful Victorian houses. The Financial District's Transamerica Pyramid is its most distinctive skyscraper. In the bay sits Alcatraz Island, site of the notorious former prison. Opening Hours Monday 8AM–5PM Tuesday 8AM–5PM Wednesday 8AM–5PM Thursday 8AM–5PM Friday 8AM–5PM Saturday Closed Sunday Closed
Store Location WeRetail San Jose Address 345 Park Ave, San Jose, CA 95110345 Park Ave, San Jose, CA 95110 Description San Jose is a large city surrounded by rolling hills in Silicon Valley, a major technology hub in California's Bay Area. Architectural landmarks, from the 1883 Italianate-style Oddfellows building to Spanish Colonial Revival structures, make up the downtown historic district. The downtown area is also home to the Tech Museum of Innovation, devoted to the exploration of science and technology. Opening Hours Monday 8AM–5PM Tuesday 8AM–5PM Wednesday 8AM–5PM Thursday 8AM–5PM Friday 8AM–5PM Saturday Closed Sunday Closed
Store Location WeRetail New York Address 1540 Broadway, 17th floor New York, NY 10036 Description New York City comprises 5 boroughs sitting where the Hudson River meets the Atlantic Ocean. At its core is Manhattan, a densely populated borough that’s among the world’s major commercial, financial and cultural centers. Its iconic sites include skyscrapers such as the Empire State Building and sprawling Central Park. Broadway theater is staged in neon-lit Times Square. Opening Hours Monday 8AM–5PM Tuesday 8AM–5PM Wednesday 8AM–5PM Thursday 8AM–5PM Friday 8AM–5PM Saturday Closed Sunday Closed
</body></html>
 
8)    Method to read external file data
 
private static void readFileData(String fileName) throws IOException {
       int ch;
       FileReader fr = null;
       try {
              fr = new FileReader(fileName);
       } catch (FileNotFoundException fe) {
              System.out.println("File not found");
       }
       while ((ch = fr.read()) != -1)
              System.out.print((char) ch);
       fr.close();
}
 
 
9)    Method to read Client library data
 
private static void readStylesData(Node root, String filePath, QueryManager queryManager) {
       try {
              String sqlStatement = "SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE([" + filePath + "])";
              Query query = queryManager.createQuery(sqlStatement, "JCR-SQL2");
 
              // Creating a object of FileWriter class and defining file path
              FileWriter cssFileWriter = new FileWriter("c:/temp/styles.css");
              FileWriter jsFileWriter = new FileWriter("c:/temp/styles.js");
 
              // Execute the query and get the results ...
              QueryResult result = query.execute();
 
              // Iterate over the nodes in the results ...
              NodeIterator nodeIter = result.getNodes();
              String dataNode = "jcr:data";
              while (nodeIter.hasNext()) {
                     Node node = nodeIter.nextNode();
                     NodeIterator iter = node.getNodes();
                     PropertyIterator propIter;
                     while (iter.hasNext()) {
                           Node nextNode = iter.nextNode();
                           String absPath = nextNode.getPath();
                           String modifiedPath = absPath.substring(1);
 
                           // Code to read node properties
                           if (root.hasNode(modifiedPath)) {
                                  if (modifiedPath.contains(".css") || modifiedPath.contains(".less")) {
                                          Node node1 = root.getNode(modifiedPath);
                                         propIter = node1.getProperties();
                                         while (propIter.hasNext()) {
                                                Property nextProp = propIter.nextProperty();
                                                String propertyName = nextProp.getName();
                                                if (propertyName.equals(dataNode)) {
                                                       String propertyValue = node1.getProperty(propertyName).getString();
                                                       cssFileWriter.append(propertyValue);
                                                       System.out.println(propertyValue);
                                                }
                                         }
                                  }
                                  if (modifiedPath.contains(".js")) {
                                         Node node1 = root.getNode(modifiedPath);
                                         propIter = node1.getProperties();
                                         while (propIter.hasNext()) {
                                                Property nextProp = propIter.nextProperty();
                                                String propertyName = nextProp.getName();
                                                if (propertyName.equals(dataNode)) {
                                                       String propertyValue = node1.getProperty(propertyName).getString();
                                                       jsFileWriter.append(propertyValue);
                                                       System.out.println(propertyValue);
                                                }
                                         }
                                  }
                           } else {
                                  System.out.println("Warning! Can't READ properties as path doesn't exists");
                           }
                     }
              }
              cssFileWriter.close();
              jsFileWriter.close();
       } catch (Exception e) {
              e.printStackTrace();
       }
}

Styles are stored under client library folder which contains css, less and js files.
To access those files data we have to access following property of jcr:content node and convert that data into string as follows:

String propertyValue = node.getProperty(propertyName).getString();





 

 
10.  Method to read components under project

private static void readcomponentsData(Node root, String filePath, QueryManager queryManager) {
              try {
                     String sqlStatement = "SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE([" + filePath + "])";
                     Query query = queryManager.createQuery(sqlStatement, "JCR-SQL2");
 
                     // Creating a object of FileWriter class and defining file path
                     FileWriter FileWriter = new FileWriter("c:/temp/comp.txt");
 
                     // Execute the query and get the results ...
                     QueryResult result = query.execute();
 
                     // Iterate over the nodes in the results ...
                     NodeIterator nodeIter = result.getNodes();
 
                     String dataNode = "jcr:primaryType";
                     int i=1;
                     while (nodeIter.hasNext()) {
                           Node node = nodeIter.nextNode();
                           NodeIterator iter = node.getNodes();
                           PropertyIterator propIter;
                           while (iter.hasNext()) {
                                  Node nextNode = iter.nextNode();
                                  String absPath = nextNode.getPath();
                                  String modifiedPath = absPath.substring(1);
                                  // Code to read node properties
                                  if (root.hasNode(modifiedPath)) {
                                         Node node1 = root.getNode(modifiedPath);
                                         propIter = node1.getProperties();
                                         while (propIter.hasNext()) {
                                                Property nextProp = propIter.nextProperty();
                                                String propertyName = nextProp.getName();
                                                if (propertyName.equals(dataNode)) {
                                                       String propertyValue = node1.getProperty(propertyName).getString();
                                                       if (propertyValue.equals("cq:Component")) {                                                             
                                                              FileWriter.append(i+") "+absPath+"\n");
                                                              System.out.println(i+") "+absPath);
                                                              i++;
                                                       }
                                                }
                                         }
                                  } else {
                                         System.out.println("Warning! Can't READ properties as path doesn't exists");
                                  }
                           }
                     }
                     FileWriter.close();
              } catch (Exception e) {
                     e.printStackTrace();
              }
       }

Console output:




Step 5: Logging Out From Current Session
// Save the session changes and log out
session.save();

   session.logout();