AnsweredAssumed Answered

Extended TypeConverter to support Spring Type Conversion

Question asked by bzim on Feb 13, 2012
I found it difficult to extend the standard SpringExpressionManager (org.activiti.spring.SpringExpressionManager) to supply an extended TypeConverter to support Spring 3 Type Conversion (http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch05s05.html). I like to use it to transparently convert method parameter for service tasks. One problem is the org.activiti.spring.ProcessEngineFactoryBean. In there an initialization of the "standard" SpringExpressionManager is forced and therefore an injection of an enhanced ExpressionManager via org.activiti.spring.SpringProcessEngineConfiguration is not possible. The only solution is to subclass the ProcessEngineFactoryBean and override the initializeExpressionManager method. An other problem is that the BeanELResolver does not use the self created ExpressionFactory because it is never plugged into the ELContext scope.

My request would be to make it easier to integrate extendend TypeConverters/ExpressionFactories/Resolvers.

TypeConverter i like to use:

public class SpringTypeConverter extends TypeConverterImpl{
   private static final long serialVersionUID = 327902613178752994L;
   private ConversionService
      conversionService;
   
   public SpringTypeConverter(ConversionService service){
      this.conversionService = service;
   }
   @Override
   public <T> T convert(Object value, Class<T> type) throws ELException {
      if (conversionService != null && value != null)
         if (conversionService.canConvert(value.getClass(), type))
            return conversionService.convert(value, type);
      
         return super.convert(value, type);
   }
}

The extension of SpringExpressionManager to integrate the above TypeConverter:

public class ExtendedSpringExpressionManager extends SpringExpressionManager implements ApplicationContextAware{

   public ExtendedSpringExpressionManager(Properties properties, ConversionService conversionService) {
      super(null, null);
      
      expressionFactory = new ExpressionFactoryImpl(Profile.JEE6, properties, new SpringTypeConverter(conversionService));
   }
   public void setBeans(Map<Object, Object> beans){
      this.beans = beans;
   }
   @Override
   public void setApplicationContext(ApplicationContext applicationContext)
         throws BeansException {
      this.applicationContext = applicationContext;       
   }
   @Override
   protected ActivitiElContext createElContext(VariableScope variableScope) {
      ActivitiElContext
         ctx = super.createElContext(variableScope);
      
      ctx.putContext(org.activiti.engine.impl.javax.el.ExpressionFactory.class, expressionFactory);
      
      return ctx;
   }
}
And last the extended ProcessEngineFactoryBean to let Spring externally inject the ExtendendExpressionManager above:

public class ExtendedProcessEngineFactoryBean extends ProcessEngineFactoryBean{
   @Override
   protected void initializeExpressionManager(){
   }
}

Outcomes