/* D-Bus Java Implementation Copyright (c) 2005-2006 Matthew Johnson This program is free software; you can redistribute it and/or modify it under the terms of either the GNU Lesser General Public License Version 2 or the Academic Free Licence Version 2.1. Full licence texts are included in the COPYING file with this program. */ package org.freedesktop.dbus; import cx.ath.matthew.debug.Debug; import java.util.regex.Pattern; /** * Keeps track of the exported objects for introspection data */ class ObjectTree { class TreeNode { String name; ExportedObject object; String data; TreeNode right; TreeNode down; public TreeNode(String name) { this.name = name; } public TreeNode(String name, ExportedObject object, String data) { this.name = name; this.object = object; this.data = data; } } private TreeNode root; public ObjectTree() { root = new TreeNode(""); } public static final Pattern slashpattern = Pattern.compile("/"); private TreeNode recursiveFind(TreeNode current, String path) { if ("/".equals(path)) return current; String[] elements = path.split("/", 2); // this is us or a parent node if (path.startsWith(current.name)) { // this is us if (path.equals(current.name)) { return current; } // recurse down else { if (current.down == null) return null; else return recursiveFind(current.down, elements[1]); } } else if (current.right == null) { return null; } else if (0 > current.right.name.compareTo(elements[0])) { return null; } // recurse right else { return recursiveFind(current.right, path); } } private TreeNode recursiveAdd(TreeNode current, String path, ExportedObject object, String data) { String[] elements = slashpattern.split(path, 2); // this is us or a parent node if (path.startsWith(current.name)) { // this is us if (1 == elements.length || "".equals(elements[1])) { current.object = object; current.data = data; } // recurse down else { if (current.down == null) { String[] el = elements[1].split("/", 2); current.down = new TreeNode(el[0]); } current.down = recursiveAdd(current.down, elements[1], object, data); } } // need to create a new sub-tree on the end else if (current.right == null) { current.right = new TreeNode(elements[0]); current.right = recursiveAdd(current.right, path, object, data); } // need to insert here else if (0 > current.right.name.compareTo(elements[0])) { TreeNode t = new TreeNode(elements[0]); t.right = current.right; current.right = t; current.right = recursiveAdd(current.right, path, object, data); } // recurse right else { current.right = recursiveAdd(current.right, path, object, data); } return current; } public void add(String path, ExportedObject object, String data) { if (Debug.debug) Debug.print(Debug.DEBUG, "Adding " + path + " to object tree"); root = recursiveAdd(root, path, object, data); } public void remove(String path) { if (Debug.debug) Debug.print(Debug.DEBUG, "Removing " + path + " from object tree"); TreeNode t = recursiveFind(root, path); t.object = null; t.data = null; } public String Introspect(String path) { TreeNode t = recursiveFind(root, path); if (null == t) return null; StringBuilder sb = new StringBuilder(); sb.append("<node name=\""); sb.append(path); sb.append("\">\n"); if (null != t.data) sb.append(t.data); t = t.down; while (null != t) { sb.append("<node name=\""); sb.append(t.name); sb.append("\"/>\n"); t = t.right; } sb.append("</node>"); return sb.toString(); } private String recursivePrint(TreeNode current) { String s = ""; if (null != current) { s += current.name; if (null != current.object) s += "*"; if (null != current.down) s += "/{" + recursivePrint(current.down) + "}"; if (null != current.right) s += ", " + recursivePrint(current.right); } return s; } public String toString() { return recursivePrint(root); } }