Object factory

The object factory can create objects according to a beans-like xml configuration file. The configuration file specifies how objects should be created, configured and wired together to form a complete object graph. The object factory can inject the configurations and other beans into a bean.

In its simplest form, the object factory is able to create basic types and java beans from such a configuration:

<beans>
  <bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance"/>
  <string name="greeting">hello world</string>
  <int name="answer">42</int>
  <boolean name="javaisold">true</boolean>
  <float name="percentage">10.2</float>
  <double name="salary">100000000.32</double>
  <char name="java">j</char>
  <null name="dusttodust" />
</beans>

---------------------------------------------------------

ObjectFactory of = ObjectFactory.parseXmlFromAbove();
assertEquals(TaskInstance.class, of.getNewObject("task").getClass());
assertEquals("hello world", of.getNewObject("greeting"));
assertEquals(new Integer(42), of.getNewObject("answer"));
assertEquals(Boolean.TRUE, of.getNewObject("javaisold"));
assertEquals(new Float(10.2), of.getNewObject("percentage"));
assertEquals(new Double(100000000.32), of.getNewObject("salary"));
assertEquals(new Character('j'), of.getNewObject("java"));
assertNull(of.getNewObject("dusttodust"));

Also you can configure lists:

<beans>
  <list name="numbers">
    <string>one</string>
    <string>two</string>
    <string>three</string>
  </list>
</beans>

and maps

<beans>
  <map name="numbers">
    <entry><key><int>1</int></key><value><string>one</string></value></entry>
    <entry><key><int>2</int></key><value><string>two</string></value></entry>
    <entry><key><int>3</int></key><value><string>three</string></value></entry>
  </map>
</beans>

Beans can be configured with direct field injection and via property setters.

<beans>
  <bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
    <field name="name"><string>do dishes</string></field>
    <property name="actorId"><string>theotherguy</string></property>
  </bean>
</beans>

Beans can be referenced. The referenced object doesn't have to be a bean, it can be a string, integer or any other object.

<beans>
  <bean name="a" class="org.jbpm.A" />
  <ref name="b" bean="a" />
</beans>

Beans can be constructed with any constructor

<beans>
  <bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
    <constructor>
      <parameter class="java.lang.String">
        <string>do dishes</string>
      </parameter>
      <parameter class="java.lang.String">
        <string>theotherguy</string>
      </parameter>
    </constructor>
  </bean>
</beans>

... or with a factory method on a bean ...

<beans>
  <bean name="taskFactory" 
         class="org.jbpm.UnexistingTaskInstanceFactory" 
         singleton="true"/>

  <bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
    <constructor factory="taskFactory" method="createTask" >
      <parameter class="java.lang.String">
        <string>do dishes</string>
      </parameter>
      <parameter class="java.lang.String">
        <string>theotherguy</string>
      </parameter>
    </constructor>
  </bean>
</beans>

... or with a static factory method on a class ...

<beans>
  <bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
    <constructor factory-class="org.jbpm.UnexistingTaskInstanceFactory" method="createTask" >
      <parameter class="java.lang.String">
        <string>do dishes</string>
      </parameter>
      <parameter class="java.lang.String">
        <string>theotherguy</string>
      </parameter>
    </constructor>
  </bean>
</beans>

Each named object can be marked as singleton with the attribute singleton="true". That means that a given object factory will always return the same object for each request. Note that singletons are not shared between different object factories.

The singleton feature causes the differentiation between the methods getObject and getNewObject. Typical users of the object factory will use the getNewObject. This means that first the object factory's object cache is cleared before the new object graph is constructed. During construction of the object graph, the non-singleton objects are stored in the object factory's object cache to allow for shared references to one object. The singleton object cache is different from the plain object cache. The singleton cache is never cleared, while the plain object cache is cleared at the start of every getNewObject method.