package com.bansheeproject.engine.converters;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Collections;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import com.bansheeproject.exceptions.ConverterException;
import com.bansheeproject.log.BansheeLogFactory;
import com.bansheeproject.log.BansheeLogger;
/**
* A converter based on JAXB. It is the default converter of the
* framework.
*
* @author Alexandre Saudate
* @since 1.0
*/
public class JAXBConverter extends ObjectConverter{
private static BansheeLogger logger = BansheeLogFactory.getDefaultLogger(JAXBConverter.class);
@Override
public Object decode(String response, Class<?> expectedType) {
logger.debug(new StringBuilder("Decoding response: ").append(response));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
JAXBContext context = getJAXBContext(expectedType);
Unmarshaller unmarshaller = context.createUnmarshaller();
Reader reader = new StringReader(response);
Object responseObject = unmarshaller.unmarshal(reader);
logger.debug("Response: ".concat(responseObject.toString()));
return responseObject;
}
catch (ClassCastException ex) {
logger.warn("ClassCastException: ".concat(ex.getMessage()));
throw new ConverterException("Expected response type is different than the actual response", ex);
} catch (ConverterException ex) {
logger.warn("ConverterException: ".concat(ex.getMessage()));
throw ex;
} catch (Exception ex) {
if (! (ex instanceof ConverterException)) {
logger.warn("Exception: ".concat(ex.getMessage()));
throw new ConverterException(ex);
}
throw (ConverterException)ex;
}
finally {
try {
baos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@Override
public String encodeImpl(Object source) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
JAXBContext context = getJAXBContext(source);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(source, baos);
String encoded = new String(baos.toByteArray());
return encoded;
} catch (ConverterException ex) {
throw ex;
} catch (Exception ex) {
throw new ConverterException(ex);
}
finally {
try {
baos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
protected JAXBContext getJAXBContext(Class<? extends Object> clazz) {
try {
logger.debug(new StringBuilder("Retrieving JAXBContext for class ").append(clazz));
JAXBContext context = JAXBContext.newInstance(new Class[]{clazz}, Collections.<String, Object>emptyMap());
logger.debug(new StringBuilder("Context created: ").append(context));
return context;
} catch (JAXBException e) {
logger.warn("Exception happened when building JAXBContext.");
logger.warn("Exception data: ".concat(e.getMessage()));
logger.warn("Throwing converter exception...");
throw new ConverterException(e);
}
}
private JAXBContext getJAXBContext(Object source) {
return getJAXBContext(source.getClass());
}
}