Construct business object (BObj)

During parsing, a business object is constructed and populated.

However, the parser does not have any information about the business object itself except its simple name that it got from the request XML:
<TCRMTxObject>TCRMAddressBObj</TCRMTxObject>

Before OSGi

If you were using the out-of-the-box InfoSphere® MDM parsers, the business objects were specified in properties files like this:
####################################
# COREPARTY BUSINESS OBJECTS       #
####################################
TCRMAddressBObj=com.dwl.tcrm.coreParty.component
TCRMPartyAddressBObj=com.dwl.tcrm.coreParty.component

The parser would look up the correct fully qualified class name of the business object using the simple name included in the request. The value would represent the package name of the business object. By attaching the key (or BObj simple name) to the value (or package name), the parser could derive the fully qualified class name and have enough information to use reflection to construct the business object.

With OSGi

In OSGi, the parser cannot use reflection to get business objects because they could be in any bundle. Instead, OSGi services are used. OSGi services are singletons, so it is not possible to just make each business object a service. Instead, InfoSphere MDM employs a new business object factory that is an OSGi service, and business objects remain as plain Java™ objects. Any bundle containing business objects must define this factory service in a blueprint file. Here is an example blueprint service definition:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
	<service id="BObjFactoryService" 
		interface="com.ibm.mdm.common.bobj.api.BObjFactoryService">
		<service-properties>
			<entry key="business.object">
				<list>
					<value>MyBObj</value>
					<value>...</value>
				</list>
			</entry>
		</service-properties>
		<bean class="com.ibm.mdm.common.bobj.BObjFactoryServiceImpl">
			<argument>
				<map key-type="java.lang.String" value-type="java.lang.Class">
					<entry key="MyBObj" value="com.org.MyBObj"/>
					<entry key="..." value="com.org..."/>
				</map>
			</argument>
			<argument ref="blueprintBundle"/>
		</bean>
	</service>
</blueprint>

The service has a property called business.object that lists the simple names of the business objects found in the bundle. Like most OSGi services, this service consists of a service interface and a service implementation. The interface is com.ibm.mdm.common.bobj.api.BObjFactoryService and the implementation is com.ibm.mdm.common.bobj.BObjFactoryServiceImpl. A technique used in OSGi known as injection is used to load a java.util.Map type object with the business objects contained in this bundle into the factory service implementation.

For every business object in the bundle, an entry such as <entry key="MyBObj" value="com.org.MyBObj"/> is included in the map. This map is passed as a Java constructor <argument> to the service implementation by the blueprint container.

When you extend a business object, you must ensure that the extending business object always supersedes the base business object and is always used instead of the base business object, regardless of which business object was specified in a transaction request. In order to do that, the business object factory OSGi service includes both the base and extending business object in the service properties. If your business object is extending another business object, the BObj Factory service you declare must look like the following:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
	<service id="BObjFactoryService" 
		interface="com.ibm.mdm.common.bobj.api.BObjFactoryService"
		ranking="10">
		<service-properties>
			<entry key="business.object">
				<list>
					<value>PersonBObj</value>
					<value>PersonBObjEXT</value>
				</list>
			</entry>
		</service-properties>
		<bean class="com.ibm.mdm.common.bobj.BObjFactoryServiceImpl">
			<argument>
				<map key-type="java.lang.String" value-type="java.lang.Class">
					<entry key="PersonBObj" value="com.org.BaseBObjEXT"/>
					<entry key="PersonBObjEXT" value="com.org.BaseBObjEXT"/>
				</map>
			</argument>
			<argument ref="blueprintBundle"/>
		</bean>
	</service>
</blueprint>

In the preceding example, PersonBObj is extended by PersonBObjEXT. The service declaration includes a ranking setting: ranking="10". The ranking can be any value, provided it is greater than the ranking of the original service where PersonBObj is specified. All default services in InfoSphere MDM have a ranking of 0, so a ranking of 10 will do. Notice, however, that the map that is injected into the factory service implementation, the name of the PersonBObj and the name of the PersonBObjEXT are linked to the extending business object class name: com.org.BaseBObjEXT. This ensures that the extending business object will always be used throughout InfoSphere MDM.