View Javadoc

    1   package org.codehaus.xfire.aegis.stax;
    2
    3   import java.io.InputStream;
    4
    5   import javax.xml.namespace.QName;
    6   import javax.xml.stream.XMLInputFactory;
    7   import javax.xml.stream.XMLStreamException;
    8   import javax.xml.stream.XMLStreamReader;
    9
    10  import org.codehaus.xfire.XFireRuntimeException;
    11  import org.codehaus.xfire.aegis.AbstractMessageReader;
    12  import org.codehaus.xfire.aegis.MessageReader;
    13  import org.codehaus.xfire.util.DepthXMLStreamReader;
    14
    15  /***
    16   * Reads literal encoded messages.
    17   *
    18   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
    19   */
    20  public class ElementReader
    21      extends AbstractMessageReader
    22      implements MessageReader
    23  {
    24      private DepthXMLStreamReader root;
    25      private StringBuffer value;
    26      private String localName;
    27      private QName name;
    28      private boolean hasCheckedChildren = false;
    29      private boolean hasChildren = false;
    30      private boolean hasFoundText = false;
    31      private String namespace;
    32      private int depth;
    33      private int currentAttribute = 0;
    34
    35      /***
    36       * Expects the XMLStreamReader in the START_DOCUMENT event.
    37       * @param root
    38       */
    39      public ElementReader(DepthXMLStreamReader root)
    40      {
    41          this.root = root;
    42          this.localName = root.getLocalName();
    43          this.name = root.getName();
    44          this.namespace = root.getNamespaceURI();
    45
    46          depth = root.getDepth();
    47      }
    48
    49      public ElementReader(XMLStreamReader reader)
    50      {
    51          this.root = new DepthXMLStreamReader(reader);
    52          this.localName = root.getLocalName();
    53          this.name = root.getName();
    54          this.namespace = root.getNamespaceURI();
    55
    56          depth = root.getDepth();
    57      }
    58
    59      /***
    60       * @param resourceAsStream
    61       * @throws XMLStreamException
    62       */
    63      public ElementReader(InputStream is)
    64          throws XMLStreamException
    65      {
    66          XMLInputFactory factory = XMLInputFactory.newInstance();
    67          XMLStreamReader xmlReader = factory.createXMLStreamReader(is);
    68
    69          while ( xmlReader.getEventType() != XMLStreamReader.START_ELEMENT )
    70              xmlReader.next();
    71
    72          this.root = new DepthXMLStreamReader(xmlReader);
    73          this.localName = root.getLocalName();
    74          this.name = root.getName();
    75          this.namespace = root.getNamespaceURI();
    76
    77          depth = root.getDepth();
    78      }
    79
    80      /***
    81       * @see org.codehaus.xfire.aegis.MessageReader#getValue()
    82       */
    83      public String getValue()
    84      {
    85          while( !hasFoundText && checkHasMoreChildReaders() )
    86          {
    87          }
    88
    89          if (value == null)
    90              return null;
    91
    92          return value.toString().trim();
    93      }
    94
    95      public String getValue( String ns, String attr )
    96      {
    97          return root.getAttributeValue(ns, attr);
    98      }
    99
    100     public boolean hasMoreElementReaders()
    101     {
    102         // Check to see if we checked before,
    103         // so we don't mess up the stream position.
    104         if ( !hasCheckedChildren )
    105             checkHasMoreChildReaders();
    106
    107         return hasChildren;
    108     }
    109
    110     private boolean checkHasMoreChildReaders()
    111     {
    112         try
    113         {
    114             int event = root.getEventType();
    115             while ( true )
    116             {
    117                 switch( event )
    118                 {
    119                 case XMLStreamReader.START_ELEMENT:
    120                     if ( root.getDepth() > depth )
    121                     {
    122                         hasCheckedChildren = true;
    123                         hasChildren = true;
    124                         return true;
    125                     }
    126                     break;
    127                 case XMLStreamReader.END_ELEMENT:
    128                     if ( root.getDepth() <= depth )
    129                     {
    130                         hasCheckedChildren = true;
    131                         hasChildren = false;
    132                         root.next();
    133                         return false;
    134                     }
    135                     break;
    136                 case XMLStreamReader.CHARACTERS:
    137                     if (value == null)
    138                         value = new StringBuffer();
    139
    140                     value.append(root.getText());
    141                     hasFoundText = true;
    142                     break;
    143                 case XMLStreamReader.END_DOCUMENT:
    144                     // We should never get here...
    145                     hasCheckedChildren = true;
    146                     hasChildren = false;
    147                     return false;
    148                 default:
    149                     break;
    150                 }
    151                 event = root.next();
    152             }
    153         }
    154         catch (XMLStreamException e)
    155         {
    156             throw new XFireRuntimeException("Error parsing document.", e);
    157         }
    158     }
    159
    160     public MessageReader getNextElementReader()
    161     {
    162         if ( !hasCheckedChildren )
    163             checkHasMoreChildReaders();
    164
    165         if ( !hasChildren )
    166             return null;
    167
    168         hasCheckedChildren = false;
    169
    170         return new ElementReader( root );
    171     }
    172
    173     public QName getName()
    174     {
    175         return name;
    176     }
    177
    178     public String getLocalName()
    179     {
    180         return localName;
    181     }
    182
    183     public String getNamespace()
    184     {
    185         return namespace;
    186     }
    187
    188     public XMLStreamReader getXMLStreamReader()
    189     {
    190         return root;
    191     }
    192
    193     public boolean hasMoreAttributeReaders()
    194     {
    195         return currentAttribute < root.getAttributeCount();
    196     }
    197
    198     public MessageReader getNextAttributeReader()
    199     {
    200         MessageReader reader = new AttributeReader(root.getAttributeName(currentAttribute),
    201                                                    root.getAttributeValue(currentAttribute));
    202         currentAttribute++;
    203
    204         return reader;
    205     }
    206 }