diff options
author | Matthew Johnson <mjj29@hecate.matthew.ath.cx> | 2007-12-02 20:12:45 +0000 |
---|---|---|
committer | Matthew Johnson <mjj29@hecate.matthew.ath.cx> | 2007-12-02 20:12:45 +0000 |
commit | 6f338b55f673f4bc30dcb665576e11185ab23932 (patch) | |
tree | 9901836fba76e5623d9e3df256daa2bc0243a551 | |
parent | 0c7a8b7a43d9d81809808a90c5a8574a6040ac69 (diff) |
add fallback objects
-rw-r--r-- | changelog | 2 | ||||
-rw-r--r-- | debug.conf | 1 | ||||
-rw-r--r-- | org/freedesktop/dbus/AbstractConnection.java | 65 | ||||
-rw-r--r-- | org/freedesktop/dbus/test/test.java | 7 |
4 files changed, 73 insertions, 2 deletions
@@ -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: @@ -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: "); |