package org.codehaus.xfire.xmlbeans.client;

import java.util.ArrayList;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.codehaus.xfire.client.AbstractClientHandler;
import org.codehaus.xfire.fault.XFireFault;
import org.codehaus.xfire.util.STAXUtils;
import org.codehaus.xfire.xmlbeans.XMLBeansFault;


/**
 * Handles XmlBeans requests and response for SOAP/REST clients.
 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
 * @since Oct 27, 2004
 */
public class XMLBeansClientHandler
    extends AbstractClientHandler
{
    private XmlObject[] request;
    private XmlObject[] response;
    private XmlOptions options;
    
    public XMLBeansClientHandler()
    {
        options = new XmlOptions();
        options.setCharacterEncoding("UTF-8");
    }
    
    public XMLBeansClientHandler(XmlOptions options)
    {
        this.options = options;
    }
    
    /**
     * @return Returns the request.
     */
    public XmlObject[] getRequest()
    {
        return request;
    }
    
    /**
     * @param request The request to set.
     */
    public void setRequest(XmlObject[] request)
    {
        this.request = request;
    }
    
    /**
     * @return Returns the response.
     */
    public XmlObject[] getResponse()
    {
        return response;
    }
    
    /**
     * @param response The response to set.
     */
    public void setResponse(XmlObject[] response)
    {
        this.response = response;
    }

    public void writeRequest( XMLStreamWriter writer ) 
    	throws XMLStreamException
    {
        for ( int i = 0; i < request.length; i++ )
        {
            STAXUtils.copy(request[i].newXMLStreamReader(options), writer);
        }
    }

    
    public void handleResponse(XMLStreamReader reader) 
    	throws XMLStreamException, XFireFault
    {
        try
        {
            ArrayList responseElements = new ArrayList();
            
            boolean more = true;
            int event = reader.getEventType();
            while ( more )
            {
                switch( event )
                {
                    case XMLStreamReader.END_DOCUMENT:
                        more = false;
                        break;
                    case XMLStreamReader.START_ELEMENT:
                        responseElements.add(XmlObject.Factory.parse( reader ));
                    case XMLStreamReader.END_ELEMENT:
                        // TODO: there should be a more generic way to do this
                        // so that it works with SOAP and REST at any point
                        // in any stream.
                        if ( reader.getLocalName().equals("Envelope") )
                            more = false;
                        else if ( reader.getLocalName().equals("Header") )
                            more = false;
                        break;
                    default:
                        break;
                }
                
                if ( more )
                    event = reader.next();
            }
            
            response = (XmlObject[]) responseElements.toArray(new XmlObject[responseElements.size()]);
            
            if ( response.length == 1 
                 && 
                 response[0].getDomNode().getLocalName().equals("Fault") )
            {
                throw new XMLBeansFault(response[0]);
            }
        }
        catch (XmlException e)
        {
            throw new XMLStreamException("Couldn't parse response.", e);
        }
    }
}

@@ -1745,24 +1745,66 @@
 ption%0A    %7B%0A
+        if ( request != null )%0A        %7B%0A%09
         for 
@@ -1842,16 +1842,17 @@
 ; i++ )%0A
+%09
         
@@ -1845,32 +1845,33 @@
 ++ )%0A%09        %7B%0A
+%09
             STAX
@@ -1930,16 +1930,27 @@
 riter);%0A
+%09        %7D%0A
         

Check if there's anything to write for the request.