Skip to content

Commit cfdbaa4

Browse files
committed
Improved InterfaceCode generator to include proper generic information when creating structs
1 parent 383999b commit cfdbaa4

File tree

4 files changed

+136
-83
lines changed

4 files changed

+136
-83
lines changed

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

Lines changed: 71 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@
44
import java.lang.annotation.Annotation;
55
import java.util.ArrayList;
66
import java.util.HashSet;
7-
import java.util.LinkedHashMap;
87
import java.util.LinkedHashSet;
98
import java.util.List;
10-
import java.util.Map;
11-
import java.util.Map.Entry;
129
import java.util.Set;
1310
import java.util.TreeSet;
1411
import java.util.stream.Collectors;
@@ -84,7 +81,7 @@ public class ClassBuilderInfo {
8481
/** Imported files for this class. */
8582
private final Set<String> imports = new TreeSet<>();
8683
/** Members/Fields of this class. */
87-
private final List<ClassMember> members = new ArrayList<>();
84+
private final List<MemberOrArgument> members = new ArrayList<>();
8885
/** Interfaces implemented by this class. */
8986
private final Set<String> implementedInterfaces = new LinkedHashSet<>();
9087
/** Methods provided by this class. */
@@ -159,7 +156,7 @@ public List<ClassMethod> getMethods() {
159156
return methods;
160157
}
161158

162-
public List<ClassMember> getMembers() {
159+
public List<MemberOrArgument> getMembers() {
163160
return members;
164161
}
165162

@@ -239,33 +236,28 @@ private List<String> createClassFileContent(boolean _staticClass, Set<String> _o
239236
}
240237

241238
// add member fields
242-
for (ClassMember member : members) {
239+
for (MemberOrArgument member : members) {
243240
if (!member.getAnnotations().isEmpty()) {
244241
content.addAll(member.getAnnotations().stream().map(l -> memberIndent + l).collect(Collectors.toList()));
245242
}
246-
String memberType = TypeConverter.getProperJavaClass(member.getType(), allImports);
247-
if (!member.getGenerics().isEmpty()) {
248-
memberType += "<" + member.getGenerics().stream().map(c -> TypeConverter.getProperJavaClass(c, allImports)).collect(Collectors.joining(" ,")) + ">";
249-
}
250-
content.add(memberIndent + "private " + (member.isFinalMember() ? "final " : "") + memberType + " "
251-
+ member.getName() + ";");
252-
243+
content.add(memberIndent + "private " + member.asOneLineString(allImports, false) + ";");
253244
}
254245

255246
if (!getConstructors().isEmpty()) {
256247
content.add("");
257248
for (ClassConstructor constructor : getConstructors()) {
258249
String outerIndent = _staticClass ? " " : " ";
259250
String cstr = outerIndent + "public " + getClassName() + "(";
251+
260252
if (!constructor.getSuperArguments().isEmpty()) {
261-
cstr += constructor.getSuperArguments().entrySet().stream().map(e -> e.getValue() + " " + e.getKey()).collect(Collectors.joining(", "));
253+
cstr += constructor.getSuperArguments().stream().map(e -> e.asOneLineString(allImports, false)).collect(Collectors.joining(", "));
262254
if (!constructor.getArguments().isEmpty()) {
263255
cstr += ", ";
264256
}
265257
}
258+
266259
if (!constructor.getArguments().isEmpty()) {
267-
cstr += constructor.getArguments().entrySet().stream()
268-
.map(e -> TypeConverter.getProperJavaClass(e.getValue(), allImports) + " " + e.getKey()).collect(Collectors.joining(", "));
260+
cstr += constructor.argumentsAsString(allImports);
269261
}
270262

271263
if (constructor.getThrowArguments().isEmpty()) {
@@ -279,11 +271,12 @@ private List<String> createClassFileContent(boolean _staticClass, Set<String> _o
279271
String innerIndent = _staticClass ? " " : " ";
280272

281273
if (!constructor.getSuperArguments().isEmpty()) {
282-
content.add(innerIndent + "super(" + String.join(", ", constructor.getSuperArguments().keySet()) + ");");
274+
content.add(innerIndent + "super(" + constructor.getSuperArguments().stream().map(c -> c.getName()).collect(Collectors.joining(", ")) + ");");
283275
}
276+
284277
if (!constructor.getArguments().isEmpty()) {
285-
for (Entry<String, String> e : constructor.getArguments().entrySet()) {
286-
content.add(innerIndent + "this." + e.getKey().replaceFirst("^_(.+)", "$1") + " = " + e.getKey() + ";");
278+
for (MemberOrArgument e : constructor.getArguments()) {
279+
content.add(innerIndent + "this." + e.getName().replaceFirst("^_(.+)", "$1") + " = " + e.getName() + ";");
287280
}
288281
}
289282

@@ -294,15 +287,15 @@ private List<String> createClassFileContent(boolean _staticClass, Set<String> _o
294287
content.add("");
295288

296289
// add getter and setter
297-
for (ClassMember member : members) {
290+
for (MemberOrArgument member : members) {
298291
String memberType = TypeConverter.getProperJavaClass(member.getType(), allImports);
299292

300293
if (!member.getGenerics().isEmpty()) {
301-
memberType += "<" + member.getGenerics().stream().map(c -> TypeConverter.getProperJavaClass(c, allImports)).collect(Collectors.joining(" ,")) + ">";
294+
memberType += "<" + member.getGenerics().stream().map(c -> TypeConverter.getProperJavaClass(c, allImports)).collect(Collectors.joining(", ")) + ">";
302295
}
303296

304297
String getterSetterName = StringUtil.snakeToCamelCase(StringUtil.upperCaseFirstChar(member.getName()));
305-
if (!member.isFinalMember()) {
298+
if (!member.isFinalArg()) {
306299
content.add(memberIndent + "public void set" + getterSetterName + "("
307300
+ memberType + " arg) {");
308301
content.add(memberIndent + " " + member.getName() + " = arg;");
@@ -325,7 +318,7 @@ private List<String> createClassFileContent(boolean _staticClass, Set<String> _o
325318
String clzMth = memberIndent + "public " + (mth.getReturnType() == null ? "void " : TypeConverter.getProperJavaClass(mth.getReturnType(), allImports) + " ");
326319
clzMth += mth.getName() + "(";
327320
if (!mth.getArguments().isEmpty()) {
328-
clzMth += mth.getArguments().entrySet().stream().map(e -> e.getValue() + " " + e.getKey())
321+
clzMth += mth.getArguments().stream().map(e -> e.asOneLineString(allImports, true))
329322
.collect(Collectors.joining(", "));
330323
}
331324
clzMth += ");";
@@ -429,7 +422,7 @@ public static class ClassMethod {
429422
/** True if method should be final, false otherwise. */
430423
private final boolean finalMethod;
431424
/** Arguments for this method, key is argument name, value is argument type. */
432-
private final Map<String, String> arguments = new LinkedHashMap<>();
425+
private final List<MemberOrArgument> arguments = new ArrayList<>();
433426
/** List of annotations for this method. */
434427
private final List<String> annotations = new ArrayList<>();
435428

@@ -451,7 +444,7 @@ public boolean isFinalMethod() {
451444
return finalMethod;
452445
}
453446

454-
public Map<String, String> getArguments() {
447+
public List<MemberOrArgument> getArguments() {
455448
return arguments;
456449
}
457450

@@ -462,28 +455,32 @@ public List<String> getAnnotations() {
462455
}
463456

464457
/**
465-
* Pojo which represents a class member/field.
458+
* Pojo which represents a class member/field or argument.
466459
*
467460
* @author hypfvieh
468461
* @since v3.0.1 - 2018-12-20
469462
*/
470-
public static class ClassMember {
463+
public static class MemberOrArgument {
471464
/** Name of member/field. */
472465
private final String name;
473466
/** Type of member/field (e.g. String, int...). */
474467
private final String type;
475468
/** True to force this member to be final, false otherwise. */
476-
private final boolean finalMember;
469+
private final boolean finalArg;
477470
/** List of classes/types or placeholders put into diamond operators to use as generics. */
478471
private final List<String> generics = new ArrayList<>();
479472
/** List of annotations for this member. */
480473
private final List<String> annotations = new ArrayList<>();
481474

482-
public ClassMember(String _name, String _type, boolean _finalMember) {
475+
public MemberOrArgument(String _name, String _type, boolean _finalMember) {
483476
// repair reserved words by adding 'Param' as appendix
484477
name = RESERVED.contains(_name) ? _name + "param" : _name;
485478
type = _type;
486-
finalMember = _finalMember;
479+
finalArg = _finalMember;
480+
}
481+
482+
public MemberOrArgument(String _name, String _type) {
483+
this(_name, _type, false);
487484
}
488485

489486
public List<String> getAnnotations() {
@@ -498,14 +495,48 @@ public String getType() {
498495
return type;
499496
}
500497

501-
public boolean isFinalMember() {
502-
return finalMember;
498+
public boolean isFinalArg() {
499+
return finalArg;
503500
}
504501

505502
public List<String> getGenerics() {
506503
return generics;
507504
}
508505

506+
public String getFullType(Set<String> _allImports) {
507+
StringBuilder sb = new StringBuilder();
508+
sb.append(TypeConverter.getProperJavaClass(getType(), _allImports));
509+
510+
if (!getGenerics().isEmpty()) {
511+
sb.append("<")
512+
.append(getGenerics().stream().map(c -> TypeConverter.getProperJavaClass(c, _allImports)).collect(Collectors.joining(", ")))
513+
.append(">");
514+
}
515+
516+
return sb.toString();
517+
}
518+
519+
public String asOneLineString(Set<String> _allImports, boolean _includeAnnotations) {
520+
StringBuilder sb = new StringBuilder();
521+
522+
if (isFinalArg()) {
523+
sb.append("final ");
524+
}
525+
526+
if (_includeAnnotations && !getAnnotations().isEmpty()) {
527+
sb.append(String.join(" ", getAnnotations()))
528+
.append(" ");
529+
}
530+
531+
sb.append(getFullType(_allImports));
532+
533+
sb.append(" ");
534+
535+
sb.append(getName());
536+
537+
return sb.toString();
538+
}
539+
509540
}
510541

511542
/**
@@ -516,9 +547,9 @@ public List<String> getGenerics() {
516547
*/
517548
public static class ClassConstructor {
518549
/** Map of arguments for the constructor. Key is argument name, value is argument type. */
519-
private final Map<String, String> arguments = new LinkedHashMap<>();
550+
private final List<MemberOrArgument> arguments = new ArrayList<>();
520551
/** Map of arguments for the super-constructor. Key is argument name, value is argument type. */
521-
private final Map<String, String> superArguments = new LinkedHashMap<>();
552+
private final List<MemberOrArgument> superArguments = new ArrayList<>();
522553

523554
/** List of throws arguments. */
524555
private final List<String> throwArguments = new ArrayList<>();
@@ -527,13 +558,17 @@ public List<String> getThrowArguments() {
527558
return throwArguments;
528559
}
529560

530-
public Map<String, String> getArguments() {
561+
public List<MemberOrArgument> getArguments() {
531562
return arguments;
532563
}
533564

534-
public Map<String, String> getSuperArguments() {
565+
public List<MemberOrArgument> getSuperArguments() {
535566
return superArguments;
536567
}
568+
569+
public String argumentsAsString(Set<String> _allImports) {
570+
return getArguments().stream().map(a -> a.asOneLineString(_allImports, true)).collect(Collectors.joining(", "));
571+
}
537572
}
538573

539574
/**

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

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.io.StringReader;
66
import java.nio.charset.Charset;
77
import java.util.ArrayList;
8+
import java.util.HashSet;
89
import java.util.LinkedHashMap;
910
import java.util.List;
1011
import java.util.Map;
@@ -23,9 +24,9 @@
2324
import org.freedesktop.dbus.interfaces.Introspectable;
2425
import org.freedesktop.dbus.messages.DBusSignal;
2526
import org.freedesktop.dbus.utils.generator.ClassBuilderInfo.ClassConstructor;
26-
import org.freedesktop.dbus.utils.generator.ClassBuilderInfo.ClassMember;
2727
import org.freedesktop.dbus.utils.generator.ClassBuilderInfo.ClassMethod;
2828
import org.freedesktop.dbus.utils.generator.ClassBuilderInfo.ClassType;
29+
import org.freedesktop.dbus.utils.generator.ClassBuilderInfo.MemberOrArgument;
2930
import org.slf4j.Logger;
3031
import org.slf4j.LoggerFactory;
3132
import org.w3c.dom.Document;
@@ -230,21 +231,21 @@ private List<ClassBuilderInfo> extractSignals(Element _signalElement, ClassBuild
230231

231232

232233
for (Entry<String, String> argEntry : args.entrySet()) {
233-
innerClass.getMembers().add(new ClassMember(argEntry.getKey(), argEntry.getValue(), true));
234+
innerClass.getMembers().add(new MemberOrArgument(argEntry.getKey(), argEntry.getValue(), true));
234235
}
235236

236237
ClassConstructor classConstructor = new ClassBuilderInfo.ClassConstructor();
237238

238-
Map<String, String> argsMap = new LinkedHashMap<>();
239+
List<MemberOrArgument> argsList = new ArrayList<>();
239240
for (Entry<String, String> e : args.entrySet()) {
240-
argsMap.put("_" + e.getKey(), e.getValue());
241+
argsList.add(new MemberOrArgument("_" + e.getKey(), e.getValue(), false));
241242
}
242243

243-
classConstructor.getArguments().putAll(argsMap);
244+
classConstructor.getArguments().addAll(argsList);
244245
classConstructor.getThrowArguments().add(DBusException.class.getSimpleName());
245246

246-
classConstructor.getSuperArguments().put("_path", "String");
247-
classConstructor.getSuperArguments().put("_interfaceName", "String");
247+
classConstructor.getSuperArguments().add(new MemberOrArgument("_path", "String", false));
248+
classConstructor.getSuperArguments().add(new MemberOrArgument("_interfaceName", "String", false));
248249

249250
innerClass.getConstructors().add(classConstructor);
250251

@@ -269,8 +270,8 @@ private List<ClassBuilderInfo> extractMethods(Element _methodElement, ClassBuild
269270
if (_methodElement.hasChildNodes()) {
270271
List<Element> methodArgs = convertToElementList(XmlUtil.applyXpathExpressionToDocument("./arg", _methodElement));
271272

272-
Map<String, String> inputArgs = new LinkedHashMap<>();
273-
Map<String, String> outputArgs = new LinkedHashMap<>();
273+
List<MemberOrArgument> inputArgs = new ArrayList<>();
274+
List<MemberOrArgument> outputArgs = new ArrayList<>();
274275

275276
int unknownArgNameCnt = 0;
276277
for (Element argElm : methodArgs) {
@@ -297,9 +298,9 @@ private List<ClassBuilderInfo> extractMethods(Element _methodElement, ClassBuild
297298
}
298299

299300
if ("in".equals(argElm.getAttribute("direction"))) {
300-
inputArgs.put(argName, TypeConverter.getProperJavaClass(argType, _clzBldr.getImports()));
301+
inputArgs.add(new MemberOrArgument(argName, TypeConverter.getProperJavaClass(argType, _clzBldr.getImports())));
301302
} else if ("out".equals(argElm.getAttribute("direction"))) {
302-
outputArgs.put(argName, TypeConverter.getProperJavaClass(argType, _clzBldr.getImports()));
303+
outputArgs.add(new MemberOrArgument(argName, TypeConverter.getProperJavaClass(argType, _clzBldr.getImports()), false));
303304
}
304305
}
305306

@@ -308,11 +309,14 @@ private List<ClassBuilderInfo> extractMethods(Element _methodElement, ClassBuild
308309
logger.debug("Found method with multiple return values: {}", _methodElement.getAttribute("name"));
309310
resultType = createTuple(outputArgs, _methodElement.getAttribute("name") + "Tuple", _clzBldr, additionalClasses);
310311
}
312+
311313
logger.debug("Found method with arguments: {}({})", _methodElement.getAttribute("name"), inputArgs);
312-
resultType = outputArgs.isEmpty() ? "void" : outputArgs.get(new ArrayList<>(outputArgs.keySet()).get(0));
314+
315+
resultType = outputArgs.isEmpty() ? "void" : outputArgs.get(0).getFullType(new HashSet<>());
313316

314317
ClassMethod classMethod = new ClassMethod(_methodElement.getAttribute("name"), resultType, false);
315-
classMethod.getArguments().putAll(inputArgs);
318+
classMethod.getArguments().addAll(inputArgs);
319+
316320
_clzBldr.getMethods().add(classMethod);
317321

318322
} else { // method has no arguments
@@ -334,7 +338,7 @@ private List<ClassBuilderInfo> extractMethods(Element _methodElement, ClassBuild
334338
* @param _additionalClasses list where the new created tuple class will be added to
335339
* @return FQCN of the newly created tuple based class
336340
*/
337-
private String createTuple(Map<String, String> _outputArgs, String _className, ClassBuilderInfo _parentClzBldr, List<ClassBuilderInfo> _additionalClasses) {
341+
private String createTuple(List<MemberOrArgument> _outputArgs, String _className, ClassBuilderInfo _parentClzBldr, List<ClassBuilderInfo> _additionalClasses) {
338342
if (_outputArgs == null || _outputArgs.isEmpty() || _additionalClasses == null) {
339343
return null;
340344
}
@@ -349,12 +353,11 @@ private String createTuple(Map<String, String> _outputArgs, String _className, C
349353
}
350354

351355
int position = 0;
352-
for (Entry<String, String> entry : _outputArgs.entrySet()) {
353-
ClassMember member = new ClassMember(entry.getKey(), entry.getValue(), true);
354-
member.getAnnotations().add("@Position(" + position + ")");
356+
for (MemberOrArgument entry : _outputArgs) {
357+
entry.getAnnotations().add("@Position(" + position + ")");
355358
}
356359
ClassConstructor cnstrct = new ClassConstructor();
357-
cnstrct.getArguments().putAll(_outputArgs);
360+
cnstrct.getArguments().addAll(_outputArgs);
358361

359362
_additionalClasses.add(info);
360363

0 commit comments

Comments
 (0)