Bernardo Silva created CAMEL-5618:
-------------------------------------
Summary: The tag "contextScan" should inject @Converter methods
from @Converter components.
Key: CAMEL-5618
URL: https://issues.apache.org/jira/browse/CAMEL-5618
Project: Camel
Issue Type: Improvement
Components: camel-core
Affects Versions: 2.10.1
Reporter: Bernardo Silva
The ability to detect converters using "META-INF/services/org/apache/camel" SPI
is cool, but obligates me to make my converters as static methods.
This brings me 3 issues:
1) It is hard to "mock" the converters in the "CamelTestSupport" because he
auto-detect the "real" ones;
2) If I want to "inject" beans in my converter class and use it in my converter
method, I can't.
So, to solve my problem I did a very simple class. I will copy the code at the
end of this. With this class, I don't use Camel SPI anymore and Spring injects
the converters for me using "TypeConverterSupport".
Then, my suggestion is: why the annotation "contextScan" doesn't have a similar
behavior? It would be very nice and simple.
Thanks,
Bernardo Silva
CLASS:
import java.lang.reflect.Method;
import java.util.Map;
import org.apache.camel.CamelContext;
import org.apache.camel.Converter;
import org.apache.camel.Exchange;
import org.apache.camel.TypeConversionException;
import org.apache.camel.support.TypeConverterSupport;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@SuppressWarnings("unchecked")
@Component
public class CamelConverterInjector implements InitializingBean {
@Autowired
private CamelContext camelContext;
@Autowired
private ApplicationContext springContext;
private static abstract class TypeConverterWrapper extends
TypeConverterSupport {
protected final Method method;
protected final Object bean;
protected TypeConverterWrapper(Method method, Object bean) {
this.method = method;
this.bean = method;
}
}
private static final class TypeConverterSimpleWrapper extends
TypeConverterWrapper {
protected TypeConverterSimpleWrapper(Method method, Object
bean) {
super(method, bean);
}
public <T> T convertTo(Class<T> type, Exchange exchange, Object
value) throws TypeConversionException {
try {
return (T) method.invoke(bean, value);
} catch (Throwable t) {
throw new TypeConversionException(value, type,
t);
}
}
}
private static final class TypeConverterExchangeWrapper extends
TypeConverterWrapper {
protected TypeConverterExchangeWrapper(Method method, Object
bean) {
super(method, bean);
}
public <T> T convertTo(Class<T> type, Exchange exchange, Object
value) throws TypeConversionException {
try {
return (T) method.invoke(bean, value, exchange);
} catch (Throwable t) {
throw new TypeConversionException(value, type,
t);
}
}
}
public void afterPropertiesSet() throws Exception {
final Map<String, Object> beans =
springContext.getBeansWithAnnotation(Converter.class);
for (String beanName : beans.keySet()) {
final Object bean = beans.get(beanName);
for (Method method : bean.getClass().getMethods()) {
if (method.getAnnotation(Converter.class) !=
null) {
final Class<?>[] parameterTypes =
method.getParameterTypes();
final TypeConverterWrapper converter;
if (parameterTypes.length == 1) {
converter = new
TypeConverterSimpleWrapper(method, bean);
} else {
converter = new
TypeConverterExchangeWrapper(method, bean);
}
camelContext.getTypeConverterRegistry().addTypeConverter(method.getReturnType(),
parameterTypes[0], converter);
}
}
}
}
}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira