This section describes how to handle the type data mapping compatibility with sample code.
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.
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.
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 |
<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 id="srcFieldCtxt" type="test"> <refKColl refId="srcFieldKColl"></refKColl> </context> <context id="destFieldCtxt" type="test"> <refKColl refId="destFieldKColl"></refKColl> </context>
<fmtDef id="fieldToDataFmt"> <mapperConverterExpression> <map from="srcField1" to="integerNumberData" /> <map from="srcField2" to="bigDecimalNumberData" /> <map from="srcField3" to="dateData" /> </mapperConverterExpression> </fmtDef>
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()); } }
<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 id="srcTypedDataCtxt" type="test"> <refKColl refId="srcTypeDataKColl"></refKColl> </context> <context id="destFieldCtxt" type="test"> <refKColl refId="destFieldKColl"></refKColl> </context>
<fmtDef id="typeDataToTypeDataFmt"> <mapperConverterExpression> <map from="shortNumberData" to="integerNumberData" /> <map from="doubleNumberData" to="bigDecimalNumberData" /> </mapperConverterExpression> </fmtDef>
<fmtDef id="typeDataToTypeDataPrecisionLossFmt"> <mapperConverterExpression> <map from="doubleNumberData" to="integerNumberData" /> </mapperConverterExpression> </fmtDef>
<fmtDef id="typeDataToTypeDataErr1Fmt"> <mapperConverterExpression> <map from="bigIntegerData" to="dateData" /> </mapperConverterExpression> </fmtDef>
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()); } }
<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 id="srcKCollCtxt" type="test"> <refKColl refId="srcKeyedCollectionKColl"></refKColl> </context> <context id="destKCollCtxt" type="test"> <refKColl refId="destKeyedCollectionKColl"></refKColl> </context>
<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>
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()); } }
<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 id="srcICollCtxt" type="test"> <refKColl refId="srcIndexedCollectionKColl"></refKColl> </context> <context id="destICollCtxt" type="test"> <refKColl refId="destIndexedCollectionKColl"></refKColl> </context>
<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>
@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()); } }
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.