001: /*
002: * Copyright (C) 2004, 2005, 2006 Joe Walnes.
003: * Copyright (C) 2006, 2007, 2008 XStream Committers.
004: * All rights reserved.
005: *
006: * The software in this package is published under the terms of the BSD
007: * style license a copy of which has been included with this distribution in
008: * the LICENSE.txt file.
009: *
010: * Created on 07. March 2004 by Joe Walnes
011: */
012: package com.thoughtworks.xstream.converters.reflection;
013:
014: import com.thoughtworks.acceptance.objects.StandardObject;
015: import com.thoughtworks.xstream.XStream;
016: import com.thoughtworks.xstream.converters.Converter;
017: import com.thoughtworks.xstream.core.util.CompositeClassLoader;
018: import com.thoughtworks.xstream.io.xml.XppDriver;
019: import com.thoughtworks.xstream.mapper.AttributeMapper;
020: import com.thoughtworks.xstream.mapper.DefaultMapper;
021: import com.thoughtworks.xstream.mapper.Mapper;
022:
023: import junit.framework.TestCase;
024:
025: public class ReflectionConverterTest extends TestCase {
026:
027: public static class World extends StandardObject {
028: int anInt = 1;
029: Integer anInteger = new Integer(2);
030: char anChar = 'a';
031: Character anCharacter = new Character('w');
032: boolean anBool = true;
033: Boolean anBoolean = new Boolean(false);
034: byte aByte = 4;
035: Byte aByteClass = new Byte("5");
036: short aShort = 6;
037: Short aShortClass = new Short("7");
038: float aFloat = 8f;
039: Float aFloatClass = new Float("9");
040: long aLong = 10;
041: Long aLongClass = new Long("11");
042: String anString = new String("XStream programming!");
043: }
044:
045: public void testSerializesAllPrimitiveFieldsInACustomObject() {
046: World world = new World();
047:
048: XStream xstream = new XStream(new XppDriver());
049: xstream.alias("world", World.class);
050:
051: String expected = "<world>\n" + " <anInt>1</anInt>\n"
052: + " <anInteger>2</anInteger>\n"
053: + " <anChar>a</anChar>\n"
054: + " <anCharacter>w</anCharacter>\n"
055: + " <anBool>true</anBool>\n"
056: + " <anBoolean>false</anBoolean>\n"
057: + " <aByte>4</aByte>\n"
058: + " <aByteClass>5</aByteClass>\n"
059: + " <aShort>6</aShort>\n"
060: + " <aShortClass>7</aShortClass>\n"
061: + " <aFloat>8.0</aFloat>\n"
062: + " <aFloatClass>9.0</aFloatClass>\n"
063: + " <aLong>10</aLong>\n"
064: + " <aLongClass>11</aLongClass>\n"
065: + " <anString>XStream programming!</anString>\n"
066: + "</world>";
067:
068: assertEquals(expected, xstream.toXML(world));
069: }
070:
071: public static class TypesOfFields extends StandardObject {
072: String normal = "normal";
073: transient String trans = "transient";
074: static String stat = "stat";
075: }
076:
077: public void testDoesNotSerializeTransientOrStaticFields() {
078: TypesOfFields fields = new TypesOfFields();
079: String expected = "" + "<types>\n"
080: + " <normal>normal</normal>\n" + "</types>";
081:
082: XStream xstream = new XStream(new XppDriver());
083: xstream.alias("types", TypesOfFields.class);
084:
085: String xml = xstream.toXML(fields);
086: assertEquals(expected, xml);
087:
088: }
089:
090: public void testCanBeOverloadedToDeserializeTransientFields() {
091: XStream xstream = new XStream(new XppDriver());
092: xstream.alias("types", TypesOfFields.class);
093: xstream.registerConverter(new ReflectionConverter(xstream
094: .getMapper(), xstream.getReflectionProvider()) {
095:
096: public boolean canConvert(Class type) {
097: return type == TypesOfFields.class;
098: }
099:
100: protected boolean shouldUnmarshalTransientFields() {
101: return true;
102: }
103: });
104:
105: String xml = "" + "<types>\n" + " <normal>normal</normal>\n"
106: + " <trans>foo</trans>\n" + "</types>";
107:
108: TypesOfFields fields = (TypesOfFields) xstream.fromXML(xml);
109: assertEquals("foo", fields.trans);
110: }
111:
112: public void testCustomConverterCanBeInstantiatedAndRegisteredWithDesiredPriority() {
113: XStream xstream = new XStream(new XppDriver());
114: // using default mapper instead of XStream#buildMapper()
115: Mapper mapper = new DefaultMapper(new CompositeClassLoader());
116: // AttributeMapper required by ReflectionConverter
117: mapper = new AttributeMapper(mapper, xstream
118: .getConverterLookup());
119: Converter converter = new CustomReflectionConverter(mapper,
120: new PureJavaReflectionProvider());
121: xstream.registerConverter(converter, -20);
122: xstream.alias("world", World.class);
123: World world = new World();
124:
125: String expected = "<world>\n"
126: + " <anInt class=\"java.lang.Integer\">1</anInt>\n"
127: + " <anInteger>2</anInteger>\n"
128: + " <anChar class=\"java.lang.Character\">a</anChar>\n"
129: + " <anCharacter>w</anCharacter>\n"
130: + " <anBool class=\"java.lang.Boolean\">true</anBool>\n"
131: + " <anBoolean>false</anBoolean>\n"
132: + " <aByte class=\"java.lang.Byte\">4</aByte>\n"
133: + " <aByteClass>5</aByteClass>\n"
134: + " <aShort class=\"java.lang.Short\">6</aShort>\n"
135: + " <aShortClass>7</aShortClass>\n"
136: + " <aFloat class=\"java.lang.Float\">8.0</aFloat>\n"
137: + " <aFloatClass>9.0</aFloatClass>\n"
138: + " <aLong class=\"java.lang.Long\">10</aLong>\n"
139: + " <aLongClass>11</aLongClass>\n"
140: + " <anString>XStream programming!</anString>\n"
141: + "</world>";
142: assertEquals(expected, xstream.toXML(world));
143:
144: }
145:
146: static class CustomReflectionConverter extends ReflectionConverter {
147:
148: public CustomReflectionConverter(Mapper mapper,
149: ReflectionProvider reflectionProvider) {
150: super(mapper, reflectionProvider);
151: }
152: }
153:
154: }
|