Skip to content

Instantly share code, notes, and snippets.

@alexkli
Last active March 12, 2022 15:42
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • 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

This is a Groovy script that allows to render hidden Oak content structures within the Sling script console on a running Oak/Sling system. This is useful for inspecting the oak:index structures for examples. Hidden nodes in Oak start with ":".

Instructions

  1. Install Sling Script Console bundle
  2. Install Groovy Bundle
  3. Go to http://localhost:4502/system/console/scriptconsole
  4. Ensure "Groovy" is selected as language
  5. Copy & paste oak-browse-tree.groovy from this gist
  6. Adapt "path" and "depth" to what part of the repository you want to look at
  7. Hit "Execute"

Example output

Note: (...) after a node name indicates the depth limit stopped here.

/var
  - jcr:primaryType = sling:Folder
  - jcr:mixinTypes = [rep:AccessControllable]
  - jcr:createdBy = admin
  - jcr:created = 2013-07-08T13:25:36.725-04:00
  + discovery
    - jcr:primaryType = sling:Folder
    - jcr:createdBy = admin
    - jcr:created = 2015-01-31T04:02:42.262Z
    + oak
      - jcr:primaryType = sling:Folder
      - jcr:createdBy = admin
      - jcr:created = 2016-12-16T13:28:38.239Z
      - sling:resourceType = sling:Folder
      + idMap (...)
      + clusterInstances (...)
      + syncTokens (...)
    + impl
      - jcr:primaryType = sling:Folder
      - jcr:createdBy = admin
      - jcr:created = 2015-01-31T04:02:42.263Z
      + establishedView (...)
      + ongoingVotings (...)
      + previousView (...)
      + clusterInstances (...)
// --------------------------------------------------------------
// 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 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) {
def p = new IndentPrinter(out)
def repo = sling.getService(SlingRepository.class)
def session = null
try {
session = repo.loginAdministrative(null);
def cs = getOakContentSession(session);
def rootNode = cs.latestRoot.getTree("/").nodeState;
def node = NodeStateUtils.getNode(rootNode, path);
if (node.exists()) {
p.println(path);
renderNode(node, p, depth);
} else {
p.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));
if (i < prop.count() - 1) {
p.print(", ");
}
}
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) {
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