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 }