summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelog2
-rw-r--r--debug.conf1
-rw-r--r--org/freedesktop/dbus/AbstractConnection.java65
-rw-r--r--org/freedesktop/dbus/test/test.java7
4 files changed, 73 insertions, 2 deletions
diff --git a/changelog b/changelog
index 4e68933..6a9c161 100644
--- a/changelog
+++ b/changelog
@@ -7,6 +7,8 @@ Version 2.4:
(pointed out by Serkan Kaba <serkan_kaba -at- yahoo -dot- com>)
* Automatically unexport objects which go out of scope in the
parent program (don't hold a strong reference).
+ * Add fallback objects---a single object can be called for any
+ object under a given path prefix.
Version 2.3.2:
diff --git a/debug.conf b/debug.conf
index 272642a..6843191 100644
--- a/debug.conf
+++ b/debug.conf
@@ -4,6 +4,7 @@ org.freedesktop.dbus.Message = ERR
org.freedesktop.dbus.MethodCall = ERR
org.freedesktop.dbus.MethodTuple = ERR
org.freedesktop.dbus.AbstractConnection = VERBOSE
+org.freedesktop.dbus.AbstractConnection$FallbackContainer = VERBOSE
org.freedesktop.dbus.AbstractConnection$_thread = ERR
org.freedesktop.dbus.AbstractConnection$_sender = ERR
org.freedesktop.dbus.DirectConnection = ERR
diff --git a/org/freedesktop/dbus/AbstractConnection.java b/org/freedesktop/dbus/AbstractConnection.java
index 6d45c69..2a9b74c 100644
--- a/org/freedesktop/dbus/AbstractConnection.java
+++ b/org/freedesktop/dbus/AbstractConnection.java
@@ -41,6 +41,37 @@ import cx.ath.matthew.debug.Debug;
*/
public abstract class AbstractConnection
{
+ protected class FallbackContainer
+ {
+ private Map<String[], ExportedObject> fallbacks = new HashMap<String[], ExportedObject>();
+ public synchronized void add(String path, ExportedObject eo)
+ {
+ if (Debug.debug) Debug.print(Debug.DEBUG, "Adding fallback on "+path+" of "+eo);
+ fallbacks.put(path.split("/"), eo);
+ }
+ public synchronized void remove(String path)
+ {
+ if (Debug.debug) Debug.print(Debug.DEBUG, "Removing fallback on "+path);
+ fallbacks.remove(path.split("/"));
+ }
+ public synchronized ExportedObject get(String path)
+ {
+ int best = 0;
+ int i = 0;
+ ExportedObject bestobject = null;
+ String[] pathel = path.split("/");
+ for (String[] fbpath: fallbacks.keySet()) {
+ if (Debug.debug) Debug.print(Debug.VERBOSE, "Trying fallback path "+Arrays.deepToString(fbpath)+" to match "+Arrays.deepToString(pathel));
+ for (i = 0; i < pathel.length && i < fbpath.length; i++)
+ if (!pathel[i].equals(fbpath[i])) break;
+ if (i > 0 && i == fbpath.length && i > best)
+ bestobject = fallbacks.get(fbpath);
+ if (Debug.debug) Debug.print(Debug.VERBOSE, "Matches "+i+" bestobject now "+bestobject);
+ }
+ if (Debug.debug) Debug.print(Debug.DEBUG, "Found fallback for "+path+" of "+bestobject);
+ return bestobject;
+ }
+ }
protected class _thread extends Thread
{
public _thread()
@@ -199,6 +230,7 @@ public abstract class AbstractConnection
protected Map<MethodCall, DBusAsyncReply> pendingCallbackReplys;
protected LinkedList<Runnable> runnables;
protected LinkedList<_workerthread> workers;
+ protected FallbackContainer fallbackcontainer;
protected boolean _run;
EfficientQueue outgoing;
LinkedList<Error> pendingErrors;
@@ -250,6 +282,7 @@ public abstract class AbstractConnection
runnables = new LinkedList<Runnable>();
workers = new LinkedList<_workerthread>();
objectTree = new ObjectTree();
+ fallbackcontainer = new FallbackContainer();
synchronized (workers) {
for (int i = 0; i < THREADCOUNT; i++) {
_workerthread t = new _workerthread();
@@ -333,7 +366,7 @@ public abstract class AbstractConnection
/**
* Export an object so that its methods can be called on DBus.
- * @param objectpath The path to the object we are exposing. MUST be in slash-notation, like "org/freedesktop/Local",
+ * @param objectpath The path to the object we are exposing. MUST be in slash-notation, like "/org/freedesktop/Local",
* and SHOULD end with a capitalised term. Only one object may be exposed on each path at any one time, but an object
* may be exposed on several paths at once.
* @param object The object to export.
@@ -355,6 +388,32 @@ public abstract class AbstractConnection
}
}
/**
+ * Export an object as a fallback object.
+ * This object will have it's methods invoked for all paths starting
+ * with this object path.
+ * @param objectprefix The path below which the fallback handles calls.
+ * MUST be in slash-notation, like "/org/freedesktop/Local",
+ * @param object The object to export.
+ * @throws DBusException If the objectpath is incorrectly formatted,
+ */
+ public void addFallback(String objectprefix, DBusInterface object) throws DBusException
+ {
+ if (null == objectprefix || "".equals(objectprefix))
+ throw new DBusException("Must Specify an Object Path");
+ if (!objectprefix.matches(OBJECT_REGEX)||objectprefix.length() > MAX_NAME_LENGTH)
+ throw new DBusException("Invalid object path ("+objectprefix+")");
+ ExportedObject eo = new ExportedObject(object);
+ fallbackcontainer.add(objectprefix, eo);
+ }
+ /**
+ * Remove a fallback
+ * @param objectprefix The prefix to remove the fallback for.
+ */
+ public void removeFallback(String objectprefix)
+ {
+ fallbackcontainer.remove(objectprefix);
+ }
+ /**
* Stop Exporting an object
* @param objectpath The objectpath to stop exporting.
*/
@@ -632,6 +691,10 @@ public abstract class AbstractConnection
}
if (null == eo) {
+ eo = fallbackcontainer.get(m.getPath());
+ }
+
+ if (null == eo) {
try {
queueOutgoing(new Error(m, new DBus.Error.UnknownObject(m.getPath()+" is not an object provided by this process.")));
} catch (DBusException DBe) {}
diff --git a/org/freedesktop/dbus/test/test.java b/org/freedesktop/dbus/test/test.java
index 2eb16bd..e2dad6c 100644
--- a/org/freedesktop/dbus/test/test.java
+++ b/org/freedesktop/dbus/test/test.java
@@ -453,6 +453,7 @@ public class test
serverconn.exportObject("/Test", tclass);
serverconn.exportObject("/BadTest", tclass);
serverconn.exportObject("/BadTest2", tclass2);
+ serverconn.addFallback("/FallbackTest", tclass);
// explicitly unexport object
serverconn.unExportObject("/BadTest");
@@ -609,7 +610,11 @@ public class test
System.out.println("Remote Method Failed with: "+UO.getClass().getName()+" "+UO.getMessage());
}
- System.out.println("Calling Method5--8");
+ System.out.println("Calling Method6");
+ tri = clientconn.getRemoteObject("foo.bar.Test", "/FallbackTest/0/1", TestRemoteInterface.class);
+ System.out.println("Got Fallback Name: "+tri.getName());
+
+ System.out.println("Calling Method7--9");
/** This gets a remote object matching our bus name and exported object path. */
TestRemoteInterface2 tri2 = clientconn.getRemoteObject("foo.bar.Test", "/Test", TestRemoteInterface2.class);
System.out.print("Calling the other introspect method: ");