Type data mapping compatibility

This section describes how to handle the type data mapping compatibility with sample code.

Purpose

In the data mappings, the data types in the mapping source and mapping target should be compatible. If the two types are compatible, the source data value will be mapped into the target data value. If the two types are not compatible, server side will throw exceptions and the mapping will fail.

Parameter

In the following tables, it list the compatibility of the data types. In the leftmost column, the data types represent the mapping source data type, and all other columns represent the mapping target data type. The letter Y indicates compatible types. The letter N means the types are not compatible. In some situations, the compatibility depends on the more details about the data. You can refer to the detailed information according to the guide below the table.
Table 1. Data Compatibility in server side:
Mapping source data type Mapping target data type
  [context] field [context] typed Data [context] kColl [context] iColl
context -> field Y Yes. If the source value can be correctly converted to destination type. Please see Example 1. N N
context -> typed Data Y Yes If the source value can be correctly converted to destination type. Please see Example 2. Note that, value conversion might lead the loss of precision. N N
context -> kColl N N Yes. Please see Example 3. N
context -> iColl N N N Yes, please see Example 4.
String (The string can be constant or the returned value from function or expressions) Y Yes If the source value can be correctly converted to destination type. Please see Example 1. N N
NLS (The NLS is set from tooling using Constant->NLS or the expressions) Y N N N

In tooling side, if the types of the chosen source data and target data are not compatible, the "Bind" button will be disabled. If the types are compatible, the "Bind" button will be enabled. Tooling provides a basic but not completely compatibility validation that helps you avoid some errors. For example, mapping from filed to kColl is avoided from tooling.

However, the mapping among the type data is not validated accurately according to the real inner data type. Tooling always allow all the mappings among the type data. For example, mapping from "abc" with type String to a data with type Numer is allowed in tooling, but it will cause exception in server side.

Best practice is set correct mapping according to the compatibility in server side.

Sample

Example 1:

  • Data definitions:
     <kColl id="srcFieldKColl" dynamic="false">
    		<field id="srcField1" ></field>
    		<field id="srcField2" ></field>
    		<field id="srcField3" ></field>
    	</kColl>
    	
    	<kColl id="destFieldKColl" dynamic="false">
    		<data id="integerNumberData" refType="Integer"/>
    		<data id="bigDecimalNumberData" refType="BigDecimal"/>
    		<data id="dateData" refType="Date"/>
    	</kColl>				
  • Context definitions:
     <context id="srcFieldCtxt" type="test">
    		<refKColl refId="srcFieldKColl"></refKColl>
    	</context>
    	
    	<context id="destFieldCtxt" type="test">
    		<refKColl refId="destFieldKColl"></refKColl>
    	</context>			
  • Mapping format definitions:
     <fmtDef id="fieldToDataFmt">
    		<mapperConverterExpression>
    			<map from="srcField1" to="integerNumberData" />
    			<map from="srcField2" to="bigDecimalNumberData" />
    			<map from="srcField3" to="dateData" />
    		</mapperConverterExpression>
    	</fmtDef>			
  • Runnable test sample code:
     public void testFieldConvertToDestTypeData() {
    		try {
    			Context ctxtSrc = ContextFactory.createContext("srcFieldCtxt",
    					false);
    			ctxtSrc.setValueAt("srcField1", "1024");
    			ctxtSrc.setValueAt("srcField2", "1048576.9123");
    			ctxtSrc.setValueAt("srcField3", "2011-12-21");
    			Context ctxtDest = ContextFactory.createContext("destFieldCtxt",
    					false);
    			DataMapperExpressionConverterFormat fieldToDataFmt = (DataMapperExpressionConverterFormat) FormatElement
    					.readObject("fieldToDataFmt");
    			fieldToDataFmt.mapContents(ctxtSrc, ctxtDest);
    			assertEquals(Integer.class, ctxtDest
    					.getValueAt("integerNumberData").getClass());
    			assertEquals(new Integer(1024),
    					ctxtDest.getValueAt("integerNumberData"));
    
    			assertEquals(BigDecimal.class,
    					ctxtDest.getValueAt("bigDecimalNumberData").getClass());
    			assertEquals(new BigDecimal("1048576.912300000"),
    					ctxtDest.getValueAt("bigDecimalNumberData"));
    
    			assertEquals(Date.class, ctxtDest.getValueAt("dateData").getClass());
    			assertEquals(
    					new SimpleDateFormat("yyyy-MM-dd").parse("2011-12-21"),
    					ctxtDest.getValueAt("dateData"));
    		} catch (Exception e) {
    			fail("Exception encountered: " + e.getMessage());
    		}
    	}			

Example 2:

  • Data definitions:
    <kColl id="srcTypeDataKColl" dynamic="false">
    		<data id="shortNumberData" refType="Short"/>
    		<data id="doubleNumberData" refType="Double"/>
    		<data id="bigIntegerData" refType="BigInteger"/>
    	</kColl>
    
    	<kColl id="destFieldKColl" dynamic="false">
    		<data id="integerNumberData" refType="Integer"/>
    		<data id="bigDecimalNumberData" refType="BigDecimal"/>
    		<data id="dateData" refType="Date"/>
    	</kColl> 			
  • Context definitions:
     <context id="srcTypedDataCtxt" type="test">
    		<refKColl refId="srcTypeDataKColl"></refKColl>
    	</context>
    	
    	<context id="destFieldCtxt" type="test">
    		<refKColl refId="destFieldKColl"></refKColl>
    	</context>			
  • Mapping format definitions:
    <fmtDef id="typeDataToTypeDataFmt">
    		<mapperConverterExpression>
    			<map from="shortNumberData" to="integerNumberData" />
    			<map from="doubleNumberData" to="bigDecimalNumberData" />
    		</mapperConverterExpression>
    	</fmtDef> 			
    Note: Following format will cause precision loss:
    <fmtDef id="typeDataToTypeDataPrecisionLossFmt">
    		<mapperConverterExpression>
    			<map from="doubleNumberData" to="integerNumberData" />
    		</mapperConverterExpression>
    	</fmtDef>
    Note: Following format cannot be correctly executed:
    <fmtDef id="typeDataToTypeDataErr1Fmt">
    		<mapperConverterExpression>
    			<map from="bigIntegerData" to="dateData" />
    		</mapperConverterExpression>
    	</fmtDef>
  • Runnable test sample code:
    public void testTypedDataConvertToTypedData() {
    		try {
    			Context ctxtSrc = ContextFactory.createContext("srcTypedDataCtxt",
    					false);
    			ctxtSrc.setValueAt("shortNumberData", (short) 512);
    			ctxtSrc.setValueAt("doubleNumberData", 1048576.1024d);
    			Context ctxtDest = ContextFactory.createContext("destFieldCtxt",
    					false);
    			DataMapperExpressionConverterFormat typeDataToTypeDataFmt = (DataMapperExpressionConverterFormat) FormatElement
    					.readObject("typeDataToTypeDataFmt");
    			typeDataToTypeDataFmt.mapContents(ctxtSrc, ctxtDest);
    
    			assertEquals(Integer.class, ctxtDest
    					.getValueAt("integerNumberData").getClass());
    			assertEquals(new Integer(512),
    					ctxtDest.getValueAt("integerNumberData"));
    
    			assertEquals(BigDecimal.class,
    					ctxtDest.getValueAt("bigDecimalNumberData").getClass());
    			assertEquals(new BigDecimal("1048576.102000000"),
    					ctxtDest.getValueAt("bigDecimalNumberData"));
    
    			ctxtSrc.setValueAt("doubleNumberData", 1048576.1024d);
    			DataMapperExpressionConverterFormat typeDataToTypeDataPrecisionLossFmt = (DataMapperExpressionConverterFormat) FormatElement
    					.readObject("typeDataToTypeDataPrecisionLossFmt");
    			typeDataToTypeDataPrecisionLossFmt.mapContents(ctxtSrc, ctxtDest);
    			System.out.println(ctxtDest.getKeyedCollection());
    			assertEquals(Integer.class, ctxtDest
    					.getValueAt("integerNumberData").getClass());
    			assertEquals(new Integer(1048576),
    					ctxtDest.getValueAt("integerNumberData"));
    
    			try {
    				ctxtSrc.setValueAt("bigIntegerData", new BigInteger(
    						"102857600000"));
    				DataMapperExpressionConverterFormat typeDataToTypeDataErr1Fmt = (DataMapperExpressionConverterFormat) FormatElement
    						.readObject("typeDataToTypeDataErr1Fmt");
    				typeDataToTypeDataErr1Fmt.mapContents(ctxtSrc, ctxtDest);
    			} catch (Exception e) {
    				e.printStackTrace();
    				assertEquals(DSETypeException.class, e.getCause().getClass());
    				assertEquals("CONVERT006",((DSETypeException)e.getCause()).getCode());
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			fail("Encounter exception: " + e.getMessage());
    		}
    	} 			

Example 3:

  • Data definitions:
     <kColl id="srcKeyedCollectionKColl" dynamic="false">
    		<kColl id="srcKColl" dynamic="false">
    			<field id="srcF1" />
    			<field id="srcF2" />
    			<field id="srcF3" />
    		</kColl>
    	</kColl>
    	
    	<kColl id="destKeyedCollectionKColl" dynamic="false">
    		<kColl id="destKColl" dynamic="false">
    			<field id="destF1" />
    			<field id="destF2" />
    			<field id="destF3" />
    		</kColl>
    	</kColl>			
  • Context definitions:
     <context id="srcKCollCtxt" type="test">
    		<refKColl refId="srcKeyedCollectionKColl"></refKColl>
    	</context>
    	
    	<context id="destKCollCtxt" type="test">
    		<refKColl refId="destKeyedCollectionKColl"></refKColl>
    	</context>			
  • Mapping format definitions:
    <fmtDef id="kCollToKCollFmt">
    		<mapperConverterExpression>
    			<map from="srcKColl" to="destKColl" />
    		</mapperConverterExpression>
    	</fmtDef>
    	
    
    	<fmtDef id="kCollToKCollDetailFmt">
    		<mapperConverterExpression>
    			<map from="srcKColl.srcF1" to="destKColl.destF1" />
    			<map from="srcKColl.srcF2" to="destKColl.destF2" />
    			<map from="srcKColl.srcF3" to="destKColl.destF3" />
    		</mapperConverterExpression>
    	</fmtDef> 			
  • Runnable test sample code:
     public void testKCollToKColl() {
    		try {
    			Context srcKCollCtxt = ContextFactory.createContext("srcKCollCtxt",
    					false);
    			Date newDate = new Date();
    			srcKCollCtxt.setValueAt("srcKColl.srcF1", (short) 512);
    			srcKCollCtxt.setValueAt("srcKColl.srcF2", 1048576.1024d);
    			srcKCollCtxt.setValueAt("srcKColl.srcF3", newDate);
    			Context destKCollCtxt = ContextFactory.createContext(
    					"destKCollCtxt", false);
    
    			DataMapperExpressionConverterFormat kCollToKCollFmt = (DataMapperExpressionConverterFormat) FormatElement
    					.readObject("kCollToKCollFmt");
    			kCollToKCollFmt.mapContents(srcKCollCtxt, destKCollCtxt);
    
    			// value are not mapped to destination, since there is no dataName
    			// completely match
    			assertNull(destKCollCtxt.getValueAt("destKColl.destF1"));
    			assertNull(destKCollCtxt.getValueAt("destKColl.destF2"));
    			assertNull(destKCollCtxt.getValueAt("destKColl.destF3"));
    
    			DataMapperExpressionConverterFormat kCollToKCollDetailFmt = (DataMapperExpressionConverterFormat) FormatElement
    					.readObject("kCollToKCollDetailFmt");
    			kCollToKCollDetailFmt.mapContents(srcKCollCtxt, destKCollCtxt);
    			assertEquals((short) 512,
    					destKCollCtxt.getValueAt("destKColl.destF1"));
    			assertEquals(1048576.1024d,
    					destKCollCtxt.getValueAt("destKColl.destF2"));
    			assertEquals(newDate, destKCollCtxt.getValueAt("destKColl.destF3"));
    
    			System.out.println(destKCollCtxt.getKeyedCollection());
    		} catch (Exception e) {
    			e.printStackTrace();
    			fail("Encounter exception: " + e.getMessage());
    		}
    	}			

Example 4:

  • Data definitions:
     <kColl id="srcIndexedCollectionKColl" dynamic="true">
    		<iColl id="srcFIColl" size="0">
    			<field id="srcF0"/>
    		</iColl>
    		<iColl id="srcKeyIColl" size="0">
    			<kColl id="srcKColl" dynamic="true">
    				<field id="srcF1" />
    				<field id="srcF2" />
    				<field id="srcF3" />
    			</kColl>
    		</iColl>
    	</kColl>
    
    	<kColl id="destIndexedCollectionKColl" dynamic="true">
    		<iColl id="destFIColl" size="0">
    			<field id="destF0"/>
    		</iColl>
    		<iColl id="destKeyIColl" size="0">
    			<kColl id="destKColl" dynamic="true">
    				<field id="destF1" />
    				<field id="destF2" />
    				<field id="destF3" />
    			</kColl>
    		</iColl>
    	</kColl>			
  • Context definitions:
    <context id="srcICollCtxt" type="test">
    		<refKColl refId="srcIndexedCollectionKColl"></refKColl>
    	</context>
    	
    	<context id="destICollCtxt" type="test">
    		<refKColl refId="destIndexedCollectionKColl"></refKColl>
    	</context>			
  • Mapping format definitions:
    <fmtDef id="fieldICollToiCollFmt">
    		<mapperConverterExpression>
    			<map from="srcFIColl" to="destFIColl" append="true"/>
    		</mapperConverterExpression>
    	</fmtDef>
    	
    	<fmtDef id="fieldICollToiCollDetailFmt">
    		<mapperConverterExpression>
    			<map from="srcFIColl.*" to="destFIColl.*" append="false"/>
    		</mapperConverterExpression>
    	</fmtDef>
    	
    	<fmtDef id="kCollICollToiCollDetailFmt">
    		<mapperConverterExpression>
    			<map from="srcKeyIColl.*.srcF1" to="destKeyIColl.*.destF1" append="false"/>
    			<map from="srcKeyIColl.*.srcF2" to="destKeyIColl.*.destF2" append="ignore"/>
    			<map from="srcKeyIColl.*.srcF3" to="destKeyIColl.*.destF3" append="ignore"/>
    		</mapperConverterExpression>
    	</fmtDef> 			
  • Runnable test sample code:
     @Test
    	public void testICollFieldToICollField1() {
    		try {
    			Context srcICollCtxt = ContextFactory.createContext("srcICollCtxt",
    					false);
    			Context destICollCtxt = ContextFactory.createContext(
    					"destICollCtxt", false);
    
    			IndexedCollection srcFIColl = (IndexedCollection) srcICollCtxt
    					.getElementAt("srcFIColl");
    			assertEquals(0, srcFIColl.size());
    			// set initial values to source indexed collection
    			for (int i = 0; i < 10; i++) {
    				srcICollCtxt.setValueAt("srcFIColl." + i, "SOURCE" + i);
    			}
    			srcFIColl = (IndexedCollection) srcICollCtxt
    					.getElementAt("srcFIColl");
    			assertEquals(10, srcFIColl.size());
    
    			IndexedCollection destFIColl = (IndexedCollection) destICollCtxt
    					.getElementAt("destFIColl");
    			assertEquals(0, destFIColl.size());
    			// set initial values to destination indexed collection
    			for (int i = 0; i < 3; i++) {
    				destICollCtxt.setValueAt("destFIColl." + i, "DOS00" + i);
    			}
    			destFIColl = (IndexedCollection) destICollCtxt
    					.getElementAt("destFIColl");
    			assertEquals(3, destFIColl.size());
    
    			DataMapperExpressionConverterFormat fieldICollToiCollFmt = (DataMapperExpressionConverterFormat) FormatElement
    					.readObject("fieldICollToiCollFmt");
    			fieldICollToiCollFmt.mapContents(srcICollCtxt, destICollCtxt);
    
    			destFIColl = (IndexedCollection) destICollCtxt
    					.getElementAt("destFIColl");
    			assertEquals(10 + 3, destFIColl.size());
    			assertEquals("DOS000", destICollCtxt.getValueAt("destFIColl.0"));
    			assertEquals("DOS002", destICollCtxt.getValueAt("destFIColl.2"));
    			assertEquals("SOURCE0", destICollCtxt.getValueAt("destFIColl.3"));
    			assertEquals("SOURCE5", destICollCtxt.getValueAt("destFIColl.8"));
    			assertEquals("SOURCE9", destICollCtxt.getValueAt("destFIColl.12"));
    		} catch (Exception e) {
    			e.printStackTrace();
    			fail("Encounter exception: " + e.getMessage());
    		}
    	}
    
    	@Test
    	public void testICollFieldToICollField2() {
    		try {
    			Context srcICollCtxt = ContextFactory.createContext("srcICollCtxt",
    					false);
    			Context destICollCtxt = ContextFactory.createContext(
    					"destICollCtxt", false);
    
    			IndexedCollection srcFIColl = (IndexedCollection) srcICollCtxt
    					.getElementAt("srcFIColl");
    			assertEquals(0, srcFIColl.size());
    			// set initial values to source indexed collection
    			for (int i = 0; i < 10; i++) {
    				srcICollCtxt.setValueAt("srcFIColl." + i, "SOURCE" + i);
    			}
    			srcFIColl = (IndexedCollection) srcICollCtxt
    					.getElementAt("srcFIColl");
    			assertEquals(10, srcFIColl.size());
    
    			IndexedCollection destFIColl = (IndexedCollection) destICollCtxt
    					.getElementAt("destFIColl");
    			assertEquals(0, destFIColl.size());
    			// set initial values to destination indexed collection
    			for (int i = 0; i < 3; i++) {
    				destICollCtxt.setValueAt("destFIColl." + i, "DOS00" + i);
    			}
    			destFIColl = (IndexedCollection) destICollCtxt
    					.getElementAt("destFIColl");
    			assertEquals(3, destFIColl.size());
    
    			DataMapperExpressionConverterFormat fieldICollToiCollDetailFmt = (DataMapperExpressionConverterFormat) FormatElement
    					.readObject("fieldICollToiCollDetailFmt");
    			fieldICollToiCollDetailFmt.mapContents(srcICollCtxt, destICollCtxt);
    
    			destFIColl = (IndexedCollection) destICollCtxt
    					.getElementAt("destFIColl");
    			assertEquals(10, destFIColl.size());
    			assertEquals("SOURCE0", destICollCtxt.getValueAt("destFIColl.0"));
    			assertEquals("SOURCE2", destICollCtxt.getValueAt("destFIColl.2"));
    			assertEquals("SOURCE5", destICollCtxt.getValueAt("destFIColl.5"));
    			assertEquals("SOURCE9", destICollCtxt.getValueAt("destFIColl.9"));
    		} catch (Exception e) {
    			e.printStackTrace();
    			fail("Encounter exception: " + e.getMessage());
    		}
    	}
    
    	@Test
    	public void testICollKCollToICollKColl() {
    		try {
    			Context srcICollCtxt = ContextFactory.createContext("srcICollCtxt",
    					false);
    			Context destICollCtxt = ContextFactory.createContext(
    					"destICollCtxt", false);
    
    			IndexedCollection srcKeyIColl = (IndexedCollection) srcICollCtxt
    					.getElementAt("srcKeyIColl");
    			assertEquals(0, srcKeyIColl.size());
    			// set initial values to source indexed collection
    			for (int i = 0; i < 10; i++) {
    				srcICollCtxt.setValueAt("srcKeyIColl." + i + ".srcF1",
    						"SOURCE_FIELD10" + i);
    				srcICollCtxt.setValueAt("srcKeyIColl." + i + ".srcF2",
    						"SOURCE_FIELD20" + i);
    				srcICollCtxt.setValueAt("srcKeyIColl." + i + ".srcF3",
    						"SOURCE_FIELD30" + i);
    			}
    			srcKeyIColl = (IndexedCollection) srcICollCtxt
    					.getElementAt("srcKeyIColl");
    			assertEquals(10, srcKeyIColl.size());
    
    			IndexedCollection destKeyIColl = (IndexedCollection) destICollCtxt
    					.getElementAt("destKeyIColl");
    			assertEquals(0, destKeyIColl.size());
    			// set initial values to destination indexed collection
    			for (int i = 0; i < 3; i++) {
    				destICollCtxt.setValueAt("destKeyIColl." + i + ".destF1",
    						"DOS10" + i);
    				destICollCtxt.setValueAt("destKeyIColl." + i + ".destF2",
    						"DOS20" + i);
    				destICollCtxt.setValueAt("destKeyIColl." + i + ".destF3",
    						"DOS30" + i);
    			}
    			destKeyIColl = (IndexedCollection) destICollCtxt
    					.getElementAt("destKeyIColl");
    			assertEquals(3, destKeyIColl.size());
    
    			DataMapperExpressionConverterFormat kCollICollToiCollDetailFmt = (DataMapperExpressionConverterFormat) FormatElement
    					.readObject("kCollICollToiCollDetailFmt");
    			kCollICollToiCollDetailFmt.mapContents(srcICollCtxt, destICollCtxt);
    
    			destKeyIColl = (IndexedCollection) destICollCtxt
    					.getElementAt("destKeyIColl");
    			assertEquals(10, destKeyIColl.size());
    
    			assertEquals("SOURCE_FIELD100", destICollCtxt.getValueAt("destKeyIColl.0.destF1"));
    			assertEquals("SOURCE_FIELD201", destICollCtxt.getValueAt("destKeyIColl.1.destF2"));
    			assertEquals("SOURCE_FIELD302", destICollCtxt.getValueAt("destKeyIColl.2.destF3"));
    			assertEquals("SOURCE_FIELD103", destICollCtxt.getValueAt("destKeyIColl.3.destF1"));
    			assertEquals("SOURCE_FIELD204", destICollCtxt.getValueAt("destKeyIColl.4.destF2"));
    			assertEquals("SOURCE_FIELD305", destICollCtxt.getValueAt("destKeyIColl.5.destF3"));
    			assertEquals("SOURCE_FIELD106", destICollCtxt.getValueAt("destKeyIColl.6.destF1"));
    			assertEquals("SOURCE_FIELD207", destICollCtxt.getValueAt("destKeyIColl.7.destF2"));
    			assertEquals("SOURCE_FIELD308", destICollCtxt.getValueAt("destKeyIColl.8.destF3"));
    		} catch (Exception e) {
    			e.printStackTrace();
    			fail("Encounter exception: " + e.getMessage());
    		}
    	}