1
1
/*
2
- * Copyright (C) 2008, 2009, 2011, 2012, 2013, 2015, 2016, 2018 XStream Committers.
2
+ * Copyright (C) 2008, 2009, 2011, 2012, 2013, 2015, 2016, 2018, 2025 XStream Committers.
3
3
* All rights reserved.
4
4
*
5
5
* The software in this package is published under the terms of the BSD
25
25
import com .thoughtworks .xstream .annotations .XStreamConverter ;
26
26
import com .thoughtworks .xstream .annotations .XStreamConverters ;
27
27
import com .thoughtworks .xstream .annotations .XStreamInclude ;
28
+ import com .thoughtworks .xstream .converters .SingleValueConverter ;
28
29
import com .thoughtworks .xstream .converters .basic .BooleanConverter ;
29
30
import com .thoughtworks .xstream .converters .collections .MapConverter ;
30
31
import com .thoughtworks .xstream .converters .extended .NamedCollectionConverter ;
@@ -117,7 +118,7 @@ public void testCanUseCurrentTypeAsParameter() {
117
118
* converterCache on AnnotationMapper is functioning properly.
118
119
*/
119
120
public void testSameConverterWithDifferentType () {
120
- final Type value = new Type (new Decimal ("1.5" ), new Boolean ( true ) );
121
+ final Type value = new Type (new Decimal ("1.5" ), Boolean . TRUE );
121
122
final String expected = ""
122
123
+ "<type>\n "
123
124
+ " <decimal>1.5</decimal>\n "
@@ -137,6 +138,18 @@ public Decimal(final String str) {
137
138
}
138
139
}
139
140
141
+ public void testDerivedTypeWithParent () {
142
+ final Type value = new Type (new Decimal ("1.5" ), Boolean .TRUE );
143
+ final String expected = ""
144
+ + "<type>\n "
145
+ + " <decimal>1.5</decimal>\n "
146
+ + " <boolean>true</boolean>\n "
147
+ + " <agreement>yes</agreement>\n "
148
+ + "</type>" ;
149
+
150
+ assertBothWays (value , expected );
151
+ }
152
+
140
153
public static class Type {
141
154
@ XStreamConverter (ToStringConverter .class )
142
155
private Decimal decimal = null ;
@@ -154,7 +167,7 @@ public Type(final Decimal decimal, final Boolean bool) {
154
167
}
155
168
156
169
public void testConverterRequiringNull () {
157
- final Type value = new DerivedType (new Decimal ("1.5" ), new Boolean ( true ) , DerivedType .E .FOO );
170
+ final Type value = new DerivedType (new Decimal ("1.5" ), Boolean . TRUE , DerivedType .E .FOO );
158
171
final String expected = "<dtype boolean='true' agreement='yes' enum='FOO'>1.5</dtype>" .replace ('\'' , '"' );
159
172
assertBothWays (value , expected );
160
173
}
@@ -168,7 +181,7 @@ public MyType(final Decimal decimal, final Boolean bool) {
168
181
}
169
182
170
183
public void testConverterWithSecondTypeParameter () {
171
- final Type value = new DerivedType (new Decimal ("1.5" ), new Boolean ( true ) , DerivedType .E .FOO );
184
+ final Type value = new DerivedType (new Decimal ("1.5" ), Boolean . TRUE , DerivedType .E .FOO );
172
185
final String expected = "<dtype boolean='true' agreement='yes' enum='FOO'>1.5</dtype>" .replace ('\'' , '"' );
173
186
assertBothWays (value , expected );
174
187
}
@@ -178,7 +191,7 @@ public void testConverterWithSecondTypeParameter() {
178
191
public static class DerivedType extends Type {
179
192
public enum E {
180
193
FOO , BAR
181
- };
194
+ }
182
195
183
196
@ XStreamAlias ("enum" )
184
197
private final E e ;
@@ -190,7 +203,7 @@ public DerivedType(final Decimal decimal, final Boolean bool, final E e) {
190
203
}
191
204
192
205
public void testConverterWithAllAttributes () {
193
- final Type value = new DerivedType2 (new Decimal ("1.5" ), new Boolean ( true ) , DerivedType2 .E .FOO );
206
+ final Type value = new DerivedType2 (new Decimal ("1.5" ), Boolean . TRUE , DerivedType2 .E .FOO );
194
207
final String expected = "<dtype2 decimal='1.5' boolean='true' agreement='yes' enum='FOO'/>" .replace ('\'' , '"' );
195
208
assertBothWays (value , expected );
196
209
}
@@ -200,7 +213,7 @@ public void testConverterWithAllAttributes() {
200
213
public static class DerivedType2 extends Type {
201
214
public enum E {
202
215
FOO , BAR
203
- };
216
+ }
204
217
205
218
@ XStreamAlias ("enum" )
206
219
private final E e ;
@@ -258,7 +271,7 @@ public static class ContainsMap extends StandardObject {
258
271
259
272
public enum E {
260
273
FOO , BAR
261
- };
274
+ }
262
275
263
276
@ XStreamConverter (value = NamedMapConverter .class , strings = {"issue" , "key" , "" }, types = {
264
277
MyEnumMap .class , E .class , String .class }, booleans = {true , false }, useImplicitType = false )
@@ -276,15 +289,15 @@ public void testAnnotatedNamedMapConverterWithMultipleSameArguments() {
276
289
map .put ("FOO" , "foo" );
277
290
map .put ("BAR" , "bar" );
278
291
final ContainsMap2 value = new ContainsMap2 (map );
279
- final String expected = ( ""
292
+ final String expected = ""
280
293
+ "<container-map>\n "
281
294
+ " <map>\n "
282
295
+ " <key>FOO</key>\n "
283
296
+ " <value>foo</value>\n "
284
297
+ " <key>BAR</key>\n "
285
298
+ " <value>bar</value>\n "
286
299
+ " </map>\n "
287
- + "</container-map>" ). replace ( '\'' , '"' ) ;
300
+ + "</container-map>" ;
288
301
assertBothWays (value , expected );
289
302
}
290
303
@@ -308,14 +321,14 @@ public static class MyEnumMap extends LinkedHashMap<ContainsMap.E, String> {
308
321
public void testAnnotatedNamedCollectionConverter () {
309
322
final List <String > names = new ArrayList <>(Arrays .asList ("joe" , "joerg" , "mauro" ));
310
323
final ContainsCollection container = new ContainsCollection (names );
311
- final String expected = ( ""
324
+ final String expected = ""
312
325
+ "<CollCont>\n "
313
326
+ " <names>\n "
314
327
+ " <name>joe</name>\n "
315
328
+ " <name>joerg</name>\n "
316
329
+ " <name>mauro</name>\n "
317
330
+ " </names>\n "
318
- + "</CollCont>" ). replace ( '\'' , '"' ) ;
331
+ + "</CollCont>" ;
319
332
assertBothWays (container , expected );
320
333
}
321
334
@@ -330,4 +343,52 @@ public ContainsCollection(final List<String> names) {
330
343
this .names = names ;
331
344
}
332
345
}
346
+
347
+ public void testAnnotatedConverterFromBaseClass () {
348
+ xstream .processAnnotations (DerivedBase .class );
349
+
350
+ final List <Base > list = new ArrayList <>();
351
+ list .add (new DerivedBase ());
352
+ final String expected = "" //
353
+ + "<list>\n "
354
+ + " <dbase>DB</dbase>\n "
355
+ + "</list>" ;
356
+ assertBothWays (list , expected );
357
+ }
358
+
359
+ public void testAutoDetectedAnnotatedConverterFromBaseClass () {
360
+ xstream .autodetectAnnotations (true );
361
+
362
+ final List <Base > list = new ArrayList <>();
363
+ list .add (new DerivedBase ());
364
+ final String expected = "" //
365
+ + "<list>\n "
366
+ + " <dbase>DB</dbase>\n "
367
+ + "</list>" ;
368
+ assertBothWays (list , expected );
369
+ }
370
+
371
+ public static class BaseConverter implements SingleValueConverter {
372
+
373
+ @ Override
374
+ public boolean canConvert (final Class <?> type ) {
375
+ return Base .class .isAssignableFrom (type );
376
+ }
377
+
378
+ @ Override
379
+ public String toString (final Object obj ) {
380
+ return obj instanceof DerivedBase ? "DB" : "B" ;
381
+ }
382
+
383
+ @ Override
384
+ public Object fromString (final String str ) {
385
+ return str .equals ("DB" ) ? new DerivedBase () : new Base ();
386
+ }
387
+ }
388
+
389
+ @ XStreamConverter (BaseConverter .class )
390
+ public static class Base {}
391
+
392
+ @ XStreamAlias ("dbase" )
393
+ public static class DerivedBase extends Base {}
333
394
}
0 commit comments