Loading TOC...
Java Application Developer's Guide (PDF)

Java Application Developer's Guide — Chapter 14

Content Transformations

The MarkLogic Java API allows you to create custom content transformations and apply them during operations such as document ingestion and retrieval. You can also apply transformations to search results. Transforms can be implemented using server-side JavaScript, XQuery, and XSLT. A transform can accept transform-specific parameters.

You can specify default transformations as well as operation-specific transformations. For example, setting the DefaultDocumentReadTransform property of ServerConfigurationManager to the name of a content transformation automatically applies the transformation to every document as it is read from the database. By default, there is no default read transform. Setting up default transforms requires rest-admin privileges.

This chapter contains the following sections:

Installing Transforms

To install a transform on your server, do the following steps:

  1. If you have not already done so, create a DatabaseClient for connecting to the database. For example, if using digest authentication:
    DatabaseClient client = DatabaseClientFactory.newClient(
        host, port, new DigestAuthContext(username, password));
  2. Create a manager for transform extensions. Since transforms are installed on the REST API instance, use a ServerConfigManager to create the manager.
    TransformExtensionsManager transMgr = 
        client.newServerConfigManager().newTransformExtensionsManager();
  3. Optionally, specify the metadata for the transform, using an ExtensionMetadata object.
    ExtensionMetadata metadata = new ExtensionMetadata();
    metadata.setTitle("XML-TO-HTML XSLT Transform");
    metadata.setDescription("This plugin transforms an XML document with a
                             known vocabulary to HTML");
    metadata.setProvider("MarkLogic");
    metadata.setVersion("0.1");
  4. Create a handle to the transform implementation. For example, the following code creates a handle that streams the implementation from a file.
    FileInputStream transStream = new FileInputStream(
                  "scripts"+File.separator+TRANSFORM_NAME+".xsl");
    InputStreamHandle handle = new InputStreamHandle(transStream);
  5. Install the transform and its metadata on MarkLogic Server.
    transMgr.writeXSLTransform(TRANSFORM_NAME, handle, metadata);
  6. Release the client if you no longer need the database connection.
    client.release();

Using Transforms

Once you install a transform, you can apply it under the following circumstances:

  • inserting a document into the database
  • reading a document from the database
  • retrieving search results
  • testing for alerting rule matches

This section describes how to use transforms and includes the following topics:

Transforming a Document When Reading It

A read transform receives the document from the database as input and produces the document to be returned to the client application as output. Specify a read transform by including a ServerTransform object in your call to DocumentManager.read.

Use the following procedure to transform a document when reading it:

  1. If you have not already done so, create a DatabaseClient for connecting to the database. For example, if using digest authentication:
    DatabaseClient client = DatabaseClientFactory.newClient(
        host, port, new DigestAuthContext(username, password));
  2. Create an appropriate Document Manager for the to be transformed document.
    1. In this case, we use a XMLDocumentManager.
      XMLDocumentManager XMLDocMgr = client.newXMLDocumentManager();
    2. In this case, we use JSONDocumentManager.
      JSONDocumentManager JSONDocMgr = client.newJSONDocumentManager();
  3. Create an appropriate read handle for the document's content.
    1. This example uses a com.marklogic.client.io.DOMHandle object.
      DOMHandle handleXML = new DOMHandle();
    2. This example uses a com.marklogic.client.io.JacksonHandle object.
      JacksonHandle handleJSON = new JacksonHandle();
  4. Optionally, specify the expected MIME type for the content. This is only needed if the transform supports content negotiation and changes the content from one MIME type to another.
    handleXML.setMimetype("text/xml");
    //OR
    handleJSON.setMimetype("text/json");
  5. Create a transform descriptor by creating a ServerTransform object. Specify the transform name and any parameter values expected by the transform.
    ServerTransform transform = new ServerTransform(TRANSFORM_NAME);
    transform.put("some-param", "value");
  6. Read the document from the database, supplying the ServerTransform object. The read handle will contain the transformed content.
    XMLDocMgr.read(theDocURI, handleXML, transform);
    //OR
    JSONDocMgr.read(theDocURI, handleJSON, transform);
    
  7. Release the database client if you no longer need the database connection.
    client.release();

Transforming a Document When Writing It

A write transform receives the document from the client application as input, and should produce the document to be written to the database as output. Specify a write transform by including a ServerTransform object in your call to DocumentManager.write.

Use the following procedure to transform a document when writing it:

  1. If you have not already done so, create a DatabaseClient for connecting to the database. For example, if using digest authentication:
    DatabaseClient client = DatabaseClientFactory.newClient(
        host, port, new DigestAuthContext(username, password));
  2. Create an appropriate Document Manager for the document. In this case, we use a TextDocumentManager.
    TextDocumentManager writeMgr = client.newTextDocumentManager();
  3. Create a handle to input data. For example, the following code streams the content from the file system.
    FileInputStream docStream = new FileInputStream("/path/to/my.txt");
    InputStreamHandle writeHandle = new InputStreamHandle(docStream); 
  4. Optionally, specify the MIME type for the content. This is only needed if the transform supports content negotiation and changes the content from one MIME type to another.
    writeHandle.setMimetype("text/xml");
  5. Create a transform descriptor by creating a ServerTransform object. Specify the transform name and any parameter values expected by the transform.
    ServerTransform transform = new ServerTransform(TRANSFORM_NAME);
    transform.put("drop-font-tags", "yes");
  6. Write the content to the database. The transform is applied to the content on MarkLogic Server before inserting the document into the database.
    String theDocURI = "/examples/mydoc.xml";
    writeMgr.write(docId, writeHandle, transform);
  7. Release the database client if you no longer need the database connection.
    client.release();

Transforming Search Results

When you apply a transform to search results, the transform receives the search response data prepared by MarkLogic Server as input, and should produce the output to be returned to the client application. For example, if the response is in XML, the input is a document with a <search:response/> root element.

For details, see Transforming Search Results.

Transforming Alert Match Results

When you apply a transform to the results of an alerting match, the transform receives the match results prepared by MarkLogic Server as input, and should produce the output to be returned to the client application. For example, if the response is in XML, the input is a document with a <rapi:rules> root element.

For details, see Transforming Alert Match Results.

Overall Transform Administration

You can list all currently installed transform extensions by doing the following:

String result = transMgr.listTransforms(
   new StringHandle().withFormat(Format.XML)).get();
// format can be JSON as well
   new StringHandle().withFormat(Format.JSON)).get();

By default, calling listTransforms() rebuilds the transform metadata to ensure the metadata is up to date. If you find this refresh makes discovery take too long, you can disable the refresh by setting the refresh parameter to false:

String result = transMgr.listTransforms(
   new StringHandle().withFormat(Format.XML), false).get();
//Or
   new StringHandle().withFormat(Format.JSON), false).get();

Disabling the refresh can result in this request returning inaccurate information, but it does not affect the freshness or availability of the implementation of any transforms.

To delete a transform, effectively uninstalling it from the server do the following:

transMgr.deleteTransform(TRANSFORM_NAME);

Reading Transforms

To read the source code of an XQuery implemented transform into your application, do:

StringHandle textHandle = transMgr.readXQueryTransform(TRANSFORM_NAME, 
   new StringHandle()); // can be any text handle

To read the source code of an XSLT implemented transform into your application, do:

XMLReadHandle xHandle = transMgr.readXSLTransform(TRANSFORM_NAME,
   new XMLReadhandle());

To read the source code of an Javascript implemented transform into your application, do:

JSONReadHandle jHandle = transMgr.readJavascriptTransform(TRANSFORM_NAME,
   new JSONReadHandle());

Logging

Since it is a manager, you can define a RequestLogger object and start and stop logging client requests to the TransformExtensionsManager. For more information, see Logging

RequestLogger logger = client.newLogger(stream);
transformsMgr.startLogging(logger);
transformsMgr.stopLogging();

Writing Transformations

You can write transforms using server-side JavaScript, XQuery, or XSLT. The transform interface is shared across multiple MarkLogic client APIs, so you can use the same transforms with the Java Client API, Node.js Client API, and the REST Client API. For the interface definition, authoring guidelines, and example implementations, see Writing Transformations in the REST Application Developer's Guide.

Resource service extensions, transforms, row mappers and reducers, and other hooks cannot be implemented as JavaScript MJS modules.

« Previous chapter
Next chapter »