Overview | Package | Class | Tree | Deprecated | Index | Help
| XCC/J 4.2-9
PREV NEXT | FRAMES NO FRAMES

# MarkLogic XML Content Connector For Java (XCC/J) Version 4.2-9

MarkLogic XML Content Connector for Java (XCC/J).

See:
Description

Packages
com.marklogic.xcc | XCC Core Public Interfaces.
com.marklogic.xcc.examples | XCC Examples.
com.marklogic.xcc.exceptions | XCC Exceptions.
com.marklogic.xcc.jndi | XCC Java Naming and Directory Interface (JNDI) Support.
com.marklogic.xcc.spi | XCC Service Provider Interface Package.
com.marklogic.xcc.types | XCC Type Definitions.

## MarkLogic XML Content Connector for Java (XCC/J).

This is XCC, the MarkLogic XML Content Connector API. This interface varies significantly from the original MarkLogic connector solution, XDBC. One of the goals of the new API is to simplify the public interface to make it easier to understand and to use.

## Basic Concepts

The XCC API has been designed so that client code will be easier to write, less error prone and more robust. With those goals in mind, the new public API intentionally doesn't use abstrations like "connection" or "statement". The new model is that of a session, or conversation, between client code and a contentbase.

The session metaphor is not only simpler and more natural, it makes it easier to hide implementation details. It also emphasizes that XCC is not like JDBC. Common JDBC usage patterns, such as pooling connections, are not appropriate with XCC.

### Sessions

The central metaphor used in XCC is the `Session` interface. A `Session` object is the facade through which client code performs all interaction with a contentbase.

`Session` instances encapsulate the location of a particular server, a contentbase on that server and authentication credentials (user identity) for that contentbase. A `Session` also holds dynamic state, but it is a lightweight object. It is OK to create and release `Session` objects as needed. Do not expend effort to pool and reuse them, they are not expensive to create.

### Content Sources

`Session` objects are created by factory methods on a `ContentSource` instance. A `ContentSource` object statically defines where a content server (an instance of MarkLogic Server) can be found.

At a minimum, a `ContentSource` object identifies a MarkLogic XDBC Server (host and port). It may also optionally hold default authentication credentials (user and password) and/or a contentbase (database) identifier on that server. There are several variations of the `ContentSource.newSession()` factory method which take arguments to provide this `Session`-specific information or to override the defaults.

#### JNDI Binding

Like J2EE DataSource objects, a `ContentSource` instance may be bound to a JNDI naming service. This allows the runtime environment (a J2EE container for example) to supply a pre-initialized `ContentSource` instance. This allows specification of the connection details at deployment time. Application code uses a JNDI lookup key to obtain a `ContentSource` instance. A typical JNDI lookup in a J2EE container would look like this:

    private ContentSource findContentSource() throws ServletException
    {
        try {
            Context initCtx = new InitialContext();
            Context envCtx = (Context) initCtx.lookup ("java:comp/env");

            return (ContentSource) envCtx.lookup("marklogic/ContentSource");
        } catch (NamingException e) {
            throw new ServletException ("ContentSource lookup failed: " + e, e);
        }
    }

See `ContentSourceBeanFactory` for more details about integrating with JNDI.

### Content Source Factory

If using JNDI to externalize `ContentSource` configuration is not appropriate, the helper class `ContentSourceFactory` may be used to instantiate `ContentSource` objects directly.

Several variations of the `ContentSourceFactory.newContentSource(String, int)` method are available:

    ContentSource contentSource =
        ContentSourceFactory.newContentSource ("somehost", 1234);

    ContentSource contentSource =
        ContentSourceFactory.newContentSource ("localhost", 1234, "fred", "secret");

    ContentSource contentSource =
        ContentSourceFactory.newContentSource ("host", 5678, "tony", "hush", "pubsdb");

Of note is the signature which takes a URI argument (`ContentSourceFactory.newContentSource(URI)`). This factory method accepts a URI of the form:

> `xdbc://user:password@host:port/contentbase`

Which encapsulates all the connection information into a single argument. The URL scheme "xdbc" means the connection will be made to an XDBC server port. The scheme "xcc" may also be used, it's an alias for "xdbc". Additional schemes may be added in the future, but these are the only two currently supported.

Passing a single String argument may be more convenient than passing four or five discreet values. Note that the factory method takes a `URI` object, not a `String`.

    URI uri = new URI ("xdbc://joe:secret@devhost:8050/techpubsdb");
    ContentSource contentSource = ContentSourceFactory.newContentSource (uri);

## XCC Code Samples

Following are some sample code snippets that illustrate typical usage scenarios.

### Simple Query Execution

This is an example of using `Session.submitRequest(Request)` to run an XQuery script and then iterating over the result. There is no longer an explicit connection object. The `Session` implementation manages connections automatically as needed. Also, when a `Session` object is closed, any currently open streaming `ResultSequence` objects created from that `Session` will automatically be closed. Any cached `ResultSequence`s no longer have any relationship to the `Session` that created them and will not be affected.

    Session session = contentSource.newSession ("mydatabase");
    Request request = session.newAdhocQuery ("\"Hello World\"");
    ResultSequence rs = session.submitRequest (request);

    while (rs.hasNext()) {
        ResultItem rsItem = rs.next();
        XdmItem item = rsItem.getItem();

        if (item instanceof XSString) {
            String strValue = item.asString();
            System.out.println ("String: " + strValue);
        }

        if (item instanceof XSDateTime) {
            XSDateTime dateTime = (XSDateTime) item;
            Date date = dateTime.asDate();
            System.out.println ("DateTime: " + date);
        }

        ...

        // Each ResultItem instance will be a concrete Item class
    }

    session.close();

### Invoking a Module On The Server

In addition to ad-hoc queries, `Session.submitRequest(Request)` can take a `ModuleInvoke` or `ModuleSpawn` object as the argument. Rather than literal code to be executed, these specify the URI of a server-resident module to be evaluated. In all other respects they are the same.

    Session session = contentSource.newSession ("mydatabase");
    Request request = session.newModuleInvoke ("mymodule.xqy");
    ResultSequence rs = session.submitRequest (request);

    while (rs.hasNext()) {
        ResultItem item = rs.next();

        ... (same as previous example)
    }

    session.close();

### Passing Variables With Queries

Variables may be bound to `Request` objects. When an execution request is issued to the server with `Session.submitRequest(Request)` all the variables currently bound to the `Request` object are sent along and defined as external variables in the execution context in the server.

XCC lets you create `XdmNode`s and `XdmSequence`s, as well as `XdmAtomic` values. However, in the initial XCC release values of this type may not be bound as external variables because MarkLogic Server cannot yet accept them. This capability is anticipated for a future release.

A `XdmVariable` object is a named `XdmValue`. XCC defines interfaces that model the XQuery data types. See the package `com.marklogic.xcc.types` (click the Description link) for UML diagrams and details of the type hierarchies.

The following is a (very) verbose example of creating and setting an external variable using a namespace:

    Session session = contentSource.newSession ("mydatabase");
    Request request = session.newAdhocQuery (
        "xquery version \"1.0-ml\";\n" +
        "declare namespace xyz=\"http://xyz.com/foo/bar\";\n" +
        "declare variable $xyz:myvar as xs:string external;\n" +
        "data ($xyz:myvar)");

    // create an unnamed xs:string value
    XdmValue value = ValueFactory.newXSString ("Some string value");

    // create a new XName object referencing the above namespace
    XName xname = new XName ("http://xyz.com/foo/bar", "myvar");

    // Create a Variable (name + value) instance
    XdmVariable myVariable = ValueFactory.newVariable (xname, value);

    // bind the Variable to the Request
    request.setVariable (myVariable);

    // "$xyz:myvar as xs:string" will be defined at query run time
    ResultSequence rs = session.submitRequest (request);

See the `ValueFactory` helper class for more details about creating `XdmVariable` and `XdmValue` instances.

The following is an example of creating and binding a variable in the default namespace.

    Session session = contentSource.newSession ("mydatabase");
    Request request = session.newAdhocQuery (
        "xquery version \"1.0-ml\";\n" +
        "declare variable $myvar as xs:string external;\n" +
        "data ($myvar)");

    // create an unnamed xs:string value
    XdmValue value = ValueFactory.newXSString ("Some string value");

    // create a new XName object referencing the default namespace
    XName name = new XName ("myvar");

    // create a Variable and bind it to the Request
    request.setVariable (ValueFactory.newVariable (name, value));

    // "$myvar as xs:string" will be defined at query run time
    ResultSequence rs = session.submitRequest (request);

A conveience method on the `Session` object will create and bind a `XdmVariable` instance in one call. The following example creates the same `XdmVariable` as above, binds it to the `Request` and returns the newly created `XdmVariable` instance. In this example, the return value is ignored.

    Session session = contentSource.newSession ("mydatabase");
    Request request = session.newAdhocQuery (
        "xquery version \"1.0-ml\";\n" +
        "declare variable $myvar as xs:string external;\n" +
        "data ($myvar)");

    // create Variable "myvar", bind to Request, ignore return value
    request.setNewVariable ("myvar", ValueType.XS_STRING, "Some string value");

    // "$myvar as xs:string" will be defined at query run time
    ResultSequence rs = session.submitRequest (request);

### Inserting Content (Documents)

The model for inserting content differs in a couple of significant ways from XDBC. First of all, you no longer ask for an `XDMPDocInsertStream` and push your data into it. You now create `Content` objects which describe content (a document) to be inserted and XCC pulls the data from that source.

Secondly, because content uploads can be interrupted and XCC implements automatic recovery of uploads, instances of `Content` should be rewindable. See the `ContentFactory` class for acceptable sources of content.

This example inserts an XML document from a literal `String`, in the "MyNameSpace" namespace and requests that no automatic document repair be done. The `ContentCreateOptions` instance is created with a convenience method that is preset to select XML format.

    ContentCreateOptions options = ContentCreateOptions.newXmlInstance();

    options.setNamespace ("MyNameSpace");
    options.setRepairLevel (DocumentRepairLevel.NONE);

    Content content =
        ContentFactory.newContent ("someUri", "<root attr=\"foo\">blah</root>", options);

    session.insertContent (content);

This example inserts the content of a file in text format. It uses a `ContentCreateOptions` object to set the namespace and quality.

    File file = new File ("/some/file/path");
    ContentCreateOptions options = ContentCreateOptions.newTextInstance();

    options.setNamespace ("MyNameSpace");
    options.setQuality (20);

    Content content =
        ContentFactory.newContent ("someUri", file, options);

    session.insertContent (content);

This example takes a W3C (`Document`) Object Model (DOM) instance (an object representation of an XML tree) and inserts it via the `Session` object. No `ContentCreateOptions` object is provided, so defaults are applied. Because, by definition, the DOM is a well-formed XML tree, the content format defaults to XML. If another format (text or binary) is selected by the options, the serialized String representation of the XML tree is inserted.

    DocumentBuilder builder =
        DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document dom = builder.parse ("someDocUri");

    Content content = ContentFactory.newContent ("someUri", dom, null);

    session.insertContent (content);

If you're using JDOM, you can use one of the outputter classes in the org.jdom.output package to convert the JDOM document to a form that can be handled by a `Session`. For example, this code translates a JDOM tree to a W3C DOM and inserts it:

    Document dom = new org.jdom.output.DOMOutputter().output (jdomDocument);
    Content content = ContentFactory.newContent ("someUri", dom, null);

    session.insertContent (content);

For large JDOM trees, it may be more efficient to serialize them as Strings for insertion.

### Multi-Document Insert

Multiple documents can be atomically inserted (all or none are committed as a unit) by passing an array of `Content` objects to `Session.insertContent(Content [])`.

    Session session = contentSource.newSession ("mydatabase");
    File file = new File ("/some/file/path.xml");
    String stringDoc = "<snoop attr=\"bling\">dog</snoop>";
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document dom = builder.parse ("someDocUri");

    Content [] docGroup = {
        ContentFactory.newContent ("uri1", file, null),
        ContentFactory.newContent ("uri2", stringDoc, null),
        ContentFactory.newContent ("uri3", dom, null)
    };

    session.insertContent (docGroup);

Overview | Package | Class | Tree | Deprecated | Index | Help
| XCC/J 4.2-9
PREV NEXT | FRAMES NO FRAMES

Copyright © 2003-2012 MarkLogic Corporation, All Rights Reserved.

Complete online documentation for MarkLogic Server, XQuery and related components may be found at developer.marklogic.com