Skip to content

Commit b350512

Browse files
committed
Merge branch 'struct-return'
2 parents 18f531e + b98fce6 commit b350512

File tree

11 files changed

+153
-61
lines changed

11 files changed

+153
-61
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ The library will remain open source and MIT licensed and can still be used, fork
133133
- Remove `throws IOException` from `AbstractConnectionBase.close()` (Issue #287)
134134
- Support usage of `Struct`s as return value (as alternative to `Tuple` with generics) (based on discussion in #285)
135135
- Updated dependencies and plugins
136+
- Added support to use `Struct` datatypes as return values instead of `Tuple`
137+
- Added new commandline option `--disable-tuples` to `InterfaceCodeGenerator` to create `Struct` classes instead of `Tuple`s for multi value return (**Caution** the generated code will only work with dbus-java 5.2.0+)
136138

137139
##### Changes in 5.2.0 (2025-12-21):
138140
- removed properties from dbus-java.version which causes issues with reproducable builds ([PR#279](https://github.com/hypfvieh/dbus-java/issues/279))

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

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ public static Object[] convertParameters(Object[] _parameters, Type[] _types, Ab
567567

568568
@SuppressWarnings({ "unchecked", "rawtypes" })
569569
static Object deSerializeParameter(Object _parameter, Type _type, AbstractConnectionBase _conn) throws Exception {
570-
LOGGER.trace("Deserializing from {} to {}", _parameter.getClass(), _type);
570+
LOGGER.trace("(1) Deserializing from {} to {}", _parameter.getClass(), _type);
571571

572572
Object parameter = _parameter;
573573
// its a wrapped variant, unwrap it
@@ -619,10 +619,11 @@ static Object deSerializeParameter(Object _parameter, Type _type, AbstractConnec
619619
parameter = deSerializeParameters(objArr, ts, _conn);
620620
for (Constructor<?> con : ((Class<?>) _type).getDeclaredConstructors()) {
621621
try {
622+
LOGGER.trace("Trying to create instance of {} using constructor {} with parameters: {}", _type, con, objArr);
622623
parameter = con.newInstance(objArr);
623624
break;
624625
} catch (IllegalArgumentException _exIa) {
625-
LOGGER.trace("Could not create new instance", _exIa);
626+
LOGGER.error("Could not create new instance of " + _type, _exIa);
626627
}
627628
}
628629
}
@@ -708,7 +709,7 @@ static Object deSerializeParameter(Object _parameter, Type _type, AbstractConnec
708709
}
709710

710711
static List<Object> deSerializeParameters(List<Object> _parameters, Type _type, AbstractConnectionBase _conn) throws Exception {
711-
LOGGER.trace("Deserializing from {} to {}", _parameters, _type);
712+
LOGGER.trace("(2) Deserializing from {} to {}", _parameters, _type);
712713
if (_parameters == null) {
713714
return null;
714715
}
@@ -723,8 +724,8 @@ static List<Object> deSerializeParameters(List<Object> _parameters, Type _type,
723724
}
724725

725726
@SuppressWarnings("unchecked")
726-
public static Object[] deSerializeParameters(Object[] _parameters, Type[] _types, AbstractConnectionBase _conn) throws Exception {
727-
LoggingHelper.logIf(LOGGER.isTraceEnabled(), () -> LOGGER.trace("Deserializing from {} to {} ", Arrays.deepToString(_parameters), Arrays.deepToString(_types)));
727+
public static Object[] deSerializeParameters(Object[] _parameters, Type[] _types, AbstractConnectionBase _conn, boolean _methodCall) throws Exception {
728+
LoggingHelper.logIf(LOGGER.isTraceEnabled(), () -> LOGGER.trace("(3) Deserializing from {} to {} ", Arrays.deepToString(_parameters), Arrays.deepToString(_types)));
728729

729730
if (null == _parameters) {
730731
return null;
@@ -738,23 +739,29 @@ public static Object[] deSerializeParameters(Object[] _parameters, Type[] _types
738739
types = pt.getActualTypeArguments();
739740
}
740741

741-
if (types.length == 1 && types[0] instanceof Class<?> clz && Tuple.class.isAssignableFrom(clz)) {
742-
String typeName = types[0].getTypeName();
743-
Constructor<?>[] constructors = Class.forName(typeName).getDeclaredConstructors();
744-
if (constructors.length != 1) {
745-
throw new DBusException("Error deserializing message: "
746-
+ "We had a Tuple type but wrong number of constructors for this Tuple. "
747-
+ "There should be exactly one.");
748-
}
742+
if (types.length == 1 && types[0] instanceof Class<?> clz) {
743+
if (Tuple.class.isAssignableFrom(clz)) {
744+
String typeName = types[0].getTypeName();
745+
Constructor<?>[] constructors = Class.forName(typeName).getDeclaredConstructors();
746+
if (constructors.length != 1) {
747+
throw new DBusException("Error deserializing message: "
748+
+ "We had a Tuple type but wrong number of constructors for this Tuple. "
749+
+ "There should be exactly one.");
750+
}
749751

750-
if (constructors[0].getParameterCount() != parameters.length) {
751-
throw new DBusException("Error deserializing message: "
752-
+ "We had a Tuple type but it had wrong number of constructor arguments. "
753-
+ "The number of constructor arguments should match the number of parameters to deserialize.");
754-
}
752+
if (constructors[0].getParameterCount() != parameters.length) {
753+
throw new DBusException("Error deserializing message: "
754+
+ "We had a Tuple type but it had wrong number of constructor arguments. "
755+
+ "The number of constructor arguments should match the number of parameters to deserialize.");
756+
}
755757

756-
Object o = constructors[0].newInstance(parameters);
757-
return new Object[] {o};
758+
Object o = constructors[0].newInstance(parameters);
759+
return new Object[] {o};
760+
} else if (!_methodCall && Struct.class.isAssignableFrom(clz)) {
761+
LOGGER.trace("(4) Deserializing Struct return");
762+
Object[] val = deSerializeParameters(_parameters, types, _conn, true);
763+
return val;
764+
}
758765
}
759766

760767
for (int i = 0; i < parameters.length; i++) {
@@ -808,4 +815,8 @@ public static Object[] deSerializeParameters(Object[] _parameters, Type[] _types
808815
}
809816
return parameters;
810817
}
818+
819+
public static Object[] deSerializeParameters(Object[] _parameters, Type[] _types, AbstractConnectionBase _conn) throws Exception {
820+
return deSerializeParameters(_parameters, _types, _conn, false);
821+
}
811822
}

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ public Object invoke(Object _proxy, Method _method, Object[] _args) throws Throw
101101
}
102102

103103
public static Object convertRV(Object[] _rp, Method _m, AbstractConnection _conn) throws DBusException {
104-
return convertRV(_rp, new Type[] {_m.getGenericReturnType()}, _m, _conn);
104+
return convertRV(false, _rp, new Type[] {_m.getGenericReturnType()}, _m, _conn);
105105
}
106106

107-
public static Object convertRV(Object[] _rp, Type[] _types, Method _m, AbstractConnection _conn) throws DBusException {
107+
static Object convertRV(boolean _methodCall, Object[] _rp, Type[] _types, Method _m, AbstractConnection _conn) throws DBusException {
108108
Class<? extends Object> c = _m.getReturnType();
109109
Object[] rp = _rp;
110110
if (rp == null) {
@@ -118,7 +118,7 @@ public static Object convertRV(Object[] _rp, Type[] _types, Method _m, AbstractC
118118
LoggingHelper.logIf(LOGGER.isTraceEnabled(), () -> LOGGER.trace("Converting return parameters from {} to type {}",
119119
Arrays.deepToString(_rp), _m.getGenericReturnType()));
120120

121-
rp = Marshalling.deSerializeParameters(rp, _types, _conn);
121+
rp = Marshalling.deSerializeParameters(rp, _types, _conn, _methodCall);
122122
} catch (Exception _ex) {
123123
LOGGER.debug("Wrong return type.", _ex);
124124
throw new DBusException(String.format("Wrong return type (failed to de-serialize correct types: %s )", _ex.getMessage()), _ex);
@@ -153,7 +153,7 @@ public static Object convertRV(Object[] _rp, Type[] _types, Method _m, AbstractC
153153

154154
public static Object executeRemoteMethod(final RemoteObject _ro, final Method _m,
155155
final AbstractConnection _conn, final int _syncmethod, final CallbackHandler<?> _callback, Object... _args) throws DBusException {
156-
return executeRemoteMethod(_ro, _m, new Type[] {_m.getGenericReturnType()}, _conn, _syncmethod, _callback, _args);
156+
return executeRemoteMethod(false, _ro, _m, new Type[] {_m.getGenericReturnType()}, _conn, _syncmethod, _callback, _args);
157157
}
158158

159159
/**
@@ -172,7 +172,7 @@ public static Object executeRemoteMethod(final RemoteObject _ro, final Method _m
172172
*
173173
* @throws DBusException when call fails
174174
*/
175-
public static Object executeRemoteMethod(final RemoteObject _ro, final Method _m, String[] _customSignatures,
175+
public static Object executeRemoteMethod(boolean _methodCall, final RemoteObject _ro, final Method _m, String[] _customSignatures,
176176
final Type[] _types, final AbstractConnection _conn, final int _syncmethod, final CallbackHandler<?> _callback, Object... _args) throws DBusException {
177177

178178
Type[] ts = _m.getGenericParameterTypes();
@@ -242,16 +242,16 @@ public static Object executeRemoteMethod(final RemoteObject _ro, final Method _m
242242
}
243243

244244
try {
245-
return convertRV(reply.getParameters(), _types, _m, _conn);
245+
return convertRV(_methodCall, reply.getParameters(), _types, _m, _conn);
246246
} catch (DBusException _ex) {
247247
LOGGER.debug("", _ex);
248248
throw new DBusExecutionException(_ex.getMessage(), _ex);
249249
}
250250
}
251251

252-
public static Object executeRemoteMethod(final RemoteObject _ro, final Method _m,
252+
public static Object executeRemoteMethod(boolean _methodCall, final RemoteObject _ro, final Method _m,
253253
final Type[] _types, final AbstractConnection _conn, final int _syncmethod, final CallbackHandler<?> _callback, Object... _args) throws DBusException {
254-
return executeRemoteMethod(_ro, _m, null, _types, _conn, _syncmethod, _callback, _args);
254+
return executeRemoteMethod(_methodCall, _ro, _m, null, _types, _conn, _syncmethod, _callback, _args);
255255
}
256256

257257
}

dbus-java-core/src/main/java/org/freedesktop/dbus/connections/base/ConnectionMethodInvocation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ protected Object setupAndInvoke(final MethodCall _methodCall, Method _meth, fina
4848
try {
4949
Type[] ts = _meth.getGenericParameterTypes();
5050
Object[] params2 = _methodCall.getParameters();
51-
_methodCall.setArgs(Marshalling.deSerializeParameters(params2, ts, this));
51+
_methodCall.setArgs(Marshalling.deSerializeParameters(params2, ts, this, true));
5252
LoggingHelper.logIf(getLogger().isTraceEnabled(), () -> {
5353
try {
5454
Object[] params3 = _methodCall.getParameters();

dbus-java-core/src/main/java/org/freedesktop/dbus/connections/base/DBusBoundPropertyHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ protected PropHandled handleSet(ExportedObject _exportObject, final MethodCall _
246246
myVal = new ArrayList<>(Arrays.asList(Util.toObjectArray(myVal)));
247247
}
248248
}
249-
_methodCall.setArgs(Marshalling.deSerializeParameters(new Object[] {myVal}, new Type[] {type}, this));
249+
_methodCall.setArgs(Marshalling.deSerializeParameters(new Object[] {myVal}, new Type[] {type}, this, true));
250250
invokeMethodAndReply(_methodCall, propMeth, object, 1 == (_methodCall.getFlags() & Flags.NO_REPLY_EXPECTED));
251251
} catch (Exception _ex) {
252252
getLogger().debug("Failed to invoke method call on Properties", _ex);

dbus-java-core/src/main/java/org/freedesktop/dbus/propertyref/PropRefRemoteHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import java.util.Optional;
1818

1919
/**
20-
* Contains {@link DBusBoundProperty} code used for remote method invokation.
20+
* Contains {@link DBusBoundProperty} code used for remote method invocation.
2121
*
2222
* @author hypfvieh
2323
* @since 5.0.0 - 2023-10-20
@@ -68,10 +68,10 @@ public static Object handleDBusBoundProperty(AbstractConnection _conn, RemoteObj
6868
Object result = null;
6969

7070
if (access == Access.READ) {
71-
result = RemoteInvocationHandler.executeRemoteMethod(propertiesRemoteObj, PROP_GET_METHOD,
71+
result = RemoteInvocationHandler.executeRemoteMethod(true, propertiesRemoteObj, PROP_GET_METHOD,
7272
new Type[] {_method.getGenericReturnType()}, _conn, RemoteInvocationHandler.CALL_TYPE_SYNC, null, DBusNamingUtil.getInterfaceName(_method.getDeclaringClass()), name);
7373
} else {
74-
result = RemoteInvocationHandler.executeRemoteMethod(propertiesRemoteObj, PROP_SET_METHOD, variantType,
74+
result = RemoteInvocationHandler.executeRemoteMethod(false, propertiesRemoteObj, PROP_SET_METHOD, variantType,
7575
new Type[] {_method.getGenericReturnType()}, _conn, RemoteInvocationHandler.CALL_TYPE_SYNC, null, DBusNamingUtil.getInterfaceName(_method.getDeclaringClass()), name, _args[0]);
7676
}
7777

dbus-java-tests/src/test/resources/logback-test.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
<logger name="org.freedesktop.dbus.messages" level="INFO" />
1919
<logger name="org.freedesktop.dbus.MessageWriter" level="INFO" />
2020
<logger name="org.freedesktop.dbus.connections.SASL" level="INFO" />
21-
<logger name="org.freedesktop.dbus.connections.ReceivingService" level="DEBUG" />
21+
<logger name="org.freedesktop.dbus.connections.ReceivingService" level="DEBUG" />
2222

2323
<logger name="org.freedesktop.dbus.bin" level="INFO" />
2424

2525
<root level="TRACE">
2626
<appender-ref ref="STDOUT" />
2727
</root>
2828

29-
</configuration>
29+
</configuration>

dbus-java-utils/src/main/java/org/freedesktop/dbus/utils/generator/ClassBuilderInfo.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,13 +655,15 @@ public List<String> generatedCode(String _indent, String _className, String _arg
655655
String assignments = "";
656656

657657
if (!getSuperArguments().isEmpty()) {
658-
assignments = _indent + "super(" + getSuperArguments().stream().map(MemberOrArgument::getName).collect(Collectors.joining(", ")) + ");";
658+
assignments = " ".repeat(_indent.length() / 2) + "super(" + getSuperArguments().stream()
659+
.map(e -> maybePrefix(e.getName(), _argumentPrefix))
660+
.collect(Collectors.joining(", ")) + ");";
659661
}
660662

661663
if (!getArguments().isEmpty()) {
662664
List<String> assigns = new ArrayList<>();
663665
for (MemberOrArgument e : getArguments()) {
664-
assigns.add(_indent + "this." + e.getName().replaceFirst("^_(.+)", "$1") + " = " + maybePrefix(e.getName(), _argumentPrefix) + ";");
666+
assigns.add(_indent + "this." + e.getName() + " = " + maybePrefix(e.getName(), _argumentPrefix) + ";");
665667
}
666668
assignments += String.join(System.lineSeparator(), assigns);
667669
}

0 commit comments

Comments
 (0)