Skip to content

Instantly share code, notes, and snippets.

@alexkli
Last active June 25, 2024 16:30
Show Gist options
  • Save alexkli/fe955b1d651e68b2a01db24be31c844f to your computer and use it in GitHub Desktop.
Save alexkli/fe955b1d651e68b2a01db24be31c844f to your computer and use it in GitHub Desktop.
Groovy script for displaying hidden Oak content structures
// --------------------------------------------------------------
// change these input values
// path: what oak path to show
def path = "/oak:index/nodetype/:index";
// depth: how deep the tree structure should be rendered
def depth = 2;
// --------------------------------------------------------------
import org.apache.sling.jcr.api.SlingRepository
import javax.jcr.Session
import org.apache.jackrabbit.oak.api.Type
import org.apache.jackrabbit.oak.spi.state.NodeStateUtils
showTree(sling, out, path, depth);
static def showTree(sling, out, path, depth) {
SlingRepository repo = sling.getService(SlingRepository.class)
Session session = null
try {
session = repo.loginAdministrative(null);
def cs = getOakContentSession(session);
def p = new IndentPrinter(out)
def rootNode = cs.latestRoot.getTree("/").nodeState;
def node = NodeStateUtils.getNode(rootNode, path);
if (node.exists()) {
out.println(path);
renderNode(node, p, depth);
} else {
out.println("Path not found: " + path)
}
} finally {
session?.logout()
}
}
static def renderNode(node, p, depth) {
p.incrementIndent();
node.properties.each { prop ->
p.printIndent()
if (prop.isArray()) {
p.print("- " + prop.name + " = [");
for (def i = 0; i < prop.count(); i++) {
p.print(prop.getValue(Type.STRING, i) + ", ");
}
p.println("]")
} else {
p.println("- " + prop.name + " = " + prop.getValue(Type.STRING))
}
}
node.childNodeEntries.each { child ->
p.printIndent()
if (depth == 0) {
p.println("+ " + child.name + " (...)")
} else {
p.println("+ " + child.name)
renderNode(child.nodeState, p, depth - 1)
}
}
p.decrementIndent();
}
// get oak ContentSession via reflection
static def getOakContentSession(Session session) {
def obj1 = java.lang.reflect.Proxy.getInvocationHandler(session).delegatee;
def field = obj1.class.superclass.getDeclaredField("sd");
field.setAccessible(true);
def obj2 = field.get(obj1);
field = obj2.class.superclass.getDeclaredField("contentSession");
field.setAccessible(true);
return field.get(obj2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment