tags:

views:

246

answers:

3

Imagine the UI passes back an XMl node as such:

<properties>
<type> Source </type>
<name> Blooper </name>
<delay>
    <type> Deterministic </type>
    <parameters>
       <param>  4 </param>
    </parameters>
<delay>
<batch>
    <type> Erlang </type>
    <parameters>
       <param>  4 </param>
        <param>  6 </param>
    </parameters>
<batch>

And behind the scene what it is asking that you instantiate a class as such:

new Source("blooper", new Exp(4), new Erlang(4,6);

The problem lies in the fact that you don't know what class you will need to processing, and you will be sent a list of these class definitions with instructions on how they can be linked to each other.

I've heard that using a BeanFactoryPostProcessor might be helpful, or a property editor/convertor. However I am at a loss as to how best to use them to solve my problem.

Any help you can provide will be much appreciated.

+1  A: 

if all the classes are loaded into spring context (which means they are instantiated), you can write a factory implementing BeanFactoryAware and get the classes you need calling BeanFactory.getBean("beanId").

config

<bean id="randomIntArrayGenerator" class="com.mirror.exp.RandomIntArrayGenerator">
    <constructor-arg index="0" value="10"/>
</bean>

<bean id="arrayGeneratorFactory" class="com.mirror.exp.ArrayGeneratorFactory"/>

class

public class ArrayGeneratorFactory implements BeanFactoryAware {

private BeanFactory _context;

public ArrayGenerator getGenerator(String type) {
    ArrayGenerator generator = null;
    if ("int".equals(type))
        generator = (ArrayGenerator) _context.getBean("randomIntArrayGenerator");
    return generator;
}

public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    _context = beanFactory;
}

}

gunduz
generator = (ArrayGenerator) _context.getBean("randomIntArrayGenerator");Would I need to do this for every class? ... There's like 200 of them!
Also am I going to have to set each attribute on the bean individually?That makes my beanfactory aware class heavily coupled to all the classes I use.
+1  A: 

I can't seem any reference to spring in your question, so I'll write a spring-less solution. If you have some spring-flex integration that you didn't mention, please share.

Class<?> clazz = Class.forName(type);
return type.newInstance(); // returns a new instance of the specified type

You have two conditions:

  • type must be fully qualified - i.e. com.foo.bar.MyType. If it is not, you have to convert it somehow beforehand
  • the class must have a default (no-arg) constructor.

Then, if you want these classes to have their dependencies autowired by the spring context, you can do this via:

WebApplicationContextUtils.getRequiredWebApplicationContext()
     .getAutowireCapableBeanFactory().autowire(..);

(or autowireBean). If you use the one that takes a Class argument, you should define the beans upfront of scope prototype. Otherwise you just instantiated them and let spring inject their dependencies without configuring them upfront.

Bozho
Yes I do have a Spring-Flex integration. Apologies for not mentioning that earlier, but that is part of the problem. Basically given the bean name I want to instantiate the bean with the properties I get from the UI. And the given an instatiated bean/class I want to be able to call its methods or call methods on it.
@babyangel86 check my update
Bozho
A: 

Castor allows you to map XML to java objects, and XSLT will allow you tweek the GUI XML to match what Castor is expecting

Thanks for all the hints and tips guys!