Skip to content

Commit fef9b2f

Browse files
committed
Issue #163: Applied patch provided by brettsmith
1 parent 2ecfcb0 commit fef9b2f

File tree

4 files changed

+113
-54
lines changed

4 files changed

+113
-54
lines changed

dbus-java-core/src/main/java/org/freedesktop/dbus/Marshalling.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ static Object deSerializeParameter(Object _parameter, Type _type, AbstractConnec
493493
// its an object path, get/create the proxy
494494
if (_parameter instanceof ObjectPath) {
495495
if (_type instanceof Class && DBusInterface.class.isAssignableFrom((Class<?>) _type)) {
496-
_parameter = _conn.getExportedObject(((ObjectPath) _parameter).getSource(), ((ObjectPath) _parameter).getPath());
496+
_parameter = _conn.getExportedObject(((ObjectPath) _parameter).getSource(), ((ObjectPath) _parameter).getPath(), (Class<DBusInterface>)_type);
497497
} else {
498498
_parameter = new DBusPath(((ObjectPath) _parameter).getPath());
499499
}

dbus-java-core/src/main/java/org/freedesktop/dbus/connections/AbstractConnection.java

+21
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,29 @@ protected AbstractConnection(String _address, int _timeout, ReceivingServiceConf
151151
}
152152
}
153153

154+
/**
155+
* Retrieves an remote object using source and path.
156+
* Will try to find suitable exported DBusInterface automatically.
157+
*
158+
* @param _source source
159+
* @param _path path
160+
*
161+
* @return {@link DBusInterface} compatible object
162+
*/
154163
public abstract DBusInterface getExportedObject(String _source, String _path) throws DBusException;
155164

165+
/**
166+
* Retrieves an remote object using source and path.
167+
* Will use the given type as object class.
168+
*
169+
* @param _source source
170+
* @param _path path
171+
* @param _type class of remote object
172+
*
173+
* @return {@link DBusInterface} compatible object
174+
*/
175+
public abstract <T extends DBusInterface> T getExportedObject(String _source, String _path, Class<T> _type) throws DBusException;
176+
156177
/**
157178
* Remove a match rule with the given {@link DBusSigHandler}.
158179
* The rule will only be removed from DBus if no other additional handlers are registered to the same rule.

dbus-java-core/src/main/java/org/freedesktop/dbus/connections/impl/DBusConnection.java

+56-30
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,22 @@ void connect(boolean _registerSelf) throws DBusException {
259259
}
260260
}
261261

262-
protected DBusInterface dynamicProxy(String _source, String _path) throws DBusException {
262+
/**
263+
* Tries to resolve a proxy to a remote object.
264+
* If a type class is given, it tries to convert the object using that class.
265+
* If null is given as type, it tries to find a proper interface for this object.
266+
*
267+
* @param <T> object type (DBusInterface compatible)
268+
* @param _source source
269+
* @param _path path
270+
* @param _type class of object type
271+
*
272+
* @return DBusInterface compatible object
273+
*
274+
* @throws DBusException when something goes wrong
275+
*/
276+
@SuppressWarnings("unchecked")
277+
protected <T extends DBusInterface> T dynamicProxy(String _source, String _path, Class<T> _type) throws DBusException {
263278
logger.debug("Introspecting {} on {} for dynamic proxy creation", _path, _source);
264279
try {
265280
Introspectable intro = getRemoteObject(_source, _path, Introspectable.class);
@@ -278,39 +293,44 @@ protected DBusInterface dynamicProxy(String _source, String _path) throws DBusEx
278293
})
279294
.collect(Collectors.toList());
280295
List<Class<?>> ifcs = new ArrayList<>();
281-
for (String iface : ifaces) {
282-
283-
logger.debug("Trying interface {}", iface);
284-
int j = 0;
285-
while (j >= 0) {
286-
try {
287-
Class<?> ifclass = Class.forName(iface);
288-
if (!ifcs.contains(ifclass)) {
289-
ifcs.add(ifclass);
290-
}
291-
break;
292-
} catch (Exception _ex) {
293-
}
294-
j = iface.lastIndexOf('.');
295-
char[] cs = iface.toCharArray();
296-
if (j >= 0) {
297-
cs[j] = '$';
298-
iface = String.valueOf(cs);
299-
}
300-
}
296+
if(_type == null) {
297+
for (String iface : ifaces) {
298+
299+
logger.debug("Trying interface {}", iface);
300+
int j = 0;
301+
while (j >= 0) {
302+
try {
303+
Class<?> ifclass = Class.forName(iface);
304+
if (!ifcs.contains(ifclass)) {
305+
ifcs.add(ifclass);
306+
}
307+
break;
308+
} catch (Exception _ex) {
309+
}
310+
j = iface.lastIndexOf('.');
311+
char[] cs = iface.toCharArray();
312+
if (j >= 0) {
313+
cs[j] = '$';
314+
iface = String.valueOf(cs);
315+
}
316+
}
317+
}
318+
}
319+
else {
320+
ifcs.add(_type);
301321
}
302322

303323
// interface could not be found, we guess that this exported object at least support DBusInterface
304324
if (ifcs.isEmpty()) {
305-
// throw new DBusException("Could not find an interface to cast to");
306325
ifcs.add(DBusInterface.class);
307326
}
308327

309328
RemoteObject ro = new RemoteObject(_source, _path, null, false);
310329
DBusInterface newi = (DBusInterface) Proxy.newProxyInstance(ifcs.get(0).getClassLoader(),
311330
ifcs.toArray(Class[]::new), new RemoteInvocationHandler(this, ro));
312331
getImportedObjects().put(newi, ro);
313-
return newi;
332+
333+
return (T) newi;
314334
} catch (Exception e) {
315335
logger.debug("", e);
316336
throw new DBusException(
@@ -319,23 +339,29 @@ protected DBusInterface dynamicProxy(String _source, String _path) throws DBusEx
319339
}
320340
}
321341

342+
@SuppressWarnings("unchecked")
322343
@Override
323-
public DBusInterface getExportedObject(String _source, String _path) throws DBusException {
324-
ExportedObject o;
344+
public <T extends DBusInterface> T getExportedObject(String _source, String _path, Class<T> _type) throws DBusException {
345+
ExportedObject o;
325346
synchronized (getExportedObjects()) {
326347
o = getExportedObjects().get(_path);
327348
}
328-
if (null != o && null == o.getObject().get()) {
349+
if (null != o && o.getObject().get() == null) {
329350
unExportObject(_path);
330351
o = null;
331352
}
332353
if (null != o) {
333-
return o.getObject().get();
354+
return (T) o.getObject().get();
334355
}
335356
if (null == _source) {
336357
throw new DBusException("Not an object exported by this connection and no remote specified");
337358
}
338-
return dynamicProxy(_source, _path);
359+
return (T) dynamicProxy(_source, _path, _type);
360+
}
361+
362+
@Override
363+
public DBusInterface getExportedObject(String _source, String _path) throws DBusException {
364+
return getExportedObject(_source, _path, null);
339365
}
340366

341367
/**
@@ -456,7 +482,7 @@ public DBusInterface getPeerRemoteObject(String _busname, String _objectpath) th
456482

457483
String unique = dbus.GetNameOwner(_busname);
458484

459-
return dynamicProxy(unique, _objectpath);
485+
return dynamicProxy(unique, _objectpath, null);
460486
}
461487

462488
/**
@@ -498,7 +524,7 @@ public DBusInterface getRemoteObject(String _busname, String _objectpath) throws
498524
throw new DBusException("Invalid object path: " + _objectpath);
499525
}
500526

501-
return dynamicProxy(_busname, _objectpath);
527+
return dynamicProxy(_busname, _objectpath, null);
502528
}
503529

504530
/**

dbus-java-core/src/main/java/org/freedesktop/dbus/connections/impl/DirectConnection.java

+35-23
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ private String createMachineId() {
9696
return Util.randomString(32);
9797
}
9898

99-
DBusInterface dynamicProxy(String _path) throws DBusException {
99+
@SuppressWarnings("unchecked")
100+
<T> T dynamicProxy(String _path, Class<T> _type) throws DBusException {
100101
try {
101102
Introspectable intro = getRemoteObject(_path, Introspectable.class);
102103
String data = intro.Introspect();
@@ -108,21 +109,26 @@ DBusInterface dynamicProxy(String _path) throws DBusException {
108109
.collect(Collectors.toList());
109110

110111
List<Class<? extends Object>> ifcs = new ArrayList<>();
111-
for (String iface : ifaces) {
112-
int j = 0;
113-
while (j >= 0) {
114-
try {
115-
ifcs.add(Class.forName(iface));
116-
break;
117-
} catch (Exception _ex) {
118-
}
119-
j = iface.lastIndexOf('.');
120-
char[] cs = iface.toCharArray();
121-
if (j >= 0) {
122-
cs[j] = '$';
123-
iface = String.valueOf(cs);
124-
}
125-
}
112+
if(_type == null) {
113+
for (String iface : ifaces) {
114+
int j = 0;
115+
while (j >= 0) {
116+
try {
117+
ifcs.add(Class.forName(iface));
118+
break;
119+
} catch (Exception _ex) {
120+
}
121+
j = iface.lastIndexOf('.');
122+
char[] cs = iface.toCharArray();
123+
if (j >= 0) {
124+
cs[j] = '$';
125+
iface = String.valueOf(cs);
126+
}
127+
}
128+
}
129+
}
130+
else {
131+
ifcs.add(_type);
126132
}
127133

128134
if (ifcs.isEmpty()) {
@@ -132,14 +138,15 @@ DBusInterface dynamicProxy(String _path) throws DBusException {
132138
RemoteObject ro = new RemoteObject(null, _path, null, false);
133139
DBusInterface newi = (DBusInterface) Proxy.newProxyInstance(ifcs.get(0).getClassLoader(), ifcs.toArray(new Class[0]), new RemoteInvocationHandler(this, ro));
134140
getImportedObjects().put(newi, ro);
135-
return newi;
141+
return (T)newi;
136142
} catch (Exception e) {
137143
logger.debug("", e);
138144
throw new DBusException(String.format("Failed to create proxy object for %s; reason: %s.", _path, e.getMessage()));
139145
}
140146
}
141147

142-
DBusInterface getExportedObject(String _path) throws DBusException {
148+
@SuppressWarnings("unchecked")
149+
<T extends DBusInterface> T getExportedObject(String _path, Class<T> _type) throws DBusException {
143150
ExportedObject o = null;
144151
synchronized (getExportedObjects()) {
145152
o = getExportedObjects().get(_path);
@@ -149,9 +156,9 @@ DBusInterface getExportedObject(String _path) throws DBusException {
149156
o = null;
150157
}
151158
if (null != o) {
152-
return o.getObject().get();
159+
return (T)o.getObject().get();
153160
}
154-
return dynamicProxy(_path);
161+
return dynamicProxy(_path, _type);
155162
}
156163

157164
/**
@@ -181,7 +188,7 @@ public DBusInterface getRemoteObject(String _objectPath) throws DBusException {
181188
throw new DBusException("Invalid object path: " + _objectPath);
182189
}
183190

184-
return dynamicProxy(_objectPath);
191+
return dynamicProxy(_objectPath, null);
185192
}
186193

187194
/**
@@ -280,12 +287,17 @@ protected void addGenericSigHandler(DBusMatchRule _rule, DBusSigHandler<DBusSign
280287
}
281288

282289
@Override
283-
public DBusInterface getExportedObject(String _source, String _path) throws DBusException {
284-
return getExportedObject(_path);
290+
public <T extends DBusInterface> T getExportedObject(String _source, String _path, Class<T> _type) throws DBusException {
291+
return getExportedObject(_path, _type);
285292
}
286293

287294
@Override
288295
public String getMachineId() {
289296
return machineId;
290297
}
298+
299+
@Override
300+
public DBusInterface getExportedObject(String _source, String _path) throws DBusException {
301+
return getExportedObject(_path, (Class<DBusInterface>)null);
302+
}
291303
}

0 commit comments

Comments
 (0)