Recursive search in JCR repository via java

I know how to search for something in JCR through SQL2 JCR Queries .

However, I would like to use Java in some cases using the JCR API : javax.jcr.Node , javax.jcr.NodeIterator and the like.

I’m afraid that I’ll just reinvent the wheel by encoding it.

Is there anything already available ( Gist , Github or else )?

+1
source share
3 answers

You can use SlingQuery for this. It is inspired by jQuery and follows the syntax. You should only use it to search for a small number of nodes (at best, less than 100), since workarounds are slow.

Edit

Your example can be converted to the following SlingQueries (not verified):

 SlingQuery.$(startResource).find("[name=teasers][title=awesome-teaser]") SlingQuery.$(startResource).find("[name][controlName]") 

SlingQuery has been part of Apache Sling ever since the github repository seems to be abandoned.

Note. You can statically import the dollar sign and refuse static access to SlingQuery in syntax such as $ (resource) .find ("...");

+2
source

I ended up writing my own implementations.

Feel free to improve or add comments for potential improvements.


Additional Information

Java is probably NOT the most efficient way to search through JCR, so be aware of performance (vs using JCR SQL2 ).

However, there are times when using JCR SQL2 will be quite annoying. For example: JCR SQL2 - the order of the query result, as in the JCR browser

I would recommend starting the search as little as possible in the tree.


Decision

Read the comments above each method to find more.

 package com.nameoforganization.jcr; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class JcrSearchUtils { private static final Logger log = LoggerFactory.getLogger(JcrUtil.class); /* * Recursive search in JCR tree: properties matching values * Parameters: * - node: node to start the search from * - propertyValueConditions: properties searched along with the value expected for it * - searchResults: set this to null when launching the search */ public static ArrayList<Node> searchRecursivelyPropMatchVal(Node node, HashMap<String, String> propertyValueConditions, ArrayList<Node> searchResults) { if(searchResults == null){ searchResults = new ArrayList<Node>(); } try{ NodeIterator list = node.getNodes(); while(list.hasNext()) { Node currentSubNode = list.nextNode(); Boolean hasAllRequiredPropsAndVals = true; for (Map.Entry<String, String> entry : propertyValueConditions.entrySet()) { String propertyName = entry.getKey(); Object searchedValue = entry.getValue(); if ( !currentSubNode.hasProperty(propertyName) || !currentSubNode.getProperty(propertyName).getString().equals(searchedValue) ){ hasAllRequiredPropsAndVals = false; } } if ( hasAllRequiredPropsAndVals ){ searchResults.add(currentSubNode); } searchRecursivelyPropMatchVal(currentSubNode, propertyValueConditions, searchResults); } return searchResults; } catch (RepositoryException rpe){ log.info("Recursive search in JCR tree (properties matching values) via JCR API failed"); } return null; } /* * Recursive search in JCR tree: required properties present * Parameters: * - node: node to start the search from * - propertyValueConditions: properties searched along with the value expected for it * - searchResults: set this to null when launching the search */ public static ArrayList<Node> searchRecursivelyPropPres(Node node, ArrayList<String> propertyPresConditions, ArrayList<Node> searchResults) { if(searchResults == null){ searchResults = new ArrayList<Node>(); } try{ NodeIterator list = node.getNodes(); while(list.hasNext()) { Node currentSubNode = list.nextNode(); Boolean hasAllRequiredProperties = true; for (String propertyName : propertyPresConditions) { if ( !currentSubNode.hasProperty(propertyName) ){ hasAllRequiredProperties = false; } } if( hasAllRequiredProperties ){ searchResults.add(currentSubNode); } searchRecursivelyPropPres(currentSubNode, propertyPresConditions, searchResults); } return searchResults; } catch (RepositoryException rpe){ log.info("Recursive search in JCR tree (required properties present) via JCR API failed"); } return null; } } 

Using the first utility method

  /* * Search nodes with properties: * "name" having value "teasers" * "title" having value "awesome-teaser" */ // Node startingNode = set this yourself :) HashMap<String, String> propertyValueConditions = new HashMap<String, String>(); propertyValueConditions.put("name", "teasers"); propertyValueConditions.put("title", "awesome-teaser"); ArrayList<Node> nodesFound = JcrUtil.searchRecursivelyPropMatchVal(startingNode, propertyValueConditions, null); 

Using the second utility method

  /* * Search nodes having properties "name" and "controlName" */ // Node startingNode = set this yourself :) ArrayList<String> propertyPresConditions = new ArrayList<String>(); propertyPresConditions.add("name"); propertyPresConditions.add("controlName"); ArrayList<Node> nodesFound = JcrUtil.searchRecursivelyPropPres(startingNode, propertyPresConditions, null); 

Resources:

+1
source

You can use ItemVisitor to recursively go through the repository, collecting all items matching your criteria along the way.

eg. print all properties of type Long :

 Node root = session.getRootNode(); root.accept(new ItemVisitor() { @Override public void visit(Property property) throws RepositoryException { if (!property.isMultiple() && property.getType() == PropertyType.LONG) { System.out.println(property.getName() + " = " + property.getLong()); } } @Override public void visit(Node node1) throws RepositoryException { NodeIterator children = node1.getNodes(); while (children.hasNext()) { visit(children.nextNode()); } } }); 
+1
source

Source: https://habr.com/ru/post/1485000/


All Articles