diff options
Diffstat (limited to 'site/trunk/site-publish/tuscany-databinding-guide.html')
-rw-r--r-- | site/trunk/site-publish/tuscany-databinding-guide.html | 754 |
1 files changed, 754 insertions, 0 deletions
diff --git a/site/trunk/site-publish/tuscany-databinding-guide.html b/site/trunk/site-publish/tuscany-databinding-guide.html new file mode 100644 index 0000000000..7aefffeb45 --- /dev/null +++ b/site/trunk/site-publish/tuscany-databinding-guide.html @@ -0,0 +1,754 @@ + +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE- 2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + + +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<HTML> + <HEAD> + <!-- generateKeywords macro --> + <META name="description" content="Apache Tuscany"> + <META name="keywords" content="apache, apache tuscany, tuscany, service, services, fabric, soa, service oriented architecture, sca, service component architecture, das, sdo, csa, ruby, opensource"> + <!-- generateKeywords macro end --> + + <LINK type="text/css" rel="stylesheet" href="http://tuscany.apache.org/stylesheets/default.css"> + <LINK rel="SHORTCUT ICON" href="https://cwiki.apache.org/confluence/display/TUSCANY/$images/favicon.ico"> + <TITLE>Apache Tuscany : Tuscany Databinding Guide</TITLE> + <META http-equiv="Content-Type" content="text/html;charset=UTF-8"></HEAD> + + <BODY onload="init()"> + <!-- topNav macro --> + <TABLE valign="top" border="0" cellspacing="0" cellpadding="0" width="100%" background="http://tuscany.apache.org/images/TuscanyLogoNEW_Text_120px_bg.jpg"> + <TR> + <TD valing="top" align="left"> + <A href="https://cwiki.apache.org/confluence/pages/viewpage.action?spaceKey=TUSCANY&title=$siteroot"><IMG src="http://tuscany.apache.org/images/TuscanyLogoNEW_Text_120px_bg.jpg" height="91" width="25" border="0"></A> + </TD> + <TD> + <A href="http://tuscany.apache.org/"><IMG src="http://tuscany.apache.org/images/TuscanyLogo.jpg" border="0"></A> + </TD> + + <TD width="100%"> + + </TD> + + <!-- Adds the edit page link to the top banner--> + <TD valign="bottom"> + <DIV style="padding: 2px 10px; margin: 0px;"> + <A href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=52118"> + <IMG src="http://tuscany.apache.org/images/notep_16.gif" height="16" width="16" border="0" align="absmiddle" title="Edit Page"></A> + </DIV> + </TD> + + </TR> + </TABLE> + <!-- topNav macro end --> + + <!-- breadCrumbs macro --> + <TABLE border="0" cellpadding="2" cellspacing="0" width="100%"> + <TR class="topBar"> + <TD align="left" valign="middle" class="topBarDiv" nowrap="true" width="100%"> + <A href="home.html" title="Apache Tuscany">Apache Tuscany</A> > <A href="home.html" title="Home">Home</A> > <A href="sca-overview.html" title="SCA Overview">SCA Overview</A> > <A href="sca-java.html" title="SCA Java">SCA Java</A> > <A href="java-sca-documentation-menu.html" title="Java SCA Documentation Menu">Java SCA Documentation Menu</A> > <A href="" title="Tuscany Databinding Guide">Tuscany Databinding Guide</A> + </TD> + + <TD align="right" valign="middle" class="topBarDiv" align="left" nowrap="true"> + <A href="http://mail-archives.apache.org/mod_mbox/tuscany-user">User List</A> | <A href="http://mail-archives.apache.org/mod_mbox/tuscany-dev">Dev List</A> | <A href="http://issues.apache.org/jira/browse/Tuscany">Issue Tracker</A> + </TD> + </TR> + </TABLE> + <!-- breadCrumbs macro end --> + + + <TABLE border="0" cellpadding="0" width="100%" bgcolor="#FFFFFF"> + <TR> + <TD align="left" valign="top"> + + <!-- pageContent macro --> + <DIV id="PageContent"> + + <DIV class="pagecontent"> + <DIV class="wiki-content"> + <H1><A name="TuscanyDatabindingGuide-TuscanyDatabindingFramework"></A>Tuscany Databinding Framework</H1> + + +<H2><A name="TuscanyDatabindingGuide-Overview"></A>Overview</H2> + +<P>In an SOA environment, business functions can be implemented in various technologies such as Java, C++, Scripting, BPEL, Spring, OSGi and XQuery. The business data can also be represented in different formats such as DOM, JAXB, SDO, AXIOM or POJO. Business services often communicate with each other on the network using various protocols such as RMI, RMI/IIOP, SOAP/HTTP, JMS, JCA, FEED and JSON-RPC. The service collaborations are achieved by data exchanges between service components. The SCA programming model defines an extension model for interface, implementation and binding types. The extensibility is essential to SOA as we need to be able to leverage and integrate all kinds of technologies. On the data side, we also need the extensibility for different formats so that we can flow any data type that is supported by both the client and the provider. </P> + +<P>Business data are represented in different ways even they are for the same infoset. For example, we can model a Customer business object as:</P> +<UL> + <LI>JavaBeans</LI> + <LI>SDO</LI> + <LI>JAXB</LI> + <LI>XMLBeans</LI> + <LI>DOM</LI> +</UL> + + +<P>And different protocol implementation stacks support different data representations. For example, in the Web Service domain, we have:</P> +<UL> + <LI>Axis1 uses DOM</LI> + <LI>Axis2 uses AXIOM</LI> + <LI>JAX-WS uses JAXB</LI> +</UL> + + +<P>Implementation technologies may impose requirements on the data too. For example, </P> +<UL> + <LI>Apache ODE BPEL engine only consumes/produces data using DOM</LI> + <LI>SAXON XQuery engine consumes/produces data using NodeInfo</LI> + <LI>DAS implementation requires SDO</LI> + <LI>Script Implementation uses AXIOM</LI> +</UL> + + +<P>Application developers should have the freedom to choose their preferred data representation and components with compatible data should be able to interoperate without the intervention of the business logic. With the ability to attach data transformation mediations to wires, this actually becomes a requirement to support any data type that can be mapped from client to provider and back again.</P> + +<P>In any interchange there are just two things that are defined: the format of data that will be supplied by the client and the format of data that will be consumed by (delivered to) the provider. Neither client or provider needs to be aware of the format of data on the other end or of what gyrations the fabric went though in order to make the connection. As part of making the connection, it is the fabric's job to make the connection as efficient as possible, factoring in the semantic meaning of the data, the policies that need to be applied, and what the different containers support.</P> + +<P>Each SCA implementation and binding type just needs to declare which data formats it can support for each endpoint it manages. The wiring framework need to know about these formats and about what transformations can be engaged in the invocation pipeline.</P> + +<P>For example, the Axis2 transport may declare that it can support Axiom and StAX for a certain port and the Java container may declare that it can only handle SDOs for an implementation that expects to be passed a DataObject. The wiring framework can resolve this by adding a StAX->SDO transform into the pipeline.</P> + +<P>The limitation here is whether a transformation can be constructed to match the formats on either end. If one exists then great, but as the number increases then developing n-squared transforms becomes impractical. A better approach would be to pick the most common formats and require bindings and containers to support those at a minimum, with other point-to-point transforms being added as warranted. </P> + +<H2><A name="TuscanyDatabindingGuide-UsageScenarios"></A>Usage Scenarios</H2> + +<P>Let's look at a simple scenario. The business function is to report all accounts for a given customer. The data exchanged between the client and server side will be Customer and AccountReport. Let's assume that the business objects are modeled using XML schema and the client side will talk to the server side over Web Service using Axis2. The client program decides to use SDO to represent the business data while the server side prefers to use JAXB.</P> + +<P><SPAN class="image-wrap" style="display: block; text-align: center"><IMG src="tuscany-databinding-guide.data/databinding_scenario.jpg" style="border: 0px solid black"></SPAN></P> + +<P>In this case, there are three data formats involved: SDO, JAXB and AXIOM (The AXIS2 XML Infoset) and all of them come from the same model in the following XSD type definitions:</P> + +<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent"> +<PRE class="code-java"> + <xsd:complexType name=<SPAN class="code-quote">"Customer"</SPAN>> + <xsd:sequence> + <xsd:element name=<SPAN class="code-quote">"id"</SPAN> type=<SPAN class="code-quote">"xsd:string"</SPAN>></xsd:element> + <xsd:element name=<SPAN class="code-quote">"firstName"</SPAN> type=<SPAN class="code-quote">"xsd:string"</SPAN>></xsd:element> + <xsd:element name=<SPAN class="code-quote">"lastName"</SPAN> type=<SPAN class="code-quote">"xsd:string"</SPAN>></xsd:element> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name=<SPAN class="code-quote">"AccountReport"</SPAN>> + <xsd:sequence> + <xsd:element name=<SPAN class="code-quote">"id"</SPAN> type=<SPAN class="code-quote">"xsd:string"</SPAN>></xsd:element> + <xsd:element name=<SPAN class="code-quote">"type"</SPAN> type=<SPAN class="code-quote">"xsd:string"</SPAN>></xsd:element> + <xsd:element name=<SPAN class="code-quote">"balance"</SPAN> type=<SPAN class="code-quote">"xsd:<SPAN class="code-object">double</SPAN>"</SPAN>></xsd:element> + </xsd:sequence> + </xsd:complexType> +</PRE> +</DIV></DIV> + +<P>Client java component:</P> +<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent"> +<PRE class="code-java"> +SDO_AccountReport getAccountReport(SDO_Customer customer); <SPAN class="code-comment">// SDO_Customer and SDO_AccountReport are generated SDO interfaces</SPAN> +</PRE> +</DIV></DIV> + +<P>AXIS2 Web Service Stack:</P> +<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent"> +<PRE class="code-java"> +OMElement getAccountReport(OMElement customer); <SPAN class="code-comment">// pseudo method, the operation is defined in WSDL</SPAN> +</PRE> +</DIV></DIV> + +<P>Service java component:</P> +<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent"> +<PRE class="code-java"> +JAXB_AccountReport getAccountReport(JAXB_Customer customer); <SPAN class="code-comment">// JAXB_Customer and JAXB_AccountReport are generated JAXB classes</SPAN> +</PRE> +</DIV></DIV> + + +<H2><A name="TuscanyDatabindingGuide-What%27sadatabinding%3F"></A>What's a databinding?</H2> + +<P>A databinding represents a specific data format in the Tuscany runtime. Each databinding has a unique name which identifies the data format.</P> + +<P>Typical databindings</P> +<UL> + <LI>XML/Java databinding frameworks + <UL> + <LI>SDO</LI> + <LI>JAXB</LI> + <LI>XMLBeans</LI> + <LI>Castor</LI> + <LI>AXIOM</LI> + <LI>FastInfoset</LI> + </UL> + </LI> + <LI>XML Parsing Technologies + <UL> + <LI>SAX (InputSource, ContentHandler)</LI> + <LI>DOM (Node)</LI> + <LI>StAX (XMLStreamReader/XMLStreamWriter/XMLEventReader/XMLEventWriter)</LI> + </UL> + </LI> + <LI>I/O + <UL> + <LI>InputStream/OutputStream</LI> + <LI>Reader/Writer</LI> + <LI>byte[] or String</LI> + </UL> + </LI> + <LI>Other + <UL> + <LI>JavaBeans</LI> + <LI>Simple Java Types</LI> + <LI>JSON</LI> + </UL> + </LI> +</UL> + + + +<DIV class="panelMacro"><TABLE class="noteMacro"><COLGROUP><COL width="24"><COL></COLGROUP><TR><TD valign="top"><IMG src="https://cwiki.apache.org/confluence/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></TD><TD><B>Overloaded data fomats</B><BR>Please note the I/O kind of databindings are further defined by the type of the content. For example, the InputStream can feed XML stream, fastinfoset, or something else. The context of a String can be a XML document, a JSON string or a CSV.</TD></TR></TABLE></DIV> + + +<H2><A name="TuscanyDatabindingGuide-What%27satransformer%3F"></A>What's a transformer?</H2> + +<P>A transformer is the data conversation logic that transforms data from one format to another format. For example, a transformer can convert the DOM Node into a SDO dataobject. A transformer will be registered as an edge connecting the source databinding to the target databinding. The weight of a transformer represents the cost<BR> +of the transformation.</P> + +<P>The following is an incomplete list of transformers that we ship in 1.0-incubating release.</P> +<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent"> +<PRE class="code-java"> +org.apache.tuscany.sca.databinding.sdo.DataObject2String;source=commonj.sdo.DataObject,target=java.lang.<SPAN class="code-object">String</SPAN>,weight=40 +org.apache.tuscany.sca.databinding.sdo.DataObject2XMLStreamReader;source=commonj.sdo.DataObject,target=javax.xml.stream.XMLStreamReader,weight=10 +org.apache.tuscany.sca.databinding.sdo.XMLDocument2String;source=commonj.sdo.helper.XMLDocument,target=java.lang.<SPAN class="code-object">String</SPAN>,weight=40 +org.apache.tuscany.sca.databinding.sdo.String2DataObject;source=java.lang.<SPAN class="code-object">String</SPAN>,target=commonj.sdo.DataObject,weight=50 +org.apache.tuscany.sca.databinding.sdo.XMLDocument2XMLStreamReader;source=commonj.sdo.helper.XMLDocument,target=javax.xml.stream.XMLStreamReader,weight=10 +org.apache.tuscany.sca.databinding.sdo.XMLStreamReader2DataObject;source=javax.xml.stream.XMLStreamReader,target=commonj.sdo.DataObject,weight=15 +org.apache.tuscany.sca.databinding.sdo.XMLStreamReader2XMLDocument;source=javax.xml.stream.XMLStreamReader,target=commonj.sdo.helper.XMLDocument,weight=15 +org.apache.tuscany.sca.databinding.sdo.DataObject2Node;source=commonj.sdo.DataObject,target=org.w3c.dom.Node,weight=40 +org.apache.tuscany.sca.databinding.sdo.Node2DataObject;source=org.w3c.dom.Node,target=commonj.sdo.DataObject,weight=40 + +org.apache.tuscany.sca.databinding.xml.InputSource2Node;source=org.xml.sax.InputSource,target=org.w3c.dom.Node,weight=40 +org.apache.tuscany.sca.databinding.xml.InputStream2Node;source=java.io.InputStream,target=org.w3c.dom.Node,weight=40 +org.apache.tuscany.sca.databinding.javabeans.DOMNode2JavaBeanTransformer;source=org.w3c.dom.Node,target=java.lang.<SPAN class="code-object">Object</SPAN>,weight=10000 +org.apache.tuscany.sca.databinding.xml.Node2String;source=org.w3c.dom.Node,target=java.lang.<SPAN class="code-object">String</SPAN>,weight=40 +org.apache.tuscany.sca.databinding.xml.Node2XMLStreamReader;source=org.w3c.dom.Node,target=javax.xml.stream.XMLStreamReader,weight=40 +org.apache.tuscany.sca.databinding.javabeans.JavaBean2DOMNodeTransformer;source=java.lang.<SPAN class="code-object">Object</SPAN>,target=org.w3c.dom.Node,weight=10000 +org.apache.tuscany.sca.databinding.xml.Reader2Node;source=java.io.Reader,target=org.w3c.dom.Node,weight=40 +org.apache.tuscany.sca.databinding.xml.SAX2DOMPipe;source=org.xml.sax.ContentHandler,target=org.w3c.dom.Node,weight=30 +org.apache.tuscany.sca.databinding.xml.StreamDataPipe;source=java.io.OutputStream,target=java.io.InputStream,weight=50 +org.apache.tuscany.sca.databinding.xml.String2Node;source=java.lang.<SPAN class="code-object">String</SPAN>,target=org.w3c.dom.Node,weight=50 +org.apache.tuscany.sca.databinding.xml.String2XMLStreamReader;source=java.lang.<SPAN class="code-object">String</SPAN>,target=javax.xml.stream.XMLStreamReader,weight=50 +org.apache.tuscany.sca.databinding.xml.Writer2ReaderDataPipe;source=java.io.Writer,target=java.io.Reader,weight=50 +org.apache.tuscany.sca.databinding.xml.XMLStreamReader2Node;source=javax.xml.stream.XMLStreamReader,target=org.w3c.dom.Node,weight=40 +org.apache.tuscany.sca.databinding.xml.XMLStreamReader2String;source=javax.xml.stream.XMLStreamReader,target=java.lang.<SPAN class="code-object">String</SPAN>,weight=40 +org.apache.tuscany.sca.databinding.xml.Node2SimpleJavaType;source=org.w3c.dom.Node,target=java:simpleType,weight=10000 +org.apache.tuscany.sca.databinding.xml.SimpleJavaType2Node;source=java:simpleType,target=org.w3c.dom.Node,weight=10000 + +org.apache.tuscany.sca.databinding.axiom.Object2OMElement;source=java:simpleType,target=org.apache.axiom.om.OMElement,weight=10000 +org.apache.tuscany.sca.databinding.axiom.OMElement2Object;source=org.apache.axiom.om.OMElement,target=java:simpleType,weight=10000 +org.apache.tuscany.sca.databinding.axiom.OMElement2String;source=org.apache.axiom.om.OMElement,target=java.lang.<SPAN class="code-object">String</SPAN>,weight=40 +org.apache.tuscany.sca.databinding.axiom.OMElement2XMLStreamReader;source=org.apache.axiom.om.OMElement,target=javax.xml.stream.XMLStreamReader,weight=10 +org.apache.tuscany.sca.databinding.axiom.String2OMElement;source=java.lang.<SPAN class="code-object">String</SPAN>,target=org.apache.axiom.om.OMElement,weight=40 +org.apache.tuscany.sca.databinding.axiom.XMLStreamReader2OMElement;source=javax.xml.stream.XMLStreamReader,target=org.apache.axiom.om.OMElement,weight=10 + +org.apache.tuscany.sca.databinding.jaxb.JAXB2Node;source=javax.xml.bind.JAXBElement,target=org.w3c.dom.Node,weight=30 +org.apache.tuscany.sca.databinding.jaxb.Node2JAXB;source=org.w3c.dom.Node,target=javax.xml.bind.JAXBElement,weight=30 +org.apache.tuscany.sca.databinding.jaxb.Reader2JAXB;source=java.io.Reader,target=javax.xml.bind.JAXBElement,weight=30 +org.apache.tuscany.sca.databinding.jaxb.XMLStreamReader2JAXB;source=javax.xml.stream.XMLStreamReader,target=javax.xml.bind.JAXBElement,weight=10 + +org.apache.tuscany.sca.databinding.saxon.Node2NodeInfoTransformer;source=org.w3c.dom.Node,target=net.sf.saxon.om.NodeInfo,weight=10 +org.apache.tuscany.sca.databinding.saxon.NodeInfo2NodeTransformer;source=net.sf.saxon.om.NodeInfo,target=org.w3c.dom.Node,weight=10 +org.apache.tuscany.sca.databinding.saxon.Object2ValueTransformer;source=java.lang.<SPAN class="code-object">Object</SPAN>,target=net.sf.saxon.value.Value,weight=10000 +org.apache.tuscany.sca.databinding.saxon.Value2ObjectTransformer;source=net.sf.saxon.value.Value,target=java.lang.<SPAN class="code-object">Object</SPAN>,weight=10000 +org.apache.tuscany.sca.databinding.saxon.SimpleType2ValueTransformer;source=java:simpleType,target=net.sf.saxon.value.Value,weight=10000 +org.apache.tuscany.sca.databinding.saxon.Value2SimpleTypeTransformer;source=net.sf.saxon.value.Value,target=java:simpleType,weight=10000 +org.apache.tuscany.sca.databinding.saxon.NodeInfo2DataObjectTransformer;source=net.sf.saxon.om.NodeInfo,target=commonj.sdo.DataObject,weight=20 +org.apache.tuscany.sca.databinding.saxon.DataObject2NodeInfoTransformer;source=commonj.sdo.DataObject,target=net.sf.saxon.om.NodeInfo,weight=10 + +org.apache.tuscany.sca.databinding.sdo2om.DataObject2OMElement;source=commonj.sdo.DataObject,target=org.apache.axiom.om.OMElement,weight=1000 +org.apache.tuscany.sca.databinding.sdo2om.XMLDocument2OMElement;source=commonj.sdo.helper.XMLDocument,target=org.apache.axiom.om.OMElement,weight=1000 + +</PRE> +</DIV></DIV> + +<H2><A name="TuscanyDatabindingGuide-Thedatatransformationgraph"></A>The data transformation graph</H2> + +<P>In Tuscany, we register transformers to form a graph as folllows:</P> + +<UL> + <LI>The data transformation capabilities for various databindings can be nicely modeled as a weighted, directed graph with the following rules. (Illustrated in the attached diagram).</LI> + <LI>Each databinding is mapped to a vertex.</LI> + <LI>If databinding A can be transformed to databinding B, then an edge will be added from vertex A to vertex B.</LI> + <LI>The weight of the edge is the cost of the transformation from the source to the sink.</LI> +</UL> + + +<P><SPAN class="image-wrap" style="display: block; text-align: center"><IMG src="tuscany-databinding-guide.data/databinding_graph.jpg" style="border: 0px solid black"></SPAN></P> + +<P>With the transformer graph, we support not only point-to-point transformations but also multiple-hop transformations. This approach greatly reduces the number of transformers required and makes it possible to transform data without a direct transformation logic. It's very common that some databindings will be supported as the intermediaries, for example, the XML Sting, DOM Node and StAX XMLStreamReader are very populate in the XML world. </P> + +<P>The algorithm to calculate the transformation path</P> +<UL> + <LI>In the data interceptor on the wire, if we find out that the data needs to be transformed from databinding A to databinding E. Then we can apply Dijkstra's Shortest Path Algorithm to the graph and figure the most performed path. It can be A-<DEL>>E, or A</DEL><DEL>>C</DEL>->E depending on the weights. If no path can be found, then the data cannot be mediated.</LI> +</UL> + + + +<H2><A name="TuscanyDatabindingGuide-What%27adatatype%3F"></A>What' a data type?</H2> + +<P>DataType is the decription of the data. It contains three pieces: the data binding, the physical type and the logical type. The runtime's main job is to connect user components together so typically the actual type used would be determined by the user code that implements the source or target. The databinding framework's role here is to convert from the type used by the source to the type used by the target. The internal types used by the runtime should not influence this - which is an essential separation to maintain given the components and the wire connecting them need to work on different runtimes (implemented in different languages).</P> + +<P>Where runtime types do matter is in the conversion between some serialized form and an in-memory representation and the two places where that occurs are in the configuration properties and in the binding implementations. To handle configuration properties (with the XPath requirement) we use DOM in the Java runtime. Each transport binding also tends to deserialize using a specific technology - for example, AXIOM for Axis2, JAXB for JAX-WS, Serializable for RMI and so the databinding framework is used to convert between the form generated by the binding and the form used by the component.</P> + +<P>The logical type represents the data type the user thinks is flowing across a wire. This could be a Java type, a XML type, a CORBA type, whatever depending on the /logical/ service contract defined in the assembly.</P> + +<P>The physical type is the actual representation of that type that is flowed by the runtime. In the Java runtime this will always be a Java type (i.e. some subclass of Object). In some cases it will be the same as the logical type - e.g. when a Java component calls another Java component over a local wire using a Java interface then both logical and physical types will be the same. In many cases though they will be different - for example, if the service contract was WSDL then the logical type would be the XML type used by the WSDL.</P> + +<P>Within the runtime the same logical type may have different physical forms. For example, the same XML document could be represented physically as a DOM, a StAX stream, an SDO, a JAXB object, or an AXIOM stream. The framework supports conversion between these different physical forms.</P> + +<P>1. A component (A) consumes a service provided by another component (B). The implementation of A prefers SDO while the implementation of B prefers JAXB.</P> + +<P>In the SCA term, A is wired to B using a reference.</P> +<UL> + <LI>Data is represented by an interface which is independent of the databinding</LI> + <LI>Data is represented by an interface or class which is databinding-specific (either generated or dynamic)</LI> +</UL> + + +<P>2. A component (A) consumes a web service using axis2. Axis2 engine expects to handle AXIOM objects.</P> + +<P>3. A component is exposed as a service over a transport/protocol.</P> + +<P>Where runtime types do matter is in the conversion between some serialized form and an in-memory representation and the two places where that occurs are in the configuration properties and in the binding implementations. To handle configuration properties (with the XPath requirement) we use DOM in the Java runtime; I believe the C++ runtime uses SDO. Each transport binding also tends to deserialize using a specific technology - for example, AXIOM for Axis2, JAXB for JAX-WS, Serializable for RMI and so the databinding framework is used to convert between the form generated by the binding and the form used by the component.</P> + +<P>interfaces for services and references are the contracts for SCA assembly.</P> + + +<H2><A name="TuscanyDatabindingGuide-Introspectionofjavainterfacesfordatatypes"></A>Introspection of java interfaces for data types</H2> + +<P>The DataBindingJavaInterfaceProcessor is responsible to introspect the java interfaces to figure out the databindings of the parameters and return types. It delegates to all of the databinding implementations which will set the databinding and logical type if such data type is recognized by the databinding. This introspection process can handle most of the cases as the java types usually have some patterns, for example, implementing a know interface.</P> + + +<H2><A name="TuscanyDatabindingGuide-DatamediationintheSCAassembly"></A>Data mediation in the SCA assembly</H2> + +<P>DataBindingRuntimeWireProcessor is responsible to insert a DataTransformationInteceptor into the invovcation chains if the data transformation is required between the source and target operations. Depending on the invocation patterns, it uses the effective interface contracts to determine if transformation should be applied.</P> + +<P>Typically, there are three cases:</P> + +<DIV class="table-wrap"> +<TABLE class="confluenceTable"><TBODY> +<TR> +<TD class="confluenceTd"><B>Interaction</B></TD> +<TD class="confluenceTd"><B>Effective Source Interface contract</B></TD> +<TD class="confluenceTd"><B>Effective Target Interface Contract</B></TD> +</TR> +<TR> +<TD class="confluenceTd">A SCA component talks to another SCA component over a remotable interface using binding.sca</TD> +<TD class="confluenceTd">The interface contract of the reference defined by the source component type</TD> +<TD class="confluenceTd">The interface contract of the service defined by the target component type</TD> +</TR> +<TR> +<TD class="confluenceTd">A SCA component talks to an external service using binding.x</TD> +<TD class="confluenceTd">The interface contract of the reference defined by the source component type</TD> +<TD class="confluenceTd">The interface contract imposed by the binding protocol</TD> +</TR> +<TR> +<TD class="confluenceTd">The request from binding.y is routed to a component service</TD> +<TD class="confluenceTd">The interface contract imposed by binding.y</TD> +<TD class="confluenceTd">The interface contract of the service defined by the target component type</TD> +</TR> +</TBODY></TABLE> +</DIV> + + +<H3><A name="TuscanyDatabindingGuide-DatatransformationbetweenSCAcomponents"></A>Data transformation between SCA components</H3> + +<UL> + <LI>Data transformation can be performed on wire for remotable interfaces</LI> + <LI>Data transformation can handle interfaces defined using different IDLs such as Java or WSDL.</LI> +</UL> + + +<P><SPAN class="image-wrap" style="display: block; text-align: center"><IMG src="tuscany-databinding-guide.data/databinding_components.jpg" style="border: 0px solid black"></SPAN></P> + +<H3><A name="TuscanyDatabindingGuide-Datatransformationforservicebindings"></A>Data transformation for service bindings</H3> + +<UL> + <LI><interface.xxx> defines the outbound service contract (SC2) which can be wired to a target component, reference or service (SC3).</LI> + <LI><binding.xxx> can optionally hint a service contract for the inbound data from the binding protocol layer. <SPAN class="image-wrap" style="display: block; text-align: center"><IMG src="tuscany-databinding-guide.data/databinding_service.jpg" style="border: 0px solid black"></SPAN></LI> +</UL> + + +<H3><A name="TuscanyDatabindingGuide-Datatransformationforreferencebindings"></A>Data transformation for reference bindings</H3> + +<UL> + <LI><interface.xxx> defines the inbound service contract (SC2) which can be wired from a source component, reference or service (SC1).</LI> + <LI><binding.xxx> can optionally hint a service contract (SC3) for the outbound data to the binding protocol layer.</LI> +</UL> + + +<P><SPAN class="image-wrap" style="display: block; text-align: center"><IMG src="tuscany-databinding-guide.data/databinding_reference.jpg" style="border: 0px solid black"></SPAN></P> + +<H3><A name="TuscanyDatabindingGuide-Datatransformationforpropertyvalues"></A>Data transformation for property values</H3> + +<UL> + <LI>Property values are loaded from SCDLs as DOM documents</LI> + <LI>The DOM Document can be transformed into a java object under a databinding, such as SDO, JAXB so that the component implementation code can work with the databinding directly instead of DOM.</LI> +</UL> + + +<P><SPAN class="image-wrap" style="display: block; text-align: center"><IMG src="tuscany-databinding-guide.data/databinding_property.jpg" style="border: 0px solid black"></SPAN></P> + + +<H2><A name="TuscanyDatabindingGuide-Specialdatabindingsandtransformerstodealwithoperationleveltransformations"></A>Special databindings and transformers to deal with operation-level transformations</H2> +<UL> + <LI>Input2InputTransformer: Transform the input data from the source operation to the input data expected by the target operation</LI> + <LI>Output2OutputTransformer: Transform the output data from the target operation to the output data expected by the source operation</LI> + <LI>Exception2ExceptionTransformer: Transform the fault data from the target operation to the fault data expected by the source operaion</LI> +</UL> + + +<P>Deal with interfaces defined using different IDLs </P> +<UL> + <LI>SCA allows the interfaces to be defined using various IDLs, for example, java interface or WSDL portType</LI> + <LI>IDLs may have different ways to represent the input/output/fault data</LI> + <LI>The databinding framework is designed to support the transformation across IDLs</LI> +</UL> + + +<UL> + <LI>Some special databindings are internally used for this purpose: + <UL> + <LI>idl:input The input data format for an operation</LI> + <LI>idl:output: The output data format for an operation</LI> + <LI>idl:fault: The fault data format for an operation</LI> + </UL> + </LI> +</UL> + + +<UL> + <LI>SimpleTypeMapper: convert data between XSD simple types (by the databinding, for example, OMElement with an OMText child) and java objects</LI> +</UL> + + + +<H3><A name="TuscanyDatabindingGuide-Operationleveltransformations"></A>Operation-level transformations</H3> + +<P>The signature of an operation is modeled as follows:</P> + +<UL> + <LI>InputType: The data type for the input. The logical type is a list of data types that represent the list of parameters</LI> + <LI>OutputType: The data type for the output. The logical type is the data type that represents the return value</LI> + <LI>FaultTypes: The list of data types for all the faults</LI> +</UL> + + +<P><SPAN class="image-wrap" style="display: block; text-align: center"><IMG src="tuscany-databinding-guide.data/databinding_operation.jpg" style="border: 0px solid black"></SPAN></P> + +<H3><A name="TuscanyDatabindingGuide-WrapperstyleWSDLoperation"></A>Wrapper style WSDL operation</H3> + +<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent"> +<PRE class="code-java"> +<?xml version=<SPAN class="code-quote">"1.0"</SPAN> encoding=<SPAN class="code-quote">"UTF-8"</SPAN>?> +<wsdl:definitions name=<SPAN class="code-quote">"AccountService"</SPAN> targetNamespace=<SPAN class="code-quote">"http:<SPAN class="code-comment">//www.example.org/AccountService/"</SPAN> +</SPAN> xmlns:wsdl=<SPAN class="code-quote">"http:<SPAN class="code-comment">//schemas.xmlsoap.org/wsdl/"</SPAN> xmlns:tns=<SPAN class="code-quote">"http://www.example.org/AccountService/"</SPAN> +</SPAN> xmlns:xsd=<SPAN class="code-quote">"http:<SPAN class="code-comment">//www.w3.org/2001/XMLSchema"</SPAN>> +</SPAN> <wsdl:types> + <xsd:schema xmlns:xsd=<SPAN class="code-quote">"http:<SPAN class="code-comment">//www.w3.org/2001/XMLSchema"</SPAN> +</SPAN> targetNamespace=<SPAN class="code-quote">"http:<SPAN class="code-comment">//www.example.org/AccountService/"</SPAN>> +</SPAN> + <xsd:complexType name=<SPAN class="code-quote">"Customer"</SPAN>> + <xsd:sequence> + <xsd:element name=<SPAN class="code-quote">"id"</SPAN> type=<SPAN class="code-quote">"xsd:string"</SPAN>></xsd:element> + <xsd:element name=<SPAN class="code-quote">"firstName"</SPAN> type=<SPAN class="code-quote">"xsd:string"</SPAN>></xsd:element> + <xsd:element name=<SPAN class="code-quote">"lastName"</SPAN> type=<SPAN class="code-quote">"xsd:string"</SPAN>></xsd:element> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name=<SPAN class="code-quote">"AccountReport"</SPAN>> + <xsd:sequence> + <xsd:element name=<SPAN class="code-quote">"id"</SPAN> type=<SPAN class="code-quote">"xsd:string"</SPAN>></xsd:element> + <xsd:element name=<SPAN class="code-quote">"type"</SPAN> type=<SPAN class="code-quote">"xsd:string"</SPAN>></xsd:element> + <xsd:element name=<SPAN class="code-quote">"balance"</SPAN> type=<SPAN class="code-quote">"xsd:<SPAN class="code-object">double</SPAN>"</SPAN>></xsd:element> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name=<SPAN class="code-quote">"getAccountReport"</SPAN>> + <xsd:complexType> + <xsd:sequence> + <xsd:element name=<SPAN class="code-quote">"customer"</SPAN> type=<SPAN class="code-quote">"tns:Customer"</SPAN>></xsd:element> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name=<SPAN class="code-quote">"getAccountReportResponse"</SPAN>> + <xsd:complexType> + <xsd:sequence> + <xsd:element name=<SPAN class="code-quote">"report"</SPAN> type=<SPAN class="code-quote">"tns:AccountReport"</SPAN>></xsd:element> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + </xsd:schema> + </wsdl:types> + <wsdl:message name=<SPAN class="code-quote">"getAccountReportRequest"</SPAN>> + <wsdl:part name=<SPAN class="code-quote">"parameters"</SPAN> element=<SPAN class="code-quote">"tns:getAccountReport"</SPAN>></wsdl:part> + </wsdl:message> + <wsdl:message name=<SPAN class="code-quote">"getAccountReportResponse"</SPAN>> + <wsdl:part name=<SPAN class="code-quote">"<SPAN class="code-keyword">return</SPAN>"</SPAN> element=<SPAN class="code-quote">"tns:getAccountReportResponse"</SPAN>></wsdl:part> + </wsdl:message> + <wsdl:portType name=<SPAN class="code-quote">"AccountService"</SPAN>> + <wsdl:operation name=<SPAN class="code-quote">"getAccountReport"</SPAN>> + <wsdl:input message=<SPAN class="code-quote">"tns:getAccountReportRequest"</SPAN>></wsdl:input> + <wsdl:output message=<SPAN class="code-quote">"tns:getAccountReportResponse"</SPAN>></wsdl:output> + </wsdl:operation> + </wsdl:portType> +</wsdl:definition +</PRE> +</DIV></DIV> + +<P>The WrapperHandler provides wrapper style WSDL wrapping/unwrapping support</P> + +<P><SPAN class="image-wrap" style="display: block; text-align: center"><IMG src="tuscany-databinding-guide.data/wrapper_transformation.jpg" style="border: 0px solid black"></SPAN></P> + +<H2><A name="TuscanyDatabindingGuide-Extendthedatabindingframework"></A>Extend the databinding framework</H2> + + +<H3><A name="TuscanyDatabindingGuide-Whatcanbeextended%3F"></A>What can be extended?</H3> + +<P>The Tuscany databinding framework can be extended in two ways:</P> + +<P>1. Add more databinding providers to support new formats to represent business data</P> + +<P>2. Add more transformers to facilitate the data exchange accross databindings </P> + +<H3><A name="TuscanyDatabindingGuide-Howtocontributeanewdatabindingortransformer%3F"></A>How to contribute a new databinding or transformer?</H3> + +<P>Databindings and transformers can be plugged into Tuscany runtime following the Tuscany extensibility story. It can be achieved in the following steps:</P> + +<P>Add a new databinding:<BR> +1. Provide a java class which implements the DataBinding interface. You can subclass the BaseDataBinding.<BR> +2. Register your databindings against the DataBindingExtensionPoint.</P> + +<P>Add a new transformer:<BR> +1. Provide a java class which implements the Transformer interface. You can subclass the BasePullTransformer or BasePushTransformer.<BR> +2. Register your transformers against the TransformerExtensionPoint.</P> + +<H4><A name="TuscanyDatabindingGuide-TheDataBindingSPI%3A"></A>The DataBinding SPI:</H4> + +<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent"> +<PRE class="code-java"> +/** + * DataBinding represents a data representation, <SPAN class="code-keyword">for</SPAN> example, SDO, JAXB and AXIOM + */ +<SPAN class="code-keyword">public</SPAN> <SPAN class="code-keyword">interface</SPAN> DataBinding { + /** + * A special databinding <SPAN class="code-keyword">for</SPAN> input message of an operation + */ + <SPAN class="code-object">String</SPAN> IDL_INPUT = <SPAN class="code-quote">"idl:input"</SPAN>; + /** + * A special databinding <SPAN class="code-keyword">for</SPAN> output message of an operation + */ + <SPAN class="code-object">String</SPAN> IDL_OUTPUT = <SPAN class="code-quote">"idl:output"</SPAN>; + /** + * A special databinding <SPAN class="code-keyword">for</SPAN> fault message of an operation + */ + <SPAN class="code-object">String</SPAN> IDL_FAULT = <SPAN class="code-quote">"idl:fault"</SPAN>; + /** + * The name of a databinding should be <SPAN class="code-keyword">case</SPAN>-insensitive and unique + * + * @<SPAN class="code-keyword">return</SPAN> The name of the databinding + */ + <SPAN class="code-object">String</SPAN> getName(); + + /** + * Get the aliases <SPAN class="code-keyword">for</SPAN> the databinding + * + * @<SPAN class="code-keyword">return</SPAN> An array of aliases + */ + <SPAN class="code-object">String</SPAN>[] getAliases(); + + /** + * Introspect and populate information to a DataType model + * + * @param dataType The data type to be introspected + * @param annotations The java annotations + * @<SPAN class="code-keyword">return</SPAN> <SPAN class="code-keyword">true</SPAN> <SPAN class="code-keyword">if</SPAN> the databinding has recognized the given data type + */ + <SPAN class="code-object">boolean</SPAN> introspect(DataType dataType, Annotation[] annotations); + + /** + * Introspect the data to figure out the corresponding data type + * + * @param value The object to be checked + * @<SPAN class="code-keyword">return</SPAN> The DataType or <SPAN class="code-keyword">null</SPAN> <SPAN class="code-keyword">if</SPAN> the java type is not supported by <SPAN class="code-keyword">this</SPAN> databinding + */ + DataType introspect(<SPAN class="code-object">Object</SPAN> value); + + /** + * Provide a WrapperHandler <SPAN class="code-keyword">for</SPAN> <SPAN class="code-keyword">this</SPAN> databinding + * @<SPAN class="code-keyword">return</SPAN> A wrapper handler which can handle wrapping/wrapping <SPAN class="code-keyword">for</SPAN> <SPAN class="code-keyword">this</SPAN> databinding + */ + WrapperHandler getWrapperHandler(); + + /** + * Make a copy of the object <SPAN class="code-keyword">for</SPAN> <SPAN class="code-quote">"pass-by-value"</SPAN> semantics + * @param source object to copy + * @<SPAN class="code-keyword">return</SPAN> copy of the object passed in as argument + */ + <SPAN class="code-object">Object</SPAN> copy(<SPAN class="code-object">Object</SPAN> object); + + /** + * Get the type mapper <SPAN class="code-keyword">for</SPAN> simple types + * @<SPAN class="code-keyword">return</SPAN> The databinding-specific simple type mapper + */ + SimpleTypeMapper getSimpleTypeMapper(); + + /** + * Get the handler that can handle exceptions/faults in the + * databinding-specific way + * + * @<SPAN class="code-keyword">return</SPAN> An instance of the exception handler + */ + ExceptionHandler getExceptionHandler(); +} +</PRE> +</DIV></DIV> + +<UL> + <LI>Support introspection of java types</LI> + <LI>Support data copying for pass-by-value</LI> + <LI>Support warpping/unwrapping for WSDL wrapper style</LI> + <LI>Support exception handling</LI> +</UL> + + +<H4><A name="TuscanyDatabindingGuide-TransformerSPI"></A>Transformer SPI</H4> + +<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent"> +<PRE class="code-java"> +/** + * A transformer provides the data transformation from source type to target type. The cost of the transformation is + * modeled as weight. + */ +<SPAN class="code-keyword">public</SPAN> <SPAN class="code-keyword">interface</SPAN> Transformer { + /** + * Get the source type that <SPAN class="code-keyword">this</SPAN> transformer transforms data from. The type is used as the key when the transformer + * is registered with TransformerRegistry. + * + * @<SPAN class="code-keyword">return</SPAN> A key indentifying the source type + */ + <SPAN class="code-object">String</SPAN> getSourceDataBinding(); + + /** + * Get the target type that <SPAN class="code-keyword">this</SPAN> transformer transforms data into. The type is used as the key when the transformer + * is registered with TransformerRegistry. + * + * @<SPAN class="code-keyword">return</SPAN> A key indentifying the target type + */ + <SPAN class="code-object">String</SPAN> getTargetDataBinding(); + + /** + * Get the cost of the transformation. The weight can be used to choose the most efficient path <SPAN class="code-keyword">if</SPAN> there are more + * than one available from the source to the target. + * + * @<SPAN class="code-keyword">return</SPAN> An integer representing the cost of the transformation + */ + <SPAN class="code-object">int</SPAN> getWeight(); +} + + +/** + * PullTransformer transforms data from one binding format to the other one which can be directly consumed + * + * @param <S> The source data type + * @param <R> the target data type + */ +<SPAN class="code-keyword">public</SPAN> <SPAN class="code-keyword">interface</SPAN> PullTransformer<S, R> <SPAN class="code-keyword">extends</SPAN> Transformer { + /** + * Transform source data into the result type. + * + * @param source The source data + * @param context The context <SPAN class="code-keyword">for</SPAN> the transformation + * @<SPAN class="code-keyword">return</SPAN> The transformed result + */ + R transform(S source, TransformationContext context); +} +</PRE> +</DIV></DIV> + +<H4><A name="TuscanyDatabindingGuide-Registerdatabindingsandtransformers"></A>Register databindings and transformers</H4> + +<P>To regsiter one or more databindings, you need to add entries to a plain text file named as META-INF/services/org.apache.tuscany.sca.databinding.DataBinding. This service provider file needs to be on the classpath when Tuscany is bootstrapped.</P> +<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent"> +<PRE class="code-java"> +# implementation classes <SPAN class="code-keyword">for</SPAN> the databindings +org.apache.tuscany.sca.databinding.axiom.AxiomDataBinding;type=org.apache.axiom.om.OMElement,name=axiom +</PRE> +</DIV></DIV> + +<P>The syntax is: <implementation_class_name>;type=<databinding_id>,name=<databinding_alias></P> + +<P>To register one or more transformers, you need to add entries to a plain text file named as META-INF/services/org.apache.tuscany.sca.databinding.PullTransformer. This service provider file needs to be on the classpath when Tuscany is bootstrapped.</P> +<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent"> +<PRE class="code-java"> +# Implementation classes <SPAN class="code-keyword">for</SPAN> the transformers +org.apache.tuscany.sca.databinding.axiom.Object2OMElement;source=java:simpleType,target=org.apache.axiom.om.OMElement,weight=10000 +org.apache.tuscany.sca.databinding.axiom.OMElement2Object;source=org.apache.axiom.om.OMElement,target=java:simpleType,weight=10000 +org.apache.tuscany.sca.databinding.axiom.OMElement2String;source=org.apache.axiom.om.OMElement,target=java.lang.<SPAN class="code-object">String</SPAN>,weight=40 +org.apache.tuscany.sca.databinding.axiom.OMElement2XMLStreamReader;source=org.apache.axiom.om.OMElement,target=javax.xml.stream.XMLStreamReader,weight=10 +org.apache.tuscany.sca.databinding.axiom.String2OMElement;source=java.lang.<SPAN class="code-object">String</SPAN>,target=org.apache.axiom.om.OMElement,weight=40 +org.apache.tuscany.sca.databinding.axiom.XMLStreamReader2OMElement;source=javax.xml.stream.XMLStreamReader,target=org.apache.axiom.om.OMElement,weight=10 +</PRE> +</DIV></DIV> + +<P>The syntax is: <implementation_class_name>;source=<source_databinding_id>,target=<target_databinding_id>,weight=<cost_of_the_transformation></P> + +<H1><A name="TuscanyDatabindingGuide-TODOList"></A>TODO List</H1> + +<UL> + <LI>Support Collection or Array data types</LI> + <LI>Better support interface/operation level databinding mappings</LI> + <LI>Support databinding for java types which can be used for multiple datatypes, for example, InputStream or String can be used to represent various formats</LI> + <LI>Better support exception/fault</LI> + <LI>Support application data based introspection of operations</LI> +</UL> + + </DIV> + </DIV> + </DIV> + <!-- pageContent macro end --> + + </TD> + </TR> + </TABLE> + + <!-- footer macro --> + <SCRIPT src="http://www.google-analytics.com/urchin.js" type="text/javascript"> + </SCRIPT> + <SCRIPT type="text/javascript"> + _uacct = "UA-1174707-5"; + urchinTracker(); + </SCRIPT> + + <A href="http://www.statcounter.com/" target="_blank"><IMG src="http://c26.statcounter.com/counter.php?sc_project=2619156&java=0&security=94bd7e7d&invisible=0" alt="website stats" border="0"></A> + + <DIV class="footer"> + Copyright � 2003-2012, The Apache Software Foundation </BR> + Apache Tuscany and the Apache Tuscany project logo are trademarks of The Apache Software Foundation. + </DIV> + <!-- footer macro end --> + + </BODY> +</HTML> |