Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Stardust/Knowledge Base/Web Service API/Structured Data Types as JAXB Objects"

m (Example Process)
m
Line 1: Line 1:
 
== Introduction  ==
 
== Introduction  ==
  
Currently, IPP WS expects out data in the form of ParametersXto which in turn takes list of ParameterXto. This ParameterXto is easy to use for primitive data types, but for SDTs we (WS Client) further need to create new XmlValueXto with some implementation of org.w3c.dom.Element with childs and/or attributes to form required xml structure.  
+
Currently, Stardust WS API expects out data in the form of ParametersXto which in turn takes list of ParameterXto. This ParameterXto is easy to use for primitive data types, but for structure data type (SDT) we (WS Client) further need to create new XmlValueXto with some implementation of org.w3c.dom.Element with childs and/or attributes to form required xml structure.  
  
Here one creates the implementation of the Element, and populate the required xml structure [as per your process SDT] and pass it to XmlValueXto and finally, pass the ParametersXto to the completeActivity method as out data. All this is not suitable/easy for WS consumer to deal with.  
+
Here one creates the implementation of the Element, and populate the required xml structure [as per your process SDT] and pass it to XmlValueXto and finally, pass the ParametersXto to the completeActivity method as out data. This all is not easy for WS consumer to deal with and can be avoided with the approach mentioned in this article.
  
This article provides the work around and utility code for IPP WS consumers to enable them to use SDTs as JAXB objects. <br>
+
This article provides the work around and utility code for&nbsp;Stardust WS consumers to enable them to use SDTs as JAXB objects.
 +
 
 +
For this article, it is assumed that you already worked with Stardust WS API.
  
 
== Example Process  ==
 
== Example Process  ==
  
text goes here;
+
To demonstrate, we will use the following process model.<br>
  
 
<br>
 
<br>
  
 +
==== StudentData and Institue Sructure Data ====
  
====StudentData and Institue Sructure Data====
+
The XSDs for StudentData and Institue Sructure Data Tpye looks like following;  
The XSDs for StudentData and Institue Sructure Data Tpye looks like following;
+
  
StudentData XSD:
+
StudentData XSD: <source lang="XML">
<source lang="XML">
+
 
<?xml version="1.0" encoding="UTF-8"?>
 
<?xml version="1.0" encoding="UTF-8"?>
 
<xsd:schema xmlns:stu="http://www.infinity.com/bpm/model/WSModelWithSDT/StudentData" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.infinity.com/bpm/model/WSModelWithSDT/StudentData">
 
<xsd:schema xmlns:stu="http://www.infinity.com/bpm/model/WSModelWithSDT/StudentData" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.infinity.com/bpm/model/WSModelWithSDT/StudentData">
  <xsd:complexType name="StudentData">
+
<xsd:complexType name="StudentData">
    <xsd:sequence>
+
<xsd:sequence>
      <xsd:element name="fname" type="xsd:string"/>
+
<xsd:element name="fname" type="xsd:string"/>
      <xsd:element name="lname" type="xsd:string"/>
+
<xsd:element name="lname" type="xsd:string"/>
    </xsd:sequence>
+
</xsd:sequence>
  </xsd:complexType>
+
</xsd:complexType>
  <xsd:element name="StudentData" type="stu:StudentData"/>
+
<xsd:element name="StudentData" type="stu:StudentData"/>
 
</xsd:schema>
 
</xsd:schema>
  
</source>
+
</source>  
  
 
+
<br>Institue XSD: <source lang="XML">
Institue XSD:
+
<source lang="XML">
+
 
<?xml version="1.0" encoding="UTF-8"?>
 
<?xml version="1.0" encoding="UTF-8"?>
 
<xsd:schema xmlns:ins="http://www.infinity.com/bpm/model/WSModelWithSDT/Institute" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.infinity.com/bpm/model/WSModelWithSDT/Institute">
 
<xsd:schema xmlns:ins="http://www.infinity.com/bpm/model/WSModelWithSDT/Institute" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.infinity.com/bpm/model/WSModelWithSDT/Institute">
  <xsd:complexType name="Institute">
+
<xsd:complexType name="Institute">
    <xsd:sequence>
+
<xsd:sequence>
      <xsd:element name="name" type="xsd:string"/>
+
<xsd:element name="name" type="xsd:string"/>
      <xsd:element name="city" type="xsd:string"/>
+
<xsd:element name="city" type="xsd:string"/>
    </xsd:sequence>
+
</xsd:sequence>
  </xsd:complexType>
+
</xsd:complexType>
  <xsd:element name="Institute" type="ins:Institute"/>
+
<xsd:element name="Institute" type="ins:Institute"/>
 
</xsd:schema>
 
</xsd:schema>
</source>
+
</source>  
  
== How normally you can use structured data with the Stardust WS API  ==
+
== How can you normally&nbsp;use structured data with the Stardust WS API  ==
  
some text goes here
+
Usually you can form the required XML element according to the SDT schema mannually and pass it&nbsp;to the API&nbsp;in the form of String object. This is explained by the code snippets below.
 +
 
 +
&nbsp;
  
 
<source lang="Java">
 
<source lang="Java">
 
private static void startProcessAndComleteFistActivity() throws BpmFault {
 
private static void startProcessAndComleteFistActivity() throws BpmFault {
  
ProcessInstanceXto startProcess = workflowService.startProcess(
+
ProcessInstanceXto startProcess = workflowService.startProcess(
"TakeInSTDAndShow", null, true, null);
+
"TakeInSTDAndShow", null, true, null);
ActivityInstanceXto activateNextActivityForProcess = workflowService
+
ActivityInstanceXto activateNextActivityForProcess = workflowService
.activateNextActivityForProcess(startProcess.getOid());
+
.activateNextActivityForProcess(startProcess.getOid());
  
ParametersXto outData = new ParametersXto();
+
ParametersXto outData = new ParametersXto();
ParameterXto para1 = new ParameterXto();
+
ParameterXto para1 = new ParameterXto();
para1.setName("StudData");
+
para1.setName("StudData");
// para1.setType(QNameConstants.QN_BASE64BINARY);
+
// para1.setType(QNameConstants.QN_BASE64BINARY);
String xmlValStr = "<StudData>" + "<fname>Ganesh</fname>"
+
String xmlValStr = "<StudData>" + "<fname>Ganesh</fname>"
+ "<lname>Lawande</lname>" + "</StudData>";
+
+ "<lname>Lawande</lname>" + "</StudData>";
  
// Custom code to get XML/SDT in form of Element
+
// Custom code to get XML/SDT in form of Element
Document doc = XmlUtils.parseString(xmlValStr);
+
Document doc = XmlUtils.parseString(xmlValStr);
Element documentElement = doc.getDocumentElement();
+
Element documentElement = doc.getDocumentElement();
// Custom code ends here
+
// Custom code ends here
  
XmlValueXto xmlVal = new XmlValueXto();
+
XmlValueXto xmlVal = new XmlValueXto();
xmlVal.getAny().add(documentElement);
+
xmlVal.getAny().add(documentElement);
para1.setXml(xmlVal);
+
para1.setXml(xmlVal);
outData.getParameter().add(para1);
+
outData.getParameter().add(para1);
  
workflowService.completeActivity(activateNextActivityForProcess
+
workflowService.completeActivity(activateNextActivityForProcess
.getOid(), null, outData, true);
+
.getOid(), null, outData, true);
+
+
}
+
}
</source>
+
</source>  
  
 
== How to use Structured Data Types as JAXB objects?  ==
 
== How to use Structured Data Types as JAXB objects?  ==
  
text goes in here;  
+
As explained in the previous section, forming XML data elements mannually&nbsp;is&nbsp;very tedious and error prone task&nbsp;expecially for complex SDT.
 +
 
 +
In this section we will see that how we can use the JAXB here to make life easier. Take a look at code snippets below;
  
 
<source lang="Java">
 
<source lang="Java">
 
private static void startProcessAndComleteFistActivityWithJaxbClass()
 
private static void startProcessAndComleteFistActivityWithJaxbClass()
throws BpmFault, IOException, JAXBException {
+
throws BpmFault, IOException, JAXBException {
  
ProcessInstanceXto startProcess = workflowService.startProcess(
+
ProcessInstanceXto startProcess = workflowService.startProcess(
"TakeInSTDAndShow", null, true, null);
+
"TakeInSTDAndShow", null, true, null);
  
ActivityInstanceXto activateNextActivityForProcess = workflowService
+
ActivityInstanceXto activateNextActivityForProcess = workflowService
.activateNextActivityForProcess(startProcess.getOid());
+
.activateNextActivityForProcess(startProcess.getOid());
  
Institute institute = new Institute();
+
Institute institute = new Institute();
institute.setName("Pune university of applied sciences");
+
institute.setName("Pune university of applied sciences");
institute.setCity("Pune");
+
institute.setCity("Pune");
  
StudentData studentData = new StudentData();
+
StudentData studentData = new StudentData();
studentData.setFname("Tanaji");
+
studentData.setFname("Tanaji");
studentData.setLname("BB");
+
studentData.setLname("BB");
  
ParameterXto para1 = new ParameterXto();
+
ParameterXto para1 = new ParameterXto();
para1.setName("InstituteData");
+
para1.setName("InstituteData");
para1.setType(QNameConstants.QN_BASE64BINARY);
+
para1.setType(QNameConstants.QN_BASE64BINARY);
XmlValueXto xmlVal1 = new XmlValueXto();
+
XmlValueXto xmlVal1 = new XmlValueXto();
xmlVal1.getAny().add(JaxbParserUtility.getAsElement(institute));
+
xmlVal1.getAny().add(JaxbParserUtility.getAsElement(institute));
para1.setXml(xmlVal1);
+
para1.setXml(xmlVal1);
  
ParameterXto para2 = new ParameterXto();
+
ParameterXto para2 = new ParameterXto();
para2.setName("StudData");
+
para2.setName("StudData");
para2.setType(QNameConstants.QN_BASE64BINARY);
+
para2.setType(QNameConstants.QN_BASE64BINARY);
XmlValueXto xmlVal2 = new XmlValueXto();
+
XmlValueXto xmlVal2 = new XmlValueXto();
xmlVal2.getAny().add(JaxbParserUtility.getAsElement(studentData));
+
xmlVal2.getAny().add(JaxbParserUtility.getAsElement(studentData));
para2.setXml(xmlVal2);
+
para2.setXml(xmlVal2);
  
ParametersXto outData = new ParametersXto();
+
ParametersXto outData = new ParametersXto();
outData.getParameter().add(para1);
+
outData.getParameter().add(para1);
outData.getParameter().add(para2);
+
outData.getParameter().add(para2);
  
workflowService.completeActivity(activateNextActivityForProcess
+
workflowService.completeActivity(activateNextActivityForProcess
.getOid(), null, outData, true);
+
.getOid(), null, outData, true);
}
+
}
</source>
+
</source>  
  
 +
&nbsp;
  
Now lets analyze the code line by line;<br>• Code at line no 103 to 108, starts the process synchronouly and activates the first activity of the current process instance.<br>• The code at line no 109 to 116 will be of most interest to you as an Infinity WS consumer or developer. Here Institute and StudentData classes are JAXB objects generated from our Process Model structured types explained above. This means, you are using SDT as POJO and set the required values in an intuitive way. <br>Note that to make these classes available in your project; you will have to export your structured types as XSD and generate the classes from them. And copy those classes into your client project.<br>For exporting structured types as XSD and generating the classes from it, refer the respective sections given below.<br>• Line no 117 to 133, creates the two instances of ParameterXto for InstituteData and StudData each, set the names (as per structure data ids in process model) and types. On line number 121, we know org.w3c.dom.Element type is expected; hence we need to convert our JAXB POJO to XML Element. This is done with the help of getAsElement utility method.<br>• The getAsElement utility method converts JAXB object to required org.w3c.dom.Element. This method is generic enough to take in any JAXB object and convert it into XML Element. The method source code is given below. <br>
+
Here we have replaced the manual task of formming XML element&nbsp;with JAXB. The changes we have done to achive this are explained below:
 +
 
 +
*First we have used the JAXB to create Java POJOs to represent STD types. Here ''StudentData ''and ''Institute ''are JAXB pojos representing corrresponding structured data tyes.
 +
*Then we use these pojos and initialize them with requierd values.  
 +
*Once JAXB pojos are initialized, we the utility class (Explained below)&nbsp;to serialize the pojos into XML form.&nbsp;
 +
 
 +
&nbsp;
 +
 
 +
Note: To make these JAXB pojos&nbsp;available in your project; you will have to export your structured types as XSD and generate the classes from them. And copy those classes into your client project. For exporting structured types as XSD and generating the classes from it, refer the product workbench documentation.<br><br>
  
 
==== Utility To Convert JAXB objects to XML  ====
 
==== Utility To Convert JAXB objects to XML  ====
  
source code goes here;  
+
The utility method, given below,&nbsp;converts JAXB object to required org.w3c.dom.Element. This method is generic enough to take in any JAXB object and convert it into XML Element. The method source code is given below.
 +
 
 +
&nbsp;
  
 
<source lang="Java">
 
<source lang="Java">
Line 151: Line 165:
 
public final class JaxbParserUtility {
 
public final class JaxbParserUtility {
  
public static Element getAsElement(Object dataObj) throws JAXBException,
+
public static Element getAsElement(Object dataObj) throws JAXBException,
IOException {
+
IOException {
  
JAXBContext jc = JAXBContext.newInstance(dataObj.getClass()
+
JAXBContext jc = JAXBContext.newInstance(dataObj.getClass()
.getPackage().getName());
+
.getPackage().getName());
Marshaller m = jc.createMarshaller();
+
Marshaller m = jc.createMarshaller();
  
ByteArrayOutputStream out = new ByteArrayOutputStream();
+
ByteArrayOutputStream out = new ByteArrayOutputStream();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(dataObj, out);
+
m.marshal(dataObj, out);
out.close();
+
out.close();
String tempStr = new String(out.toByteArray());
+
String tempStr = new String(out.toByteArray());
Element elementSDT = XmlUtils.parseString(tempStr).getDocumentElement();
+
Element elementSDT = XmlUtils.parseString(tempStr).getDocumentElement();
  
return elementSDT;
+
return elementSDT;
  
}
+
}
 
}
 
}
  
 
</source>
 
</source>

Revision as of 07:20, 14 November 2011

Introduction

Currently, Stardust WS API expects out data in the form of ParametersXto which in turn takes list of ParameterXto. This ParameterXto is easy to use for primitive data types, but for structure data type (SDT) we (WS Client) further need to create new XmlValueXto with some implementation of org.w3c.dom.Element with childs and/or attributes to form required xml structure.

Here one creates the implementation of the Element, and populate the required xml structure [as per your process SDT] and pass it to XmlValueXto and finally, pass the ParametersXto to the completeActivity method as out data. This all is not easy for WS consumer to deal with and can be avoided with the approach mentioned in this article.

This article provides the work around and utility code for Stardust WS consumers to enable them to use SDTs as JAXB objects.

For this article, it is assumed that you already worked with Stardust WS API.

Example Process

To demonstrate, we will use the following process model.


StudentData and Institue Sructure Data

The XSDs for StudentData and Institue Sructure Data Tpye looks like following;

StudentData XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:stu="http://www.infinity.com/bpm/model/WSModelWithSDT/StudentData" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.infinity.com/bpm/model/WSModelWithSDT/StudentData">
 <xsd:complexType name="StudentData">
 <xsd:sequence>
 <xsd:element name="fname" type="xsd:string"/>
 <xsd:element name="lname" type="xsd:string"/>
 </xsd:sequence>
 </xsd:complexType>
 <xsd:element name="StudentData" type="stu:StudentData"/>
</xsd:schema>

Institue XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:ins="http://www.infinity.com/bpm/model/WSModelWithSDT/Institute" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.infinity.com/bpm/model/WSModelWithSDT/Institute">
 <xsd:complexType name="Institute">
 <xsd:sequence>
 <xsd:element name="name" type="xsd:string"/>
 <xsd:element name="city" type="xsd:string"/>
 </xsd:sequence>
 </xsd:complexType>
 <xsd:element name="Institute" type="ins:Institute"/>
</xsd:schema>

How can you normally use structured data with the Stardust WS API

Usually you can form the required XML element according to the SDT schema mannually and pass it to the API in the form of String object. This is explained by the code snippets below.

 

private static void startProcessAndComleteFistActivity() throws BpmFault {
 
 ProcessInstanceXto startProcess = workflowService.startProcess(
 "TakeInSTDAndShow", null, true, null);
 ActivityInstanceXto activateNextActivityForProcess = workflowService
 .activateNextActivityForProcess(startProcess.getOid());
 
 ParametersXto outData = new ParametersXto();
 ParameterXto para1 = new ParameterXto();
 para1.setName("StudData");
 // para1.setType(QNameConstants.QN_BASE64BINARY);
 String xmlValStr = "<StudData>" + "<fname>Ganesh</fname>"
 + "<lname>Lawande</lname>" + "</StudData>";
 
 // Custom code to get XML/SDT in form of Element
 Document doc = XmlUtils.parseString(xmlValStr);
 Element documentElement = doc.getDocumentElement();
 // Custom code ends here
 
 XmlValueXto xmlVal = new XmlValueXto();
 xmlVal.getAny().add(documentElement);
 para1.setXml(xmlVal);
 outData.getParameter().add(para1);
 
 workflowService.completeActivity(activateNextActivityForProcess
 .getOid(), null, outData, true);
 
 
 }

How to use Structured Data Types as JAXB objects?

As explained in the previous section, forming XML data elements mannually is very tedious and error prone task expecially for complex SDT.

In this section we will see that how we can use the JAXB here to make life easier. Take a look at code snippets below;

private static void startProcessAndComleteFistActivityWithJaxbClass()
 throws BpmFault, IOException, JAXBException {
 
 ProcessInstanceXto startProcess = workflowService.startProcess(
 "TakeInSTDAndShow", null, true, null);
 
 ActivityInstanceXto activateNextActivityForProcess = workflowService
 .activateNextActivityForProcess(startProcess.getOid());
 
 Institute institute = new Institute();
 institute.setName("Pune university of applied sciences");
 institute.setCity("Pune");
 
 StudentData studentData = new StudentData();
 studentData.setFname("Tanaji");
 studentData.setLname("BB");
 
 ParameterXto para1 = new ParameterXto();
 para1.setName("InstituteData");
 para1.setType(QNameConstants.QN_BASE64BINARY);
 XmlValueXto xmlVal1 = new XmlValueXto();
 xmlVal1.getAny().add(JaxbParserUtility.getAsElement(institute));
 para1.setXml(xmlVal1);
 
 ParameterXto para2 = new ParameterXto();
 para2.setName("StudData");
 para2.setType(QNameConstants.QN_BASE64BINARY);
 XmlValueXto xmlVal2 = new XmlValueXto();
 xmlVal2.getAny().add(JaxbParserUtility.getAsElement(studentData));
 para2.setXml(xmlVal2);
 
 ParametersXto outData = new ParametersXto();
 outData.getParameter().add(para1);
 outData.getParameter().add(para2);
 
 workflowService.completeActivity(activateNextActivityForProcess
 .getOid(), null, outData, true);
 }

 

Here we have replaced the manual task of formming XML element with JAXB. The changes we have done to achive this are explained below:

  • First we have used the JAXB to create Java POJOs to represent STD types. Here StudentData and Institute are JAXB pojos representing corrresponding structured data tyes.
  • Then we use these pojos and initialize them with requierd values.
  • Once JAXB pojos are initialized, we the utility class (Explained below) to serialize the pojos into XML form. 

 

Note: To make these JAXB pojos available in your project; you will have to export your structured types as XSD and generate the classes from them. And copy those classes into your client project. For exporting structured types as XSD and generating the classes from it, refer the product workbench documentation.

Utility To Convert JAXB objects to XML

The utility method, given below, converts JAXB object to required org.w3c.dom.Element. This method is generic enough to take in any JAXB object and convert it into XML Element. The method source code is given below.

 

package com.sungard.ipp.bootcamp.ws.client;
 
import java.io.ByteArrayOutputStream;
import java.io.IOException;
 
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
 
import org.w3c.dom.Element;
 
import ag.carnot.utils.xml.XmlUtils;
 
public final class JaxbParserUtility {
 
 public static Element getAsElement(Object dataObj) throws JAXBException,
 IOException {
 
 JAXBContext jc = JAXBContext.newInstance(dataObj.getClass()
 .getPackage().getName());
 Marshaller m = jc.createMarshaller();
 
 ByteArrayOutputStream out = new ByteArrayOutputStream();
 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 m.marshal(dataObj, out);
 out.close();
 String tempStr = new String(out.toByteArray());
 Element elementSDT = XmlUtils.parseString(tempStr).getDocumentElement();
 
 return elementSDT;
 
 }
}

Back to the top