Index: src/test/com/thoughtworks/acceptance/InheritanceMappingTest.java =================================================================== --- src/test/com/thoughtworks/acceptance/InheritanceMappingTest.java (revision 0) +++ src/test/com/thoughtworks/acceptance/InheritanceMappingTest.java (revision 0) @@ -0,0 +1,76 @@ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + +public class InheritanceMappingTest extends AbstractAcceptanceTest { + public static class Base { + public final int value; + + public Base(int value) { + this.value = value; + } + + public String toString() { + String name = getClass().getSimpleName(); + return name.charAt(name.length()-1) + String.valueOf(value) ; + } + } + + public static class DerivedA extends Base { + public DerivedA(int value) { + super(value); + } + } + + public static class DerivedB extends Base { + public DerivedB(int value) { + super(value); + } + } + + public static class Thing { + public final Base value; + + public Thing(Base value) { + this.value = value; + } + } + + public class Converter extends AbstractSingleValueConverter { + @Override + public boolean canConvert(Class type) { + return Base.class.isAssignableFrom(type); + } + + @Override + public Object fromString(String str) { + int value = Integer.parseInt(str.substring(1)); + if (str.startsWith("A")) { + return new DerivedA(value); + } + else if (str.startsWith("B")) { + return new DerivedB(value); + } + else { + throw new ConversionException("cannot convert: str"); + } + } + + } + + public void testExplicitlyConvertingInheritanceElidesClassAttribute() { + xstream.alias("thing", Thing.class); + xstream.convertInheritance(Base.class, new Converter(), new Class[]{DerivedA.class, DerivedB.class}); + + //Note: no class attribute + assertBothWays(new Thing(new DerivedA(77)), + "\n" + + " A77\n" + + ""); + assertBothWays(new Thing(new DerivedB(99)), + "\n" + + " B99\n" + + ""); + } +} Index: src/java/com/thoughtworks/xstream/XStream.java =================================================================== --- src/java/com/thoughtworks/xstream/XStream.java (revision 1649) +++ src/java/com/thoughtworks/xstream/XStream.java (working copy) @@ -11,6 +11,9 @@ */ package com.thoughtworks.xstream; +import com.thoughtworks.acceptance.InheritanceMappingTest.Base; +import com.thoughtworks.acceptance.InheritanceMappingTest.DerivedA; +import com.thoughtworks.acceptance.InheritanceMappingTest.DerivedB; import com.thoughtworks.xstream.alias.ClassMapper; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.ConverterLookup; @@ -1694,4 +1697,17 @@ return this; } + public void convertInheritance(Class supertype, SingleValueConverter converter, + Class[] subtypes) + { + convertInheritance(supertype, (Converter)new SingleValueConverterWrapper(converter), subtypes); + } + + private void convertInheritance(Class supertype, Converter converter, Class[] subtypes) { + registerConverter(converter); + for (int i = 0; i < subtypes.length; i++) { + Class subtype = subtypes[i]; + addDefaultImplementation(subtype, supertype); + } + } }