Introduction
I envisioned to create a Generic ADF Human Task Form to support all of our human task (workflow) activities, and in the solution that I thought of, I need an SDO HashMap.
For those who are not familiar, the ADF Human Task Form are remotely deployed bounded task flows (BTFs) that are being accessed by the Oracle BPM woklist app in showing the details of a listed task. The remotely deployed BTFs can support multiple human task as long as they have have identical payload elements. I will describe some more details in subsequent posts.
Problem Description
I need some sort of HashMap like SDO because I need to pass a parameterMap from a human task payload into the dynamic region inside my envisioned Generic ADF Human Task Form, but there is no such HashMap equivalent in SDO or in XML Schema. This post provides an implemented schema and classes to support a HashMap like SDO in Oracle SOA Suite 11g BPEL processes.Artifacts
To create the SDO HashMap we need to have the following artifacts:- MyMapSDO.xsd - Contains the definition of "MyMapSDO" and "MyEntrySDO" complex types to hold the list of entries and the key-value pairs respectively.
- MyEntrySDO.java - Java representation of the MyEntrySDO complex type.
- MyMapSDO.java - Java representation of the MyMapSDO complex type.
- MyEntrySDOImpl.java - implementation
- MyMapSDOImpl.java
- SimpleWrapperUtils.java - this class handles wrapping of simple types like string, integer, long , etc. to dataobjects as described in my previous post.
- Below is the concrete "MyMapSDO.xsd" schema that contains both complex types:
<?xml version="1.0" encoding="windows-1252" ?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://soadev.blogspot.com/map" targetNamespace="http://soadev.blogspot.com/map" xmlns:sdoJava="commonj.sdo/java" sdoJava:package="soadev.sdo.sdohashmap.model"> <xsd:import namespace="commonj.sdo/java"/> <xsd:complexType name="MyMapSDO"> <xsd:sequence> <xsd:element name="entry" type="MyEntrySDO" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="MyEntrySDO"> <xsd:sequence> <xsd:element name="key" type="xsd:string" minOccurs="0"/> <xsd:element name="value" type="xsd:anyType" minOccurs="0"/> </xsd:sequence> </xsd:complexType> <xsd:element name="myMapSDO" type="MyMapSDO"/> </xsd:schema>
- MyEntrySDO.java
package soadev.sdo.sdohashmap.model; public interface MyEntrySDO { String getKey(); void setKey(String key); Object getValue(); void setValue(Object value); }
- MyMapSDO.java
package soadev.sdo.sdohashmap.model; import java.util.List; public interface MyMapSDO { List getEntry(); void setEntry(List value); }
- MyEntrySDOImpl.java
package soadev.sdo.sdohashmap.model; import org.eclipse.persistence.sdo.SDODataObject; public class MyEntrySDOImpl extends SDODataObject implements MyEntrySDO { public String getKey() { return getString("key"); } public void setKey(String key) { set("key", key); } public Object getValue() { return get("value"); } public void setValue(Object value) { set("value", value); } }
- MyMapSDOImpl.java
package soadev.sdo.sdohashmap.model; import commonj.sdo.DataObject; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.persistence.sdo.SDODataObject; import static soadev.sdo.utils.SimpleTypeWrapperUtils.unwrap; public class MyMapSDOImpl extends SDODataObject implements MyMapSDO { public List getEntry() { return getList("entry"); } public void setEntry(List value) { set("entry", value); } //EL reachable public Map<String, Object> getMap(){ Map<String, Object> map = new HashMap<String, Object>(); for(Object obj: getEntry()){ MyEntrySDO entry = (MyEntrySDO)obj; map.put(entry.getKey(), unwrap((DataObject)entry.getValue())); } return map; } }
Testing ...
Below is a sample runner class to illustrate the use case:package soadev.sdo.sdohashmap.main; import commonj.sdo.helper.DataFactory; import commonj.sdo.helper.XMLHelper; import java.math.BigDecimal; import java.util.HashMap; import java.util.List; import java.util.Map; import oracle.jbo.common.sdo.SDOHelper; import soadev.sdo.sdohashmap.model.MyEntrySDO; import soadev.sdo.sdohashmap.model.MyMapSDO; import soadev.sdo.sdohashmap.model.MyMapSDOImpl; import soadev.sdo.sdohashmap.sampleentity.JobSDO; import static soadev.sdo.utils.SimpleTypeWrapperUtils.*; public class Runner { public static void main(String[] args) { try { SDOHelper.INSTANCE.defineSchema("soadev/sdo/sdohashmap/sampleentity/", "JobSDO.xsd"); SDOHelper.INSTANCE.defineSchema("soadev/sdo/sdohashmap/model/", "MyMapSDO.xsd"); MyMapSDO myMapSDO = (MyMapSDO)DataFactory.INSTANCE.create(MyMapSDO.class); MyEntrySDO entry = (MyEntrySDO)DataFactory.INSTANCE.create(MyEntrySDO.class); entry.setKey("param1"); entry.setValue(wrap("SampleValue")); MyEntrySDO entry2 = (MyEntrySDO)DataFactory.INSTANCE.create(MyEntrySDO.class); entry2.setKey("param2"); entry2.setValue(wrap(1)); MyEntrySDO entry3 = (MyEntrySDO)DataFactory.INSTANCE.create(MyEntrySDO.class); entry.setKey("param1"); JobSDO job = (JobSDO)DataFactory.INSTANCE.create(JobSDO.class); job.setJobId("SOADev"); job.setJobTitle("SOA Developer"); job.setMaxSalary(20000L); job.setMinSalary(10000L); entry3.setKey("param3-job"); entry3.setValue(job); MyEntrySDO entry4 = (MyEntrySDO)DataFactory.INSTANCE.create(MyEntrySDO.class); entry4.setKey("param4"); entry4.setValue(wrap(100L)); MyEntrySDO entry5 = (MyEntrySDO)DataFactory.INSTANCE.create(MyEntrySDO.class); entry5.setKey("param5"); entry5.setValue(wrap(true)); MyEntrySDO entry6 = (MyEntrySDO)DataFactory.INSTANCE.create(MyEntrySDO.class); entry6.setKey("param6"); entry6.setValue(wrap(200.50)); MyEntrySDO entry7 = (MyEntrySDO)DataFactory.INSTANCE.create(MyEntrySDO.class); entry7.setKey("param7"); entry7.setValue(wrap(new BigDecimal("550.90"))); List entries = myMapSDO.getEntry(); entries.add(entry); entries.add(entry2); entries.add(entry3); entries.add(entry4); entries.add(entry5); entries.add(entry6); entries.add(entry7); //print XML representation String xmlFragment = XMLHelper.INSTANCE.save((MyMapSDOImpl)myMapSDO, null, "myMapSDO"); System.out.println(xmlFragment); //get map Object Map<String, Object> parameterMap = ((MyMapSDOImpl)myMapSDO).getMap(); for(Map.Entry<String, Object> mapEntry: parameterMap.entrySet()){ System.out.println("key: " + mapEntry.getKey()); System.out.println("value: " + mapEntry.getValue()); System.out.println("value class: " + mapEntry.getValue().getClass()); System.out.println("-----------------------------------------------"); } } catch (Exception ex) { ex.printStackTrace(); } } }Below is the output in the console after running the runner class above:
C:\Oracle\11gR1PS2\jdk160_18\bin\javaw.exe -client -classpath ////--removed very long classpath---//// Djavax.net.ssl.trustStore=C:\Oracle\11gR1PS2\wlserver_10.3\server\lib\DemoTrust.jks soadev.sdo.sdohashmap.main.Runner [EL Warning]: 2010-09-30 03:22:46.25--SDOUtil: Generated Type [ChangeSummary] conflicts with SDO specification naming rules for [ChangeSummary] and should be renamed. <?xml version="1.0" encoding="UTF-8"?> <myMapSDO xsi:type="ns1:MyMapSDO" xmlns:ns1="http://soadev.blogspot.com/map" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <entry> <key>param1</key> <value xsi:type="ns0:string" xmlns:ns0="http://www.w3.org/2001/XMLSchema">SampleValue</value> </entry> <entry> <key>param2</key> <value xsi:type="ns0:int" xmlns:ns0="http://www.w3.org/2001/XMLSchema">1</value> </entry> <entry> <key>param3-job</key> <value xsi:type="ns0:JobSDO" xmlns:ns0="http://soadev.blogspot.com/sampleentity"> <jobId>SOADev</jobId> <jobTitle>SOA Developer</jobTitle> <maxSalary>20000</maxSalary> <minSalary>10000</minSalary> </value> </entry> <entry> <key>param4</key> <value xsi:type="ns0:long" xmlns:ns0="http://www.w3.org/2001/XMLSchema">100</value> </entry> <entry> <key>param5</key> <value xsi:type="ns0:boolean" xmlns:ns0="http://www.w3.org/2001/XMLSchema">true</value> </entry> <entry> <key>param6</key> <value xsi:type="ns0:double" xmlns:ns0="http://www.w3.org/2001/XMLSchema">200.5</value> </entry> <entry> <key>param7</key> <value xsi:type="ns0:decimal" xmlns:ns0="http://www.w3.org/2001/XMLSchema">550.90</value> </entry> </myMapSDO> key: param1 value: SampleValue value class: class java.lang.String ----------------------------------------------- key: param2 value: 1 value class: class java.lang.Integer ----------------------------------------------- key: param4 value: 100 value class: class java.lang.Long ----------------------------------------------- key: param5 value: true value class: class java.lang.Boolean ----------------------------------------------- key: param6 value: 200.5 value class: class java.lang.Double ----------------------------------------------- key: param7 value: 550.90 value class: class java.math.BigDecimal ----------------------------------------------- key: param3-job value: soadev.sdo.sdohashmap.sampleentity.JobSDOImpl@1c208b0 value class: class soadev.sdo.sdohashmap.sampleentity.JobSDOImpl ----------------------------------------------- Process exited with exit code 0.