




















































(For more resources related to this topic, see here.)
The Business Process Execution Language (BPEL) is based on XML, which means that all the internal variables and data are presented in XML. BPEL and Java technologies are complementary, we seek ways to ease the integration of the technologies. In order to handle the XML content from BPEL variables in Java resources (classes), we have a couple of possibilities:
oracle.xml.parser.v2.XMLElement input_cf= (oracle.xml.parser.
v2.XMLElement)getVariableData("inputVariable","payload","/
client:Cashflows");
We receive the XMLElement class, which we need to handle further, either be assignment, reading of content, iteration, or something else.
java.util.List<org.packt.cashflow.facade.PrincipalExchange>
princEx= cf.getPrincipalExchange();
We can see that there is neither XML content nor DOM API anymore. Furthermore, we have to access the whole XML structure represented by Java classes.
The latest specification of JAXB at the time of writing is 2.2.7, and its specification can be found at the following location: https://jaxb.java.net/.
The purpose of an XML facade operation is the marshalling and un-marshalling of Java classes. When the originated content is presented in XML, we use un-marshalling methods in order to generate the correspondent Java classes. In cases where we have content stored in Java classes and we want to present the content in XML, we use the marshalling methods.
JAXB provides the ability to create XML facade from an XML schema definition or from the WSDL (Web Service Definition/Description Language). The latter method provides a useful approach as we, in most cases, orchestrate web services whose operations are defined in WSDL documents.
Throughout this article, we will work on a sample from the banking world. On top of this sample, we will show how to build the XML facade. The sample contains the simple XML types, complex types, elements, and cardinality, so we cover all the essential elements of functionality in XML facade.
We start generating XML facade by setting up a project in a JDeveloper environment which provides convenient tools for building XML facades. This recipe will describe how to set up a JDeveloper project in order to build XML facade.
To complete the recipe, we need the XML schema of the BPEL process variables based on which we build XML facade. Explore the XML schema of our banking BPEL process. We are interested in the structure of the BPEL request message:
<xsd:complexType name="PrincipalExchange">
<xsd:sequence>
<xsd:element minOccurs="0"
name="unadjustedPrincipalExchangeDate" type="xsd:date"/>
<xsd:element minOccurs="0"
name="adjustedPrincipalExchangeDate" type="xsd:date"/>
<xsd:element minOccurs="0" name="principalExchangeAmount"
type="xsd:decimal"/>
<xsd:element minOccurs="0" name="discountFactor"
type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:int"/>
</xsd:complexType>
<xsd:complexType name="CashflowsType">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0"
name="principalExchange" type="prc:PrincipalExchange"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="Cashflows" type="prc:CashflowsType"/>
The request message structure presents just a small fragment of cash flows modeled in the banks. The concrete definition of a cash flow is much more complex. However, our definition contains all the right elements so that we can show the advantages of using XML facade in a BPEL process.
The steps involved in setting up a JDeveloper project for XML façade are as follows:
After the wizard has finished, we can see the project structure created in JDeveloper. Also, the corresponding file structure is created in the filesystem.
This recipe explains how to generate XML facade with the use of the Apache ANT utility. We use the ANT scripts when we want to build or rebuild the XML facade in many iterations, for example, every time during nightly builds. Using ANT to build XML façade is very useful when XML definition changes are constantly in phases of development. With ANT, we can ensure continuous synchronization between XML and generated Java code.
The official ANT homepage along with detailed information on how to use it can be found at the following URL: http://ant.apache.org/.
By completing our previous recipe, we built up a JDeveloper project ready to create XML facade out of XML schema. To complete this recipe, we need to add ANT project technology to the project. We achieve this through the Project Properties dialog:
The following are the steps we need to take to create a project in JDeveloper for building XML façade with ANT:
<property name="schema_file" location="../Banking_BPEL/xsd/
Derivative_Cashflow.xsd"/>
<property name="dest_dir" location="./src"/>
<property name="package" value="org.packt.cashflow.facade"/>
<target name="xjc">
<delete dir="src"/>
<mkdir dir="src"/>
<echo message="Compiling the schema..." />
<exec executable="xjc">
<arg value="-xmlschema"/>
<arg value="${schema_file}"/>
<arg value="-d"/>
<arg value="${dest_dir}"/>
<arg value="-p"/>
<arg value="${package}"/>
</exec>
</target>
ANT is used as a build tool and performs various tasks. As such, we can easily use it to build XML facade. Java Architecture for XML Binding provides the xjc utility, which can help us in building XML facade.
We have provided the following parameters to the xjc utility:
There are a number of other parameters, however we will not go into detail about them here. Based on the parameters we provided to the xjc utility, the Java representation of the XML schema is generated. If we examine the generated classes, we can see that there exists a Java class for every type defined in the XML schema. Also, we can see that the ObjectFactory class is generated, which eases the generation of Java class instances.
There is a difference in creating XML facade between Versions 10g and 11g of Oracle SOA Suite. In Oracle SOA Suite 10g, there was a convenient utility named schema, which is used for building XML facade. However, in Oracle SOA Suite 11g, the schema utility is not available anymore.
To provide a similar solution, we create a template class, which is later copied to a real code package when needed to provide functionality for XML facade. We create a new class Facade in the called facade package. The only method in the class is static and serves as a creation point of facade:
public static Object createFacade(String context, XMLElement doc)
throws Exception {
JAXBContext jaxbContext;
Object zz= null;
try {
jaxbContext = JAXBContext.newInstance(context);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
zz = unmarshaller.unmarshal(doc);
return zz;
} catch (JAXBException e) {
throw new Exception("Cannot create facade from the XML content. "
+ e.getMessage());
}
}
The class code implementation is simple and consists of creating the JAXB context. Further, we un-marshall the context and return the resulting class to the client. In case of problems, we either throw an exception or return a null object.
Now the calling code is trivial. For example, to create XML facade for the XML content, we call as follows:
Object zz = facade.Facade.createFacade("org.packt.cashflow.facade",
document.getSrcRoot());
This recipe describes how to create XML facade classes from XSD. Usually, the necessity to access XML content out of Java classes comes from already defined XML schemas in BPEL processes.
We have already defined the BPEL process and the XML schema (Derivative_Cashflow.xsd) in the project. The following steps will show you how to create the XML facade from the XML schema:
The corresponding Java classes for the XML schema were generated.
Now compare the classes generated via the ANT utility in the Generating XML facade using ANT recipe with this one. In essence, the generated files are the same. However, we see the additional file jaxb.properties, which holds the configuration of the JAXB factory used for the generation of Java classes.
It is recommended to create the same access class (Facade.java) in order to simplify further access to XML facade.
It is possible to include the definitions of schema elements into WSDL. To overcome the extraction of XML schema content from the WSDL document, we would rather take the WSDL document and create XML facade for it. This recipe explains how to create XML facade out of the WSDL document.
To complete the recipe, we need the WSDL document with the XML schema definition. Luckily, we already have one automatically generated WSDL document, which we received during the Banking_BPEL project creation.
We will amend the already created project, so it is recommended to complete the Generating XML facade using ANT recipe before continuing with this recipe.
The following are the steps involved in creating XML façade from WSDL:
<property name="wsdl_file" location="../Banking_BPEL/Derivative_
Cashflow.wsdl"/>
<target name="xjc_wsdl">
<delete dir="src/org"/>
<mkdir dir="src/org"/>
<echo message="Compiling the schema..." />
<exec executable="xjc">
<arg value="-wsdl"/>
<arg value="${schema_file}"/>
<arg value="-d"/>
<arg value="${dest_dir}"/>
<arg value="-p"/>
<arg value="${package}"/>
</exec>
</target>
The generation of Java representation classes from WSDL content works similar to the generation of Java classes from XSD content. Only the source of the XML input content is different from the xjc utility.
In case we execute the ANT task with the wrong XML or WSDL content, we receive a kind notification from the xjc utility. For example, if we run the utility xjc with the parameter –xmlschema over the WSDL document, we get a warning that we should use different parameters for generating XML façade from WSDL.
Note that generation of Java classes from the WSDL document via JAXB is only available through ANT task definition or the xjc utility. If we try the same procedure with JDeveloper, an error is reported.
This recipe explains how to prepare a package containing XML facade to be used in BPEL processes and in Java applications in general.
To complete this recipe, we need the XML facade created out of the XML schema. Also, the generated Java classes need to be compiled.
The steps involved for packaging XML façade into JAR are as follows:
In this article, we also cover the building of XML facade with the ANT tool. To support an automatic build process, we can also define an ANT target to build the JAR file. We open the build.xml file and define a new target for packaging purposes. With this target, we first recreate the deploy directory and then prepare the package to be utilized in the BPEL process:
<target name="pack" depends="compile">
<delete dir="deploy"/>
<mkdir dir="deploy"/>
<jar destfile="deploy/CFacade.jar"
basedir="./classes"
excludes="**/*data*"
/>
</target>
To automate the process even further, we define the target to copy generated JAR files to the location of the BPEL process. Usually, this means copying the JAR files to the SCA-INF/lib directory:
<target name="copyLib" depends="pack">
<copy file="deploy/CFacade.jar" todir="../Banking_BPEL/SCAINF/
lib"/>
</target>
The task depends on the successful creation of a JAR package, and when the JAR package is created, it is copied over to the BPEL process library folder.
Well prepared documentation presents important aspect of further XML facade integration. Suppose we only receive the JAR package containing XML facade. It is virtually impossible to use XML facade if we don't know what the purpose of each data type is and how we can utilize it. With documentation, we receive a well-defined XML facade capable of integrating XML and Java worlds together. This recipe explains how to document the XML facade generated Java classes.
To complete this recipe, we only need the XML schema defined. We already have the XML schema in the Banking_BPEL project (Derivative_Cashflow.xsd).
The following are the steps we need to take in order to generate Java documents for XML facade:
<xsd:schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://
jxb_version="2.1">
</xsd:schema>
<xsd:annotation>
<xsd:appinfo>
<jxb:schemaBindings>
<jxb:package name="org.packt.cashflow.facade">
<jxb:javadoc>This package represents the XML facade
of the cashflows in the financial derivatives
structure.</jxb:javadoc>
</jxb:package>
</jxb:schemaBindings>
</xsd:appinfo>
</xsd:annotation>
<xsd:annotation>
<xsd:appinfo>
<jxb:class>
<jxb:javadoc>This class defines the data for the
events, when principal exchange occurs.</jxb:javadoc>
</jxb:class>
</xsd:appinfo>
</xsd:annotation>
<xsd:annotation>
<xsd:appinfo>
<jxb:property>
<jxb:javadoc>Raw principal exchange
date.</jxb:javadoc>
</jxb:property>
</xsd:appinfo>
</xsd:annotation>
During the conversion from XML schema to Java classes, JAXB is also processing possible annotations inside the XML schema file. When the conversion utility (xjc or execution through JDeveloper) finds the annotation in the XML schema file, it decorates the generated Java classes according to the specification.
The XML schema file must contain the following declarations. In the <xsd:schema> element, the following declaration of the JAXB schema namespace must exist:
jxb:version="2.1"
Note that the xjb:version attribute is where the Version of the JAXB specification is defined. The most common Version declarations are 1.0, 2.0, and 2.1.
The actual definition of javadoc resides within the <xsd:annotation> and <xsd:appinfo> blocks. To annotate at package level, we use the following code:
<jxb:schemaBindings>
<jxb:package name="PKG_NAME">
<jxb:javadoc>TEXT</jxb:javadoc>
</jxb:package>
</jxb:schemaBindings>
We define the package name to annotate and a javadoc text containing the documentation for the package level.
The annotation of javadoc at class or attribute level is similar to the following code:
<jxb:class|property>
<jxb:javadoc>TEXT</jxb:javadoc>
</jxb:class|property>
If we want to annotate the XML schema at complexType level, we use the <jaxb:class> element. To annotate the XML schema at element level, we use the <jaxb:property> element.
In many cases, we need to annotate the XML schema file directly for various reasons. The XML schema defined by different vendors is automatically generated. In such cases, we would need to annotate the XML schema each time we want to generate Java classes out of it. This would require additional work just for annotation decoration tasks.
In such situations, we can separate the annotation part of the XML schema to a separate file. With such an approach, we separate the annotating part from the XML schema content itself, over which we usually don't have control. For that purpose, we create a binding file in our CashflowFacade project and name it extBinding.xjb. We put the annotation documentation into this file and remove it from the original XML schema. We start by defining the binding file header declaration:
<jxb:bindings version="1.0"
>
<jxb:bindings schemaLocation="file:/D:/delo/source_code/Banking_
BPEL/xsd/Derivative_Cashflow.xsd" node="/xs:schema">
We need to specify the name of the schema file location and the root node of the XML schema which corresponds to our mapping. We continue by declaring the package level annotation:
<jxb:schemaBindings>
<jxb:package name="org.packt.cashflow.facade">
<jxb:javadoc><![CDATA[<body>This package represents
the XML facade of the cashflows in the financial
derivatives structure.</body>]]>
</jxb:javadoc>
</jxb:package>
<jxb:nameXmlTransform>
<jxb:elementName suffix="Element"/>
</jxb:nameXmlTransform>
</jxb:schemaBindings>
We notice that the structure of the package level annotation is identical to those in the inline XML schema annotation. To annotate the class and its attribute, we use the following declaration:
<jxb:bindings node="//xs:complexType[@name='CashflowsType']">
<jxb:class>
<jxb:javadoc>
<![CDATA[This class defines the data for the events, when
principal exchange occurs.]]>
</jxb:javadoc>
</jxb:class>
<jxb:bindings
node=".//xs:element[@name='principalExchange']">
<jxb:property>
<jxb:javadoc>TEST prop</jxb:javadoc>
</jxb:property>
</jxb:bindings>
</jxb:bindings>
Notice the indent annotation of attributes inside the class annotation that naturally correlates to the object programming paradigm.
Now that we have the external binding file, we can regenerate the XML facade.
Note that external binding files are not used only for the creation of javadoc. Inside the external binding file, we can include various rules to be followed during conversion. One such rule is aimed at data type mapping; that is, which Java data type will match the XML data type.
In JDeveloper, if we are building XML facade for the first time, we follow either the Creating XML facade from XSD or the Creating XML facade from WSDL recipe. To rebuild XML facade, we use the following procedure:
This recipe explains how to use XML facade inside BPEL processes. We can use XML façade to simplify access of XML content from Java code. When using XML façade, the XML content is exposed over Java code.
To complete the recipe, there are no special prerequisites. Remember that in the Packaging XML facade into JAR recipe, we defined the ANT task to copy XML facade to the BPEL process library directory. This task basically presents all the prerequisites for XML facade utilization.
Open a BPEL process (Derivative_Cashflow.bpel) in JDeveloper and insert the Java Embedding activity into it:
try {
oracle.xml.parser.v2.XMLElement input_cf= (oracle.xml.parser.
v2.XMLElement)getVariableData("inputVariable","payload","/
client:Cashflows");
Object obj_cf = facade.Facade.createFacade("org.packt.cashflow.
facade", input_cf);
javax.xml.bind.JAXBElement<org.packt.cashflow.facade.
CashflowsType> cfs = (javax.xml.bind.JAXBElement<org.packt.
cashflow.facade.CashflowsType>)obj_cf;
org.packt.cashflow.facade.CashflowsType cf= cfs.getValue();
} catch (Exception e) {
e.printStackTrace();
addAuditTrailEntry("Error in XML facade occurred: " +
e.getMessage());
}
Actually, the execution of the BPEL process will not produce any output, since we have no output lines defined. In case some exception occurs, we will receive information about the exception in the audit trail as well as the BPEL server console.
We add the XML facade JAR file to the BPEL process library directory (<BPEL_process_home>SCA-INFlib). Before we are able to access the XML facade classes, we need to extract the XML content from the BPEL process. To create the Java representation classes, we transform the XML content through the JAXB context. As a result, we receive an un-marshalled Java class ready to be used further in Java code.
The advantage of using XML facade is to provide the ability to access the XML content via Java classes and methods. This recipe explains how to access the complex types through XML facade.
To complete the recipe, we will amend the example BPEL process from the Invoking XML facade from BPEL processes recipe.
The steps involved in accessing the complex types through XML façade are as follows:
java.util.List<org.packt.cashflow.facade.PrincipalExchange>
princEx= cf.getPrincipalExchange();
In the previous example, we receive a list of cash flows. The corresponding XML content definition states:
<xsd:complexType name="PrincipalExchange">
<xsd:sequence>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:int"/>
</xsd:complexType>
We can conclude that each of the principle exchange cash flows is modeled as an individual Java class.
Depending on the hierarchy level of the complex type, it is modeled either as a Java class or as a Java class member. Complex types are organized in the Java object hierarchy according to the XML schema definition. Mostly, complex types can be modeled as a Java class and at the same time as a member of an other Java class.
This recipe explains how to access simple types through XML facade.
To complete the recipe, we will amend the example BPEL process from our previous recipe, Accessing complex types through XML facade.
for (org.packt.cashflowfacade.PrincipalExchange pe: princEx) {
addAuditTrailEntry("Received cashflow with id: " + pe.getId() +
"n" +
" Unadj. Principal Exch. Date ...: " + pe.getUnadjust
edPrincipalExchangeDate() + "n" +
" Adj. Principal Exch. Date .....: " + pe.getAdjusted
PrincipalExchangeDate() + "n" +
" Discount factor ...............: " +
pe.getDiscountFactor() + "n" +
" Principal Exch. Amount ........: " +
pe.getPrincipalExchangeAmount() + "n"
);
}
The XML schema simple types are mapped to Java classes as members. If we check our example, we have three simple types in the XML schema:
<xsd:complexType name="PrincipalExchange">
<xsd:sequence>
<xsd:element minOccurs="0" name="unadjustedPrincipalExchangeDate"
type="xsd:date"/>
<xsd:element minOccurs="0" name="adjustedPrincipalExchangeDate"
type="xsd:date"/>
<xsd:element minOccurs="0" name="principalExchangeAmount"
type="xsd:decimal"/>
<xsd:element minOccurs="0" name="discountFactor"
type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:int"/>
</xsd:complexType>
The simple types defined in the XML schema are <xsd:date>, <xsd:decimal>, and <xsd:int>. Let us find the corresponding Java class member definitions. Open the PrincipalExchange.java file. The definition of members we can see is as follows:
@XmlSchemaType(name = "date")
protected XMLGregorianCalendar unadjustedPrincipalExchangeDate;
@XmlSchemaType(name = "date")
protected XMLGregorianCalendar adjustedPrincipalExchangeDate;
protected BigDecimal principalExchangeAmount;
protected BigDecimal discountFactor;
@XmlAttribute
protected Integer id;
We can see that the mapping between the XML content and the Java classes was performed as shown in the following table:
XML schema simple type
|
Java class member
|
<xsd:date>
|
javax.xml.datatype.XMLGregorianCalendar
|
<xsd:decimal>
|
java.math.BigDecimal
|
<xsd:int>
|
java.lang.Integer
|
Also, we can identify that the XML simple type definitions as well as the XML attributes are always mapped as members in corresponding Java class representations.
In this article, we have learned how to set up an XML facade project, generate XML facade using ANT, create XML facade from XSD and WSDL, Package XML facade into a JAR file, generate Java documents for XML facade, Invoke XML facade from BPEL processes, and access complex and simple types through XML facade.
Further resources on this subject: