Preparsers

In this section:

A preparser is a Java class designed to convert an incoming non-XML source into an XML document. This preparsed document then passes through the standard transform services to reach the designated processing business agent. Preparsers are not invoked when the Accepts non-XML (flat) only property in listeners is set to true.

The engine calls the preparser with the appropriate data form, if possible. Otherwise, an XDException is thrown. Stream and byte[] format can only be specified for the first preparser in a sequence.

The preparser is called on the worker thread, and one instance exists for each worker operating under the listener.

The preparser must support the appropriate transformations.

Preparsers execute for all documents (flat and XML) as well as streaming listeners. The XDDocument object passed to your exit contains the input and APIs are available to determine the type. For example if the input type in reports true to isBytes(), then you would convert the input from bytes to the desired output format.

On completion of the stream, the preparser is responsible for emitting a "default" dummy document to satisfy the preparser specification (do not emit null) and to call

setStreamProcessed(true);

to signal to the engine that work with this stream is complete.

Note: <BATCH>EOT</BATCH> is emitted as a dummy, which is the format generated automatically by the Preparser Wizard.

Stream preparsers interact with the transaction control system slightly differently than do single entity preparsers. All documents on the stream are treated as a single transaction, and commit is not called until the setStreamProcessed(true) is called by the preparser. The signal to business agents that the stream of related documents is complete is the call to commit() in the business agent XDTx class. For example, an acknowledgment business agent might need to accumulate the acknowledgment until an entire EDI document has been handled. Its commit() method or its rollback() method would be the signal to assemble the final acknowledgment (EDI 997) and emit it to the proper destination.


Top of page

x
public int inputForm()

Returns whether the preparser expects:

Mnemonic

Input Format

XDPreParser.BOTH

Byte array and String are both accepted.

XDPreParser.BYTE

Byte array.

XDPreParser.STREAM

InputStream. Used by splitting preparsers only. Can apply only to the first preparser in a stack.

XDPreParser.STRING

String.


Top of page

x
public int resultForm()

Returns whether the remainder of the message handling is to treat this document as flat or XML. A flat document is not parsed, but is sent to the business agents in the form returned from the preparser.

Mnemonic

Input Format

XDPreParser.XML_OUTPUT

Treats this message as an XML document to be parsed. This is the default value.

XDPreParser.FLAT_OUTPUT

Prevents parsing of the document and treats the message as flat (non-XML).

XDPreParser.DOCUMENT

Provides an alternate call to transform the message. The result of this call is an XDDocument; this is an XML tree. Preparsers that can automatically construct a tree can avoid the subsequent parse.

The resultForm() value is only checked for the last preparser to be executed. Values returned from preparsers earlier in the chain are ignored.

The return should always be "success" unless the preparser needs to report an error.


Top of page

x
Writing a Splitting Preparser

Splitting preparsers enable a message to be divided into sections for processing. A splitting preparser must be the first configured preparser in the message flow. Such a preparser must implement the getInputForm() method, returning XDPreParser.STREAM.

The preparser reads the stream, dividing the message into portions for processing. At the end of stream, it emits an end of stream document <batch>EOT</batch> and signals to the worker that the end of stream has been reached. Your agent or reviewer can optionally elect to "see" the end of stream signal.

This example is taken from the flat document preparser. It uses a method isDelim() to determine whether the character read from the stream is a delimiter. Several delimiters in a row are permitted; for example, if the delimiter were \n, then several blank lines would be treated as a single delimiter.

StringBuffer sb = new StringBuffer(100);
BufferedInputStream bis = null;
boolean delimChar = false;
int lastChar = -1;
public String transform(InputStream is) throws Exception
{
    if (bis == null)   // initial state
    {
        bis = new BufferedInputStream(is);
    }
     String s;
    sb.setLength(0);      // clear out for next message
    int v = -1;
    for (;;)
    {
        if (!delimChar)   // need to read from stream
        {
            v = bis.read();
        }
        else              // filled lastChar trying to swallow delimiters
        {
            v = lastChar;
            delimChar = false;
        }
        if (v == -1)
        {
            break;
        }
        else
        {
            char c = (char)v;
            if (isDelim(c))     // delimiter?
            {
                for (;;)        // swallow any other delimiters
                {
                    v = bis.read();
                    char cc = (char)v;
                    if (!isDelim(cc))    // oops, read a valid char
                    {
                        lastChar = v;    // save it and signal
                        delimChar = true;
                        break;
                    }
                }
                break;
            }
            else       // append to output
            {
                sb.append(c);
            }
        }
    }
    s = sb.toString();       // create output
    if (s.length() == 0)     // end of processing?
    {
        s = "<batch>EOT</batch>";           // eos signal
        worker.setStreamProcessed(true);    // mark end of stream reached
        bis = null;                         // reset
        delimChar = false;                  // reset
    }
    return s;
}

Note the call to setStreamProcessed() on completion of the stream. This is required to instruct the flow to take end of stream actions on the EOT message.


iWay Software