6
6
*/
7
7
package org .hibernate .type .format .jackson ;
8
8
9
- import org .hibernate .type .format .FormatMapper ;
9
+ import java .lang .reflect .Type ;
10
+ import java .util .ArrayList ;
11
+ import java .util .List ;
12
+
10
13
import org .hibernate .type .descriptor .WrapperOptions ;
11
14
import org .hibernate .type .descriptor .java .JavaType ;
15
+ import org .hibernate .type .format .FormatMapper ;
12
16
17
+ import com .fasterxml .jackson .annotation .JsonCreator ;
18
+ import com .fasterxml .jackson .annotation .JsonInclude ;
19
+ import com .fasterxml .jackson .annotation .JsonProperty ;
13
20
import com .fasterxml .jackson .core .JsonProcessingException ;
14
21
import com .fasterxml .jackson .databind .ObjectMapper ;
22
+ import com .fasterxml .jackson .databind .SerializationFeature ;
15
23
import com .fasterxml .jackson .dataformat .xml .XmlMapper ;
16
24
17
25
/**
@@ -24,10 +32,13 @@ public final class JacksonXmlFormatMapper implements FormatMapper {
24
32
private final ObjectMapper objectMapper ;
25
33
26
34
public JacksonXmlFormatMapper () {
27
- this (new XmlMapper ());
35
+ this ( new XmlMapper () );
28
36
}
29
37
30
38
public JacksonXmlFormatMapper (ObjectMapper objectMapper ) {
39
+ // needed to automatically find and register Jackson's jsr310 module for java.time support
40
+ objectMapper .findAndRegisterModules ();
41
+ objectMapper .configure ( SerializationFeature .WRITE_DATES_AS_TIMESTAMPS , false );
31
42
this .objectMapper = objectMapper ;
32
43
}
33
44
@@ -36,8 +47,25 @@ public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, Wrapper
36
47
if ( javaType .getJavaType () == String .class || javaType .getJavaType () == Object .class ) {
37
48
return (T ) charSequence .toString ();
38
49
}
50
+ if ( javaType .getJavaTypeClass ().isArray () && javaType .getJavaTypeClass ().getComponentType () == String .class ) {
51
+ final StringWrapper [] array = (StringWrapper []) readValueFromString (
52
+ charSequence ,
53
+ javaType ,
54
+ StringWrapper [].class
55
+ );
56
+ final List <String > list = new ArrayList <>( array .length );
57
+ for ( StringWrapper sw : array ) {
58
+ list .add ( sw .getValue () );
59
+ }
60
+ //noinspection unchecked
61
+ return (T ) list .toArray ( String []::new );
62
+ }
63
+ return readValueFromString ( charSequence , javaType , javaType .getJavaType () );
64
+ }
65
+
66
+ private <T > T readValueFromString (CharSequence charSequence , JavaType <T > javaType , Type type ) {
39
67
try {
40
- return objectMapper .readValue ( charSequence .toString (), objectMapper .constructType ( javaType . getJavaType () ) );
68
+ return objectMapper .readValue ( charSequence .toString (), objectMapper .constructType ( type ) );
41
69
}
42
70
catch (JsonProcessingException e ) {
43
71
throw new IllegalArgumentException ( "Could not deserialize string to java type: " + javaType , e );
@@ -49,12 +77,43 @@ public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapper
49
77
if ( javaType .getJavaType () == String .class || javaType .getJavaType () == Object .class ) {
50
78
return (String ) value ;
51
79
}
80
+ else if ( javaType .getJavaTypeClass ().isArray () ) {
81
+ if ( javaType .getJavaTypeClass ().getComponentType () == String .class ) {
82
+ final String [] array = (String []) value ;
83
+ final List <StringWrapper > list = new ArrayList <>( array .length );
84
+ for ( String s : array ) {
85
+ list .add ( new StringWrapper ( s ) );
86
+ }
87
+ return writeValueAsString ( list .toArray ( StringWrapper []::new ), javaType , StringWrapper [].class );
88
+ }
89
+ else if ( javaType .getJavaTypeClass ().getComponentType ().isEnum () ) {
90
+ // for enum arrays we need to explicitly pass Byte[] as the writer type
91
+ return writeValueAsString ( value , javaType , Byte [].class );
92
+ }
93
+ }
94
+ return writeValueAsString ( value , javaType , javaType .getJavaType () );
95
+ }
96
+
97
+ private <T > String writeValueAsString (Object value , JavaType <T > javaType , Type type ) {
52
98
try {
53
- return objectMapper .writerFor ( objectMapper .constructType ( javaType .getJavaType () ) )
54
- .writeValueAsString ( value );
99
+ return objectMapper .writerFor ( objectMapper .constructType ( type ) ).writeValueAsString ( value );
55
100
}
56
101
catch (JsonProcessingException e ) {
57
102
throw new IllegalArgumentException ( "Could not serialize object of java type: " + javaType , e );
58
103
}
59
104
}
105
+
106
+ @ JsonInclude ( JsonInclude .Include .NON_NULL )
107
+ private static class StringWrapper {
108
+ private final String value ;
109
+
110
+ @ JsonCreator
111
+ public StringWrapper (@ JsonProperty ( "value" ) String value ) {
112
+ this .value = value ;
113
+ }
114
+
115
+ public String getValue () {
116
+ return value ;
117
+ }
118
+ }
60
119
}
0 commit comments