001: /*
002: * Copyright (C) 2005 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 06. March 2005 by Joe Walnes
011: */
012: package com.thoughtworks.acceptance;
013:
014: import com.thoughtworks.acceptance.objects.Software;
015: import com.thoughtworks.acceptance.objects.StandardObject;
016: import com.thoughtworks.xstream.XStream;
017: import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
018: import com.thoughtworks.xstream.io.xml.DomDriver;
019: import com.thoughtworks.xstream.mapper.DefaultMapper;
020: import com.thoughtworks.xstream.mapper.Mapper;
021: import com.thoughtworks.xstream.mapper.MapperWrapper;
022:
023: public class CustomMapperTest extends AbstractAcceptanceTest {
024:
025: /**
026: * A sample mapper strips the underscore prefix of field names in the XML
027: */
028: private static class FieldPrefixStrippingMapper extends
029: MapperWrapper {
030: public FieldPrefixStrippingMapper(Mapper wrapped) {
031: super (wrapped);
032: }
033:
034: public String serializedMember(Class type, String memberName) {
035: if (memberName.startsWith("_")) {
036: // _blah -> blah
037: memberName = memberName.substring(1); // chop off leading char (the underscore)
038: } else if (memberName.startsWith("my")) {
039: // myBlah -> blah
040: memberName = memberName.substring(2, 3).toLowerCase()
041: + memberName.substring(3);
042: }
043: return super .serializedMember(type, memberName);
044: }
045:
046: public String realMember(Class type, String serialized) {
047: String fieldName = super .realMember(type, serialized);
048: // Not very efficient or elegant, but enough to get the point across.
049: // Luckily the CachingMapper will ensure this is only ever called once per field per class.
050: try {
051: type.getDeclaredField("_" + fieldName);
052: return "_" + fieldName;
053: } catch (NoSuchFieldException e) {
054: try {
055: String myified = "my"
056: + fieldName.substring(0, 1).toUpperCase()
057: + fieldName.substring(1);
058: type.getDeclaredField(myified);
059: return myified;
060: } catch (NoSuchFieldException e2) {
061: return fieldName;
062: }
063: }
064: }
065: }
066:
067: public static class ThingWithStupidNamingConventions extends
068: StandardObject {
069: String _firstName;
070: String lastName;
071: int myAge;
072:
073: public ThingWithStupidNamingConventions(String firstname,
074: String lastname, int age) {
075: _firstName = firstname;
076: this .lastName = lastname;
077: myAge = age;
078: }
079: }
080:
081: public void testUserDefinedMappingCanAlterFieldName() {
082: xstream = new XStream() {
083: protected MapperWrapper wrapMapper(MapperWrapper next) {
084: return new FieldPrefixStrippingMapper(next);
085: }
086: };
087: xstream.alias("thing", ThingWithStupidNamingConventions.class);
088:
089: ThingWithStupidNamingConventions in = new ThingWithStupidNamingConventions(
090: "Joe", "Walnes", 10);
091: String expectedXml = ""
092: + "<thing>\n"
093: + " <firstName>Joe</firstName>\n" // look, no underscores!
094: + " <lastName>Walnes</lastName>\n"
095: + " <age>10</age>\n" + "</thing>";
096:
097: assertBothWays(in, expectedXml);
098: }
099:
100: private static class PackageStrippingMapper extends MapperWrapper {
101: public PackageStrippingMapper(Mapper wrapped) {
102: super (wrapped);
103: }
104:
105: public String serializedClass(Class type) {
106: return type.getName().replaceFirst(".*\\.", "");
107: }
108: }
109:
110: public void testStripsPackagesUponDeserialization() {
111: // obviously this isn't deserializable!
112: xstream = new XStream() {
113: protected MapperWrapper wrapMapper(MapperWrapper next) {
114: return new PackageStrippingMapper(next);
115: }
116: };
117:
118: // NOTE: no aliases defined!
119:
120: String expectedXml = "" + "<Software>\n"
121: + " <vendor>ms</vendor>\n" + " <name>word</name>\n"
122: + "</Software>";
123: assertEquals(expectedXml, xstream.toXML(new Software("ms",
124: "word")));
125: }
126:
127: public void testOwnMapperChainCanBeRegistered() {
128: Mapper mapper = new DefaultMapper(getClass().getClassLoader());
129: xstream = new XStream(new PureJavaReflectionProvider(),
130: new DomDriver(), getClass().getClassLoader(), mapper);
131:
132: String expected = ""
133: + "<com.thoughtworks.acceptance.objects.Software>\n"
134: + " <vendor>ms</vendor>\n" + " <name>word</name>\n"
135: + "</com.thoughtworks.acceptance.objects.Software>";
136: assertEquals(expected, xstream
137: .toXML(new Software("ms", "word")));
138: }
139:
140: public void testCanBeUsedToOmitUnexpectedElements() {
141: String expectedXml = "" + "<software>\n"
142: + " <version>1.0</version>\n"
143: + " <vendor>Joe</vendor>\n"
144: + " <name>XStream</name>\n" + "</software>";
145:
146: xstream = new XStream() {
147:
148: protected MapperWrapper wrapMapper(MapperWrapper next) {
149: return new MapperWrapper(next) {
150:
151: public boolean shouldSerializeMember(
152: Class definedIn, String fieldName) {
153: return definedIn != Object.class ? super
154: .shouldSerializeMember(definedIn,
155: fieldName) : false;
156: }
157:
158: };
159: }
160:
161: };
162: xstream.alias("software", Software.class);
163:
164: Software out = (Software) xstream.fromXML(expectedXml);
165: assertEquals("Joe", out.vendor);
166: assertEquals("XStream", out.name);
167: }
168: }
|