package br.com.caelum.example.vraptor.component; import java.io.InputStream; import java.lang.reflect.Method; import br.com.caelum.vraptor.deserialization.XMLDeserializer; import br.com.caelum.vraptor.http.ParameterNameProvider; import br.com.caelum.vraptor.ioc.ApplicationScoped; import br.com.caelum.vraptor.ioc.Component; import br.com.caelum.vraptor.resource.ResourceMethod; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; @ApplicationScoped @Component public class CustomXStreamXMLDeserializer implements XMLDeserializer { private final ParameterNameProvider provider; public CustomXStreamXMLDeserializer(ParameterNameProvider provider) { this.provider = provider; } public Object[] deserialize(InputStream inputStream, ResourceMethod method) { Method javaMethod = method.getMethod(); Class<?>[] types = javaMethod.getParameterTypes(); if (types.length == 0) { throw new IllegalArgumentException("Methods that consumes xml must receive just one argument: the xml root element"); } XStream xStream = getConfiguredXStream(javaMethod, types); Object[] params = new Object[types.length]; chooseParam(types, params, xStream.fromXML(inputStream)); return params; } /** * Returns an xstream instance already configured. */ public XStream getConfiguredXStream(Method javaMethod, Class<?>[] types) { XStream xStream = getXStream(); aliasParams(javaMethod, types, xStream); return xStream; } private void chooseParam(Class<?>[] types, Object[] params, Object deserialized) { for (int i = 0; i < types.length; i++) { if (types[i].isInstance(deserialized)) { params[i] = deserialized; } } } private void aliasParams(Method method, Class<?>[] types, XStream deserializer) { String[] names = provider.parameterNamesFor(method); for (int i = 0; i < names.length; i++) { deserializer.alias(names[i], types[i]); } } /** * Extension point to configure your xstream instance. * @return the configured xstream instance */ protected XStream getXStream() { return new XStream(new DomDriver()); } }