Jump to: navigation, search

Stardust/Knowledge Base/Web Service API/Structured Data Types as JAXB Objects

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 children 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 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 have already worked with Stardust WS API.

Example Process

To demonstrate, we will use the following process. There are only two activities. The first activity updates structure data types, StudentData and Institute. The second activity just shows the updated data.

The Process

Stardust SDTProcess.jpg

StudData and Institute Sructure Data

The process data of type structured data StudentData and InstituteData are defined by the following XSDs

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>

Structured Data Usage on 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.

Here, 'TakeInSTDAndShow' is the ID of the above shown process. The 'StudData' is the ID of StudentData structured type.

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); 
 }

Structured Data Types as JAXB Objects

As explained in the previous section, forming XML data elements manually 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);
 }

 

If you noticed, here we have replaced the manual task of forming XML elements with JAXB objects. The changes we have done to achieve this are explained below:

  • First we have used the JAXB to create Java POJOs to represent SDT types. Here, StudentData and Institute are JAXB POJOs representing corresponding structured data types.
  • Then we used these POJOs and initialized them with required values.
  • Once JAXB POJOs are initialized, we use 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, generate the classes from them and copy those classes into your project. For exporting structured types as XSD and generating the classes from it, refer the product documentation.

JAXB Object to XML Conversion

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;
 
 }
}