From f5e648cb75a8ad8a279f1f39e1a07699747039d0 Mon Sep 17 00:00:00 2001 From: Roan Hofland Date: Wed, 10 Apr 2024 11:37:24 +0200 Subject: [PATCH 1/2] XML values are always required --- .../github/sabomichal/immutablexjc/PluginImpl.java | 5 +++++ .../immutablexjc/test/TestMiscOptions.java | 7 +++++++ src/test/xsd/basic.xsd | 14 ++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/src/main/java/com/github/sabomichal/immutablexjc/PluginImpl.java b/src/main/java/com/github/sabomichal/immutablexjc/PluginImpl.java index 3ee93f1..3e030a4 100644 --- a/src/main/java/com/github/sabomichal/immutablexjc/PluginImpl.java +++ b/src/main/java/com/github/sabomichal/immutablexjc/PluginImpl.java @@ -48,6 +48,7 @@ import com.sun.tools.xjc.outline.Outline; import jakarta.xml.bind.annotation.XmlAttribute; import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlValue; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.FieldUtils; import org.xml.sax.ErrorHandler; @@ -938,6 +939,10 @@ private boolean isMap(JClass clazz) { } private boolean isRequired(JFieldVar field) { + if (getAnnotation(field.annotations(), XmlValue.class.getCanonicalName()).isPresent()) { + return true; + } + return Stream.of(XmlElement.class, XmlAttribute.class) .map(annotationType -> getAnnotation(field.annotations(), annotationType.getCanonicalName()) diff --git a/src/test/java/com/github/sabomichal/immutablexjc/test/TestMiscOptions.java b/src/test/java/com/github/sabomichal/immutablexjc/test/TestMiscOptions.java index 52b974d..aafe28c 100644 --- a/src/test/java/com/github/sabomichal/immutablexjc/test/TestMiscOptions.java +++ b/src/test/java/com/github/sabomichal/immutablexjc/test/TestMiscOptions.java @@ -9,6 +9,8 @@ import org.junit.jupiter.api.Test; +import java.math.BigDecimal; + import static org.junit.jupiter.api.Assertions.*; @@ -100,5 +102,10 @@ public void testOptionalGetter() { assertTrue(new com.github.sabomichal.immutablexjc.test.optionalgetter.Declaration(null, null, null, "documentation", null) .getDocumentation() .isPresent()); + + com.github.sabomichal.immutablexjc.test.optionalgetter.DecimalExtensionType type = new com.github.sabomichal.immutablexjc.test.optionalgetter.DecimalExtensionType(BigDecimal.valueOf(1), "s"); + assertNotNull(type.getValue()); + assertEquals(BigDecimal.class, type.getValue().getClass()); + assertTrue(type.getUnit().isPresent()); } } diff --git a/src/test/xsd/basic.xsd b/src/test/xsd/basic.xsd index 62f4480..cd76ce4 100644 --- a/src/test/xsd/basic.xsd +++ b/src/test/xsd/basic.xsd @@ -37,4 +37,18 @@ + + + + + + + + + + + + + + \ No newline at end of file From 830a0c6a5e4a8e6656248ca84d30b093da9eb4df Mon Sep 17 00:00:00 2001 From: Roan Hofland Date: Wed, 10 Apr 2024 15:09:19 +0200 Subject: [PATCH 2/2] Do not wrap primitives in optionals Since a primitive will always be present with some value it does not really make sense to wrap them in an optional. fix issue #107 --- .../com/github/sabomichal/immutablexjc/PluginImpl.java | 6 +++++- .../sabomichal/immutablexjc/test/TestMiscOptions.java | 8 +++++++- src/test/xsd/basic.xsd | 5 +++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/sabomichal/immutablexjc/PluginImpl.java b/src/main/java/com/github/sabomichal/immutablexjc/PluginImpl.java index 3e030a4..a6b2b79 100644 --- a/src/main/java/com/github/sabomichal/immutablexjc/PluginImpl.java +++ b/src/main/java/com/github/sabomichal/immutablexjc/PluginImpl.java @@ -341,7 +341,7 @@ private JMethod addBuildMethod(JDefinedClass clazz, JDefinedClass builderClass, } for (JFieldVar field : declaredFields) { if (mustAssign(field)) { - if (isRequired(field)) { + if (isRequired(field) && !field.type().isPrimitive()) { JBlock block = method.body(); JConditional conditional = block._if(field.eq(JExpr._null())); conditional._then()._throw(JExpr._new(builderClass.owner().ref(NullPointerException.class)) @@ -939,6 +939,10 @@ private boolean isMap(JClass clazz) { } private boolean isRequired(JFieldVar field) { + if (field.type().isPrimitive()) { + return true; + } + if (getAnnotation(field.annotations(), XmlValue.class.getCanonicalName()).isPresent()) { return true; } diff --git a/src/test/java/com/github/sabomichal/immutablexjc/test/TestMiscOptions.java b/src/test/java/com/github/sabomichal/immutablexjc/test/TestMiscOptions.java index aafe28c..6d6687a 100644 --- a/src/test/java/com/github/sabomichal/immutablexjc/test/TestMiscOptions.java +++ b/src/test/java/com/github/sabomichal/immutablexjc/test/TestMiscOptions.java @@ -4,6 +4,8 @@ import com.github.sabomichal.immutablexjc.test.misc.Model; import com.github.sabomichal.immutablexjc.test.misc.NameExpression; import com.github.sabomichal.immutablexjc.test.misc.Parameters; +import com.github.sabomichal.immutablexjc.test.optionalgetter.DecimalExtensionType; +import com.github.sabomichal.immutablexjc.test.optionalgetter.NoOptionalForPrimitive; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.Marshaller; import org.junit.jupiter.api.Test; @@ -103,9 +105,13 @@ public void testOptionalGetter() { .getDocumentation() .isPresent()); - com.github.sabomichal.immutablexjc.test.optionalgetter.DecimalExtensionType type = new com.github.sabomichal.immutablexjc.test.optionalgetter.DecimalExtensionType(BigDecimal.valueOf(1), "s"); + DecimalExtensionType type = new DecimalExtensionType(BigDecimal.valueOf(1), "s"); assertNotNull(type.getValue()); assertEquals(BigDecimal.class, type.getValue().getClass()); assertTrue(type.getUnit().isPresent()); + + NoOptionalForPrimitive primitive = new NoOptionalForPrimitive(1); + assertNotNull(primitive.getIndex()); + assertEquals(1, primitive.getIndex()); } } diff --git a/src/test/xsd/basic.xsd b/src/test/xsd/basic.xsd index cd76ce4..e9f620b 100644 --- a/src/test/xsd/basic.xsd +++ b/src/test/xsd/basic.xsd @@ -51,4 +51,9 @@ + + + + + \ No newline at end of file