1
1
package com .fasterxml .jackson .dataformat .xml .ser ;
2
2
3
3
import java .io .IOException ;
4
+ import java .util .Collection ;
5
+
4
6
import javax .xml .namespace .QName ;
5
7
import javax .xml .stream .XMLStreamException ;
6
8
7
9
import com .fasterxml .jackson .core .*;
8
10
import com .fasterxml .jackson .databind .JavaType ;
11
+ import com .fasterxml .jackson .databind .JsonMappingException ;
9
12
import com .fasterxml .jackson .databind .JsonSerializer ;
10
13
import com .fasterxml .jackson .databind .SerializationConfig ;
11
14
import com .fasterxml .jackson .databind .ser .SerializerFactory ;
12
15
import com .fasterxml .jackson .databind .ser .DefaultSerializerProvider ;
13
16
import com .fasterxml .jackson .dataformat .xml .util .StaxUtil ;
17
+ import com .fasterxml .jackson .dataformat .xml .util .TypeUtil ;
14
18
import com .fasterxml .jackson .dataformat .xml .util .XmlRootNameLookup ;
15
19
16
20
@@ -56,37 +60,141 @@ public DefaultSerializerProvider createInstance(SerializationConfig config,
56
60
{
57
61
return new XmlSerializerProvider (this , config , jsf );
58
62
}
59
-
63
+
60
64
@ Override
61
65
public void serializeValue (JsonGenerator jgen , Object value )
62
66
throws IOException , JsonProcessingException
63
67
{
64
- QName rootName = (value == null ) ? ROOT_NAME_FOR_NULL
65
- : _rootNameLookup .findRootName (value .getClass (), _config );
68
+ if (value == null ) {
69
+ _serializeNull (jgen );
70
+ return ;
71
+ }
72
+ Class <?> cls = value .getClass ();
73
+ QName rootName = _rootNameFromConfig ();
74
+ if (rootName == null ) {
75
+ rootName = _rootNameLookup .findRootName (cls , _config );
76
+ }
66
77
_initWithRootName (jgen , rootName );
67
- super .serializeValue (jgen , value );
68
- }
78
+ final boolean asArray = Collection .class .isAssignableFrom (cls ) ||
79
+ (cls .isArray () && cls != byte [].class );
80
+ if (asArray ) {
81
+ _startRootArray (jgen , rootName );
82
+ }
83
+
84
+ // From super-class implementation
85
+ final JsonSerializer <Object > ser = findTypedValueSerializer (cls , true , null );
86
+ try {
87
+ ser .serialize (value , jgen , this );
88
+ } catch (IOException ioe ) { // As per [JACKSON-99], pass IOException and subtypes as-is
89
+ throw ioe ;
90
+ } catch (Exception e ) { // but wrap RuntimeExceptions, to get path information
91
+ String msg = e .getMessage ();
92
+ if (msg == null ) {
93
+ msg = "[no message for " +e .getClass ().getName ()+"]" ;
94
+ }
95
+ throw new JsonMappingException (msg , e );
96
+ }
97
+ // end of super-class implementation
69
98
99
+ if (asArray ) {
100
+ jgen .writeEndObject ();
101
+ }
102
+ }
103
+
70
104
@ Override
71
105
public void serializeValue (JsonGenerator jgen , Object value , JavaType rootType )
72
106
throws IOException , JsonProcessingException
73
107
{
74
- QName rootName = _rootNameLookup .findRootName (rootType , _config );
108
+ if (value == null ) {
109
+ _serializeNull (jgen );
110
+ return ;
111
+ }
112
+ QName rootName = _rootNameFromConfig ();
113
+ if (rootName == null ) {
114
+ rootName = _rootNameLookup .findRootName (rootType , _config );
115
+ }
75
116
_initWithRootName (jgen , rootName );
76
- super .serializeValue (jgen , value , rootType );
77
- }
117
+ final boolean asArray = TypeUtil .isIndexedType (rootType );
118
+ if (asArray ) {
119
+ _startRootArray (jgen , rootName );
120
+ }
78
121
122
+ final JsonSerializer <Object > ser = findTypedValueSerializer (rootType , true , null );
123
+ // From super-class implementation
124
+ try {
125
+ ser .serialize (value , jgen , this );
126
+ } catch (IOException ioe ) { // no wrapping for IO (and derived)
127
+ throw ioe ;
128
+ } catch (Exception e ) { // but others do need to be, to get path etc
129
+ String msg = e .getMessage ();
130
+ if (msg == null ) {
131
+ msg = "[no message for " +e .getClass ().getName ()+"]" ;
132
+ }
133
+ throw new JsonMappingException (msg , e );
134
+ }
135
+ // end of super-class implementation
136
+
137
+ if (asArray ) {
138
+ jgen .writeEndObject ();
139
+ }
140
+ }
141
+
79
142
// @since 2.1
80
143
@ Override
81
144
public void serializeValue (JsonGenerator jgen , Object value , JavaType rootType ,
82
145
JsonSerializer <Object > ser )
83
146
throws IOException , JsonGenerationException
84
147
{
85
- QName rootName = _rootNameLookup .findRootName (rootType , _config );
148
+ if (value == null ) {
149
+ _serializeNull (jgen );
150
+ return ;
151
+ }
152
+ QName rootName = _rootNameFromConfig ();
153
+ if (rootName == null ) {
154
+ rootName = _rootNameLookup .findRootName (rootType , _config );
155
+ }
86
156
_initWithRootName (jgen , rootName );
87
- super .serializeValue (jgen , value , rootType , ser );
157
+ final boolean asArray = TypeUtil .isIndexedType (rootType );
158
+ if (asArray ) {
159
+ _startRootArray (jgen , rootName );
160
+ }
161
+ if (ser == null ) {
162
+ ser = findTypedValueSerializer (rootType , true , null );
163
+ }
164
+ // From super-class implementation
165
+ try {
166
+ ser .serialize (value , jgen , this );
167
+ } catch (IOException ioe ) { // no wrapping for IO (and derived)
168
+ throw ioe ;
169
+ } catch (Exception e ) { // but others do need to be, to get path etc
170
+ String msg = e .getMessage ();
171
+ if (msg == null ) {
172
+ msg = "[no message for " +e .getClass ().getName ()+"]" ;
173
+ }
174
+ throw new JsonMappingException (msg , e );
175
+ }
176
+ // end of super-class implementation
177
+ if (asArray ) {
178
+ jgen .writeEndObject ();
179
+ }
88
180
}
89
-
181
+
182
+ protected void _startRootArray (JsonGenerator jgen , QName rootName )
183
+ throws IOException , JsonProcessingException
184
+ {
185
+ jgen .writeStartObject ();
186
+ // Could repeat root name, but what's the point? How to customize?
187
+ ((ToXmlGenerator ) jgen ).writeFieldName ("item" );
188
+ }
189
+
190
+ @ Override
191
+ protected void _serializeNull (JsonGenerator jgen )
192
+ throws IOException , JsonProcessingException
193
+ {
194
+ _initWithRootName (jgen , ROOT_NAME_FOR_NULL );
195
+ super .serializeValue (jgen , null );
196
+ }
197
+
90
198
protected void _initWithRootName (JsonGenerator jgen , QName rootName )
91
199
throws IOException , JsonProcessingException
92
200
{
@@ -103,7 +211,7 @@ protected void _initWithRootName(JsonGenerator jgen, QName rootName)
103
211
}
104
212
xgen .initGenerator ();
105
213
String ns = rootName .getNamespaceURI ();
106
- /* [Issue- 26] If we just try writing root element with namespace,
214
+ /* [Issue# 26] If we just try writing root element with namespace,
107
215
* we will get an explicit prefix. But we'd rather use the default
108
216
* namespace, so let's try to force that.
109
217
*/
@@ -115,4 +223,10 @@ protected void _initWithRootName(JsonGenerator jgen, QName rootName)
115
223
}
116
224
}
117
225
}
226
+
227
+ protected QName _rootNameFromConfig ()
228
+ {
229
+ String name = _config .getRootName ();
230
+ return (name == null ) ? null : new QName (name );
231
+ }
118
232
}
0 commit comments