/*
* 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 java.util.regex.Pattern;
/**
* Keeps track of the exported objects for introspection data
*/
class ObjectTree {
class TreeNode {
String data;
TreeNode down;
String name;
ExportedObject object;
TreeNode right;
public TreeNode(String name) {
this.name = name;
}
public TreeNode(String name, ExportedObject object, String data) {
this.name = name;
this.object = object;
this.data = data;
}
}
public static final Pattern slashpattern = Pattern.compile("/");
private TreeNode root;
public ObjectTree() {
root = new TreeNode("");
}
public void add(String path, ExportedObject object, String data) {
root = recursiveAdd(root, path, object, data);
}
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 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;
}
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 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 void remove(String path) {
TreeNode t = recursiveFind(root, path);
t.object = null;
t.data = null;
}
@Override
public String toString() {
return recursivePrint(root);
}
}
|