dev@fi.java.net

Re: JAXB Hook for FI

From: Kohsuke Kawaguchi <Kohsuke.Kawaguchi_at_Sun.COM>
Date: Tue, 10 May 2005 15:33:35 -0700

Paul Sandoz wrote:
> One of the general problems we will have to tackle is the push me pull
> me creature that is JAX-RPC + JAXB. JAX-RPC processing of SOAP messages
> is done using a pull model. I could write a rather odd parser that
> allows for a pull model via StAX for JAX-RPC to process the SOAP message
> infoset and a push model for JAXB to process the content of the SOAP
> message (header blocks, body and fault detail children).

When the JAXB RI accepts a StAX parser as an input, we internally run
the 'message pump' that peeks the next event and send it into this
interface. I think this is easier to manage, rather than to mix pull and
push both into the same FI parser class. Any reason why this isn't
desirable?

On a different note, I added IntArrayData. This can be passed to
XmlVisitor.text.

One thing the current XmlVisitor doesn't do well is the attributes. It
relies on SAX's definition, so we can only pass String, not
CharSequence. This has been OK for the MTOM support, but I guess it's
not good for FI. Should I be changing this to something else?

-- 
Kohsuke Kawaguchi
Sun Microsystems                   kohsuke.kawaguchi_at_sun.com


package com.sun.xml.bind.v2.runtime.unmarshaller;

/**
 * Typed {_at_link CharSequence} for int[].
 *
 * <p>
 * Fed to unmarshaller when the 'text' data is actually
 * a virtual image of int array.
 *
 * <p>
 * This class holds int[] as a triplet of (data,start,len)
 * where 'start' and 'len' represents the start position of the
 * data and the length.
 *
 * @author Kohsuke Kawaguchi
 */
public class IntArrayData implements CharSequence {

    private int[] data;
    private int start;
    private int len;

    /**
     * String representation of the data. Lazily computed.
     */
    private StringBuilder literal;


    public IntArrayData(int[] data, int start, int len) {
        set(data, start, len);
    }

    public IntArrayData() {
    }

    /**
     * Sets the int[] data to this object.
     *
     * <p>
     * This method doesn't make a copy for a performance reason.
     * The caller is still free to modify the array it passed to this method,
     * but he should do so with a care. The unmarshalling code isn't expecting
     * the value to be changed while it's being routed.
     */
    public void set(int[] data, int start, int len) {
        this.data = data;
        this.start = start;
        this.len = len;
        this.literal = null;
    }

    public int length() {
        return getLiteral().length();
    }

    public char charAt(int index) {
        return getLiteral().charAt(index);
    }

    public CharSequence subSequence(int start, int end) {
        return getLiteral().subSequence(start,end);
    }

    /**
     * Computes the literal form from the data.
     */
    private StringBuilder getLiteral() {
        if(literal!=null) return literal;

        literal = new StringBuilder();
        int p = start;
        for( int i=len; i>0; i-- ) {
            if(literal.length()>0) literal.append(' ');
            literal.append(data[p++]);
        }

        return literal;
    }
}