/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. 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
*******************************************************************************/
package org.ebayopensource.turmeric.runtime.common.impl.binding.jaxb;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.ebayopensource.turmeric.runtime.common.binding.DataBindingDesc;
import org.ebayopensource.turmeric.runtime.common.binding.TypeConverter;
import org.ebayopensource.turmeric.runtime.common.exceptions.ErrorDataFactory;
import org.ebayopensource.turmeric.runtime.common.exceptions.ServiceException;
import org.ebayopensource.turmeric.runtime.common.pipeline.InboundMessage;
import org.ebayopensource.turmeric.runtime.common.pipeline.Message;
import org.ebayopensource.turmeric.runtime.common.pipeline.MessageContext;
import org.ebayopensource.turmeric.runtime.common.pipeline.OutboundMessage;
import org.ebayopensource.turmeric.runtime.errorlibrary.ErrorConstants;
/**
* @author wdeng
*
*/
public class TypeConversionAdapter extends XmlAdapter<Object, Object> {
private static ThreadLocal<MessageContext> s_threadContext
= new ThreadLocal<MessageContext>();
public TypeConversionAdapter() {
// local instance
}
public static void setMessageContext(MessageContext ctx) {
s_threadContext.set(ctx);
}
public static MessageContext getMessageContext() {
return s_threadContext.get();
}
/* (non-Javadoc)
* @see javax.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object)
*/
@Override
@SuppressWarnings("unchecked")
public Object marshal(Object v) throws Exception {
if (null == v) {
return null;
}
TypeConverter converter = getTypeConverter(Direction.Outbound, v.getClass());
if (null == converter) {
return null;
}
Class<?> expectedType = converter.getBoundType();
if (!expectedType.isAssignableFrom(v.getClass())) {
throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_DATA_UNEXPECTED_BOUND_TYPE,
ErrorConstants.ERRORDOMAIN, new Object[] {expectedType, v.getClass()}));
}
return converter.preSerializationConvert(getMessageContext(), v);
}
/* (non-Javadoc)
* @see javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object)
*/
@Override
@SuppressWarnings("unchecked")
public Object unmarshal(Object v) throws Exception {
if (null == v) {
return null;
}
TypeConverter converter = getTypeConverter(Direction.Inbound, v.getClass());
if (null == converter) {
return null;
}
Class<?> expectedType = converter.getValueType();
if (!expectedType.isAssignableFrom(v.getClass())) {
throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_DATA_UNEXPECTED_VALUE_TYPE,
ErrorConstants.ERRORDOMAIN, new Object[] {expectedType, v.getClass()}));
}
return converter.postDeserializationConvert(getMessageContext(), v);
}
private TypeConverter getTypeConverter(Direction direction, Class type) throws ServiceException {
MessageContext ctx = getMessageContext();
Message msg = ctx.getRequestMessage();
if (direction == Direction.Inbound && msg instanceof OutboundMessage) {
msg = ctx.getResponseMessage();
}
if (direction == Direction.Outbound && msg instanceof InboundMessage) {
msg = ctx.getResponseMessage();
}
DataBindingDesc dbDesc = msg.getDataBindingDesc();
if (direction == Direction.Inbound) {
return dbDesc.getConverterForValueType(type.getName());
}
return dbDesc.getConverterForBoundType(type.getName());
}
private enum Direction {Inbound, Outbound}
}