From 9ee57ce90fe638b8ad1b8e246114ff0f882ed255 Mon Sep 17 00:00:00 2001 From: Lucas Cavalcanti Date: Thu, 23 Feb 2012 19:07:44 -0200 Subject: [PATCH] extracting nasty and buggy code to a new class, and testing it --- .../OldAndProbablyBuggyConfigurer.java | 79 +++++++++++++++++++ .../xstream/XStreamSerializer.java | 57 +------------ .../xstream/XStreamSerializerTest.java | 67 ++++++++++++++++ .../xstream/XStreamXMLSerializationTest.java | 4 +- 4 files changed, 149 insertions(+), 58 deletions(-) create mode 100644 vraptor-core/src/main/java/br/com/caelum/vraptor/serialization/xstream/OldAndProbablyBuggyConfigurer.java create mode 100644 vraptor-core/src/test/java/br/com/caelum/vraptor/serialization/xstream/XStreamSerializerTest.java diff --git a/vraptor-core/src/main/java/br/com/caelum/vraptor/serialization/xstream/OldAndProbablyBuggyConfigurer.java b/vraptor-core/src/main/java/br/com/caelum/vraptor/serialization/xstream/OldAndProbablyBuggyConfigurer.java new file mode 100644 index 000000000..0b4b61ddf --- /dev/null +++ b/vraptor-core/src/main/java/br/com/caelum/vraptor/serialization/xstream/OldAndProbablyBuggyConfigurer.java @@ -0,0 +1,79 @@ +package br.com.caelum.vraptor.serialization.xstream; + +import static br.com.caelum.vraptor.serialization.xstream.VRaptorClassMapper.isPrimitive; +import static com.google.common.base.Objects.firstNonNull; + +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.Map.Entry; + +import net.vidageek.mirror.dsl.Mirror; + +import com.google.common.collect.LinkedListMultimap; +import com.google.common.collect.Multimap; +import com.thoughtworks.xstream.XStream; + +public class OldAndProbablyBuggyConfigurer { + + private final XStream xstream; + + public OldAndProbablyBuggyConfigurer(XStream xstream) { + this.xstream = xstream; + } + + public void configure(Serializee serializee) { + Multimap, String> excludesMap = LinkedListMultimap.create(); + if (!serializee.isRecursive()) { + Class type = serializee.getRootClass(); + excludeNonPrimitiveFields(excludesMap, type); + + for (Class eType : firstNonNull(serializee.getElementTypes(), Collections.>emptySet())) { + excludeNonPrimitiveFields(excludesMap, eType); + } + } + for (Entry> exclude : serializee.getExcludes().entries()) { + parseExclude(exclude); + } + for (Entry> include : serializee.getIncludes().entries()) { + parseInclude(excludesMap, include); + } + + for (Entry, String> exclude : excludesMap.entries()) { + xstream.omitField(exclude.getKey(), exclude.getValue()); + } + } + + private void parseExclude(Entry> exclude) { + xstream.omitField(exclude.getValue(), getNameFor(exclude.getKey())); + } + + + private void parseInclude(Multimap, String> excludesMap, Entry> include) { + Class parentType = include.getValue(); + String fieldName = getNameFor(include.getKey()); + Field field = new Mirror().on(parentType).reflect().field(fieldName); + if (field == null) return; + Type genericType = field.getGenericType(); + Class fieldType = Serializee.getActualType(genericType); + + if (!excludesMap.containsKey(fieldType)) { + excludeNonPrimitiveFields(excludesMap, fieldType); + } + excludesMap.remove(parentType, fieldName); + } + + private String getNameFor(String name) { + String[] path = name.split("\\."); + return path[path.length-1]; + } + + private void excludeNonPrimitiveFields(Multimap, String> excludesMap, Class type) { + for (Field field : new Mirror().on(type).reflectAll().fields()) { + if (!isPrimitive(field.getType())) { + excludesMap.put(field.getDeclaringClass(), field.getName()); + } + } + } + +} diff --git a/vraptor-core/src/main/java/br/com/caelum/vraptor/serialization/xstream/XStreamSerializer.java b/vraptor-core/src/main/java/br/com/caelum/vraptor/serialization/xstream/XStreamSerializer.java index af9225cba..3a5447010 100644 --- a/vraptor-core/src/main/java/br/com/caelum/vraptor/serialization/xstream/XStreamSerializer.java +++ b/vraptor-core/src/main/java/br/com/caelum/vraptor/serialization/xstream/XStreamSerializer.java @@ -16,28 +16,20 @@ package br.com.caelum.vraptor.serialization.xstream; import static br.com.caelum.vraptor.serialization.xstream.VRaptorClassMapper.isPrimitive; -import static com.google.common.base.Objects.firstNonNull; import static com.google.common.base.Preconditions.checkNotNull; import java.io.Writer; -import java.lang.reflect.Field; -import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Map.Entry; import java.util.Set; -import net.vidageek.mirror.dsl.Mirror; import br.com.caelum.vraptor.interceptor.TypeNameExtractor; import br.com.caelum.vraptor.serialization.ProxyInitializer; import br.com.caelum.vraptor.serialization.Serializer; import br.com.caelum.vraptor.serialization.SerializerBuilder; -import com.google.common.collect.LinkedListMultimap; -import com.google.common.collect.Multimap; import com.thoughtworks.xstream.XStream; /** @@ -133,55 +125,17 @@ private Set> findElementTypes(Collection list) { return set; } - private void excludeNonPrimitiveFields(Multimap, String> excludesMap, Class type) { - for (Field field : new Mirror().on(type).reflectAll().fields()) { - if (!isPrimitive(field.getType())) { - excludesMap.put(field.getDeclaringClass(), field.getName()); - } - } - } - public Serializer include(String... fields) { serializee.includeAll(fields); return this; } - private void parseInclude(Multimap, String> excludesMap, Entry> include) { - Class parentType = include.getValue(); - String fieldName = getNameFor(include.getKey()); - Type genericType = new Mirror().on(parentType).reflect().field(fieldName).getGenericType(); - Class fieldType = Serializee.getActualType(genericType); - - if (!excludesMap.containsKey(fieldType)) { - excludeNonPrimitiveFields(excludesMap, fieldType); - } - excludesMap.remove(parentType, fieldName); - } - public void serialize() { if (xstream instanceof VRaptorXStream) { VRaptorClassMapper mapper = ((VRaptorXStream) xstream).getVRaptorMapper(); mapper.setSerializee(serializee); } else { - Multimap, String> excludesMap = LinkedListMultimap.create(); - if (!serializee.isRecursive()) { - Class type = serializee.getRootClass(); - excludeNonPrimitiveFields(excludesMap, type); - - for (Class eType : firstNonNull(serializee.getElementTypes(), Collections.>emptySet())) { - excludeNonPrimitiveFields(excludesMap, eType); - } - } - for (Entry> exclude : serializee.getExcludes().entries()) { - parseExclude(exclude); - } - for (Entry> include : serializee.getIncludes().entries()) { - parseInclude(excludesMap, include); - } - - for (Entry, String> exclude : excludesMap.entries()) { - xstream.omitField(exclude.getKey(), exclude.getValue()); - } + new OldAndProbablyBuggyConfigurer(xstream).configure(serializee); } registerProxyInitializer(); @@ -197,13 +151,4 @@ private void registerProxyInitializer() { xstream.registerConverter(new ProxyConverter(initializer, xstream)); } - private void parseExclude(Entry> exclude) { - xstream.omitField(exclude.getValue(), getNameFor(exclude.getKey())); - } - - private String getNameFor(String name) { - String[] path = name.split("\\."); - return path[path.length-1]; - } - } diff --git a/vraptor-core/src/test/java/br/com/caelum/vraptor/serialization/xstream/XStreamSerializerTest.java b/vraptor-core/src/test/java/br/com/caelum/vraptor/serialization/xstream/XStreamSerializerTest.java new file mode 100644 index 000000000..e8cf1e24f --- /dev/null +++ b/vraptor-core/src/test/java/br/com/caelum/vraptor/serialization/xstream/XStreamSerializerTest.java @@ -0,0 +1,67 @@ +package br.com.caelum.vraptor.serialization.xstream; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; +import java.util.Collections; + +import javax.servlet.http.HttpServletResponse; + +import org.junit.Before; + +import br.com.caelum.vraptor.interceptor.DefaultTypeNameExtractor; +import br.com.caelum.vraptor.serialization.NullProxyInitializer; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +/** + * testing the same cases as {@link XStreamXMLSerializationTest} + * but using an arbitrary {@link XStream} implementation, not the {@link VRaptorXStream}. + * @author lucascs + * + */ +public class XStreamSerializerTest extends XStreamXMLSerializationTest { + + @Override + @Before + public void setup() throws Exception { + this.stream = new ByteArrayOutputStream(); + + HttpServletResponse response = mock(HttpServletResponse.class); + when(response.getWriter()).thenReturn(new PrintWriter(stream)); + + + final DefaultTypeNameExtractor extractor = new DefaultTypeNameExtractor(); + this.serialization = new XStreamXMLSerialization(response, extractor, new NullProxyInitializer(), new XStreamBuilderImpl( + new XStreamConverters(Collections.emptyList(), Collections.emptyList()), + extractor) { + @Override + public XStream xmlInstance() { + return configure(new XStream() { + {setMode(NO_REFERENCES);} + @Override + protected MapperWrapper wrapMapper(MapperWrapper next) { + + return new MapperWrapper(next) { + @Override + public String serializedClass(Class type) { + String superName = super.serializedClass(type); + if (type.getName().equals(superName)) { + return extractor.nameFor(type); + } + return superName; + } + }; + } + }); + } + }); + } + +} + diff --git a/vraptor-core/src/test/java/br/com/caelum/vraptor/serialization/xstream/XStreamXMLSerializationTest.java b/vraptor-core/src/test/java/br/com/caelum/vraptor/serialization/xstream/XStreamXMLSerializationTest.java index b71e0416e..6ad2ce2d2 100644 --- a/vraptor-core/src/test/java/br/com/caelum/vraptor/serialization/xstream/XStreamXMLSerializationTest.java +++ b/vraptor-core/src/test/java/br/com/caelum/vraptor/serialization/xstream/XStreamXMLSerializationTest.java @@ -32,8 +32,8 @@ public class XStreamXMLSerializationTest { - private Serialization serialization; - private ByteArrayOutputStream stream; + protected Serialization serialization; + protected ByteArrayOutputStream stream; @Before public void setup() throws Exception {