You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Bernardo Silva (JIRA)" <ji...@apache.org> on 2012/09/16 16:23:07 UTC

[jira] [Created] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

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

[jira] [Updated] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

Posted by "Bernardo Silva (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Bernardo Silva updated CAMEL-5618:
----------------------------------

    Description: 
The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.

This brings me 2 major 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);
				}
			}
		}
	}

}


  was:
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 2 major 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);
				}
			}
		}
	}

}


    
> 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
>         Attachments: CamelConverterInjector.java
>
>
> The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.
> This brings me 2 major 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

[jira] [Assigned] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

Posted by "Willem Jiang (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Willem Jiang reassigned CAMEL-5618:
-----------------------------------

    Assignee: Willem Jiang
    
> 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, camel-spring
>    Affects Versions: 2.10.1
>            Reporter: Bernardo Silva
>            Assignee: Willem Jiang
>         Attachments: CamelConverterInjector.java
>
>
> The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.
> This brings me 2 major 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 = bean;
> 		}
> 	}
> 	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

[jira] [Updated] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

Posted by "Bernardo Silva (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Bernardo Silva updated CAMEL-5618:
----------------------------------

    Attachment: CamelConverterInjector.java

Sample injector using Spring.
                
> 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
>         Attachments: CamelConverterInjector.java
>
>
> 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 2 major 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

[jira] [Commented] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

Posted by "Willem Jiang (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-5618?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13460310#comment-13460310 ] 

Willem Jiang commented on CAMEL-5618:
-------------------------------------

As the AnnotaionTypeConverter doesn't take consideration of the ContextScan and PackageScan this time. I think we need to consider to fix this issue in Camel 3.x.

BTW, I think the patch has no direct relation ship with this issue, but it could provide a work around for the user who uses the spring. I'm planing to apply it into the camel-spring as it is new and it doesn't introduce any other back ward compatible issue. 

                
> 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, camel-spring
>    Affects Versions: 2.10.1
>            Reporter: Bernardo Silva
>            Assignee: Willem Jiang
>             Fix For: Future
>
>         Attachments: CamelConverterInjector.java
>
>
> The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.
> This brings me 2 major 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:
> {code}
> 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 = bean;
> 		}
> 	}
> 	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);
> 				}
> 			}
> 		}
> 	}
> }
> {code}

--
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

[jira] [Updated] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

Posted by "Bernardo Silva (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Bernardo Silva updated CAMEL-5618:
----------------------------------

    Attachment:     (was: CamelConverterInjector.java)
    
> 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, camel-spring
>    Affects Versions: 2.10.1
>            Reporter: Bernardo Silva
>         Attachments: CamelConverterInjector.java
>
>
> The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.
> This brings me 2 major 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 = bean;
> 		}
> 	}
> 	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

[jira] [Commented] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

Posted by "Claus Ibsen (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-5618?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13460302#comment-13460302 ] 

Claus Ibsen commented on CAMEL-5618:
------------------------------------

There is another ticket about making it easier to configure custom type converters in the XML DSL. So hold you horses a bit on this one. The ContextScan and PackageScan etc are all currently based on discovering RouteBuilder classes. We should not expand this for just one of them. I would like to wait with this until that other ticket gets resolved. Then we can revisit whether the *Scan functionality should be expanded to look for more than only RouteBuilder instances.
                
> 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, camel-spring
>    Affects Versions: 2.10.1
>            Reporter: Bernardo Silva
>            Assignee: Willem Jiang
>         Attachments: CamelConverterInjector.java
>
>
> The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.
> This brings me 2 major 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 = bean;
> 		}
> 	}
> 	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

[jira] [Updated] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

Posted by "Bernardo Silva (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Bernardo Silva updated CAMEL-5618:
----------------------------------

    Description: 
The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.

This brings me 2 major 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 = bean;
		}
	}

	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);
				}
			}
		}
	}

}


  was:
The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.

This brings me 2 major 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);
				}
			}
		}
	}

}


    
> 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, camel-spring
>    Affects Versions: 2.10.1
>            Reporter: Bernardo Silva
>         Attachments: CamelConverterInjector.java
>
>
> The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.
> This brings me 2 major 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 = bean;
> 		}
> 	}
> 	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

[jira] [Updated] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

Posted by "Bernardo Silva (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Bernardo Silva updated CAMEL-5618:
----------------------------------

    Attachment: CamelConverterInjector.java
    
> 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, camel-spring
>    Affects Versions: 2.10.1
>            Reporter: Bernardo Silva
>         Attachments: CamelConverterInjector.java
>
>
> The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.
> This brings me 2 major 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 = bean;
> 		}
> 	}
> 	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

[jira] [Updated] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

Posted by "Bernardo Silva (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Bernardo Silva updated CAMEL-5618:
----------------------------------

    Component/s: camel-spring
    
> 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, camel-spring
>    Affects Versions: 2.10.1
>            Reporter: Bernardo Silva
>         Attachments: CamelConverterInjector.java
>
>
> The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.
> This brings me 2 major 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

[jira] [Updated] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

Posted by "Claus Ibsen (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Claus Ibsen updated CAMEL-5618:
-------------------------------

      Description: 
The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.

This brings me 2 major 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:

{code}
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 = bean;
		}
	}

	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);
				}
			}
		}
	}

}
{code}

  was:
The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.

This brings me 2 major 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 = bean;
		}
	}

	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);
				}
			}
		}
	}

}


    Fix Version/s: Future
    
> 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, camel-spring
>    Affects Versions: 2.10.1
>            Reporter: Bernardo Silva
>            Assignee: Willem Jiang
>             Fix For: Future
>
>         Attachments: CamelConverterInjector.java
>
>
> The ability to detect converters using "META-INF/services/org/apache/camel/TypeConverter" SPI is cool, but obligates me to make my converters as static methods.
> This brings me 2 major 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:
> {code}
> 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 = bean;
> 		}
> 	}
> 	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);
> 				}
> 			}
> 		}
> 	}
> }
> {code}

--
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

[jira] [Updated] (CAMEL-5618) The tag "contextScan" should inject @Converter methods from @Converter components.

Posted by "Bernardo Silva (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Bernardo Silva updated CAMEL-5618:
----------------------------------

    Description: 
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 2 major 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);
				}
			}
		}
	}

}


  was:
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);
				}
			}
		}
	}

}


    
> 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 2 major 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