Skip to content

Commit ce11a56

Browse files
committed
AnnotationType.render does not properly filter defaultValue, re #62
1 parent 974fcf1 commit ce11a56

File tree

14 files changed

+100
-84
lines changed

14 files changed

+100
-84
lines changed

generator/src/main/java/org/jsonx/AnnotationType.java

+19-10
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.jsonx;
1818

1919
import java.lang.annotation.Annotation;
20-
import java.lang.reflect.Method;
2120
import java.util.Iterator;
2221
import java.util.List;
2322
import java.util.Map;
@@ -27,18 +26,26 @@
2726
import org.libj.util.CollectionUtil;
2827

2928
class AnnotationType {
29+
static boolean appendAttribute(final StringBuilder b, final String key, final Object value, final Object defaultValue, final boolean addComma) {
30+
final Object fixedDefaultValue = defaultValue != null && value instanceof String ? "\"" + defaultValue + "\"" : defaultValue;
31+
if (Objects.equals(fixedDefaultValue, value))
32+
return false;
33+
34+
if (addComma)
35+
b.append(", ");
36+
37+
b.append(key).append(" = ").append(value instanceof Class ? ((Class<?>)value).getName() + ".class" : value);
38+
return true;
39+
}
40+
3041
@SuppressWarnings("unchecked")
3142
private void render(final StringBuilder b) {
32-
final int len = b.length();
43+
boolean addComma = false;
3344
for (final Map.Entry<String,Object> entry : attributes.entrySet()) { // [S]
34-
if (b.length() > len)
35-
b.append(", ");
36-
3745
final String key = entry.getKey();
3846
final Object value = entry.getValue();
3947

40-
final Method method = Classes.getMethod(annotationType, key);
41-
final Object defaultValue = method.getDefaultValue();
48+
final Object defaultValue = Classes.getMethod(annotationType, key).getDefaultValue();
4249
if (value instanceof List) {
4350
final Object[] defaultArray = (Object[])defaultValue;
4451
final List<Object> items = (List<Object>)value;
@@ -51,6 +58,10 @@ private void render(final StringBuilder b) {
5158
continue;
5259
}
5360

61+
if (addComma)
62+
b.append(", ");
63+
64+
addComma = true;
5465
b.append(key).append(" = ");
5566
if (i$ == 1) {
5667
b.append(items.get(0));
@@ -82,9 +93,7 @@ private void render(final StringBuilder b) {
8293
}
8394
}
8495
else {
85-
final Object fixedDefaultValue = defaultValue != null && value instanceof String ? "\"" + defaultValue + "\"" : defaultValue;
86-
if (!Objects.equals(fixedDefaultValue, value))
87-
b.append(key).append(" = ").append(value);
96+
addComma = appendAttribute(b, key, value, defaultValue, addComma);
8897
}
8998
}
9099
}

generator/src/main/java/org/jsonx/AnyModel.java

+9-6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.jsonx.www.schema_0_5.xL0gluGCXAA.$ObjectMember;
3737
import org.jsonx.www.schema_0_5.xL0gluGCXAA.$Reference;
3838
import org.jsonx.www.schema_0_5.xL0gluGCXAA.$Reference.Name$;
39+
import org.libj.lang.Classes;
3940
import org.libj.lang.IllegalAnnotationException;
4041
import org.libj.lang.Strings;
4142
import org.openjax.json.JsonUtil;
@@ -481,16 +482,18 @@ else if (type instanceof BooleanModel || type instanceof NumberModel || type ins
481482
else
482483
b.setLength(0);
483484

484-
b.append('@').append(type.typeAnnotation().getName());
485+
final Class<? extends Annotation> annotationType = type.typeAnnotation();
486+
b.append('@').append(annotationType.getName());
485487
if (attrs.size() > 0) {
486488
b.append('(');
487489
final Iterator<Map.Entry<String,Object>> iterator = attrs.entrySet().iterator();
488-
for (int j = 0; iterator.hasNext(); ++j) { // [I]
489-
if (j > 0)
490-
b.append(", ");
491-
490+
boolean addComma = false;
491+
while (iterator.hasNext()) { // [I]
492492
final Map.Entry<String,Object> entry = iterator.next();
493-
b.append(entry.getKey()).append(" = ").append(entry.getValue());
493+
final String key = entry.getKey();
494+
final Object value = entry.getValue();
495+
final Object defaultValue = Classes.getMethod(annotationType, key).getDefaultValue();
496+
addComma = AnnotationType.appendAttribute(b, key, value, defaultValue, addComma);
494497
}
495498

496499
b.append(')');

generator/src/main/java/org/jsonx/Member.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,10 @@ void toAnnotationAttributes(final AttributeMap attributes, final Member owner) {
344344
attributes.put("encode", "\"" + typeBinding.encode + "\"");
345345

346346
// Only put "type" in root object definitions, array members, and not references
347-
if ((declarer instanceof SchemaElement || declarer instanceof ArrayModel) && !(owner instanceof Reference) && typeBinding() != null)
348-
attributes.put("type", typeBinding().toCanonicalString() + ".class");
347+
if ((declarer instanceof SchemaElement || declarer instanceof ArrayModel) && !(owner instanceof Reference) && typeBinding() != null) {
348+
final Class<?> cls = typeBinding().getJavaClass();
349+
attributes.put("type", cls != null ? cls : typeBinding().toCanonicalString() + ".class"); // typeBinding().toCanonicalString() + ".class"
350+
}
349351
}
350352

351353
private static boolean isArrayOverride(final Member override) {

generator/src/main/java/org/jsonx/StringModel.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
import java.math.BigInteger;
2222
import java.util.IdentityHashMap;
2323

24+
import org.jsonx.www.binding_0_5.xL1gluGCXAA.$CodecTypeFieldBinding;
2425
import org.jsonx.www.binding_0_5.xL1gluGCXAA.$FieldBinding;
2526
import org.jsonx.www.binding_0_5.xL1gluGCXAA.$FieldIdentifier;
26-
import org.jsonx.www.binding_0_5.xL1gluGCXAA.$CodecTypeFieldBinding;
2727
import org.jsonx.www.schema_0_5.xL0gluGCXAA.$Array;
2828
import org.jsonx.www.schema_0_5.xL0gluGCXAA.$ArrayMember;
2929
import org.jsonx.www.schema_0_5.xL0gluGCXAA.$Documented;

generator/src/test/java/org/jsonx/ModelTest.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.Comparator;
3131
import java.util.HashMap;
3232
import java.util.Map;
33+
import java.util.Objects;
3334

3435
import org.jaxsb.runtime.Bindings;
3536
import org.jsonx.www.binding_0_5.xL1gluGCXAA.Binding;
@@ -318,7 +319,14 @@ private static void testSettings(final URL resource, final String fileName, fina
318319

319320
static void assertEquals(final String message, final Object expected, final Object actual) {
320321
Assert.assertNotNull(message, actual);
321-
Assert.assertEquals(message, expected, actual);
322+
if (!Objects.equals(expected, actual)) {
323+
System.out.println(expected);
324+
System.out.flush();
325+
System.err.println(actual);
326+
System.err.flush();
327+
Assert.assertEquals(message, expected, actual);
328+
}
329+
322330
if (expected != null)
323331
Assert.assertEquals(message, expected.hashCode(), actual.hashCode());
324332
}

generator/src/test/java/org/jsonx/TestHelper.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,15 @@ public static URL stringToUrlOrNull(final String str) throws MalformedURLExcepti
3535
return str == null ? null : new URL(str);
3636
}
3737

38-
public static Object toNull(final Object obj) {
38+
public static Boolean toNullBoolean(final Object obj) {
39+
return null;
40+
}
41+
42+
public static Number toNullNumber(final Object obj) {
43+
return null;
44+
}
45+
46+
public static String toNullString(final Object obj) {
3947
return null;
4048
}
4149

generator/src/test/resources/binding/array.jsbx

+3-3
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@
114114

115115
</schema>
116116

117-
<boolean path="booleanNull"><bind lang="java" decode="org.jsonx.TestHelper.toNull"/></boolean>
118-
<number path="numberNull"><bind lang="java" decode="org.jsonx.TestHelper.toNull"/></number>
119-
<string path="stringNull"><bind lang="java" decode="org.jsonx.TestHelper.toNull"/></string>
117+
<boolean path="booleanNull"><bind lang="java" decode="org.jsonx.TestHelper.toNullBoolean"/></boolean>
118+
<number path="numberNull"><bind lang="java" decode="org.jsonx.TestHelper.toNullNumber"/></number>
119+
<string path="stringNull"><bind lang="java" decode="org.jsonx.TestHelper.toNullString"/></string>
120120
<number path="coordinates[0]"><bind lang="java" type="java.lang.Float"/></number>
121121

122122
</binding>

jsonx-maven-plugin/src/test/java/org/jsonx/ArrayCreateIterator.java

+10-10
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ int nextIndex() throws IOException {
4747

4848
@Override
4949
void next() throws IOException {
50-
offLen0 = this;
50+
current = this;
5151
++cursor;
5252
}
5353

@@ -68,38 +68,38 @@ int previous() {
6868
Error validate(final Annotation annotation, final int index, final Relations relations, final IdToElement idToElement, final Class<? extends Codec> codecType, final boolean validate, final TriPredicate<JxObject,String,Object> onPropertyDecode) throws IOException {
6969
lastIndex = index;
7070
if (trialType == TrialType.NULLABLE) {
71-
offLen0 = null;
71+
current = null;
7272
}
7373
else if (annotation instanceof StringElement) {
7474
final StringElement element = (StringElement)annotation;
75-
offLen0 = element.nullable() && Math.random() < 0.5 ? null : StringTrial.createValid(element.type(), element.decode(), element.pattern());
75+
current = element.nullable() && Math.random() < 0.5 ? null : StringTrial.createValid(element.type(), element.decode(), element.pattern());
7676
}
7777
else if (annotation instanceof NumberElement) {
7878
final NumberElement element = (NumberElement)annotation;
79-
offLen0 = element.nullable() && Math.random() < 0.5 ? null : NumberTrial.createValid(element.type(), element.decode(), element.range(), element.scale());
79+
current = element.nullable() && Math.random() < 0.5 ? null : NumberTrial.createValid(element.type(), element.decode(), element.range(), element.scale());
8080
}
8181
else if (annotation instanceof ObjectElement) {
8282
final ObjectElement element = (ObjectElement)annotation;
83-
offLen0 = element.nullable() && Math.random() < 0.5 ? null : ObjectTrial.createValid(element.type());
83+
current = element.nullable() && Math.random() < 0.5 ? null : ObjectTrial.createValid(element.type());
8484
}
8585
else if (annotation instanceof ArrayElement) {
8686
final ArrayElement element = (ArrayElement)annotation;
87-
offLen0 = element.nullable() && Math.random() < 0.5 ? null : ArrayTrial.createValid(element.type(), element.minIterate(), element.maxIterate(), element.elementIds(), idToElement);
87+
current = element.nullable() && Math.random() < 0.5 ? null : ArrayTrial.createValid(element.type(), element.minIterate(), element.maxIterate(), element.elementIds(), idToElement);
8888
}
8989
else if (annotation instanceof BooleanElement) {
9090
final BooleanElement element = (BooleanElement)annotation;
91-
offLen0 = element.nullable() && Math.random() < 0.5 ? null : BooleanTrial.createValid(element.type(), element.decode());
91+
current = element.nullable() && Math.random() < 0.5 ? null : BooleanTrial.createValid(element.type(), element.decode());
9292
}
9393
else if (annotation instanceof AnyElement) {
9494
final AnyElement element = (AnyElement)annotation;
9595
if (element.nullable() && Math.random() < 0.5) {
96-
offLen0 = null;
96+
current = null;
9797
}
9898
else {
9999
AnyTrial.createValid(element, new PentaConsumer<Object,Class<?>,String,String,Annotation>() {
100100
@Override
101101
public void accept(final Object value, final Class<?> type, final String decode, final String encode, final Annotation typeAnnotation) {
102-
ArrayCreateIterator.this.offLen0 = value;
102+
ArrayCreateIterator.this.current = value;
103103
}
104104
});
105105
}
@@ -108,7 +108,7 @@ public void accept(final Object value, final Class<?> type, final String decode,
108108
throw new UnsupportedOperationException("Unsupported annotation type: " + annotation.annotationType().getName());
109109
}
110110

111-
relations.set(index, offLen0, annotation);
111+
relations.set(index, current, annotation);
112112
return null;
113113
}
114114
}

jsonx-maven-plugin/src/test/java/org/jsonx/NumberTrial.java

+2-13
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,6 @@ static Object createValid(final Class<?> type, final String decode, final String
7575
}
7676

7777
private static Double makeValid(final Range range) {
78-
// if (range != null && range.toString().equals("[10000000000,]"))
79-
// System.err.println();
80-
// System.err.println("Range: " + range);
8178
if (range == null)
8279
return null;
8380

@@ -91,9 +88,7 @@ private static Double makeValid(final Range range) {
9188
}
9289

9390
private static Double makeInvalid(final Range range) {
94-
double ensureHasFraction = range.getMin() != null ? range.getMin().doubleValue() - 1d : ensureNotTooBig(range.getMax().doubleValue()) + 1d;
95-
// System.err.println(ensureHasFraction);
96-
return ensureHasFraction;
91+
return range.getMin() != null ? range.getMin().doubleValue() - 1d : ensureNotTooBig(range.getMax().doubleValue()) + 1d;
9792
}
9893

9994
private static Number setScale(final Double value, final int scale) {
@@ -121,13 +116,7 @@ private static double ensureHasFraction(final double value) {
121116
}
122117

123118
private static Object toProperForm(final Class<?> type, final String decode, final int scale, final Double value) {
124-
final Object properForm2 = toProperForm2(type, decode, scale, value);
125-
if (properForm2 instanceof Number && ((Number)properForm2).doubleValue() > 100000) {
126-
toProperForm2(type, decode, scale, value);
127-
// System.err.println("Proper form: " + properForm2);
128-
}
129-
130-
return properForm2;
119+
return toProperForm2(type, decode, scale, value);
131120
}
132121

133122
private static Object toProperForm2(final Class<?> type, final String decode, final int scale, final Double value) {

runtime/src/main/java/org/jsonx/AnyCodec.java

+16-16
Original file line numberDiff line numberDiff line change
@@ -194,22 +194,7 @@ static Error encodeObject(final JxEncoder encoder, final Appendable out, final A
194194
final NumberType numbers;
195195
final BooleanType booleans;
196196
final Class<? extends Annotation> arrays;
197-
if (AnyType.isEnabled(strings = type.strings()) && Classes.isAssignableFrom(strings.type(), object.getClass())) {
198-
error = StringCodec.encodeObjectUnsafe(out, annotation, getMethod, strings.pattern(), strings.type(), strings.encode(), object, validate);
199-
if (error == null)
200-
return null;
201-
}
202-
else if (AnyType.isEnabled(numbers = type.numbers()) && Number.class.isAssignableFrom(numbers.type()) && object instanceof Number) {
203-
error = NumberCodec.encodeObjectUnsafe(out, annotation, numbers.scale(), numbers.range(), numbers.type(), numbers.encode(), object, validate);
204-
if (error == null)
205-
return null;
206-
}
207-
else if (AnyType.isEnabled(booleans = type.booleans()) && Classes.isAssignableFrom(booleans.type(), object.getClass())) {
208-
error = BooleanCodec.encodeObjectUnsafe(out, booleans.type(), booleans.encode(), object);
209-
if (error == null)
210-
return null;
211-
}
212-
else if (object instanceof JxObject && AnyType.isEnabled(type.objects())) {
197+
if (object instanceof JxObject && AnyType.isEnabled(type.objects())) {
213198
error = encoder.encodeObject(out, (JxObject)object, null, depth);
214199
if (error == null)
215200
return null;
@@ -228,6 +213,21 @@ else if (object instanceof List && AnyType.isEnabled(arrays = type.arrays())) {
228213
return encoder.encodeArray(out, getMethod, relations, depth);
229214
}
230215
}
216+
else if (AnyType.isEnabled(booleans = type.booleans()) && Classes.isAssignableFrom(booleans.type(), object.getClass())) {
217+
error = BooleanCodec.encodeObjectUnsafe(out, booleans.type(), booleans.encode(), object);
218+
if (error == null)
219+
return null;
220+
}
221+
else if (AnyType.isEnabled(numbers = type.numbers()) && Number.class.isAssignableFrom(numbers.type()) && object instanceof Number) {
222+
error = NumberCodec.encodeObjectUnsafe(out, annotation, numbers.scale(), numbers.range(), numbers.type(), numbers.encode(), object, validate);
223+
if (error == null)
224+
return null;
225+
}
226+
else if (AnyType.isEnabled(strings = type.strings()) && Classes.isAssignableFrom(strings.type(), object.getClass())) {
227+
error = StringCodec.encodeObjectUnsafe(out, annotation, getMethod, strings.pattern(), strings.type(), strings.encode(), object, validate);
228+
if (error == null)
229+
return null;
230+
}
231231

232232
if (++i >= len)
233233
break;

runtime/src/main/java/org/jsonx/ArrayDecodeIterator.java

+4-7
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,7 @@ void next() throws IOException {
7575
final long offLen = reader.readToken();
7676
final int off = Composite.decodeInt(offLen, 0);
7777
final int len = Composite.decodeInt(offLen, 1);
78-
if (len == 4 && reader.bufToChar(off) == 'n' && reader.bufToChar(off + 1) == 'u' && reader.bufToChar(off + 2) == 'l' && reader.bufToChar(off + 3) == 'l')
79-
offLen0 = null;
80-
else
81-
offLen0 = offLen;
78+
current = len == 4 && reader.bufToChar(off) == 'n' && reader.bufToChar(off + 1) == 'u' && reader.bufToChar(off + 2) == 'l' && reader.bufToChar(off + 3) == 'l' ? null : offLen;
8279
}
8380

8481
@Override
@@ -96,7 +93,7 @@ int previous() {
9693

9794
@Override
9895
Error validate(final Annotation annotation, final int index, final Relations relations, final IdToElement idToElement, final Class<? extends Codec> codecType, final boolean validate, final TriPredicate<JxObject,String,Object> onPropertyDecode) throws IOException {
99-
final long offLen = (long)offLen0;
96+
final long offLen = (long)current;
10097
final int off = Composite.decodeInt(offLen, 0);
10198
final int len = Composite.decodeInt(offLen, 1);
10299
final String token = new String(reader.buf(), off, len);
@@ -132,8 +129,8 @@ else if (codecType == StringCodec.class) {
132129
if (value instanceof Error)
133130
return (Error)value;
134131

135-
offLen0 = value;
136-
relations.set(index, offLen0, annotation);
132+
current = value;
133+
relations.set(index, current, annotation);
137134
return null;
138135
}
139136
}

0 commit comments

Comments
 (0)