Skip Headers
Oracle® Application Server TopLink Application Developer's Guide
10g Release 2 (10.1.2)
Part No. B15901-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

OracleAS TopLink XML Support

OracleAS TopLink enables you to read and modify objects in XML files. Object-to-XML (O-X) mapping enables your application to deal exclusively with objects, rather than managing the intricacies of XML parsing and deconstruction. You can use OracleAS TopLink XML support to exchange data with other applications (for example, legacy applications or business partner applications).

This section describes:

The OracleAS TopLink implementation of XML support uses a file and directory paradigm to store information, as follows:

Getting Started

The default XML extension is similar to a regular OracleAS TopLink project. Use the following steps to develop your application:

  1. Configure your login using an XMLFileLogin.

    XMLFileLogin login = new XMLFileLogin();
    login.setBaseDirectoryName("C:\Employee Database");
    
    // set up the sequences
    login.setSequenceRootElementName("sequence");
    login.setSequenceNameElementName("name");
    login.setSequenceCounterElementName("count");
    
    // create the directories if they don't already exist
    login.createDirectoriesAsNeeded();
    
    
  2. Build your project.

    Project project = new Project(login);
    project.addDescriptor(buildEmployeeDescriptor());
    project.addDescriptor(buildAddressDescriptor());
    project.addDescriptor(buildProjectDescriptor());
    // etc.
    
    
  3. Build your descriptors using XMLDescriptors.

    XMLDescriptor descriptor = new XMLDescriptor();
    descriptor.setJavaClass(Employee.class);
    descriptor.setRootElementName("employee");
    descriptor.setPrimaryKeyElementName("id");
    descriptor.setSequenceNumberName("employee");
    descriptor.setSequenceNumberElementName("id");
    // etc.
    
    
  4. Build your mappings. For the XML extension, OneToOneMappings and SDKObjectCollectionMappings require custom selection queries as follows:

    // 1:1 mapping
    OneToOneMapping addressMapping = new OneToOneMapping();
    addressMapping.setAttributeName("address");
    addressMapping.setReferenceClass(Address.class);
    addressMapping.privateOwnedRelationship();
    addressMapping.setForeignKeyFieldName("addressId");
    // build the custom selection query
    ReadObjectQuery addressQuery = new ReadObjectQuery();
    addressQuery.setCall(new XMLReadCall(addressMapping));
    addressMapping.setCustomSelectionQuery(addressQuery);
    descriptor.addMapping(addressMapping);
    // 1:n mapping
    
    SDKObjectCollectionMapping projectsMapping = new 
      SDKObjectCollectionMapping();
    projectsMapping.setAttributeName("projects");
    projectsMapping.setReferenceClass(Project.class);
    projectsMapping.setFieldName("projects");
    projectsMapping.setSourceForeignKeyFieldName("projectId");
    projectsMapping.setReferenceDataTypeName("project");
    // use convenience method to build the custom selection query
    projectsMapping.setSelectionCall(new XMLReadAllCall(projectsMapping));
    descriptor.addMapping(projectsMapping);
    
    
  5. Build your database session and log in.

    DatabaseSession session = project.createDatabaseSession();session.login();
    
    
  6. Configure sequencing, if necessary.

    (new XMLSchemaManager(session)).createSequences();
    
    
  7. Run your application normally.

    For example:

    Vector employees = session.readAllObjects(Employee.class);
    Employee employee = (Employee) employees.firstElement();
    UnitOfWork uow = session.acquireUnitOfWork();
    Employee employeeClone = uow.registerObject(employee);
    employeeClone.setSalary(employeeClone.getSalary() + 50);
    uow.commit();
    
    
  8. Log out when your session is complete.

    session.logout();
    
    

Customizations

You can customize the OracleAS TopLink XML extension in two key ways, by modifying:

  • Where and how you store the XML documents, by developing your own implementation of the XMLAccessor interface

  • How XML documents translate into database rows, and the converse, by developing your own implementation of the XMLTranslator interface

Implementation Details

The package oracle.toplink.xml contains the classes that implement OracleAS TopLink support for O-X mapping. These classes represent a simple example of how to use the OracleAS TopLink SDK as "Using the OracleAS TopLink SDK" describes.

The XML package defines its own set of interfaces, in addition to the SDK interfaces. You can use these interfaces to alter how you map your objects to XML documents, without re-implementing the entire SDK suite of interfaces and subclasses.

The XML extension includes the following implementations of the SDK interfaces and subclasses:

The XML extension also defines its own set of interfaces into which you can plug your own implementation classes, as follows:

These interfaces enable you to easily alter the way your objects map to XML documents.

XML File Accessor

The XMLFileAccessor is a subclass of the SDKAccessor that defines how the application stores XML documents in a native file system. As a subclass of SDK accessor, the XML file accessor does not have to implement any of the accessor protocol, although it does implement the connect(DatabaseLogin, Session) method.

The XML file accessor uses the standard SDK method of call execution and does not support transaction processing. This limitation is typical of native file systems.

XML Accessor Implementation

In addition to the Accessor interface, the XML file accessor implements the XMLAccessor interface. The XMLAccessor interface defines the protocol necessary to fetch streams of data for reading and writing XML documents. The XML file accessor implements this protocol by wrapping files in streams that can be used by the XML calls to read or write XML documents.

The XMLAccessor methods defined to fetch a stream (either a java.io.Reader or java.ioWriter) generally require three parameters:

  • A root element name

  • A database row

  • A vector of DatabaseFields (the ordered primary key element names)

The XML file accessor resolves the values of these three parameters to a File. It wraps the file in a stream (either a java.io.FileReader or a java.io.FileWriter) and returns it to the XML call for processing.

The XML file accessor calculates the file name as follows:

  • The configuration of the XML file login determines the base directory. The base directory is analogous to a relational database that contains a collection of related tables. If you do not specify a base directory name, then OracleAS TopLink uses the current working directory (for example, C:\EmployeeDB).

  • The subdirectory has the same name as the XML root element name. The root element name is analogous to the table name in the relational model, meaning that all XML documents in the same directory have the same root element name (for example, C:\EmployeeDB\employee).

  • The vector of DatabaseFields and the database row determine the file name root. The filename is analogous to a row within a table in the relational model. The vector indicates which fields in the database row make up the primary key. The values in these fields (which must all be strings) are concatenated together in the order in which they are listed in the vector. This composite string forms the root of the file name (for example, C:\EmployeeDB\employee\1234).

  • The configuration of the XML file login determines the file name extension. The extension is optional. For example, you can assign an extension to associate the file with other applications. If you do not specify a file name extension, it defaults to .xml (for example, C:\EmployeeDB\employee\1234.xml).

Directory Creation

You can configure the XML file accessor to create directories automatically when required. To enable this, include the createsDirectoriesAsNeeded call, set to TRUE, in the XML file login.

The createsDirectoriesAsNeeded call causes the accessor to create directories as required, including the base directory. If you set this call to FALSE, the accessor throws an XML data store exception if it encounters a request for an XML document that resolves to a nonexistent directory.

The default for this setting is FALSE. Set it to TRUE to enable directory creation.

XML Call

The XML call and its subclasses are the layer between the OracleAS TopLink database queries call interface and the XML document accessing protocol provided by an XML accessor.

XML calls comprise two properties:

XML Stream Policy

The XMLStreamPolicy is an interface that defines a protocol to fetch streams of data for reading and writing XML documents. XML calls use the implementation from the XML accessor stream policy. This implementation delegates every request for a stream to the XML accessor.

This policy enables you to override the default behavior on a per-call basis. For example, you can name a specific file in a call, rather than relying on the XML file accessor to resolve the required file name. XML file stream policy provides this behavior. To access it, use the methods XMLCall.setFile(File) and XMLCall.setFileName(String).

XML Translator

XMLCalls use the XMLTranslator object to translate data between an XML document and an OracleAS TopLink database row. This pluggable interface enables you to modify the behavior of the XML calls. The XML calls default implementation of XML translator is DefaultXMLtranslator.

XMLTranslator Implementations

Several subclasses of XML call provide concrete implementations of call and SDK call. These classes differ in their implementations of the Call.execute(DatabaseRow, Accessor) method.

XML translator implementations offer object calls and data calls.

Object-Level Calls

Object-level calls enable you to call for objects from the datasource. All object calls other than Read calls require an association with a database query. OracleAS TopLink provides this automatically when you build a database query and configure it to use a custom call.

Read calls are an exception, because they are associated with a relationship mapping and do not require an associated database query.

The following subclasses enable you to manipulate objects:

XML Read Call If an XMLReadCall includes a reference to a one-to-one mapping, it extracts the foreign key for the mapping relationship from the database row passed in to the execute(DatabaseRow, Accessor) method. If there is no mapping, the XML read call extracts the primary key for the associated descriptor of the query from the database row.

In either case, XML read call then uses the resulting key to find the appropriate XML document.

XML Read All Call If the XMLReadAllCall includes a reference to an SDK object collection mapping, it extracts the foreign keys for the mapping relationship from the database row passed in to the execute(DatabaseRow, Accessor) method. It then uses the foreign keys to find the appropriate XML documents.

If no mapping is present, the XML read all call determines the root element name for the associated descriptor of the query and returns all the DatasebaseRows for that root element name.

XML Insert Call An XMLInsertCall takes the database row passed in to the execute(DatabaseRow, Accessor) method and uses the primary key to find the appropriate XML document stream. It then takes the modify row from the associated ModifyQuery, converts it to an XML document, and writes it out.

If the XML document exists, XML insert call raises an XML data store exception.

XML Update Call An XMLUpdateCall takes the database row passed in to the execute(DatabaseRow, Accessor) method and uses the primary key to find the appropriate XML document stream. It then takes the modify row from the associated ModifyQuery, converts it to an XML document, and writes it out.

If the XML document does not exist, XML update call raises an XML data store exception.

XML Delete Call An XMLDeleteCall takes the database row passed in to the execute (DatabaseRow, Accessor) method and uses the primary key to find the appropriate XML document stream. It then deletes this stream.

If the XML document exists, the call returns a row count of one. If not, the call returns a row count of zero.

XML Does Exist Call An XML does exist call takes the database row passed in to the execute(DatabaseRow, Accessor) method and uses the primary key to find the appropriate XML document stream. If the document exists, OracleAS TopLink converts it to a database row to verify the existence of the object. If the object does not exist, OracleAS TopLink returns a null.

Data Calls

Data calls enable you to retrieve data, rather than objects, from the datasource. Because XML data calls are not associated with a database query, they require a root element name and a set of ordered primary key element names. Pass these settings, along with the appropriate database row, to the XML stream policy at runtime. OracleAS TopLink uses this information to determine the appropriate XML document stream.

Example 5-47 A Typical Data Call

XMLDataReadCall call = new XMLDataReadCall();
call.setRootElementName("employee");
call.setPrimaryKeyElementName("id");

The following subclasses provide data call functionality:

XML Data Read Call An XML data read call takes the database row passed in to the execute (DatabaseRow, Accessor) method and uses the primary key to find the appropriate XML document stream, then converts the stream to a database row. OracleAS TopLink returns the database row in a vector to ensure a consistent result object.

If the XML data read call does not include a primary key element, it performs a simple read-all for all the XML documents, with the specified root element name. XML data read call converts these and returns them as a vector of database rows.

You can further configure XML data read calls to specify the fields to return and their types.

Example 5-48 An XML Data Read Call

XMLDataReadCall call = new XMLDataReadCall();
call.setRootElementName("employee");
call.setPrimaryKeyElementName("id");
call.setResultElementName("salary");
call.setResultElementType(java.math.BigDecimal.class);

XML Data Insert Call An XML data insert call takes the database row passed in to the execute(DatabaseRow, Accessor) method and uses the primary key to find the appropriate XML document stream. It then converts that row to an XML document and writes it out.

If the XML document already exists, XML data insert call raises an XML data store exception.

XML Data Update Call An XML data update call takes the database row passed in to the execute(DatabaseRow, Accessor) method and uses the primary key to find the appropriate XML document stream. It then converts that row to an XML document and writes it out.

If the XML document does not already exist, XML data update call raises an XML data store exception.

XML Data Delete Call An XML data delete call takes the database row passed in to the execute(DatabaseRow, Accessor) method and uses the primary key to find the appropriate XML document stream. It then deletes this stream.

If the XML document already exists, the call returns a row count of one. If not, the call returns a row count of zero.

XML Descriptor

An XMLDescriptor is a subclass of the SDKDescriptor that:

  • Automatically initializes its query manager with a set of default database queries, configured to use the appropriate XML calls. If you use the OracleAS TopLink default support for XML documents, no further modification of these calls is required.

  • Adds methods named in accordance with XML concepts rather than relational concepts. The setRootElementName(String) method replaces the setTableName(String) method, setPrimaryKeyElementName(String) replaces setPrimaryKeyFieldName(String), and so on.

XML Platform

XML platform is a subclass of SDK platform that implements the methods required to support sequence numbers: buildSelectSequenceCall() and buildUpdateSequenceCall(). These methods build and return the XML data calls that allow OracleAS TopLink to use sequence numbers maintained in XML documents.

To set the root element name for these XML documents, and the names of the elements used to hold the sequence name and sequence counter, specify these elements through the XML file login.

XML File Login

XML file login is a subclass of SDK login that allows you to configure the XML file accessor and XML platform. Use the XML file login to configure the following settings:

  • The base directory name for the XML files. This is the directory under which you store the root element name subdirectories.

    For more information about file name resolution, see "XML File Accessor" . The default is the current working directory.

    login.setBaseDirectoryName("C:\Employee Database"); 
    
    
  • The file name extension for the XML files. The default is .xml.

    login.setFileExtension(".xml"); 
    
    
  • Whether directories for the XML files should be created as needed. The default is False.

    login.setCreatesDirectoriesAsNeeded(true); 
    
    
  • Sequence number settings.

    login.setSequenceRootElementName("sequence");
    login.setSequenceNameElementName("name");
    login.setSequenceCounterElementName("count"); 
    
    

XML Schema Manager

XML schema manager is a subclass of SDK schema manager. It provides support for building the XML-based sequences required by your OracleAS TopLink database session. After you build your OracleAS TopLink project, use it to create a database session. Then you can log in and create the required sequences with the XML schema manager.

Example 5-49 Using XML Schema Manager for Sequencing

DatabaseSession session = project.createDatabaseSession();
session.login();
SchemaManager manager = new XMLSchemaManager(session);
manager.createSequences();

XML Accessor

XMLAccessor is an interface that extends the oracle.toplink.internal.databaseaccess.Accessor interface. It is the default interface that XML calls use to access streams for a given XML document.

To store XML documents in a non-native file system, provide a custom implementation of this interface. For example, to access your XML documents with a messaging service such as the Java Message Service (JMS), you can develop an implementation of XML accessor that translates the method calls into JMS calls.

If you build a custom accessor, configure an XML login to use it.

Example 5-50 Using a Custom Accessor with XML Login

XMLLogin login = new XMLLogin();
login.setAccessorClass(XMLJMSAccessor.class);
login.setUserName("user");
login.setPassword("password");
// etc.

XML Translator

XML calls use the XMLTranslator interface to manipulate XML documents stored in a non-native file system. Each XML call has its own XML translator. The default XML translator is an instance of DefaultXMLTranslator, but you can replace the DefaultXMLTranslator with your own custom implementation.

XML translator defines the following protocol:

  • The read(java.io.Reader) method takes a Reader that streams over an XML document, converts that document into a database row, and returns that database row.

  • The write(java.io.Writer, DatabaseRow) method takes a database row, converts it into an XML document, and writes that document out on the Writer.

Default XML Translator

As the default XML translator for XML calls, DefaultXMLTranslator performs translations between database rows and XML documents. To enable translations with the default XML translator:

  • All fields in a database row must have the same table name or default XML translator raises an XMLDataStoreException. The table name is the root element name of the XML document.

    <?xml version="1.0"?>
    <employee>
        <!-- field values will go here -->
    </employee>
    
    
  • Each field in the database row maps to an XML element. The field name is the element name, and the field value is the element content.

    <?xml version="1.0"?>
    <employee>
        <id>1</id>
        <firstName>Grace</firstName>
        <lastName>Hopper</lastName>
    </employee>
    
    
  • Any field in the database row with a value of null maps to an empty XML element with an attribute named null whose value is TRUE.

    <managedEmployees null="true"/>
    
    
  • If the value of a field in the database row is an SDK field value, default XML translator converts the elements of the SDK field value into nested XML elements. If the elements of the SDK field value are also database rows, default XML translator translates these recursively, using the same set of translations.

The DefaultXMLTranslator delegates the translation to two other classes:

  • The DatabaseRowToXMLTranslator builds an XML document from a database row and writes it onto a stream.

  • The XMLToDatabaseRowTranslator reads the XML document from a stream and builds a database row.

XML ZIP File Extension

The XML ZIP file extension is an enhancement to the XML implementation of the SDK. This extension adds the flexibility of maintaining the XML data store in archive files rather than in the directory/file structure of the standard XML data store. The format is similar to the standard XML data store; however, archive files replace directories in representing tables. The archive contains XML documents that map back to a database row in the same manner as if you stored them in a directory.

Using the ZIP File Extension

To use the XML ZIP file extension, configure your XML login to use the XML ZIP file accessor.

XMLLogin login = new XMLLogin();
login.setAccessorClass(XMLZipFileAccessor.class);

Configure Direct File Access With ZIP File Extension

To access an XML document within an archive file, the call must know both the archive file location and the name of the XML document entry within the archive. Therefore, the setFileName() message sent to an XML call must include both the archive file and the XML document entry name, as follows:

XMLReadCall call = new XMLReadCall();
call.setFileName("C:/Employee DataStore/employee.zip", "1.xml");

Implementation Details

ZIP file support requires the following two packages, stored in the package oracle.toplink.xml.zip:

  • The XML ZIP file accessor extends the XML file accessor. It offers the same functionality as the XML file accessor, but supports an XML ZIP file stream policy rather than the XML file stream policy

  • The XML ZIP file stream policy manages the XML archive files, and returns streams for reading and writing from individual archive entries. It does not provide additional functionality over its XML counterpart, the XML file stream policy, other than managing the added complication of getting read and write streams from an archive file.