1
1
/*
2
- * Copyright 2002-2009 the original author or authors.
2
+ * Copyright 2002-2010 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
16
16
17
17
package org .springframework .oxm .jaxb ;
18
18
19
+ import java .awt .Image ;
19
20
import java .io .ByteArrayInputStream ;
20
21
import java .io .IOException ;
21
22
import java .io .InputStream ;
22
23
import java .io .OutputStream ;
23
24
import java .io .UnsupportedEncodingException ;
25
+ import java .lang .reflect .GenericArrayType ;
26
+ import java .lang .reflect .ParameterizedType ;
27
+ import java .lang .reflect .Type ;
28
+ import java .math .BigDecimal ;
29
+ import java .math .BigInteger ;
24
30
import java .net .URI ;
25
31
import java .net .URISyntaxException ;
26
32
import java .net .URLDecoder ;
27
33
import java .net .URLEncoder ;
28
34
import java .util .Arrays ;
35
+ import java .util .Calendar ;
36
+ import java .util .Date ;
29
37
import java .util .Map ;
30
38
import java .util .UUID ;
31
- import java .lang .reflect .Type ;
32
- import java .lang .reflect .ParameterizedType ;
33
39
import javax .activation .DataHandler ;
34
40
import javax .activation .DataSource ;
35
41
import javax .xml .XMLConstants ;
43
49
import javax .xml .bind .ValidationEventHandler ;
44
50
import javax .xml .bind .ValidationException ;
45
51
import javax .xml .bind .annotation .XmlRootElement ;
46
- import javax .xml .bind .annotation .XmlType ;
47
52
import javax .xml .bind .annotation .adapters .XmlAdapter ;
48
53
import javax .xml .bind .attachment .AttachmentMarshaller ;
49
54
import javax .xml .bind .attachment .AttachmentUnmarshaller ;
55
+ import javax .xml .datatype .Duration ;
56
+ import javax .xml .datatype .XMLGregorianCalendar ;
57
+ import javax .xml .namespace .QName ;
50
58
import javax .xml .stream .XMLEventReader ;
51
59
import javax .xml .stream .XMLEventWriter ;
52
60
import javax .xml .stream .XMLStreamReader ;
68
76
import org .springframework .beans .factory .InitializingBean ;
69
77
import org .springframework .core .annotation .AnnotationUtils ;
70
78
import org .springframework .core .io .Resource ;
79
+ import org .springframework .oxm .GenericMarshaller ;
80
+ import org .springframework .oxm .GenericUnmarshaller ;
71
81
import org .springframework .oxm .MarshallingFailureException ;
72
82
import org .springframework .oxm .UncategorizedMappingException ;
73
83
import org .springframework .oxm .UnmarshallingFailureException ;
74
84
import org .springframework .oxm .ValidationFailureException ;
75
85
import org .springframework .oxm .XmlMappingException ;
76
- import org .springframework .oxm .GenericMarshaller ;
77
- import org .springframework .oxm .GenericUnmarshaller ;
78
86
import org .springframework .oxm .mime .MimeContainer ;
79
87
import org .springframework .oxm .mime .MimeMarshaller ;
80
88
import org .springframework .oxm .mime .MimeUnmarshaller ;
@@ -120,7 +128,7 @@ public class Jaxb2Marshaller
120
128
121
129
private String contextPath ;
122
130
123
- private Class [] classesToBeBound ;
131
+ private Class <?> [] classesToBeBound ;
124
132
125
133
private Map <String , ?> jaxbContextProperties ;
126
134
@@ -134,7 +142,7 @@ public class Jaxb2Marshaller
134
142
135
143
private ValidationEventHandler validationEventHandler ;
136
144
137
- private XmlAdapter [] adapters ;
145
+ private XmlAdapter <?, ?> [] adapters ;
138
146
139
147
private Resource [] schemaResources ;
140
148
@@ -177,15 +185,15 @@ public void setContextPaths(String[] contextPaths) {
177
185
/**
178
186
* Returns the list of Java classes to be recognized by a newly created JAXBContext.
179
187
*/
180
- public Class [] getClassesToBeBound () {
188
+ public Class <?> [] getClassesToBeBound () {
181
189
return classesToBeBound ;
182
190
}
183
191
184
192
/**
185
193
* Set the list of Java classes to be recognized by a newly created JAXBContext.
186
194
* Setting this property or {@link #setContextPath "contextPath"} is required.
187
195
*/
188
- public void setClassesToBeBound (Class [] classesToBeBound ) {
196
+ public void setClassesToBeBound (Class <?> [] classesToBeBound ) {
189
197
this .classesToBeBound = classesToBeBound ;
190
198
}
191
199
@@ -247,7 +255,7 @@ public void setValidationEventHandler(ValidationEventHandler validationEventHand
247
255
* Specify the <code>XmlAdapter</code>s to be registered with the JAXB <code>Marshaller</code>
248
256
* and <code>Unmarshaller</code>
249
257
*/
250
- public void setAdapters (XmlAdapter [] adapters ) {
258
+ public void setAdapters (XmlAdapter <?, ?> [] adapters ) {
251
259
this .adapters = adapters ;
252
260
}
253
261
@@ -394,13 +402,21 @@ public boolean supports(Type genericType) {
394
402
if (genericType instanceof ParameterizedType ) {
395
403
ParameterizedType parameterizedType = (ParameterizedType ) genericType ;
396
404
if (JAXBElement .class .equals (parameterizedType .getRawType ()) &&
397
- parameterizedType .getActualTypeArguments ().length == 1 &&
398
- parameterizedType .getActualTypeArguments ()[0 ] instanceof Class ) {
399
- Class typeArgument = (Class ) parameterizedType .getActualTypeArguments ()[0 ];
400
- return supportsInternal (typeArgument , false );
405
+ parameterizedType .getActualTypeArguments ().length == 1 ) {
406
+ Type typeArgument = parameterizedType .getActualTypeArguments ()[0 ];
407
+ if (typeArgument instanceof Class ) {
408
+ Class <?> classArgument = (Class <?>) typeArgument ;
409
+ if (isPrimitiveWrapper (classArgument ) || isStandardClass (classArgument )) {
410
+ return true ;
411
+ }
412
+ return supportsInternal (classArgument , false );
413
+ } else if (typeArgument instanceof GenericArrayType ) {
414
+ GenericArrayType arrayType = (GenericArrayType ) typeArgument ;
415
+ return arrayType .getGenericComponentType ().equals (Byte .TYPE );
416
+ }
401
417
}
402
418
} else if (genericType instanceof Class ) {
403
- Class clazz = (Class ) genericType ;
419
+ Class <?> clazz = (Class <?> ) genericType ;
404
420
return supportsInternal (clazz , true );
405
421
}
406
422
return false ;
@@ -410,9 +426,6 @@ private boolean supportsInternal(Class<?> clazz, boolean checkForXmlRootElement)
410
426
if (checkForXmlRootElement && AnnotationUtils .findAnnotation (clazz , XmlRootElement .class ) == null ) {
411
427
return false ;
412
428
}
413
- if (AnnotationUtils .findAnnotation (clazz , XmlType .class ) == null ) {
414
- return false ;
415
- }
416
429
if (StringUtils .hasLength (getContextPath ())) {
417
430
String packageName = ClassUtils .getPackageName (clazz );
418
431
String [] contextPaths = StringUtils .tokenizeToStringArray (getContextPath (), ":" );
@@ -429,6 +442,44 @@ else if (!ObjectUtils.isEmpty(getClassesToBeBound())) {
429
442
return false ;
430
443
}
431
444
445
+ /**
446
+ * Checks whether the given type is a primitive wrapper type.
447
+ *
448
+ * @see section 8.5.1 of the JAXB2 spec
449
+ */
450
+ private boolean isPrimitiveWrapper (Class <?> clazz ) {
451
+ return Boolean .class .equals (clazz ) ||
452
+ Byte .class .equals (clazz ) ||
453
+ Short .class .equals (clazz ) ||
454
+ Integer .class .equals (clazz ) ||
455
+ Long .class .equals (clazz ) ||
456
+ Float .class .equals (clazz ) ||
457
+ Double .class .equals (clazz );
458
+ }
459
+
460
+ /**
461
+ * Checks whether the given type is a standard class.
462
+
463
+ * @see section 8.5.2 of the JAXB2 spec
464
+ */
465
+ private boolean isStandardClass (Class <?> clazz ) {
466
+ return String .class .equals (clazz ) ||
467
+ BigInteger .class .isAssignableFrom (clazz ) ||
468
+ BigDecimal .class .isAssignableFrom (clazz ) ||
469
+ Calendar .class .isAssignableFrom (clazz ) ||
470
+ Date .class .isAssignableFrom (clazz ) ||
471
+ QName .class .isAssignableFrom (clazz ) ||
472
+ URI .class .equals (clazz ) ||
473
+ XMLGregorianCalendar .class .isAssignableFrom (clazz ) ||
474
+ Duration .class .isAssignableFrom (clazz ) ||
475
+ Image .class .equals (clazz ) ||
476
+ DataHandler .class .equals (clazz ) ||
477
+ // Source and subclasses should be supported according to the JAXB2 spec, but aren't in the RI
478
+ // Source.class.isAssignableFrom(clazz) ||
479
+ UUID .class .equals (clazz );
480
+
481
+ }
482
+
432
483
// Marshalling
433
484
434
485
public void marshal (Object graph , Result result ) throws XmlMappingException {
@@ -504,7 +555,7 @@ protected void initJaxbMarshaller(Marshaller marshaller) throws JAXBException {
504
555
marshaller .setEventHandler (this .validationEventHandler );
505
556
}
506
557
if (this .adapters != null ) {
507
- for (XmlAdapter adapter : this .adapters ) {
558
+ for (XmlAdapter <?, ?> adapter : this .adapters ) {
508
559
marshaller .setAdapter (adapter );
509
560
}
510
561
}
@@ -589,7 +640,7 @@ protected void initJaxbUnmarshaller(Unmarshaller unmarshaller) throws JAXBExcept
589
640
unmarshaller .setEventHandler (this .validationEventHandler );
590
641
}
591
642
if (this .adapters != null ) {
592
- for (XmlAdapter adapter : this .adapters ) {
643
+ for (XmlAdapter <?, ?> adapter : this .adapters ) {
593
644
unmarshaller .setAdapter (adapter );
594
645
}
595
646
}
0 commit comments