Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ The library will remain open source and MIT licensed and can still be used, fork
- Fixed possible NullPointerException in SASL auth ([#294](https://github.com/hypfvieh/dbus-java/issues/294))
- Fixed SASL authentication issue when running in server mode in combination with unix sockets ([#298](https://github.com/hypfvieh/dbus-java/issues/298))
- Fixed various issues with `InterfaceCodeGenerator` ([#302](https://github.com/hypfvieh/dbus-java/issues/302), [#303](https://github.com/hypfvieh/dbus-java/issues/303), [#304], (https://github.com/hypfvieh/dbus-java/issues/304), [#306](https://github.com/hypfvieh/dbus-java/issues/306)
- Refactoring and overhaul of `InterfaceCodeGenerator` to improve code, reduce duplications and allow easier fixing/extending

##### Changes in 5.2.0 (2025-12-21):
- removed properties from dbus-java.version which causes issues with reproducable builds ([PR#279](https://github.com/hypfvieh/dbus-java/issues/279))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ private List<ClassBuilderInfo> extractSignals(Element _signalElement, ClassBuild

}

ClassConstructor classConstructor = new ClassConstructor(_clzBldr, className);
ClassConstructor classConstructor = new ClassConstructor(_clzBldr, 0, className);

classConstructor.getArguments().addAll(argsList);
classConstructor.getThrowArguments().add(DBusException.class.getSimpleName());
Expand Down Expand Up @@ -487,7 +487,7 @@ private List<ClassBuilderInfo> extractProperties(Element _propertyElement, Class
if (DBusProperty.Access.WRITE.getAccessName().equals(attrAccess)
|| DBusProperty.Access.READ_WRITE.getAccessName().equals(attrAccess)) {

ClassMethod classMethod = new SetterMethod(_clzBldr, attrName, rtnType);
ClassMethod classMethod = new SetterMethod(_clzBldr, 0, attrName, rtnType);
classMethod.getArguments().add(new MemberOrArgument(_clzBldr, attrName.substring(0, 1).toLowerCase()
+ attrName.substring(1), clzzName));
_clzBldr.getMethods().add(classMethod);
Expand Down Expand Up @@ -544,10 +544,10 @@ private String createTuple(List<MemberOrArgument> _outputArgs, String _className
genericTypes.put(genericName, entry.getType());
entry.getAnnotations().add(new AnnotationInfo(Position.class, AnnotArgs.create().add(position++)));
entry.setType(genericName);
cnstrctArgs.add(new MemberOrArgument(_parentClzBldr, entry.getName(), genericName));
cnstrctArgs.add(new MemberOrArgument(info, entry.getName(), genericName));
}

ClassConstructor cnstrct = new ClassConstructor(_parentClzBldr, _className);
ClassConstructor cnstrct = new ClassConstructor(info, 0, _className);
cnstrct.getArguments().addAll(cnstrctArgs);

info.getConstructors().add(cnstrct);
Expand Down Expand Up @@ -609,7 +609,7 @@ private String buildStructClass(List<DuoData> _dbusTypeStr, String _structName,
root.setExtendClass(Struct.class.getName());
root.setClassType(ClassType.CLASS);

ClassConstructor classConstructor = new ClassConstructor(_clzBldr, className);
ClassConstructor classConstructor = new ClassConstructor(_clzBldr, 0, className);
root.getConstructors().add(classConstructor);

String structFqcn = _clzBldr.getPackageName() + "." + Util.upperCaseFirstChar(_structName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public String buildStructClasses(String _dbusSig, String _structBaseFqcn, ClassB
}

if (!treeItem.getSubType().isEmpty()) {
createNested(treeItem.getSubType(), _structBaseFqcn, root, _generatedClasses);
createNested(1, treeItem.getSubType(), _structBaseFqcn, root, _generatedClasses);
}
}

Expand Down Expand Up @@ -123,19 +123,20 @@ static String findNextStructFqcn(String _structFqcn, Set<String> _generatedStruc
/**
* Create nested Struct class.
*
* @param _nestedLevel nested depth level
* @param _list List of struct tree elements
* @param _structFqcnBase base classname of created struct class
* @param _root root class of this struct (maybe other struct)
* @param _classes a list, this will contain additional struct classes created, if any. Should never be null!
*
* @return last created struct or null
*/
private ClassBuilderInfo createNested(List<StructTree> _list, String _structFqcnBase, ClassBuilderInfo _root, List<ClassBuilderInfo> _classes) {
private ClassBuilderInfo createNested(int _nestedLevel, List<StructTree> _list, String _structFqcnBase, ClassBuilderInfo _root, List<ClassBuilderInfo> _classes) {
int position = 0;

ClassBuilderInfo root = _root;
ClassBuilderInfo retval = null;
ClassConstructor classConstructor = new ClassConstructor(_root, root.getClassName());
ClassConstructor classConstructor = new ClassConstructor(_root, _nestedLevel, root.getClassName());

for (StructTree inTree : _list) {

Expand All @@ -158,7 +159,7 @@ private ClassBuilderInfo createNested(List<StructTree> _list, String _structFqcn
temp.setClassType(ClassType.CLASS);
classConstructor.getArguments().add(new MemberOrArgument(_root, constructorArg, temp.getClassName()));
member.setType(temp.getClassName());
createNested(inTree.getSubType(), _structFqcnBase, temp, _classes);
createNested(_nestedLevel + 1, inTree.getSubType(), _structFqcnBase, temp, _classes);

_classes.add(temp);
retval = temp;
Expand All @@ -167,7 +168,7 @@ private ClassBuilderInfo createNested(List<StructTree> _list, String _structFqcn

temp.setClassName(root.getClassName());
temp.setPackageName(root.getPackageName());
ClassBuilderInfo x = createNested(inTree.getSubType(), _structFqcnBase, temp, _classes);
ClassBuilderInfo x = createNested(_nestedLevel + 1, inTree.getSubType(), _structFqcnBase, temp, _classes);
if (x != null) {
member.getGenerics().add(x.getClassName());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,13 +253,12 @@ private List<String> createClassFileContent(boolean _staticClass, Set<String> _o
}
}

List<ClassMethod> allMethods = new ArrayList<>(getMethods());

// add getter and setter
for (MemberOrArgument member : members) {
addEmptyLineIfNeeded(content);
content.addAll(member.generate(memberIndentCnt));
}
getMembers().stream().map(e -> e.generateMethods(memberIndentCnt)).forEach(allMethods::addAll);

for (ClassMethod mth : getMethods()) {
for (ClassMethod mth : allMethods) {
addEmptyLineIfNeeded(content);
content.addAll(mth.generate(memberIndentCnt));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ public class ClassConstructor implements ICodeGenerator {
private final ClassBuilderInfo classBuilderInfo;

private final String className;
private final int indentLevel;

public ClassConstructor(ClassBuilderInfo _bldr, String _className) {
public ClassConstructor(ClassBuilderInfo _bldr, int _indentLevel, String _className) {
classBuilderInfo = _bldr;
className = _className;
indentLevel = _indentLevel;
}

public List<String> getThrowArguments() {
Expand All @@ -58,7 +60,7 @@ public ClassBuilderInfo getClassBuilderInfo() {

@Override
public List<String> generate(int _indentLevel) {

int indent = Math.max(indentLevel, _indentLevel);
List<MemberOrArgument> filteredSuperArguments = new ArrayList<>(getSuperArguments());
filteredSuperArguments.removeIf(e -> getArguments().contains(e));
String constructorArgs = "";
Expand All @@ -81,22 +83,22 @@ public List<String> generate(int _indentLevel) {
String prefix = getClassBuilderInfo().getArgumentPrefix();

if (!getSuperArguments().isEmpty()) {
assignments = getIndent(_indentLevel / 2) + "super(" + getSuperArguments().stream()
assignments = getIndent(indent / 2) + "super(" + getSuperArguments().stream()
.map(e -> ClassBuilderInfo.maybePrefix(e.getName(), prefix))
.collect(Collectors.joining(", ")) + ");" + System.lineSeparator();
}

if (!getArguments().isEmpty()) {
List<String> assigns = new ArrayList<>();
String innerIndent = getIndent(_indentLevel / 2);
String innerIndent = getIndent(indent);
for (MemberOrArgument e : getArguments()) {
assigns.add(innerIndent + "this." + e.getName() + " = " + ClassBuilderInfo.maybePrefix(e.getName(), prefix) + ";");
}
assignments += String.join(System.lineSeparator(), assigns);
}

return CONSTRUCTOR_TEMPL.formatted(getClassName(), constructorArgs, throwArgs, assignments)
.lines().map(l -> getIndent(_indentLevel) + l).toList();
.lines().map(l -> getIndent(indent) + l).toList();
}

public String argumentsAsString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ public List<String> generate(int _indentLevel) {

// add "name" definition if original name differs from reformatted name
// e.g. some-name != someName
if (!reformatName().equals(getName())) {
String reformattedMethodName = reformatName();
if (!reformattedMethodName.equals(getName())
|| !Util.upperCaseFirstChar(getName()).equals(reformattedMethodName)) {
currentAnnotations.stream().filter(e -> e.getAnnotationClass() == DBusBoundProperty.class)
.forEach(e -> e.getAnnotationParams().put("name", getName()));

Expand All @@ -126,7 +128,7 @@ public List<String> generate(int _indentLevel) {
result.addAll(currentAnnotations.stream().map(a -> getIndent(_indentLevel) + a.getAnnotationString()).toList());
}

String publicModifier = getClassBuilderInfo().getClassType() != ClassType.INTERFACE ? "public " : "";
String publicModifier = getClassBuilderInfo().getClassType() != ClassType.INTERFACE ? "public" : "";
String mthReturnType = getReturnType() == null ? "void"
: TypeConverter.getProperJavaClass(getReturnType(), getClassBuilderInfo().getImports());
String args = "";
Expand All @@ -143,7 +145,7 @@ public List<String> generate(int _indentLevel) {
}

protected List<String> formatMethod(int _indentLvl, String _modifier, String _returnType, String _methodName, String _args) {
return METHOD_TEMPL.formatted(_modifier, _returnType, _methodName, _args)
return METHOD_TEMPL.formatted(Util.isBlank(_modifier) ? "" : " " + _modifier, _returnType, _methodName, _args)
.lines().map(l -> getIndent(_indentLvl) + l).toList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,30 @@ public class GetterMethod extends ClassMethod {
""";
private final MemberOrArgument argument;

private final int indentLevel;

public GetterMethod(ClassBuilderInfo _bldr, String _name, String _returnType) {
this(_bldr, _name, _returnType, null);
this(_bldr, 0, _name, _returnType, null);
}

public GetterMethod(ClassBuilderInfo _bldr, String _name, String _returnType, MemberOrArgument _arguments) {
public GetterMethod(ClassBuilderInfo _bldr, int _indentLevel, String _name, String _returnType, MemberOrArgument _arguments) {
super(_bldr, _name, _returnType, "boolean".equalsIgnoreCase(_returnType) ? "is" : "get", false);
this.argument = _arguments;
this.indentLevel = _indentLevel;
}

@Override
protected List<String> formatMethod(int _indentLvl, String _modifier, String _returnType, String _methodName, String _args) {

int indent = Math.max(_indentLvl, indentLevel);
if (argument == null) {
return super.formatMethod(_indentLvl, _modifier, _returnType, _methodName, _args);
return super.formatMethod(indent, _modifier, _returnType, _methodName, _args);
}

String content = String.format("return %s;", argument.getName());

return GETTER_METHOD_TEMPL.formatted(_modifier, _returnType, _methodName, _args,
getIndent(Math.min(1, _indentLvl - 1)), content)
.lines().map(l -> getIndent(_indentLvl) + l).toList();
return GETTER_METHOD_TEMPL.formatted("public ", _returnType, _methodName, _args,
getIndent(indent), content)
.lines().map(l -> getIndent(indent) + l).toList();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* @author hypfvieh
* @since v3.0.1 - 2018-12-20
*/
public class MemberOrArgument implements ICodeGenerator {
public class MemberOrArgument {

/** Name of member/field. */
private final String name;
Expand Down Expand Up @@ -78,25 +78,25 @@ public String getFullType(Set<String> _allImports) {
return sb.toString();
}

@Override
public ClassBuilderInfo getClassBuilderInfo() {
return classBuilderInfo;
}

@Override
public List<String> generate(int _indentLevel) {
List<String> result = new ArrayList<>();
public List<ClassMethod> generateMethods(int _indentLevel) {
List<ClassMethod> result = new ArrayList<>();
String memberType = TypeConverter.getProperJavaClass(getType(), getClassBuilderInfo().getImports());

if (!getGenerics().isEmpty()) {
memberType += "<" + getGenerics().stream().map(c -> TypeConverter.convertJavaType(c, false)).collect(Collectors.joining(", ")) + ">";
memberType += "<" + getGenerics().stream()
.map(c -> TypeConverter.convertJavaType(c, false))
.collect(Collectors.joining(", ")) + ">";
}

GetterMethod getterMethod = new GetterMethod(getClassBuilderInfo(), getName(), memberType, this);
GetterMethod getterMethod = new GetterMethod(getClassBuilderInfo(), _indentLevel, getName(), memberType, this);
result.add(getterMethod);

getClassBuilderInfo().getMethods().add(getterMethod);
if (!isFinalArg()) {
getClassBuilderInfo().getMethods().add(new SetterMethod(getClassBuilderInfo(), getName(), memberType));
result.add(new SetterMethod(getClassBuilderInfo(), _indentLevel, getName(), memberType));
}

return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,26 @@ public class SetterMethod extends ClassMethod {
%s%s
}
""";
private final int indentLevel;

public SetterMethod(ClassBuilderInfo _bldr, String _name, String _setterType) {
public SetterMethod(ClassBuilderInfo _bldr, int _indentLevel, String _name, String _setterType) {
super(_bldr, _name, "void", "set", false);
indentLevel = _indentLevel;
getArguments().add(new MemberOrArgument(_bldr, _name, _setterType));
}

@Override
protected List<String> formatMethod(int _indentLvl, String _modifier, String _returnType, String _methodName, String _args) {
int indent = Math.max(indentLevel, _indentLvl);

if (getArguments() == null || getArguments().isEmpty()) {
return super.formatMethod(_indentLvl, _modifier, _returnType, _methodName, _args);
return super.formatMethod(indent, _modifier, _returnType, _methodName, _args);
}

String content = String.format("this.%s = %s;", getArguments().getFirst().getName(), getArguments().getFirst().getName());

return SETTER_METHOD_TEMPL.formatted(_modifier, _returnType, _methodName, _args,
getIndent(Math.min(1, _indentLvl - 1)), content)
.lines().map(l -> getIndent(_indentLvl) + l).toList();
return SETTER_METHOD_TEMPL.formatted("public ", _returnType, _methodName, _args,
getIndent(indent), content)
.lines().map(l -> getIndent(indent) + l).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
assertLineEquals(12, clzContent, " @DBusBoundProperty(name = \"power-saver-enabled\")");
assertLineEquals(13, clzContent, " boolean isPowerSaverEnabled();");

assertLineEquals(15, clzContent, " @DBusBoundProperty");
assertLineEquals(15, clzContent, " @DBusBoundProperty(name = \"version\")");
assertLineEquals(16, clzContent, " UInt32 getVersion();");
}

Expand Down Expand Up @@ -168,6 +168,65 @@
assertLineEquals(22, clzContent, " @DBusBoundProperty(type = PropertySupportedOptionsType.class)");
}

@Test
void testStructFormatting() throws Exception {
InterfaceCodeGenerator ci2 = loadDBusXmlFile(true,
new File("src/test/resources/CreateInterface/xdg-desktop/org.freedesktop.portal.Usb.xml"),
"/", "org.freedesktop.portal.Usb");
Map<File, String> analyze = ci2.analyze(true);

assertEquals(6, analyze.size());

String clzContent = analyze.entrySet().stream()
.filter(e -> e.getKey().getName().equals("AcquireDevicesDevicesStruct.java"))
.findFirst()
.map(e -> e.getValue())

Check warning on line 183 in dbus-java-utils/src/test/java/org/freedesktop/dbus/utils/generator/InterfaceCodeGeneratorTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this lambda with method reference 'Entry::getValue'.

See more on https://sonarcloud.io/project/issues?id=com.github.hypfvieh%3Adbus-java-parent&issues=AZ0Q-DsMEnrKnygjh7KX&open=AZ0Q-DsMEnrKnygjh7KX&pullRequest=309
.orElseThrow();

assertLineEquals(16, clzContent, " public AcquireDevicesDevicesStruct(String member0, Map<String, Variant<?>> member1) {");
assertLineEquals(17, clzContent, " this.member0 = member0;");
assertLineEquals(18, clzContent, " this.member1 = member1;");

assertLineEquals(21, clzContent, " public String getMember0() {");
assertLineEquals(22, clzContent, " return member0;");

assertLineEquals(25, clzContent, " public Map<String, Variant<?>> getMember1() {");
assertLineEquals(26, clzContent, " return member1;");
}

@Test
void testTupleFormatting() throws Exception {
InterfaceCodeGenerator ci2 = loadDBusXmlFile(true,
new File("src/test/resources/CreateInterface/xdg-desktop/org.freedesktop.portal.Documents.xml"),
"/", "org.freedesktop.portal.Documents");
Map<File, String> analyze = ci2.analyze(true);

assertEquals(4, analyze.size());

String clzContent = analyze.entrySet().stream()
.filter(e -> e.getKey().getName().equals("AddFullTuple.java"))
.findFirst()
.map(e -> e.getValue())

Check warning on line 209 in dbus-java-utils/src/test/java/org/freedesktop/dbus/utils/generator/InterfaceCodeGeneratorTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this lambda with method reference 'Entry::getValue'.

See more on https://sonarcloud.io/project/issues?id=com.github.hypfvieh%3Adbus-java-parent&issues=AZ0Q-DsMEnrKnygjh7KY&open=AZ0Q-DsMEnrKnygjh7KY&pullRequest=309
.orElseThrow();

assertLineEquals(14, clzContent, " public AddFullTuple(A docIds, B extraOut) {");
assertLineEquals(15, clzContent, " this.docIds = docIds;");
assertLineEquals(16, clzContent, " this.extraOut = extraOut;");

assertLineEquals(19, clzContent, " public A getDocIds() {");
assertLineEquals(20, clzContent, " return docIds;");

assertLineEquals(23, clzContent, " public void setDocIds(A docIds) {");
assertLineEquals(24, clzContent, " this.docIds = docIds;");

assertLineEquals(27, clzContent, " public B getExtraOut() {");
assertLineEquals(28, clzContent, " return extraOut;");

assertLineEquals(31, clzContent, " public void setExtraOut(B extraOut) {");
assertLineEquals(32, clzContent, " this.extraOut = extraOut;");

}

@Test
void testCreateSampleStructArgs() throws Exception {
InterfaceCodeGenerator ci2 = loadDBusXmlFile(
Expand Down
Loading
Loading