/*** * Copyright (c) 2009 Caelum - www.caelum.com.br/opensource All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package br.com.caelum.vraptor.serialization.xstream; import java.io.InputStream; import java.lang.reflect.Method; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import br.com.caelum.vraptor.controller.ControllerMethod; import br.com.caelum.vraptor.http.Parameter; import br.com.caelum.vraptor.http.ParameterNameProvider; import br.com.caelum.vraptor.serialization.Deserializer; import br.com.caelum.vraptor.serialization.Deserializes; import com.thoughtworks.xstream.XStream; /** * XStream based Xml Deserializer * @author Lucas Cavalcanti * @author Cecilia Fernandes * @author Guilherme Silveira * @author Rafael Viana * @since 3.0.2 */ @RequestScoped @Deserializes({"application/xml","xml", "text/xml"}) public class XStreamXMLDeserializer implements Deserializer { private final ParameterNameProvider provider; private final XStreamBuilder builder; /** * @deprecated CDI eyes only */ protected XStreamXMLDeserializer() { this(null, null); } @Inject public XStreamXMLDeserializer(ParameterNameProvider provider, XStreamBuilder builder) { this.provider = provider; this.builder = builder; } @Override public Object[] deserialize(InputStream inputStream, ControllerMethod 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; } /** * @return an xstream instance already configured. */ public XStream getConfiguredXStream(Method javaMethod, Class<?>[] types) { XStream xStream = builder.recursive().xmlInstance(); xStream.processAnnotations(types); aliasParams(javaMethod, xStream); return xStream; } private static 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, XStream deserializer) { for (Parameter param : provider.parametersFor(method)) { deserializer.alias(param.getName(), param.getType()); } } }