TIBCO Software Inc. EBX®
Documentation > Developer Guide > Introduction
Navigation modeDocumentation > Developer Guide > Introduction

Mapping to Java

How to access data from Java?

Read access

Data can be read from various generic Java classes, mainly Adaptation and ValueContext. The getter methods for these classes return objects that are typed according to the mapping rules described in the section Mapping of data types.

Write access

Data updates must be performed in a well-managed context:

Modification of mutable objects

According to the mapping that is described in the Mapping of data types section, some accessed Java objects are mutable objects. These are instances of ListDate or any JavaBean. Consequently, these objects can be locally modified by their own methods. However, such modifications will remain local to the returned object unless one of the above setters is invoked and the current transaction is successfully committed.

Transactions and concurrency

Concurrency

At the dataspace level

In a single dataspace, the system supports running only one single read-write Procedure and multiple concurrent ReadOnlyProcedures. Concurrent accesses outside any Procedure are also supported.

At the repository level

At the repository level, concurrency is limited for only some specific operations. For example (non-exhaustive list):

  • A data model publication excludes many operations.

  • A dataspace merge excludes write operations on the two dataspaces involved in the merge.

Query snapshot isolation

The following table defines the properties related to query isolation. Note that a query result is represented in the Java API by either a QueryResult or a RequestResult:

Queries outside of a Procedure

Data is frozen at the time of fetching the query result. More precisely, a query result accesses only committed data as of the last committed transaction at the time of fetching this result. The content of this result never changes afterwards.

A query outside of a Procedure can be considered as a self-containing ReadOnlyProcedure.

Queries inside of a Procedure, in the same dataspace as the Procedure underlying dataspace

The query result reflects the last committed state before the Procedure starts and the changes that occurred in the Procedure previously to the query result fetch. The content of this result never changes afterwards, whatever happens in the Procedure.

Queries inside of a Procedure, in another dataspace

The consistency is guaranteed at the repository level, so the query result reflects the last committed state before the Procedure starts. The content of this result never changes after the query is fetched, whatever happens in the whole repository.

Adaptation objects

In Java, a persistent dataset or a persistent record are both represented by an instance of the Adaptation class.

The following table defines the properties related to Adaptation objects.

Immutability

An Adaptation object instance is immutable.

Therefore, the client code should not "hold" an Adaptation object for a long time (in particular beyond a transaction boundaries). However, it is possible to invoke the method Adaptation.getUpToDateInstance.

Fetch

If an Adaptation is fetched from a QueryResult, then the snapshot isolation rules described in the previous section apply. Otherwise, if an Adaptation is fetched from a running Procedure, it reflects the last committed state before the Procedure starts. Otherwise, outside of a QueryResult or a running Procedure, the Adaptation reflects the state of the record on its fetch-time.

Mapping of data types

This section describes how XML Schema type definitions and element declarations are mapped to Java types.

Simple data types

Basic rules for simple data types

Each XML Schema simple type corresponds to a Java class; the mapping is documented in the table XML Schema built-in simple types.

Multiple cardinality on a simple element

If the attribute maxOccurs is greater than 1, then the element is an aggregated list and the corresponding instance in Java is an instance of java.util.List.

Elements of the list are instances of the Java class that is determined from the mapping of the simple type (see previous section).

Complex data types

Complex type definitions without a class declaration

By default (no attribute osd:class), a terminal node of a complex type is instantiated using an internal class. This class provides a generic JavaBean implementation. However, if a custom client Java code must access these values, use a custom JavaBean. To do so, use the osd:class declaration described in the next section.

You can transparently instantiate, read and modify the mapped Java object, with or without the attribute osd:class, by invoking the methods SchemaNode.createNewOccurrence, SchemaNode.executeRead and SchemaNode.executeWrite.

Mapping of complex types to custom JavaBeans

You can map an XML Schema complex type to a custom Java class. This is done by adding the attribute osd:class to the complex node definition. Unless the element has xs:maxOccurs > 1, you must also specify the attribute osd:access for the node to be considered a terminal node. If the element has xs:maxOccurs > 1, it is automatically considered to be terminal.

The custom Java class must conform to the JavaBean protocol. This means that each child of the complex type must correspond to a JavaBean property of the class. Additionally, each JavaBean property must be a read-write property, and its implementation must ensure that the value set by the setter method is returned, as-is, by the getter method. Contextual computations are not allowed in these methods.

Example

In this example, the Java class com.carRental.Customer must define the methods getFirstName() and setFirstName(String).

A JavaBean can have a custom user interface within TIBCO EBX®, by using a UIBeanEditor.

<xs:element name="customer" osd:access="RW">
  <xs:complexType name="subscriber" osd:class="com.carRental.Customer">
	<xs:sequence>
	  <xs:element name="firstName" type="xs:string"/>
	  ...
	</xs:sequence>
  </xs:complexType>
</xs:element>

Multiple cardinality on a complex element

If the attribute maxOccurs is greater than 1, then the corresponding instance in Java is:

Java bindings

Java bindings support generating Java types that reflect the structure of the data model. The Java code generation can be done in the user interface. See Generating Java bindings.

Benefits

Ensuring the link between XML Schema structure and Java code provides a number of benefits:

Consequently, it is strongly encouraged that you use Java bindings.

XML declaration

The specification of the Java types to be generated from the data model is included in the main schema.

Each binding element defines a generation target. It must be located at, in XPath notation, xs:schema/xs:annotation/xs:appinfo/ebxbnd:binding, where the prefix ebxbnd is a reference to the namespace identified by the URI urn:ebx-schemas:binding_1.0. Several binding elements can be defined if you have different generation targets.

The attribute targetDirectory of the element ebxbnd:binding defines the root directory used for Java type generation. Generally, it is the directory containing the project source code, src. A relative path is interpreted based on the current runtime directory of the VM, as opposed to the XML schema.

See bindings XML Schema.

XML bindings example

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:ebxbnd="urn:ebx-schemas:binding_1.0">
	<xs:annotation>
		<xs:appinfo>
			<!-- The bindings define how this schema will be represented in Java.
			Several <binding> elements may be defined, one for each target. -->
			<ebxbnd:binding
				targetDirectory="../_ebx-demos/src-creditOnLineStruts-1.0/">
				<javaPathConstants typeName="com.creditonline.RulesPaths">
					<nodes root="/rules" prefix="" />
				</javaPathConstants>
				<javaPathConstants typeName="com.creditonline.StylesheetConstants">
					<nodes root="/stylesheet" prefix="" />
				</javaPathConstants>
			</ebxbnd:binding>
		</xs:appinfo>
	</xs:annotation>
	...
</xs:schema>

Java constants can be defined for XML schema paths. To do so, generate one or more interfaces from a schema node, including the root node /. The example generates two Java path constant interfaces, one from the node /rules and the other from the node /stylesheet in the schema. Interface names are described by the element javaPathConstants with the attribute typeName. The associated node is described by the element nodes with the attribute root.

Documentation > Developer Guide > Introduction