Skip to content

Commit 21110cf

Browse files
committed
Fix #31
1 parent 0d905ee commit 21110cf

File tree

4 files changed

+163
-0
lines changed

4 files changed

+163
-0
lines changed

jaxb/src/main/java/com/fasterxml/jackson/module/jaxb/JaxbAnnotationIntrospector.java

+5
Original file line numberDiff line numberDiff line change
@@ -1265,8 +1265,13 @@ private <A extends Annotation> A findAnnotation(Class<A> annotationClass, Annota
12651265
}
12661266
} else if (annType instanceof Class<?>) {
12671267
memberClass = (Class<?>) annType;
1268+
1269+
// 20-Oct-2017, tatu: as per [modules-base#31] we may get `VirtualAnnotatedMember`, should
1270+
// not freak out
1271+
/*
12681272
} else {
12691273
throw new IllegalStateException("Unsupported annotated member: " + annotated.getClass().getName());
1274+
*/
12701275
}
12711276
}
12721277
if (memberClass != null) {

jaxb/src/test/java/com/fasterxml/jackson/module/jaxb/BaseJaxbTest.java

+20
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ protected BaseJaxbTest() { }
2020
/**********************************************************************
2121
*/
2222

23+
// @since 2.9
24+
protected ObjectMapper newObjectMapper()
25+
{
26+
return getJaxbAndJacksonMapper();
27+
}
28+
2329
protected ObjectMapper getJaxbMapper()
2430
{
2531
ObjectMapper mapper = new ObjectMapper();
@@ -77,4 +83,18 @@ protected String serializeAsString(Object value)
7783
{
7884
return serializeAsString(new ObjectMapper(), value);
7985
}
86+
87+
/*
88+
/**********************************************************
89+
/* Helper methods, other
90+
/**********************************************************
91+
*/
92+
93+
public String quote(String str) {
94+
return '"'+str+'"';
95+
}
96+
97+
protected static String aposToQuotes(String json) {
98+
return json.replace("'", "\"");
99+
}
80100
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package com.fasterxml.jackson.module.jaxb.ser;
2+
3+
import java.util.*;
4+
5+
import com.fasterxml.jackson.annotation.JsonInclude;
6+
import com.fasterxml.jackson.core.JsonGenerator;
7+
import com.fasterxml.jackson.databind.*;
8+
import com.fasterxml.jackson.databind.annotation.JsonAppend;
9+
import com.fasterxml.jackson.databind.cfg.MapperConfig;
10+
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
11+
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
12+
import com.fasterxml.jackson.databind.ser.VirtualBeanPropertyWriter;
13+
import com.fasterxml.jackson.databind.util.Annotations;
14+
import com.fasterxml.jackson.module.jaxb.BaseJaxbTest;
15+
16+
//Copied from [com.fasterxml.jackson.databind.ser]
17+
/**
18+
* Tests for verifying that one can append virtual properties after regular ones.
19+
*/
20+
public class TestVirtualProperties extends BaseJaxbTest
21+
{
22+
@JsonAppend(attrs={ @JsonAppend.Attr("id"),
23+
@JsonAppend.Attr(value="internal", propName="extra", required=true)
24+
})
25+
static class SimpleBean
26+
{
27+
public int value = 13;
28+
}
29+
30+
@JsonAppend(prepend=true, attrs={ @JsonAppend.Attr("id"),
31+
@JsonAppend.Attr(value="internal", propName="extra")
32+
})
33+
static class SimpleBeanPrepend
34+
{
35+
public int value = 13;
36+
}
37+
38+
enum ABC {
39+
A, B, C;
40+
}
41+
42+
@JsonAppend(attrs=@JsonAppend.Attr(value="desc", include=JsonInclude.Include.NON_EMPTY))
43+
static class OptionalsBean
44+
{
45+
public int value = 28;
46+
}
47+
48+
@SuppressWarnings("serial")
49+
static class CustomVProperty
50+
extends VirtualBeanPropertyWriter
51+
{
52+
private CustomVProperty() { super(); }
53+
54+
private CustomVProperty(BeanPropertyDefinition propDef,
55+
Annotations ctxtAnn, JavaType type) {
56+
super(propDef, ctxtAnn, type);
57+
}
58+
59+
@Override
60+
protected Object value(Object bean, JsonGenerator jgen, SerializerProvider prov) {
61+
if (_name.toString().equals("id")) {
62+
return "abc123";
63+
}
64+
if (_name.toString().equals("extra")) {
65+
return new int[] { 42 };
66+
}
67+
return "???";
68+
}
69+
70+
@Override
71+
public VirtualBeanPropertyWriter withConfig(MapperConfig<?> config,
72+
AnnotatedClass declaringClass, BeanPropertyDefinition propDef,
73+
JavaType type)
74+
{
75+
return new CustomVProperty(propDef, declaringClass.getAnnotations(), type);
76+
}
77+
}
78+
79+
@JsonAppend(prepend=true, props={ @JsonAppend.Prop(value=CustomVProperty.class, name="id"),
80+
@JsonAppend.Prop(value=CustomVProperty.class, name="extra")
81+
})
82+
static class CustomVBean
83+
{
84+
public int value = 72;
85+
}
86+
87+
/*
88+
/**********************************************************
89+
/* Test methods
90+
/**********************************************************
91+
*/
92+
93+
private final ObjectWriter WRITER = newObjectMapper().writer();
94+
95+
public void testAttributeProperties() throws Exception
96+
{
97+
Map<String,Object> stuff = new LinkedHashMap<String,Object>();
98+
stuff.put("x", 3);
99+
stuff.put("y", ABC.B);
100+
101+
String json = WRITER.withAttribute("id", "abc123")
102+
.withAttribute("internal", stuff)
103+
.writeValueAsString(new SimpleBean());
104+
assertEquals(aposToQuotes("{'value':13,'id':'abc123','extra':{'x':3,'y':'B'}}"), json);
105+
106+
json = WRITER.withAttribute("id", "abc123")
107+
.withAttribute("internal", stuff)
108+
.writeValueAsString(new SimpleBeanPrepend());
109+
assertEquals(aposToQuotes("{'id':'abc123','extra':{'x':3,'y':'B'},'value':13}"), json);
110+
}
111+
112+
public void testAttributePropInclusion() throws Exception
113+
{
114+
// first, with desc
115+
String json = WRITER.withAttribute("desc", "nice")
116+
.writeValueAsString(new OptionalsBean());
117+
assertEquals(aposToQuotes("{'value':28,'desc':'nice'}"), json);
118+
119+
// then with null (not defined)
120+
json = WRITER.writeValueAsString(new OptionalsBean());
121+
assertEquals(aposToQuotes("{'value':28}"), json);
122+
123+
// and finally "empty"
124+
json = WRITER.withAttribute("desc", "")
125+
.writeValueAsString(new OptionalsBean());
126+
assertEquals(aposToQuotes("{'value':28}"), json);
127+
}
128+
129+
public void testCustomProperties() throws Exception
130+
{
131+
String json = WRITER.withAttribute("desc", "nice")
132+
.writeValueAsString(new CustomVBean());
133+
assertEquals(aposToQuotes("{'id':'abc123','extra':[42],'value':72}"), json);
134+
}
135+
}

release-notes/VERSION

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Modules:
1010

1111
2.9.3 (not yet released)
1212

13+
#31: (jaxb) `@JsonAppend` causes 'IllegalStateException` `Unsupported annotated member'
14+
with `JaxbAnnotationModule`
15+
(reported by asodja@github)
1316
#32: (jaxb) Fix introspector chaining in `JaxbAnnotationIntrospector.hasRequiredMarker()`
1417
(reported by Vojtěch H)
1518
#33: (afterburner) `@JsonSerialize` with `nullUsing` option not working for `String` properties

0 commit comments

Comments
 (0)