DevOps
System Administrator
Jahia 8.2
How to retrieve nodes thanks to a Groovy script and modify one of the properties?
Question
I'd like to retrieve nodes of a specific type and modify a property. How can I do that with a Groovy script?
Answer
Let's take an example: we want to set the value of the property j:alternateText when it's empty/missing for the nodes having the type jnt:imageReferenceLink:
import org.jahia.api.Constants
import org.jahia.services.content.JCRContentUtils
import org.jahia.services.content.JCRNodeWrapper
import org.jahia.services.content.JCRSessionWrapper
import org.jahia.services.content.JCRTemplate
import org.jahia.services.query.ScrollableQueryCallback
import org.jahia.services.usermanager.JahiaUserManagerService
import org.jahia.services.query.ScrollableQuery
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import javax.jcr.ItemNotFoundException
import javax.jcr.NodeIterator
import javax.jcr.RepositoryException
import javax.jcr.query.Query
import javax.jcr.query.QueryResult
final Logger logger = LoggerFactory.getLogger("org.jahia.tools.groovyConsole")
private static Query getQuery(JCRSessionWrapper session, String nodeType, String propertyName) {
String textQuery = "SELECT * FROM [" + nodeType + "] AS node WHERE [" + propertyName + "] IS NULL order by [jcr:uuid] asc"
Query query = session.getWorkspace().getQueryManager().createQuery(textQuery, Query.JCR_SQL2)
return query
}
private static int handleNodes(JCRSessionWrapper session, QueryResult stepResult, Logger logger, String propertyName)
throws RepositoryException {
logger.info("Manage next {} nodes", JCRContentUtils.size(stepResult.getRows()))
long timer = System.currentTimeMillis()
NodeIterator nodeIterator = stepResult.getNodes()
Integer numberUpdated = 0
while (nodeIterator.hasNext()) {
JCRNodeWrapper node = (JCRNodeWrapper) nodeIterator.nextNode()
node.setProperty(propertyName, "XXXXXXXXXXXXXXXX");
numberUpdated++;
}
session.save()
session.refresh(false)
logger.info("Took {}ms to update {} nodes in default", System.currentTimeMillis() - timer, numberUpdated)
return numberUpdated
}
private void modifyNodes(Integer pageSize, Logger logger, String nodeType, String propertyName, String workspace, Locale locale, Closure handler) {
logger.info("---------------------------------------")
logger.info("Update nodes of type {} in the {} workspace", nodeType, workspace)
logger.info("---------------------------------------")
Integer numberUpdated = JCRTemplate.getInstance()
.doExecuteWithSystemSessionAsUser(JahiaUserManagerService.getInstance().lookupRootUser().getJahiaUser(),
workspace, locale, session -> {
try {
ScrollableQuery scrollableQuery = new ScrollableQuery(pageSize, getQuery(session, nodeType, propertyName))
return scrollableQuery.execute(new ScrollableQueryCallback<Integer>() {
Integer result = 0
@Override
boolean scroll() throws RepositoryException {
result += handler(session, stepResult, logger, propertyName)
return true
}
@Override
protected Integer getResult() {
return result
}
})
} catch (RepositoryException e) {
logger.error("Failed to modify nodes: ", e)
}
})
logger.info("{} nodes updated while checking {} workspace", numberUpdated, workspace)
}
Integer pageSize = 1000
modifyNodes(pageSize, logger, "jnt:imageReferenceLink", "j:alternateText", Constants.EDIT_WORKSPACE, Locale.ENGLISH, this::handleNodes)