You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by gd...@apache.org on 2001/04/27 00:53:42 UTC

cvs commit: xml-axis/java/src/org/apache/axis/message/events CharactersEvent.java EndElementEvent.java IDElementEvent.java SAXEvent.java StartElementEvent.java

gdaniels    01/04/26 15:53:42

  Modified:    java/src/org/apache/axis/message MessageElement.java
                        MessageWithAttachments.java SOAPEnvelope.java
                        SOAPHeader.java
  Added:       java/src/org/apache/axis/message DebugHeader.java
                        ElementFactory.java ElementRecorder.java
                        ElementRegistry.java RPCElement.java RPCParam.java
                        SAXOutputter.java SOAPBodyElement.java
                        SOAPSAXHandler.java ThreadedSAXAdapter.java
               java/src/org/apache/axis/message/events CharactersEvent.java
                        EndElementEvent.java IDElementEvent.java
                        SAXEvent.java StartElementEvent.java
  Removed:     java/src/org/apache/axis/message Message.java RPCArg.java
                        RPCBody.java SOAPBody.java
  Log:
  New message model.
  
  WARNING : THIS IS NOT FULLY COMPLETE.  IT NEEDS AT LEAST
  SOME SERIOUS CLEANING, IF NOT REWRITING IN PLACES.  USE
  AT YOUR OWN RISK.
  
  Summary:
  
  The big difference here is that there's no DOM.  We now use a custom data
  structure which is built by parsing a stream of SAX events.  The
  SOAPSAXParser class is the parser - you initialize it and hook it up to
  a SAX event stream, and it happily fills in the message data structures
  for you.  NOTE: it does this in a "lazy" fashion, so there are pause()
  and continue() methods which allow the parse to start, and then stop
  when you've found what you're looking for.
  
  During a parse, there is a DeserializationContext object which keeps track
  of the current namespace/prefix mappings, which elements map to which IDs,
  and the current set of type mappings for deserialization.  (see the
  encoding package)
  
  Elements that we scan over, or ones for which we don't have a particular
  deserializer, are recorded - in other words, the SAX events are placed into
  a queue which may be 'played back' at a later time to any SAX
  ContentHandler.
  
  Once a SOAPEnvelope has been built, either through a parse or manual
  construction by the user, it may be output using a SerializationContext (also
  see the encoding package).  MessageElements all have an output() method
  which lets them write out their contents.
  
  There's a lot that still needs doing, but the basics are here.  More info
  on the axis-dev list.
  
  Code-level changes:  Too many to list
  
  Revision  Changes    Path
  1.5       +194 -40   xml-axis/java/src/org/apache/axis/message/MessageElement.java
  
  Index: MessageElement.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/MessageElement.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- MessageElement.java	2001/03/29 05:37:48	1.4
  +++ MessageElement.java	2001/04/26 22:53:40	1.5
  @@ -1,8 +1,10 @@
  +package org.apache.axis.message;
  +
   /*
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 1999 The Apache Software Foundation.  All rights 
  + * Copyright (c) 2001 The Apache Software Foundation.  All rights 
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -53,48 +55,200 @@
    * <http://www.apache.org/>.
    */
   
  -package org.apache.axis.message;
   
  -import org.apache.axis.utils.*;
  +import org.xml.sax.*;
  +import org.xml.sax.helpers.AttributesImpl;
  +import org.w3c.dom.*;
  +import org.apache.axis.Constants;
  +import org.apache.axis.message.events.*;
   import org.apache.axis.encoding.*;
  +import org.apache.axis.utils.QName;
  +import java.util.*;
   import java.io.*;
   
  -/**
  - * @author James Snell (jasnell@us.ibm.com)
  - */
  -public interface MessageElement { 
  +public class MessageElement
  +{
  +    private static final boolean DEBUG_LOG = false;
  +    
  +    protected String    name ;
  +    protected String    prefix ;
  +    protected String    namespaceURI ;
  +    protected AttributesImpl attributes;
  +    protected String    id;
  +    protected boolean   isRoot = false;
  +    protected SOAPEnvelope message = null;
  +    protected DeserializationContext context = null;
  +    DeserializerBase deserializer;
  +    
  +    // The java Object value of this element.  This is either set by
  +    // deserialization, or by the user creating a message.
  +    protected Object value = null;
  +    protected QName typeQName = null;
  +    
  +    // String representation of this element.
  +    protected String stringRep = null;
  +    
  +    protected ElementRecorder recorder = null;
  +
  +    /** No-arg constructor for building messages?
  +     */
  +    MessageElement()
  +    {
  +    }
  +    
  +    MessageElement(String namespace, String localPart,
  +                    Attributes attributes, DeserializationContext context)
  +    {
  +        if (DEBUG_LOG) {
  +            System.out.println("New MessageElement named " + localPart);
  +            for (int i = 0; i < attributes.getLength(); i++) {
  +                System.out.println("  " + attributes.getQName(i) + " = '" + attributes.getValue(i) + "'");
  +            }
  +        }
  +      this.namespaceURI = namespace;
  +      this.name = localPart;
  +      this.context = context;
  +      this.attributes = new AttributesImpl();
  +      for (int i = 0; i < attributes.getLength(); i++) {
  +          this.attributes.addAttribute(attributes.getURI(i),
  +                                       attributes.getLocalName(i),
  +                                       attributes.getQName(i),
  +                                       "string",
  +                                       attributes.getValue(i));
  +      }
  +            
  +      String rootVal = attributes.getValue(Constants.URI_SOAP_ENV, Constants.ATTR_ROOT);
  +      // !!! This currently defaults to false... should it default to true?
  +      if (rootVal != null)
  +          isRoot = rootVal.equals("1");
  +      
  +      id = attributes.getValue(Constants.ATTR_ID);
  +      // Register this ID with the context.....
  +      if (id != null) {
  +          context.registerID(id, this);
  +      }
  +    }
  +    
  +    public boolean getRoot() { return isRoot; }
  +    public String getID() { return id; }
       
  - // Message Element Types.
  -    public static byte ELEMENT_TYPE_ENVELOPE = 1;
  -    public static byte ELEMENT_TYPE_HEADER = 2;
  -    public static byte ELEMENT_TYPE_BODY = 3;
  -    public static byte ELEMENT_TYPE_ENTRY = 4;
  -    public static byte ELEMENT_TYPE_FAULT = 5;
  -    public static byte ELEMENT_TYPE_ORPHAN = 99;    // No Parent
  -
  -    public byte           getMessageElementType();
  -    public QName          getQName();
  -    public QName          getTypeQName();
  -    public String         getNamespaceURI();
  -    public String         getLocalName();
  -    public String         getPrefix();
  -    
  -    public String         getAttribute(QName qname);
  -    public String         getAttribute(String name);
  -    
  -    public MessageElement getNextSibling();
  -    public MessageElement getPreviousSibling();
  -    public MessageElement getFirstChild();
  -    public MessageElement getFirstChildNamed(QName qname);
  -    public MessageElement getParent();
  -    
  -    public String         getStringValue();
  -    public Object         getValue();
  -    public Object         getValue(Deserializer deser);
  -    public Object         getValue(TypeMappingRegistry tmr);
  - 
  -    public Reader         getOuterCharacterStream();
  -    public Reader         getInnerCharacterStream();
  -    public InputStream    getOuterByteStream();
  -    public InputStream    getInnerByteStream();
  +    public String getName() { return( name ); }
  +    
  +    public String getPrefix() { return( prefix ); }
  +    public void setPrefix(String prefix) { this.prefix = prefix; }
  +    
  +    public String getNamespaceURI() { return( namespaceURI ); }
  +    public void setNamespaceURI(String nsURI) { namespaceURI = nsURI; }
  +    
  +    public QName getType() { return typeQName; }
  +    public void setType(QName qName) { typeQName = qName; }
  +
  +    public void setEnvelope(SOAPEnvelope env)
  +    {
  +        message = env;
  +    }
  +    public SOAPEnvelope getEnvelope()
  +    {
  +        return message;
  +    }
  +    
  +    public Element getAsDOM()
  +    {
  +        return null;
  +    }
  +    
  +    public Object getValue() throws IOException
  +    {
  +        if (value instanceof ElementRecorder) {
  +            // !!! Lazy deserialization here... We have the SAX events,
  +            //     but haven't run them through a deserializer yet.
  +            return null;
  +        }
  +        
  +        if (deserializer != null) {
  +            value = deserializer.getValue();
  +            deserializer = null;
  +        }
  +        
  +        return value;
  +    }
  +
  +    public void setValue(Object val)
  +    {
  +        value = val;
  +    }
  +    
  +    public ContentHandler getContentHandler()
  +    {
  +        if (recorder == null)
  +            recorder = new ElementRecorder();
  +        
  +        return recorder;
  +    }
  +    
  +    public void publishToHandler(ContentHandler handler) throws SAXException
  +    {
  +        if (recorder == null)
  +            throw new SAXException("No event recorder inside element");
  +        
  +        recorder.publishToHandler(handler);
  +    }
  +    
  +    public void output(SerializationContext context) throws IOException
  +    {
  +        context.registerPrefixForURI(prefix, namespaceURI);
  +        //System.out.println("In outputToWriter (" + this.getName() + ")");
  +        if (recorder != null) {
  +            try {
  +                recorder.publishToHandler(new SAXOutputter(context));
  +            } catch (SAXException e) {
  +                Exception ex = e.getException();
  +                if (ex instanceof IOException)
  +                    throw (IOException)ex;
  +                throw new IOException(e.toString());
  +            }
  +            return;
  +        }
  +
  +        AttributesImpl attrs = new AttributesImpl();
  +        Object val = getValue();
  +        
  +        if (val != null) {
  +            if (typeQName == null)
  +                typeQName = context.getQNameForClass(val.getClass());
  +            
  +            if (attributes != null) {
  +                // Must be writing a message we parsed earlier, so just put out
  +                // what's already there.
  +                for (int i = 0; i < attributes.getLength(); i++) {
  +                    attrs.addAttribute(attributes.getURI(i), attributes.getLocalName(i),
  +                                       attributes.getQName(i), "string",
  +                                       attributes.getValue(i));
  +                }
  +            } else {
  +                // Writing a message from memory out to XML...
  +                // !!! How do we set other attributes when serializing??
  +                
  +                ServiceDescription desc = getEnvelope().getServiceDescription();
  +                if ((desc == null) || desc.getSendTypeAttr()) {
  +                    if (typeQName != null) {
  +                        attrs.addAttribute(Constants.URI_SCHEMA_XSI, "type", "xsi:type",
  +                                           "string",
  +                                           context.qName2String(typeQName));
  +                    }
  +                }
  +                
  +                if (val == null)
  +                    attrs.addAttribute(Constants.URI_SCHEMA_XSI, "null", "xsi:null",
  +                                       "string", "1");
  +            }
  +            
  +            context.startElement(new QName(getNamespaceURI(), getName()), attrs);
  +            // Output the value...
  +            if (val != null)
  +                context.writeString(value.toString());
  +            
  +            context.endElement();
  +        }
  +    }
   }
  
  
  
  1.3       +1 -1      xml-axis/java/src/org/apache/axis/message/MessageWithAttachments.java
  
  Index: MessageWithAttachments.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/MessageWithAttachments.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- MessageWithAttachments.java	2001/03/27 06:31:16	1.2
  +++ MessageWithAttachments.java	2001/04/26 22:53:40	1.3
  @@ -60,7 +60,7 @@
   /**
    * @author James Snell (jasnell@us.ibm.com)
    */
  -public interface MessageWithAttachments extends Message { 
  +public interface MessageWithAttachments { 
       
       public boolean hasAttachments();
       public Hashtable getAttachments();
  
  
  
  1.18      +274 -201  xml-axis/java/src/org/apache/axis/message/SOAPEnvelope.java
  
  Index: SOAPEnvelope.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/SOAPEnvelope.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- SOAPEnvelope.java	2001/04/20 12:01:56	1.17
  +++ SOAPEnvelope.java	2001/04/26 22:53:40	1.18
  @@ -1,8 +1,10 @@
  +package org.apache.axis.message;
  +
   /*
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 1999 The Apache Software Foundation.  All rights 
  + * Copyright (c) 2001 The Apache Software Foundation.  All rights 
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -52,217 +54,288 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    */
  -
  -// Just a placeholder until we get the real stuff in place ****!*!*!*!*!*
  -
  -package org.apache.axis.message ;
  -
  -import java.util.* ;
  -import org.apache.axis.* ;
  -import org.apache.axis.utils.* ;
  -import org.apache.axis.message.* ;
  -
  -import org.w3c.dom.* ;
  -
  -/**
  - *
  - * @author Doug Davis (dug@us.ibm.com)
  - */
  -public class SOAPEnvelope {
  -  protected String       prefix ;
  -  protected String       namespaceURI ;
  -  protected String       encodingStyleURI ;
  -  protected Vector       headers ;
  -  protected Vector       body ; // Vector of SOAPBody's
   
  -  public SOAPEnvelope() {
  -  }
  -
  -  public void setEncodingStyleURI( String uri ) {
  -    encodingStyleURI = uri ;
  -  }
  -
  -  public String getEncodingStyleURI() {
  -    return( encodingStyleURI );
  -  }
  -
  -  public SOAPEnvelope(Document doc) {
  -    Element   root = doc.getDocumentElement();
  -    setEnvelope( root );
  -  }
  -
  -  public SOAPEnvelope(SOAPBody bod) {
  -    addBody( bod );
  -  }
  -
  -  public void setEnvelope(Element elem) {
  -    NodeList list ;
  -    Element  e = null ;
  -    int      i ;
  -
  -    if ( elem == null ) {
  -      prefix = null ;
  -      headers = null ;
  -      body = null ;
  -      return ;
  +import java.io.*;
  +import java.util.*;
  +import org.apache.axis.encoding.*;
  +import org.apache.axis.Constants;
  +import org.apache.axis.utils.QName;
  +import org.xml.sax.InputSource;
  +import org.xml.sax.helpers.AttributesImpl;
  +
  +public class SOAPEnvelope
  +{
  +    private static boolean DEBUG_LOG = false;
  +    
  +    public Vector headers = new Vector();
  +    public Vector bodyElements = new Vector();
  +    public Vector independentElements = new Vector();
  +    public Hashtable idMapping = new Hashtable();
  +    public String encodingStyleURI = null;
  +    public Hashtable nsDecls = new Hashtable();
  +                                            
  +    public SOAPSAXHandler handler;
  +    
  +    // This is a hint to any service description to tell it what
  +    // "type" of message we are.  This might be "request", "response",
  +    // or anything else your particular service descripton requires.
  +    //
  +    // This gets passed back into the service description during
  +    // deserialization 
  +    public String messageType;
  +    // Our service description, if we know it...
  +    protected ServiceDescription serviceDesc;
  +  
  +    public SOAPEnvelope()
  +    {
  +        nsDecls.put(Constants.URI_SOAP_ENV, Constants.NSPREFIX_SOAP_ENV);
  +        nsDecls.put(Constants.URI_SCHEMA_XSD, Constants.NSPREFIX_SCHEMA_XSD);
  +        nsDecls.put(Constants.URI_SCHEMA_XSI, Constants.NSPREFIX_SCHEMA_XSI);
  +        handler = null;
       }
  -
  -    prefix = elem.getPrefix();
  -    namespaceURI = Constants.URI_SOAP_ENV ; // elem.getNamespaceURI();
  -    encodingStyleURI = elem.getAttribute( Constants.ATTR_ENCODING_STYLE );
  -
  -    list = elem.getElementsByTagNameNS( Constants.URI_SOAP_ENV, 
  -                                        Constants.ELEM_HEADER );
  -    if ( list != null && list.getLength() > 0 )
  -      e = (Element) list.item(0);
  -
  -    if ( e != null ) {
  -      list = e.getChildNodes();
  -      for ( i = 0 ; i < list.getLength() ; i++ ) {
  -        Node    n = list.item(i);
  -        if ( n.getNodeType() != Node.ELEMENT_NODE ) continue ;
  -
  -        Element h = (Element) n ;
  -        if ( headers == null ) headers = new Vector();
  -        headers.add( new SOAPHeader( h ) );
  -      }
  +    
  +    SOAPEnvelope(SOAPSAXHandler handler)
  +    {
  +        this.handler = handler;
       }
  -
  -    list = elem.getElementsByTagNameNS( Constants.URI_SOAP_ENV, 
  -                                        Constants.ELEM_BODY );
  -    if ( list != null && list.getLength() > 0 )
  -      e = (Element) list.item(0);
   
  -    if ( e != null ) {
  -      list = e.getChildNodes();
  -      if ( list != null ) {
  -        for ( i = 0 ; i < list.getLength() ; i++ ) {
  -          Node   n = list.item(i);
  -          if ( n.getNodeType() != Node.ELEMENT_NODE ) continue ;
  -          if ( body == null ) body = new Vector();
  -          body.add( new SOAPBody( (Element) n ) );
  +    public String getMessageType()
  +    {
  +        return messageType;
  +    }
  +    
  +    public void setMessageType(String messageType)
  +    {
  +        this.messageType = messageType;
  +    }
  +    
  +    public ServiceDescription getServiceDescription()
  +    {
  +        return serviceDesc;
  +    }
  +    
  +    public void setServiceDescription(ServiceDescription serviceDesc)
  +    {
  +        this.serviceDesc = serviceDesc;
  +    }
  +    
  +    public void setEncodingStyleURI(String uri)
  +    {
  +        encodingStyleURI = uri;
  +    }
  +    
  +    public String getAsString()
  +    {
  +        // !!! NOT IMPLEMENTED YET
  +        return null;
  +    }
  +    
  +    public Vector getBodyElements()
  +    {
  +        if ((handler != null) && !handler.hasParsedBody()) {
  +            handler.parseToEnd();
           }
  -      }
  +        
  +        return bodyElements;
       }
  -  }
  -
  -  public Vector getHeaders() {
  -    if ( headers == null ) return( null );
  -    return( headers );
  -  }
  -
  -  public Vector getHeadersByNameAndURI(String name, String URI) {
  -    Vector tmpList = null ;
  -    /* If URI is null then they asked for the entire list */
  -    /******************************************************/
  -    if ( URI == null ) return( headers );
  -    if ( headers == null ) return( null );
  -
  -    for ( int i = 0 ; i < headers.size(); i++ ) {
  -      SOAPHeader  header = (SOAPHeader) headers.elementAt(i);
  -      if ( URI.equals( header.getNamespaceURI() ) &&
  -           name.equals( header.getName()) ) {
  -        if ( tmpList == null ) tmpList = new Vector();
  -        tmpList.add( header );
  -      }
  +    
  +    public SOAPBodyElement getFirstBody()
  +    {
  +        if ((handler != null) && !handler.hasParsedBody()) {
  +            handler.parseToEnd();
  +        }
  +        
  +        return (SOAPBodyElement)bodyElements.elementAt(0);
       }
  -    return( tmpList );
  -  }
  -
  -  public Vector getHeadersByURI(String URI) {
  -    Vector tmpList = null ;
  -    /* If URI is null then they asked for the entire list */
  -    /******************************************************/
  -    if ( URI == null ) return( headers );
  -    if ( headers == null ) return( null );
  -
  -    for ( int i = 0 ; i < headers.size(); i++ ) {
  -      SOAPHeader  header = (SOAPHeader) headers.elementAt(i);
  -      if ( URI.equals( header.getNamespaceURI() ) ) {
  -        if ( tmpList == null ) tmpList = new Vector();
  -        tmpList.add( header );
  -      }
  +    
  +    public Vector getHeaders()
  +    {
  +        if ((handler != null) && !handler.hasParsedHeaders()) {
  +            handler.parse();
  +        }
  +        
  +        return headers;
       }
  -    return( tmpList );
  -  }
  -
  -  public void addHeader(SOAPHeader header) {
  -    if ( headers == null ) headers = new Vector();
  -    headers.add( header );
  -  }
  -
  -  public int getNumBodies() {
  -    return( body == null ? 0 : body.size() );
  -  }
  -
  -  /**
  -   * Returns a vector of SOAPBody's - could be more than one
  -   */
  -  public Vector getBody() { 
  -    return( body ); 
  -  }
  -
  -  public SOAPBody getFirstBody() {
  -    return( (body == null) ? null : (SOAPBody) body.get(0) );
  -  }
  -
  -  public void addBody(SOAPBody b) {
  -    if ( body == null ) body = new Vector();
  -    body.add( b );
  -  }
  -
  -  /**
  -   * Returns a vector of RPCBody's because there could be more than
  -   * one in there.
  -   */
  -  public Vector  getAsRPCBody() {
  -    if ( body == null ) return( null );
  -    for ( int i = 0 ; i < body.size() ; i++ )
  -      if ( !(body.get(i) instanceof RPCBody) )
  -        body.set(i, new RPCBody( (SOAPBody) body.get(i) ) );
  -    return( body );
  -  }
  -
  -  public Document getDocument() {
  -    Element  root ;
  -    int      i ;
  +    
  +    void processID(MessageElement element)
  +    {
  +        String id = element.getID();
  +        if (id != null) {
  +            idMapping.put(id, element);
  +        }
  +    }
  +    
  +    public void addHeader(SOAPHeader header)
  +    {
  +        if (DEBUG_LOG)
  +            System.out.println("Adding header to message...");
  +        header.setEnvelope(this);
  +        headers.addElement(header);
  +        processID(header); // Can headers have IDs?
  +    }
  +    
  +    public void addBodyElement(SOAPBodyElement element)
  +    {
  +        if (DEBUG_LOG)
  +            System.out.println("Adding body element to message...");
  +        element.setEnvelope(this);
  +        bodyElements.addElement(element);
  +        processID(element); // Can body elements have IDs?
  +    }
  +    
  +    public void addIndependentElement(MessageElement element)
  +    {
  +        if (DEBUG_LOG)
  +            System.out.println("Adding independent element to message...");
  +        element.setEnvelope(this);
  +        independentElements.addElement(element);
  +        processID(element);
  +    }
   
  -    String tmpEnvPre = (prefix != null ? prefix : Constants.NSPREFIX_SOAP_ENV);
  -    String tmpEnvURI = (namespaceURI != null ? namespaceURI :
  -                                               Constants.URI_SOAP_ENV);
  -    String tmpEnc    = (encodingStyleURI != null ? encodingStyleURI :
  -                                                   Constants.URI_SOAP_ENC );
  +    public void parseToEnd()
  +    {
  +        if (handler != null)
  +            handler.parseToEnd();
  +    }
  +    
  +    public SOAPHeader getHeaderByName(String namespace, String localPart)
  +    {
  +        SOAPHeader header = (SOAPHeader)findElement(headers, namespace, localPart);
  +        
  +        if ((header == null) && (handler != null))
  +            return handler.parseForHeader(namespace, localPart);
  +        
  +        return header;
  +    }
   
  -    Document doc = XMLUtils.newDocument();
  +    public SOAPBodyElement getBodyByName(String namespace, String localPart)
  +    {
  +        if ((handler != null) && !handler.hasParsedBody()) {
  +            return handler.parseForBody(namespace, localPart);
  +        }
  +        
  +        return (SOAPBodyElement)findElement(bodyElements, namespace, localPart);
  +    }
  +    
  +    public MessageElement findElement(Vector vec, String namespace,
  +                                  String localPart)
  +    {
  +        if (vec.isEmpty())
  +            return null;
  +        
  +        Enumeration e = vec.elements();
  +        MessageElement element;
  +        while (e.hasMoreElements()) {
  +            element = (MessageElement)e.nextElement();
  +            if (element.getNamespaceURI().equals(namespace) &&
  +                element.getName().equals(localPart))
  +                return element;
  +        }
  +        
  +        return null;
  +    }
  +    
  +    public Enumeration getHeadersByName(String namespace, String localPart)
  +    {
  +        /** This might be optimizable by creating a custom Enumeration
  +         * which moves through the headers list (parsing on demand, again),
  +         * returning only the next one each time.... this is Q&D for now.
  +         */
  +        if ((handler != null) && !handler.hasParsedHeaders()) {
  +            handler.parse();
  +        }
  +        
  +        Vector v = new Vector();
  +        Enumeration e = headers.elements();
  +        SOAPHeader header;
  +        while (e.hasMoreElements()) {
  +            header = (SOAPHeader)e.nextElement();
  +            if (header.getNamespaceURI().equals(namespace) &&
  +                header.getName().equals(localPart))
  +                v.addElement(header);
  +        }
  +        
  +        return v.elements();
  +    }
  +    
  +    /** Should make SOAPSerializationException?
  +     */
  +    public void output(SerializationContext context)
  +        throws Exception
  +    {
  +        Enumeration enum;
  +        
  +        /** !!! Since we want this as SAX events, we need to
  +         * finish parsing our input stream.  There should be a way
  +         * for us to get the input stream itself, though, if we
  +         * haven't started parsing yet....
  +         */
  +        if ((handler != null) && !handler.hasFinished()) {
  +            handler.parseToEnd();
  +        }
  +        
  +        // Register namespace prefixes.
  +        enum = nsDecls.keys();
  +        while (enum.hasMoreElements()) {
  +            String uri = (String)enum.nextElement();
  +            context.registerPrefixForURI((String)nsDecls.get(uri), uri);
  +        }
  +        
  +        AttributesImpl attrs = null;
  +        if (encodingStyleURI != null) {
  +            attrs = new AttributesImpl();
  +            attrs.addAttribute(Constants.URI_SOAP_ENV,
  +                               Constants.ATTR_ENCODING_STYLE,
  +                               "SOAP-ENV:" + Constants.ATTR_ENCODING_STYLE, "string", encodingStyleURI);
  +        }
  +        
  +        context.startElement(new QName(Constants.URI_SOAP_ENV,
  +                                       Constants.ELEM_ENVELOPE), attrs);
  +        
  +        if (DEBUG_LOG)
  +            System.out.println(headers.size() + " headers");
  +        
  +        if (!headers.isEmpty()) {
  +            // Output <SOAP-ENV:Header>
  +            context.startElement(new QName(Constants.URI_SOAP_ENV,
  +                                           Constants.ELEM_HEADER), null);
  +            enum = headers.elements();
  +            while (enum.hasMoreElements()) {
  +                SOAPHeader header = (SOAPHeader)enum.nextElement();
  +                header.output(context);
  +                // Output this header element
  +            }
  +            // Output </SOAP-ENV:Header>
  +            context.endElement();
  +        }
   
  -    root = doc.createElementNS(tmpEnvURI,tmpEnvPre+":"+Constants.ELEM_ENVELOPE);
  -    root.setAttribute( "xmlns:" + Constants.NSPREFIX_SOAP_ENV,
  -                                  Constants.URI_SOAP_ENV );
  -    root.setAttribute( "xmlns:" + Constants.NSPREFIX_SCHEMA_XSI,
  -                                  Constants.URI_SCHEMA_XSI );
  -                    
  -    root.setAttributeNS( tmpEnvURI, tmpEnvPre+":"+Constants.ATTR_ENCODING_STYLE,
  -                         tmpEnc );
  -    doc.appendChild( root );
  +        if (bodyElements.isEmpty()) {
  +            // This is a problem.
  +            throw new Exception("No body elements!");
  +        }
   
  -    if ( headers != null && headers.size() > 0 ) {
  -      Element elem = doc.createElementNS( tmpEnvURI,
  -                                          tmpEnvPre+":"+Constants.ELEM_HEADER);
  -      root.appendChild( elem );
  -      for ( i = 0 ; i < headers.size() ; i++ ) {
  -        SOAPHeader h = (SOAPHeader) headers.get(i);
  -        elem.appendChild( doc.importNode(h.getRoot(),true) );
  -      }
  -    } 
  -    if ( body != null ) {
  -      Element elem = doc.createElementNS( tmpEnvURI,
  -                                          tmpEnvPre+":"+Constants.ELEM_BODY);
  -      root.appendChild( elem );
  -      for ( i = 0 ; i < body.size() ; i++ ) {
  -        Element  bod = ((SOAPBody)body.get(i)).getRoot();
  -        elem.appendChild( doc.importNode(bod,true) );
  -      }
  +        // Output <SOAP-ENV:Body>
  +        context.startElement(new QName(Constants.URI_SOAP_ENV,
  +                                       Constants.ELEM_BODY), null);
  +        enum = bodyElements.elements();
  +        while (enum.hasMoreElements()) {
  +            SOAPBodyElement body = (SOAPBodyElement)enum.nextElement();
  +            body.output(context);
  +            // Output this body element.
  +        }
  +        
  +        // Output </SOAP-ENV:Body>
  +        context.endElement();
  +        
  +        // Output independent elements
  +        enum = independentElements.elements();
  +        while (enum.hasMoreElements()) {
  +            MessageElement element = (MessageElement)enum.nextElement();
  +            element.output(context);
  +            // Output this independent element
  +        }
  +        
  +        // Output </SOAP-ENV:Envelope>
  +        context.endElement();
       }
  -    return( doc );
  -  }
   }
  
  
  
  1.15      +60 -91    xml-axis/java/src/org/apache/axis/message/SOAPHeader.java
  
  Index: SOAPHeader.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/SOAPHeader.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- SOAPHeader.java	2001/03/30 17:48:46	1.14
  +++ SOAPHeader.java	2001/04/26 22:53:40	1.15
  @@ -2,7 +2,7 @@
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 1999 The Apache Software Foundation.  All rights 
  + * Copyright (c) 2001 The Apache Software Foundation.  All rights 
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -55,98 +55,67 @@
   
   package org.apache.axis.message ;
   
  -// !!!!***** Just a placeholder until we get the real stuff ***!!!!!
  -
   import java.util.* ;
  -import org.apache.axis.message.* ;
   import org.apache.axis.* ;
  -
  -import org.w3c.dom.* ;
  -import javax.xml.parsers.* ;
  +import org.apache.axis.encoding.DeserializationContext;
  +import org.xml.sax.Attributes;
   
  -/**
  - *
  - * @author Doug Davis (dug@us.ibm.com)
  +/** A simple header abstraction.  Extends MessageElement with header-specific
  + * stuff like mustUnderstand, actor, and a 'processed' flag.
  + * 
  + * @author Glen Daniels (gdaniels@macromedia.com)
  + * 
    */
  -public class SOAPHeader {
  -  protected Element   root ;
  -  protected boolean   processed ;
  -
  -  // Utility vars - dup of info in 'root' but faster access here
  -  protected String    name ;
  -  protected String    prefix ;
  -  protected String    namespaceURI ;
  -  protected String    actor ;
  -  protected boolean   mustUnderstand ;
  -
  -  public SOAPHeader() {
  -    processed = false ;
  -  }
  -
  -  public SOAPHeader(Element elem) {
  -    processed = false ;
  -    setRoot( elem );
  -  }
  -
  -  public Element getRoot() {
  -    return( root );
  -  }
  -
  -  public void setRoot(Element elem) {
  -    String  value ;
  -
  -    root           = elem ;
  -    prefix         = elem.getPrefix();
  -    namespaceURI   = elem.getNamespaceURI();
  -    name           = elem.getLocalName();
  -
  -    value          = elem.getAttributeNS( elem.getNamespaceURI(),
  -                                          Constants.ATTR_ACTOR );
  -    if ( value != null )
  -      actor = value ;
  -    else 
  -      // Handle the case where they set Actor before they set the root
  -      if ( value != null ) setActor( value );
  -
  -    value = elem.getAttributeNS( elem.getNamespaceURI(),
  -                                 Constants.ATTR_MUST_UNDERSTAND );
  -    if ( value != null )
  -      mustUnderstand = "1".equals(value);
  -    else 
  -      // Handle the case where they set MU before they set the root
  -      if ( mustUnderstand ) setMustUnderstand( true );
  -  }
  -
  -  public String getName() { return( name ); }
  -  public String getPrefix() { return( prefix ); }
  -  public String getNamespaceURI() { return( namespaceURI ); }
  -
  -  public boolean getMustUnderstand() { return( mustUnderstand ); }
  -  public void setMustUnderstand(boolean b) { 
  -    mustUnderstand = b ;
  -    if ( root == null ) return ;
  -    root.setAttributeNS( Constants.URI_SOAP_ENV,
  -                         Constants.NSPREFIX_SOAP_ENV + ":" +
  -                           Constants.ATTR_MUST_UNDERSTAND,
  -                         "1" );
  -
  -  }
  -
  -  public String getActor() { return( actor ); }
  -  public void setActor(String a) { 
  -    actor = a ;
  -    root.setAttributeNS( Constants.URI_SOAP_ENV,
  -                         Constants.NSPREFIX_SOAP_ENV + ":" + 
  -                           Constants.ATTR_ACTOR,
  -                         actor );
  -  }
  -
  -  public void setProcessed(boolean value) {
  -    processed = value ;
  -  }
  -
  -  public boolean isProcessed() {
  -    return( processed );
  -  }
  -
  +public class SOAPHeader extends MessageElement {
  +    static class HeaderFactory implements ElementFactory {
  +        public MessageElement createElement(String namespace, 
  +                                        String localName,
  +                                        Attributes attributes, 
  +                                        DeserializationContext context)
  +        {
  +            return new SOAPHeader(namespace, localName, attributes, context);
  +        }
  +    }
  +    public static ElementFactory factory() { return new HeaderFactory(); }
  +    
  +    protected boolean   processed = false;
  +
  +    protected String    actor;
  +    protected boolean   mustUnderstand = false;
  +
  +    public SOAPHeader() {
  +    }
  +
  +    public SOAPHeader(String namespace, String localPart,
  +                      Attributes attributes, DeserializationContext context) {
  +        super(namespace, localPart, attributes, context);
  +        
  +        // Check for mustUnderstand
  +        String val = attributes.getValue(Constants.URI_SOAP_ENV,
  +                                         Constants.ATTR_MUST_UNDERSTAND);
  +        mustUnderstand = ((val != null) && val.equals("1")) ? true : false;
  +        
  +        actor = attributes.getValue(Constants.URI_SOAP_ENV,
  +                                    Constants.ATTR_ACTOR);
  +        
  +        processed = false;
  +    }
  +    
  +    public boolean getMustUnderstand() { return( mustUnderstand ); }
  +    public void setMustUnderstand(boolean b) { 
  +        mustUnderstand = b ;
  +    }
  +
  +    public String getActor() { return( actor ); }
  +    public void setActor(String a) { 
  +        actor = a ;
  +    }
  +
  +    public void setProcessed(boolean value) {
  +        processed = value ;
  +    }
  +
  +    public boolean isProcessed() {
  +        return( processed );
  +    }
   };
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/DebugHeader.java
  
  Index: DebugHeader.java
  ===================================================================
  package org.apache.axis.message;
  
  import java.io.*;
  import org.xml.sax.*;
  import org.xml.sax.helpers.*;
  import org.apache.axis.message.events.*;
  import org.apache.axis.encoding.*;
  import org.apache.axis.utils.QName;
  
  /** This is an example specific header class which someone might
   * implement.
   * 
   * @author Glen Daniels (gdaniels@macromedia.com)
   */
  public class DebugHeader extends SOAPHeader
  {
      static class DebugHeaderFactory implements ElementFactory
      {
          public MessageElement createElement(String namespace, String localName,
                                          Attributes attributes, DeserializationContext context)
          {
              return new DebugHeader(namespace, localName, attributes, context);
          }
      }
  
      public static DebugHeaderFactory getFactory()
      {
          return new DebugHeaderFactory();
      }
      
      class SAXHandler extends DefaultHandler
      {
          public void characters(char [] chars, int start, int end)
          {
              // Parse this as an int.  (do we need to build up a string,
              // and only do the parse at the end?)
              debugLevel = Integer.parseInt(new String(chars, start, end));
              System.out.println("[DebugHeader] debugLevel is " + debugLevel);
          }
      }
      
      private int debugLevel;
      public int getDebugLevel()
      {
          return debugLevel;
      }
      public void setDebugLevel(int level)
      {
          debugLevel = level;
      }
      
      public DebugHeader(int debugLevel)
      {
          this.name = "Debug";
          this.debugLevel = debugLevel;
      }
      
      public DebugHeader(String namespace, String localPart,
                         Attributes attributes, DeserializationContext context)
      {
          super(namespace, localPart, attributes, context);
      }
  
      // Override the default (recording) implementation because we
      // want to parse this header ourselves as it goes by.
      
      public ContentHandler getContentHandler()
      { return new SAXHandler(); }
      
      public void output(SerializationContext context)
          throws IOException
      {
          context.startElement(new QName(this.getNamespaceURI(), this.getName()), null);
          context.writeString(new Integer(debugLevel).toString());
          context.endElement();
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/ElementFactory.java
  
  Index: ElementFactory.java
  ===================================================================
  package org.apache.axis.message;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.xml.sax.Attributes;
  import org.apache.axis.encoding.DeserializationContext;
  
  /** A simple MessageElement factory interface.
   * 
   * @author Glen Daniels (gdaniels@macromedia.com)
   */
  public interface ElementFactory
  {
      public MessageElement createElement(String namespace, String localName, Attributes attributes, DeserializationContext context);
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/ElementRecorder.java
  
  Index: ElementRecorder.java
  ===================================================================
  package org.apache.axis.message;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.xml.sax.*;
  import org.apache.axis.message.events.*;
  import java.util.*;
  
  /** This guy records the basic SAX events into an event queue.  Then it can
   * play them back to any SAX ContentHandler.
   * 
   * !!! TODO: Record the rest of the events...
   * 
   * @author Glen Daniels (gdaniels@allaire.com)
   */
  class ElementRecorder extends org.xml.sax.helpers.DefaultHandler
  {
      private static final boolean DEBUG_LOG = false;
      
      // The recorded list of SAX events "inside" this element
      protected Vector _events = new Vector();
      
      public ElementRecorder()
      {
      }
      
      public void startElement(String namespace, String localName,
                               String qName, Attributes attributes)
          throws SAXException
      {
          if (DEBUG_LOG) {
              System.out.println("(rec) startElement ['" + namespace + "' " +
                             localName + "]");
          }
          
          _events.addElement(new StartElementEvent(namespace, localName, qName, attributes));
      }
      
      public void endElement(String namespace, String localName, String qName)
          throws SAXException
      {
          if (DEBUG_LOG) {
              System.out.println("(rec) endElement ['" + namespace + "' " +
                             localName + "]");
          }
  
          _events.addElement(new EndElementEvent(namespace, localName, qName));
      }
      
      public void characters(char [] chars, int start, int length)
          throws SAXException
      {
          if (DEBUG_LOG) {
              System.out.println("(rec) characters ['" +
                                 new String(chars, start, length) + "']");
          }
          
          _events.addElement(new CharactersEvent(chars, start, length));
      }
  
      /** Someone wants to deal with the XML inside me using SAX.
        * So replay all the events to their handler.
        * 
        */
      public void publishToHandler(ContentHandler handler)
          throws SAXException
      {
          Enumeration e = _events.elements();
          while (e.hasMoreElements()) {
              SAXEvent event = (SAXEvent)e.nextElement();
              event.publishToHandler(handler);
          }
      }
  }
  
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/ElementRegistry.java
  
  Index: ElementRegistry.java
  ===================================================================
  package org.apache.axis.message;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.*;
  import org.apache.axis.encoding.DeserializationContext;
  import org.xml.sax.Attributes;
  
  /** Implements a simple QName->Factory mapping.  Something like this
   * (but more complex) could be used to generate factories based on
   * attributes, position, things in the DeserializationContext, etc...
   * 
   * @author Glen Daniels (gdaniels@macromedia.com)
   */
  public class ElementRegistry implements ElementFactory
  {
      private Hashtable factories = new Hashtable();
      private ElementFactory defaultFactory = null;
      
      public ElementRegistry() {};
      
      /** The defaultFactory argument is the factory we'll use if
       * we can't find a matching one in the registry.
       * 
       */
      public ElementRegistry(ElementFactory defaultFactory)
      {
          this.defaultFactory = defaultFactory;
      }
          
      public void registerFactory(String namespace, String localName,
                                  ElementFactory factory)
      {
          // !!! This is a kludge.  Fix with QNames/hashcodes....?
          String combinedName = namespace + "|" + localName;
          
          factories.put(combinedName, factory);
      }
      
      public MessageElement createElement(String namespace, String localName,
                                      Attributes attributes, DeserializationContext context)
      {
          // !!! This is a kludge.  Fix with QNames/hashcodes....?
          String combinedName = namespace + "|" + localName;
          
          ElementFactory factory = (ElementFactory)factories.get(combinedName);
          
          //DBG:System.out.println("Factory for '" + combinedName + "' is " + factory);
          
          if (factory == null)
              factory = defaultFactory;
          
          if (factory != null)
              return factory.createElement(namespace, localName,
                                           attributes, context);
          
          return null;
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/RPCElement.java
  
  Index: RPCElement.java
  ===================================================================
  package org.apache.axis.message;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.xml.sax.*;
  import org.xml.sax.helpers.DefaultHandler;
  import org.apache.axis.encoding.*;
  import org.apache.axis.utils.QName;
  import java.util.*;
  import java.io.*;
  
  /** An RPC body element.
   * 
   * Assumes all sub-elements are parameters (see RPCParam).
   * 
   * @author Glen Daniels (gdaniels@macromedia.com)
   */
  public class RPCElement extends SOAPBodyElement
  {
      static class RPCElementFactory implements ElementFactory
      {
          public MessageElement createElement(String namespace, String localName,
                                          Attributes attributes, DeserializationContext context)
          {
              return new RPCElement(namespace, localName, attributes, context);
          }
      }
      
      public static ElementFactory getFactory()
      {
          return new RPCElementFactory();
      }
      
      class RPCContentHandler extends DefaultHandler
      {
          private boolean passedMyStart = false;
          
          public void startElement(String namespace, String name, String qName,
                                   Attributes attributes)
          {
              if (!passedMyStart) {
                  passedMyStart = true;
                  return;
              }
              
              // Start of an arg...
              RPCParam param = new RPCParam(namespace, name, attributes, context);
              params.addElement(param);
              if (param.getType() == null) {
                  // No type inline, so check service description.
                  ServiceDescription serviceDesc = getEnvelope().getServiceDescription();
                  if (serviceDesc != null) {
                      param.setType(serviceDesc.getParamTypeByName(getEnvelope().getMessageType(),
                                                                   param.getName()));
                  }
              } else {
                  /** !!! If we have a service description and this is an
                   * explicitly-typed param, we might want to check here to
                   * see if the xsi:type val is indeed a subtype of the type
                   * we expect from the service description.
                   */
                  
              }
              context.pushElementHandler(param.getContentHandler());
          }
      }
      public ContentHandler getContentHandler() { return new RPCContentHandler(); }
      
      ///////////////////////////////////////////////////////////////
      
      protected String methodName;    
      protected Vector params = new Vector();
      
      public RPCElement(String namespace, String localName, Attributes attrs,
                        DeserializationContext context)
      {
          super(namespace, localName, attrs, context);
          this.methodName = localName;
      }
      
      public RPCElement(String methodName, Object [] args)
      {
          this.methodName = methodName;
          this.name = methodName;
          
          for (int i = 0; i < args.length; i++) {
              if (args[i] instanceof RPCParam) {
                  addParam((RPCParam)args[i]);
              } else {
                  addParam(new RPCParam("arg" + i, args[i]));
              }
          }
      }
      
      public RPCElement(String methodName)
      {
          this.methodName = methodName;
          this.name = methodName;
      }
      
      public void output(SerializationContext context)
          throws IOException
      {
          context.registerPrefixForURI(prefix, namespaceURI);
          context.startElement(new QName(this.getNamespaceURI(), this.getName()), attributes);
          Enumeration e = params.elements();
          while (e.hasMoreElements()) {
              ((RPCParam)e.nextElement()).output(context);
          }
          context.endElement();
      }
      
      public String getMethodName()
      {
          return methodName;
      }
      
      /** This gets the FIRST param whose name matches.
       * !!! Should it return more in the case of duplicates?
       */
      public RPCParam getParam(String name)
      {
          for (int i = 0; i < params.size(); i++) {
              RPCParam param = (RPCParam)params.elementAt(i);
              if (param.getName().equals(name))
                  return param;
          }
          
          return null;
      }
      
      public Vector getParams()
      {
          return params;
      }
      
      public void addParam(RPCParam param)
      {
          param.setRPCElement(this);
          params.addElement(param);
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/RPCParam.java
  
  Index: RPCParam.java
  ===================================================================
  package org.apache.axis.message;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.IOException;
  import java.util.*;
  import org.apache.axis.Constants;
  import org.apache.axis.encoding.*;
  import org.apache.axis.utils.QName;
  import org.xml.sax.*;
  import org.xml.sax.helpers.AttributesImpl;
  import org.xml.sax.helpers.DefaultHandler;
  
  /** An RPC parameter element.
   * 
   * @author Glen Daniels (gdaniels@macromedia.com)
   */
  public class RPCParam extends MessageElement
  {
      private static boolean DEBUG_LOG = false;
      
      // Who's your daddy?
      RPCElement myRPCElement;
  
      /** This constructor is called during XML parsing.
       */
      public RPCParam(String namespace, String localName, Attributes attrs,
                      DeserializationContext context)
      {
          super(namespace, localName, attrs, context);
          name = localName;
  
          // Check for type
          String type = attrs.getValue(Constants.URI_SCHEMA_XSI, "type");
          
          if (DEBUG_LOG)
              System.out.println("Got param.  Name ='" + name + "' Type is '" + type + "'");
          
          if (type == null)
            return;
          
          // OK, this is a QName, so look up the prefix in our current mappings.
          
          int i = type.indexOf(":");
          
          // !!! Can we have types that are in the default namespace?
          String nsURI = context.getNamespaceURI(type.substring(0, i));
          
          //System.out.println("namespace = " + nsURI);
          
          if (nsURI == null) {
              // !!! Should we just fault here (invalid NS prefix)?
              //     This of course implies that all the MessageElement
              //     constructors would be able to throw exceptions...
              type = null;
              return;
          }
          
          typeQName = new QName(nsURI, type.substring(i + 1));
      }
      
      /** Constructor for building up messages.
       */
      public RPCParam(String name, Object value)
      {
          this.name = name;
          this.value = value;
      }
      
      public void setRPCElement(RPCElement element)
      {
          myRPCElement = element;
      }
      
      /** !!! This is a little messy... need to think about
       * how elements get connected with their envelopes a bit
       * more?
       */
      public SOAPEnvelope getEnvelope()
      {
          if (myRPCElement != null)
              return myRPCElement.getEnvelope();
          
          return super.getEnvelope();
      }
      
      public ContentHandler getContentHandler()
      {
          // Look up type and return an appropriate deserializer
          if (typeQName != null) {
              deserializer = context.getDeserializer(typeQName);
              if (deserializer != null)
                  return deserializer;
          }
          
          // If we couldn't find one, just record...
          
          /** !!! Is it possible that we'll do this now, but
           * later on we'll figure out the type (via some OOB
           * means)?  In that case we want an easy way to
           * squirt these SAX events to a deserializer.
           */
          
          value = new ElementRecorder();
          return (ElementRecorder)value;
      }
      
      public Object getValue()
      {
          if (value instanceof ElementRecorder) {
              // !!! Lazy deserialization here... We have the SAX events,
              //     but haven't run them through a deserializer yet.
              return null;
          }
          
          if (deserializer != null) {
              value = deserializer.getValue();
              deserializer = null;
          }
          
          return value;
      }
      
      public void output(SerializationContext context) throws IOException
      {
          AttributesImpl attrs = new AttributesImpl();
          Object val = getValue();
          
          if ((val != null) && (typeQName == null))
              typeQName = context.getQNameForClass(val.getClass());
          
          if (attributes != null) {
              // Must be writing a message we parsed earlier, so just put out
              // what's already there.
              for (int i = 0; i < attributes.getLength(); i++) {
                  attrs.addAttribute(attributes.getURI(i), attributes.getLocalName(i),
                                     attributes.getQName(i), "string",
                                     attributes.getValue(i));
              }
          } else {
              // Writing a message from memory out to XML...
              // !!! How do we set other attributes when serializing??
              
              ServiceDescription desc = getEnvelope().getServiceDescription();
              if ((desc == null) || desc.getSendTypeAttr()) {
                  if (typeQName != null) {
                      attrs.addAttribute(Constants.URI_SCHEMA_XSI, "type", "xsi:type",
                                         "string",
                                         context.qName2String(typeQName));
                  }
              }
          
              if (val == null)
                  attrs.addAttribute(Constants.URI_SCHEMA_XSI, "null", "xsi:null",
                                     "string", "1");
          }
          
          context.startElement(new QName(getNamespaceURI(), getName()), attrs);
          // Output the value...
          if (val != null)
              context.writeString(value.toString());
          
          context.endElement();
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/SAXOutputter.java
  
  Index: SAXOutputter.java
  ===================================================================
  package org.apache.axis.message;
  
  import java.io.*;
  import org.xml.sax.*;
  import org.xml.sax.helpers.*;
  import java.util.*;
  import org.apache.axis.encoding.*;
  import org.apache.axis.utils.QName;
  
  public class SAXOutputter extends DefaultHandler
  {
      private static final boolean DEBUG_LOG = false;
      
      SerializationContext context;
      
      public SAXOutputter(SerializationContext context)
      {
          this.context = context;
      }
      
      public void startDocument() throws SAXException {
      }
      
      public void endDocument() throws SAXException {
          System.out.println("SAXOutputter: end document.");
      }
      
      public void startPrefixMapping(String p1, String p2) throws SAXException {
          context.registerPrefixForURI(p2, p1);
      }
      
      public void endPrefixMapping(String p1) throws SAXException {
          // !!!
      }
      
      public void characters(char[] p1, int p2, int p3) throws SAXException {
          if (DEBUG_LOG) {
              System.out.println("(out) characters ['" +
                                 new String(p1, p2, p3) + "']");
          }
          try {
              context.writeChars(p1, p2, p3);
          } catch (IOException e) {
              throw new SAXException(e);
          }
      }
      
      public void ignorableWhitespace(char[] p1, int p2, int p3) 
          throws SAXException
      {
          try {
              context.writeChars(p1, p2, p3);
          } catch (IOException e) {
              throw new SAXException(e);
          }
      }
   
      public void skippedEntity(String p1) throws SAXException {
      }
      
      public void startElement(String namespace, String localName,
                               String qName, Attributes attributes)
          throws SAXException
      {
          if (DEBUG_LOG) {
              System.out.println("(out) startElement ['" + namespace + "' " +
                             localName + "]");
          }
  
          try {
              context.startElement(new QName(namespace,localName), attributes);
          } catch (IOException e) {
              throw new SAXException(e);
          }
      }
      
      public void endElement(String namespace, String localName, String qName)
          throws SAXException
      {
          if (DEBUG_LOG) {
              System.out.println("(out) endElement ['" + namespace + "' " +
                             localName + "]");
          }
          
          try {
              context.endElement();
          } catch (IOException e) {
              throw new SAXException(e);
          }
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/SOAPBodyElement.java
  
  Index: SOAPBodyElement.java
  ===================================================================
  package org.apache.axis.message;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.xml.sax.Attributes;
  import org.apache.axis.encoding.DeserializationContext;
  
  /** A Body element.
   * 
   * Useful subclass right now is RPCElement.
   */
  public class SOAPBodyElement extends MessageElement
  {
      public SOAPBodyElement(String namespace, String localPart,
                        Attributes attributes, DeserializationContext context)
      {
          super(namespace, localPart, attributes, context);
      }
      
      public SOAPBodyElement()
      {
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/SOAPSAXHandler.java
  
  Index: SOAPSAXHandler.java
  ===================================================================
  package org.apache.axis.message;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  import java.util.*;
  import org.apache.axis.*;
  import org.apache.axis.encoding.DeserializationContext;
  import org.apache.axis.utils.NSStack;
  import org.xml.sax.*;
  import org.xml.sax.helpers.DefaultHandler;
  
  /** The main SOAP envelope parsing class.  This whole system is based on
   * SAX event-style parsing, and this is the core "engine".  Subclasses
   * of this control the actual parsing in appropriate ways, including:
   * 
   * 1) using a SAX parser and two threads (parse and control) to gate
   *    the events (this was the first model we implemented)
   * 2) using a pull parser and simply returning control when we hit
   *    pauseParsing()
   * 
   * Look at the end of the class to see what subclasses must implement.
   * 
   * @author Glen Daniels (gdaniels@allaire.com)
   */
  
  public abstract class SOAPSAXHandler extends DefaultHandler
  {
      private static final boolean DEBUG_LOG = false;
      
      private NSStack namespaces = new NSStack();
  
      ///////////////
      // States
      protected static final int INITIAL_STATE  = 0;
      protected static final int IN_ENVELOPE    = 1;
      protected static final int IN_HEADER      = 2;
      protected static final int IN_BODY        = 3;
      protected static final int FINISHED       = 4;
      
      private static final int TARGET_NONE    = 0;
      private static final int TARGET_HEADER  = 1;
      private static final int TARGET_BODY    = 2;
      
      protected int state = INITIAL_STATE;
      private boolean parsedEnvelope = false;
      private boolean parsedHeaders = false;
      private boolean parsedBody    = false;
      
      // State for stopping the parse when we hit a particular
      // target element (header or body)
      private String targetNS = null;
      private String targetName = null;
      private int targetType = TARGET_NONE;
      private MessageElement targetElement = null;
      private boolean foundTarget = false;
      
      protected SOAPEnvelope envelope;
      
      protected boolean parsingToEnd = false;
      
      private ContentHandler elementHandler = null;
      private int recordingDepth = 0;
  
      protected DeserializationContext context;
  
      /** These guys know how to create the right MessageElements (and thus
       * sub-handlers) for particular XML elements.  Right now the headers
       * can be registered (see DebugHeader for an example), but the bodies
       * are fixed as RPCElements.
       */
      
      // Header factory.
      ElementRegistry headerRegistry =
                              new ElementRegistry(SOAPHeader.factory());
      
      // Body factory. Only doing rpc bodies for right now...
      ElementFactory bodyFactory = RPCElement.getFactory();
  
      public SOAPSAXHandler()
      {
          envelope = new SOAPEnvelope(this);
          this.context = new DeserializationContext(this);
  
          // just testing...
          headerRegistry.registerFactory("urn:myNS", "Debug", DebugHeader.getFactory());
      }
      
      public int getState()
      {
          return state;
      }
      
      public SOAPEnvelope getEnvelope()
      {
          return envelope;
      }
      
      /** Grab a namespace prefix
       */
      public String getNamespaceURI(String prefix)
      {
          return namespaces.getNamespaceURI(prefix);
      }
      
      /** Parse to the end of the header element
       */
      public void parseHeaders()
      {
          if (!parsedHeaders)
              parseForHeader(null, null);
      }
  
      /** Parse all the way through, without stopping.
       */
      public void parseToEnd()
      {
          parsingToEnd = true;
          parse();
      }
      
      
      public SOAPHeader parseForHeader(String namespace, String localPart)
      {
          // don't bother if we're done with the headers already.
          if (parsedHeaders)
              return null;
          
          this.targetNS = namespace;
          this.targetName = localPart;
          this.targetElement = null;
          this.targetType = TARGET_HEADER;
  
          // Because we set the target, this will stop once we hit the
          // desired header.
          parse();
          
          this.targetType = TARGET_NONE;
          
          return (SOAPHeader)this.targetElement;
      }
  
      public SOAPBodyElement parseForBody(String namespace, String localPart)
      {
          // don't bother if we're done with the body already.
          if (parsedBody)
              return null;
  
          this.targetNS = namespace;
          this.targetName = localPart;
          this.targetElement = null;
          this.targetType = TARGET_BODY;
  
          // Because we set the target, this will stop once we hit the
          // desired header.
          parse();
          
          this.targetType = TARGET_NONE;
          
          return (SOAPBodyElement)this.targetElement;
      }
      
      public SOAPHeader createHeaderElementByQName(String namespace,
                                                   String localName,
                                                   Attributes attributes)
      {
          MessageElement el = headerRegistry.createElement(namespace, localName,
                                                       attributes, context);
          return (SOAPHeader)el;
      }
      
      public boolean hasParsedHeaders()
      {
          return parsedHeaders;
      }
      public boolean hasParsedBody()
      {
          return parsedBody;
      }
      public boolean hasFinished()
      {
          return (getState() == FINISHED);
      }
      
      /****************************************************************
       * Management of sub-handlers (recorders, deserializers)
       */
  
      /** A little utility class to keep track of our parsing state.
       */
      class HandlerContext {
          public HandlerContext(int recordingDepth, ContentHandler handler)
          {
              this.recordingDepth = recordingDepth;
              this.handler = handler;
          }
          public int recordingDepth;
          public ContentHandler handler;
      }
      
      Stack handlerContexts = new Stack();
      
      public void pushElementHandler(ContentHandler handler)
      {
          // System.out.println("Pushing handler (" + recordingDepth + ") " + handler);
          
          // If we're in the middle of another element handler, keep track
          // of where we were so we can pop contexts.
          if (elementHandler != null) {
              handlerContexts.push(new HandlerContext(recordingDepth,
                                                      elementHandler));
              recordingDepth = 0;
          } else {
              recordingDepth = 1;
          }
          
          elementHandler = handler;
      }
      
      private void popElementHandler() throws SAXException
      {
          
          if (!handlerContexts.empty()) {
              HandlerContext context = (HandlerContext)handlerContexts.pop();
              elementHandler = context.handler;
              recordingDepth = context.recordingDepth;
              //System.out.println("Popping handler (" + recordingDepth + ") " + elementHandler);
          } else {
              //System.out.println("Popping handler...(null)");
              elementHandler = null;
  
              if (foundTarget) {
                  foundTarget = false;
                  pauseParsing();
              }
          }
      }
      
      /****************************************************************
       * SAX event handlers
       */
      public void startDocument() throws SAXException {
          // Should never receive this in the midst of a parse.
      }
      
      public void endDocument() throws SAXException {
          // Everything should be closed at this point
          if (state != FINISHED)
              throw new SAXException("End of document reached prematurely!");
      }
      
      /** Record the current set of prefix mappings in the nsMappings table.
       *
       * !!! We probably want to have this mapping be associated with the
       *     MessageElements, since they may potentially need access to them
       *     long after the end of the prefix mapping here.  (example:
       *     when we need to record a long string of events scanning forward
       *     in the document to find an element with a particular ID.)
       */
      public void startPrefixMapping(String prefix, String uri)
          throws SAXException
      {
         namespaces.add(uri, prefix);
         
         // System.out.println("Mapping '" + prefix +"' to '" + uri + "'");
         
         if (elementHandler != null) elementHandler.startPrefixMapping(prefix, uri);
      }
      
      public void endPrefixMapping(String prefix)
          throws SAXException
      {
          if (state == FINISHED)
            return;
          
          if (elementHandler != null) elementHandler.endPrefixMapping(prefix);
      }
      
      public void characters(char[] p1, int p2, int p3) throws SAXException {
          if (elementHandler != null) elementHandler.characters(p1, p2, p3);
      }
      
      public void ignorableWhitespace(char[] p1, int p2, int p3) throws SAXException {
          if (elementHandler != null) elementHandler.ignorableWhitespace(p1, p2, p3);
      }
   
      public void processingInstruction(String p1, String p2) throws SAXException {
          // must throw an error since SOAP doesn't allow
          // processing instructions anywhere in the message
          throw new SAXException("Processing instructions are not allowed within SOAP Messages");
      }
  
      public void skippedEntity(String p1) throws SAXException {
          if (elementHandler != null) elementHandler.skippedEntity(p1);
      }
  
      /** This is a big workhorse.  Manage the state of the parser, check for
       * basic SOAP compliance (envelope, then optional header, then body, etc).
       * 
       * This guy also handles monitoring the recording depth if we're recording
       * (so we know when to stop), and might eventually do things to help with
       * ID/HREF management as well.
       * 
       */
      public void startElement(String namespace, String localName,
                               String qName, Attributes attributes)
          throws SAXException
      {
          MessageElement element = null;
          
          if (DEBUG_LOG) {
              System.out.println("startElement ['" + namespace + "' " +
                             localName + "]");
              namespaces.dump();
          }
          
          if (elementHandler != null) {
              elementHandler.startElement(namespace, localName, qName, attributes);
              
              recordingDepth++;
              
              return;
          }
  
          try {
              switch (state) {
              case FINISHED:
                  throw new SAXException("Found XML outside <envelope>!");
                  
              case INITIAL_STATE:
                  // Confirm envelope looks right.
                  if (namespace.equals(Constants.URI_SOAP_ENV) &&
                      localName.equals(Constants.ELEM_ENVELOPE)) {
                      state = IN_ENVELOPE;
                      
                      envelope.nsDecls = (Hashtable)namespaces.peek().clone();
                      
                      if (targetType == TARGET_NONE) {
                          // Stop here to let the other thread decide what to do next.
                          // !!! Do we need to synchronize this?
                          pauseParsing();
                      }
                      return;
                  }
                  throw new SAXException("Wanted <SOAP-ENV:envelope> element, got <" + qName + ">");
  
              case IN_ENVELOPE:
                  if (namespace.equals(Constants.URI_SOAP_ENV)) {
                      if (localName.equals(Constants.ELEM_HEADER)) {
                          if (parsedHeaders)
                              throw new SAXException("Found duplicate header element");
                          state = IN_HEADER;
                          return;
                      }
                      
                      if (localName.equals(Constants.ELEM_BODY)) {
                          if (parsedBody)
                              throw new SAXException("Found duplicate body element");
                          state = IN_BODY;
                          return;
                      }
                  }
                  // Independent elements are OK at this level
                  // !!! Might want a factory-style creation for this too?
                  element = new MessageElement(namespace, localName, attributes, context);
                  envelope.addIndependentElement(element);
                  break;
                  
              case IN_HEADER:
                  // Each element inside the header gets turned into a
                  // SOAPHeader.
                  
                  // Create this header from a factory, so people can put in
                  // their own implementations which don't require storing SAX
                  // events, but parse them as the object gets scanned.
                  element = createHeaderElementByQName(namespace, localName,
                                                       attributes);
                  envelope.addHeader((SOAPHeader)element);
                  
                  if ((targetType == TARGET_HEADER) && (targetNS != null)) {
                      if (namespace.equals(targetNS) &&
                          localName.equals(targetName)) {
                          foundTarget = true;
                          targetElement = element;
                      }
                  }
                  break;
                  
              case IN_BODY:
                  // Each element inside the body gets turned into a
                  // SOAPBodyElement
                  element = bodyFactory.createElement(namespace, localName,
                                                      attributes, context);
                  envelope.addBodyElement((SOAPBodyElement)element);
                  
                  if ((targetType == TARGET_BODY) && (targetNS != null)) {
                      if (namespace.equals(targetNS) &&
                          localName.equals(targetName)) {
                          foundTarget = true;
                          targetElement = element;
                      }
                  }
                  break;
                  
              default:
                  throw new SAXException("In unknown parsing state!");
              }
              
              // Let the event stream run until the end of this element,
              // sending the events to an appropriate handler.
              if (element != null) {
                  element.setEnvelope(envelope);
                  pushElementHandler(element.getContentHandler());
                  element.setPrefix(namespaces.getPrefix(namespace));
                  elementHandler.startElement(namespace, localName, qName, attributes);
              }
          } catch (SAXException saxEx) {
              throw saxEx;
          } finally {        
              namespaces.push();
          }
      }
      
      public void endElement(String namespace, String localName, String qName)
          throws SAXException
      {
          if (DEBUG_LOG) {
              System.out.println("endElement ['" + namespace + "' " +
                             localName + "]");
          }
          
          recordingDepth--;
  
          if (elementHandler != null) {
              //System.out.println("  depth is " + recordingDepth);
              
              elementHandler.endElement(namespace, localName, qName);
  
              if (recordingDepth == 0)
                  popElementHandler();
  
              return;
          }
          
          if (state == IN_HEADER) {
              state = IN_ENVELOPE;
              parsedHeaders = true;
  
              if (targetType == TARGET_HEADER) {
                  pauseParsing();
              }
              return;
          }
          
          if (state == IN_BODY) {
              parsedBody = true;
              state = IN_ENVELOPE;
              
              /** If we were looking for a body element and got here,
               * we ain't gonna find it.  !!! How do we indicate the
               * error back to the other thread?  Right now we'll just
               * return a null... good enough?
               */
              if (targetType == TARGET_BODY) {
                  pauseParsing();
              }
              return;
          }
          
          if (state == IN_ENVELOPE) {
              if (DEBUG_LOG)
                  System.out.println("Done parsing envelope!");
              state = FINISHED;
              
              return;
          }
          
          throw new SAXException("Invalid state in endElement!");
      }
      
      public abstract void parse();
      protected abstract void continueParsing();
      protected abstract void pauseParsing() throws SAXException;
  }
  
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/ThreadedSAXAdapter.java
  
  Index: ThreadedSAXAdapter.java
  ===================================================================
  package org.apache.axis.message;
  
  import org.xml.sax.*;
  
  /** This class is an adapter for the Axis SAX-event system
   * which uses a SAX parser to parse on its own thread, synchronizing
   * when appropriate with the control thread.
   * 
   * @author Glen Daniels (gdaniels@macromedia.com)
   */
  public class ThreadedSAXAdapter extends SOAPSAXHandler
  {
      private Object _semaphore = new Object();
                                             
      private XMLReader _parser;
      InputSource inputSource;
  
      private Thread parseThread = null;
  
      private boolean doneParsing = false;
      
      /** The actual Runnable for the parse thread
       */   
      class ParseRunnable implements Runnable
      {
          public void run()
          {
              try {
                  _parser.parse(inputSource);
              } catch (Exception e) {
                  e.printStackTrace();
              }
              
              System.out.println("ThreadedSAXAdapter done.");
              doneParsing = true;
              state = FINISHED;
              
              synchronized (_semaphore) {
                  _semaphore.notify();
              }
          }
      }
      
      public ThreadedSAXAdapter(XMLReader parser, InputSource inputSource)
      {
          _parser = new org.apache.xerces.parsers.SAXParser();
          _parser.setContentHandler(this);
          //elementHandler = new SAXOutputter(new PrintWriter(System.out));
          //_parser.setContentHandler(new SAXOutputter(new PrintWriter(System.out)));
          
          this.inputSource = inputSource;
      }
      
      /*******************************************************************
       * Threading stuff
       */
      public void startParse()
      {
          // This should be using some threading infrastructure...
          parseThread = new Thread(new ParseRunnable());
          parseThread.start();
      }
      
      public void parse()
      {
          if (getState() == FINISHED) {
              return;
          }
          
          if (parseThread == null) {
              startParse();
          }
          
          // Kick the parse thread
          continueParsing();
          
          // Wait until it's done (i.e. paused or finished)
          synchronized (_semaphore) {
              while (!doneParsing) {
                  try {
                      //System.out.println("parseHeaders() waiting...");
                      _semaphore.wait();
                      //System.out.println("parseHeaders() waking...");
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                      break;
                  }
              }
          }
      }
      
      /** Called by the control thread; let the parsing thread
       * continue.
       * 
       */
      protected synchronized void continueParsing()
      {
          System.out.println("continueParsing()");
          doneParsing = false;
          notify();
      }
      
      /** Called by the parse thread once it hits a desired
       * event (found the element the control thread is looking
       * for, finished parsing the headers, etc).  Suspend
       * execution until we're told to go again.
       */
      protected void pauseParsing() throws SAXException
      {
          if (parsingToEnd)
              return;
          
          System.out.println("pauseParsing()");
          
          synchronized (this) {
              doneParsing = true;
          }
  
          /** Anyone who's waiting on us will be hanging out on
           * the semaphore.
           */
          synchronized (_semaphore) {
              _semaphore.notify();
          }
          
          synchronized (this) {
              try {
                  wait();
              } catch (InterruptedException e) {
                  throw new SAXException("SOAPSAXHandler was interrupted!");
              }
          }
      }
  
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/events/CharactersEvent.java
  
  Index: CharactersEvent.java
  ===================================================================
  package org.apache.axis.message.events;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.xml.sax.Attributes;
  import org.xml.sax.helpers.AttributesImpl;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  
  /** A <code>CharactersElementEvent</code>
   * 
   * @author Glen Daniels (gdaniels@allaire.com)
   */
  
  public class CharactersEvent implements SAXEvent
  {
      char [] _characters;
      int _start;
      int _length;
      
      public CharactersEvent(char [] characters, int start, int length)
      {
          _characters = new char[length];
          System.arraycopy(characters, start, _characters, 0, length);
          _start = 0;
          _length = length;
      }
      
      public void publishToHandler(ContentHandler handler) throws SAXException
      {
          handler.characters(_characters, _start, _length);
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/events/EndElementEvent.java
  
  Index: EndElementEvent.java
  ===================================================================
  package org.apache.axis.message.events;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.xml.sax.Attributes;
  import org.xml.sax.helpers.AttributesImpl;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  
  /** An <code>EndElementEvent</code>
   * 
   * @author Glen Daniels (gdaniels@allaire.com)
   */
  
  public class EndElementEvent implements SAXEvent
  {
      String _namespace;
      String _localPart;
      String _qName;
      
      public EndElementEvent(String namespace, String localPart, String qName)
      {
          _namespace = namespace;
          _localPart = localPart;
          _qName = qName;
      }
      
      public void publishToHandler(ContentHandler handler) throws SAXException
      {
          handler.endElement(_namespace, _localPart, _qName);
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/events/IDElementEvent.java
  
  Index: IDElementEvent.java
  ===================================================================
  package org.apache.axis.message.events;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.xml.sax.Attributes;
  import org.xml.sax.helpers.AttributesImpl;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  import org.apache.axis.message.MessageElement;
  
  /** An <code>IDElementEvent</code> represents hitting a sub-element
   * with an ID set, which means the engine put it into another MessageElement.
   * 
   * @author Glen Daniels (gdaniels@allaire.com)
   */
  
  public class IDElementEvent implements SAXEvent
  {
      String _namespace;
      String _localPart;
      MessageElement _target;
      
      public IDElementEvent(String namespace, String localPart, MessageElement target)
      {
          _namespace = namespace;
          _localPart = localPart;
          _target = target;
      }
      
      public void publishToHandler(ContentHandler handler) throws SAXException
      {
          _target.publishToHandler(handler);
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/events/SAXEvent.java
  
  Index: SAXEvent.java
  ===================================================================
  package org.apache.axis.message.events;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  
  /** This is a simple interface for classes which store cached SAX events.
   * Each implementing class should keep some representation of the particular
   * event it reflects, and know how to "replay" that event to a ContentHandler.
   * 
   * @author Glen Daniels (gdaniels@macromedia.com)
   */
  public interface SAXEvent
  {
      public void publishToHandler(ContentHandler handler)
          throws SAXException;
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/message/events/StartElementEvent.java
  
  Index: StartElementEvent.java
  ===================================================================
  package org.apache.axis.message.events;
  
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.xml.sax.Attributes;
  import org.xml.sax.helpers.AttributesImpl;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  
  /** A <code>StartElementEvent</code>
   * 
   * @author Glen Daniels (gdaniels@allaire.com)
   */
  
  public class StartElementEvent implements SAXEvent
  {
      String _namespace;
      String _localPart;
      String _qName;
      Attributes _attributes;
      
      public StartElementEvent(String namespace, String localPart,
                               String qName, Attributes attributes)
      {
          _namespace = namespace;
          _localPart = localPart;
          _qName = qName;
          _attributes = new AttributesImpl(attributes);
      }
      
      public void publishToHandler(ContentHandler handler) throws SAXException
      {
          handler.startElement(_namespace, _localPart, _qName, _attributes);
      }
  }