Groovy script to insert jcr:Content node at folder level | Community
Skip to main content
Level 3
February 7, 2025
Solved

Groovy script to insert jcr:Content node at folder level

  • February 7, 2025
  • 4 replies
  • 947 views

Hi, after running Best Practices Analyzer tool, we have found lot of issues with " is missing mandatory 'jcr:content' child node." in some of our folders. how to fix this issue? i know a groovy script can be used, but any other ways?

with groovy script can we insert an empty jcr:content node to fix the issue? if yes, any code snipped to help achieve this?

thank

 

I went through https://github.com/hashimkhan786/aem-groovy-scripts , but couldn't find any script to help in the direction iam looking for

Best answer by Shiv_Prakash_Patel

Hey @asp_corp ,

Yes, a Groovy script can be used to fix this issue efficiently. Below is a Groovy script that recursively scans and adds the missing jcr:content nodes to cq:Page under a given path. Similarly, you can update for other node primary types.

import com.day.cq.commons.jcr.JcrUtil import javax.jcr.* def session = resourceResolver.adaptTo(Session) def rootPath = "/content/we-retail/it" // Change this to the desired root path def processNode(node) { if (!node.hasNode("jcr:content")) { def contentNode = node.addNode("jcr:content", "nt:unstructured") contentNode.setProperty("createdBy", session.getUserID()) contentNode.setProperty("createdDate", Calendar.getInstance()) println "Added missing jcr:content node at: ${node.path}" } } // Recursively scan folders and add missing jcr:content nodes def scanAndFixMissingContentNodes(node) { if (node.isNodeType("cq:Page")) { //Use other condition to handle the allowed primanryType to add child jcr:content processNode(node) } def nodeIterator = node.getNodes() while (nodeIterator.hasNext()) { scanAndFixMissingContentNodes(nodeIterator.nextNode()) } } def rootNode = session.getNode(rootPath) scanAndFixMissingContentNodes(rootNode) session.save() println "Completed processing for missing jcr:content nodes."

Regards,

4 replies

Shiv_Prakash_Patel
Community Advisor
Shiv_Prakash_PatelCommunity AdvisorAccepted solution
Community Advisor
February 8, 2025

Hey @asp_corp ,

Yes, a Groovy script can be used to fix this issue efficiently. Below is a Groovy script that recursively scans and adds the missing jcr:content nodes to cq:Page under a given path. Similarly, you can update for other node primary types.

import com.day.cq.commons.jcr.JcrUtil import javax.jcr.* def session = resourceResolver.adaptTo(Session) def rootPath = "/content/we-retail/it" // Change this to the desired root path def processNode(node) { if (!node.hasNode("jcr:content")) { def contentNode = node.addNode("jcr:content", "nt:unstructured") contentNode.setProperty("createdBy", session.getUserID()) contentNode.setProperty("createdDate", Calendar.getInstance()) println "Added missing jcr:content node at: ${node.path}" } } // Recursively scan folders and add missing jcr:content nodes def scanAndFixMissingContentNodes(node) { if (node.isNodeType("cq:Page")) { //Use other condition to handle the allowed primanryType to add child jcr:content processNode(node) } def nodeIterator = node.getNodes() while (nodeIterator.hasNext()) { scanAndFixMissingContentNodes(nodeIterator.nextNode()) } } def rootNode = session.getNode(rootPath) scanAndFixMissingContentNodes(rootNode) session.save() println "Completed processing for missing jcr:content nodes."

Regards,

Shiv Prakash
Uppari_Ramesh
Level 5
February 10, 2025

@asp_corp  by any chance folders are indexed and if jcr:content nodes are missing in multiple paths where each path contains huge data then better to go with (SQL2 query + groovy script) instead of iterating the nodes in groovy script . To avoid putting a check for each node and checking if is a folder and then folder has node jcr:content, you can directly write a SQL2 query  which will directly give you the folders which doesn't have jcr:content nodes. Sample code is 

import javax.jcr.Session import javax.jcr.query.Query import javax.jcr.query.QueryManager import javax.jcr.query.QueryResult def session = resourceResolver.adaptTo(Session.class)//get resolver first and then session def queryManager = session.workspace.queryManager// get query manager def folderPath = "/path/to/your/folder" // Replace with your folder path // SQL2 query to find folders missing jcr:content nodes def sql2Query = """ SELECT * FROM [nt:folder] AS folder WHERE ISDESCENDANTNODE(folder, '${folderPath}') AND NOT EXISTS (SELECT * FROM [nt:base] AS content WHERE ISCHILDNODE(content, folder) AND NAME(content) = 'jcr:content') """ //You can try below query in above sql2Query variable: SELECT * FROM [nt:folder] AS folder WHERE ISDESCENDANTNODE(folder, '/path/to/your/folder') AND folder.[jcr:content/jcr:primaryType] IS NULL def query = queryManager.createQuery(sql2Query, Query.JCR_SQL2) def result = query.execute() result.nodes.each { node -> def folderNode = node if (!folderNode.hasNode("jcr:content")) { def jcrContentNode = folderNode.addNode("jcr:content", "nt:unstructured") jcrContentNode.setProperty("jcr:primaryType", "nt:unstructured") session.save() println "Added jcr:content node to ${folderNode.path}" } }

 

Thanks

Ramesh

ASP_CorpAuthor
Level 3
February 12, 2025

Hi Ramesh,

thanks for the help. the query 

SELECT * FROM [nt:folder] AS folder
WHERE ISDESCENDANTNODE(folder, '/path/to/your/folder')
AND folder.[jcr:content/jcr:primaryType] IS NULL

is giving out a lot of results and along with the folders it is giving the renditions too. for e.g it gives /content/dam/_folder and also /content/dam/_CSS/_OOTB/AudioCaptionsButton_sprite.png/jcr:content/renditions ..etc...we are expecting 345 results from the BPA but the query is giving around 60000 results

kautuk_sahni
Community Manager
Community Manager
February 18, 2025

@asp_corp Did you find the suggestion helpful? Please let us know if you need more information. If a response worked, kindly mark it as correct for posterity; alternatively, if you found a solution yourself, we’d appreciate it if you could share it with the community. Thank you!

Kautuk Sahni
kautuk_sahni
Community Manager
Community Manager
February 18, 2025

@asp_corp Did you find the suggestions helpful? Please let us know if you need more information. If a response worked, kindly mark it as correct for posterity; alternatively, if you found a solution yourself, we’d appreciate it if you could share it with the community. Thank you!

Kautuk Sahni