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

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
  6. Adapt "path" and "depth" to what part of the repository you want to look at
  7. Hit "Execute"

Example output

/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) + ", ");
}
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