Coverage Report - org.mule.module.xml.stax.XMLStreamReaderToContentHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
XMLStreamReaderToContentHandler
67%
108/162
54%
41/76
3.5
XMLStreamReaderToContentHandler$1
40%
2/5
N/A
3.5
 
 1  
 /* $Id: XMLStreamReaderToContentHandler.java,v 1.6 2006/01/23 18:50:02 sandoz Exp $
 2  
  *
 3  
  * Copyright (c) 2004, Sun Microsystems, Inc.
 4  
  * All rights reserved.
 5  
  *
 6  
  * Redistribution and use in source and binary forms, with or without
 7  
  * modification, are permitted provided that the following conditions are
 8  
  * met:
 9  
  *
 10  
  *     * Redistributions of source code must retain the above copyright
 11  
  *      notice, this list of conditions and the following disclaimer.
 12  
  *
 13  
  *     * Redistributions in binary form must reproduce the above
 14  
  *      copyright notice, this list of conditions and the following
 15  
  *       disclaimer in the documentation and/or other materials provided
 16  
  *       with the distribution.
 17  
  *
 18  
  *     * Neither the name of Sun Microsystems, Inc. nor the names of its
 19  
  *       contributors may be used to endorse or promote products derived
 20  
  *       from this software without specific prior written permission.
 21  
  *
 22  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 23  
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 24  
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 25  
  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 26  
  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 27  
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 28  
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 29  
  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 30  
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 31  
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 32  
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 33  
  */
 34  
 
 35  
 package org.mule.module.xml.stax;
 36  
 
 37  
 import javanet.staxutils.DummyLocator;
 38  
 import javanet.staxutils.StAXReaderToContentHandler;
 39  
 import javanet.staxutils.helpers.XMLFilterImplEx;
 40  
 
 41  
 import javax.xml.namespace.QName;
 42  
 import javax.xml.stream.Location;
 43  
 import javax.xml.stream.XMLStreamConstants;
 44  
 import javax.xml.stream.XMLStreamException;
 45  
 import javax.xml.stream.XMLStreamReader;
 46  
 
 47  
 import org.xml.sax.Attributes;
 48  
 import org.xml.sax.Locator;
 49  
 import org.xml.sax.SAXException;
 50  
 import org.xml.sax.helpers.AttributesImpl;
 51  
 
 52  
 /**
 53  
  * This is a simple utility class that adapts StAX events from an
 54  
  * {@link javax.xml.stream.XMLStreamReader} to SAX events on a
 55  
  * {@link org.xml.sax.ContentHandler}, bridging between the two parser technologies.
 56  
  * 
 57  
  * @author Ryan.Shoemaker@Sun.COM
 58  
  * @version 1.0
 59  
  */
 60  
 public class XMLStreamReaderToContentHandler implements StAXReaderToContentHandler
 61  
 {
 62  
 
 63  
     // StAX event source
 64  
     private final XMLStreamReader staxStreamReader;
 65  
 
 66  
     // SAX event sinks
 67  
     private XMLFilterImplEx filter;
 68  
 
 69  
     /**
 70  
      * Construct a new StAX to SAX adapter that will convert a StAX event stream into
 71  
      * a SAX event stream.
 72  
      * 
 73  
      * @param staxCore StAX event source
 74  
      * @param filter SAX event sink
 75  
      */
 76  
     public XMLStreamReaderToContentHandler(XMLStreamReader staxCore, XMLFilterImplEx filter)
 77  12
     {
 78  12
         staxStreamReader = staxCore;
 79  
 
 80  12
         this.filter = filter;
 81  12
     }
 82  
 
 83  
     /*
 84  
      * @see StAXReaderToContentHandler#bridge()
 85  
      */
 86  
     public void bridge() throws XMLStreamException
 87  
     {
 88  
 
 89  
         try
 90  
         {
 91  
             // remembers the nest level of elements to know when we are done.
 92  12
             int depth = 0;
 93  12
             boolean isDocument = false;
 94  
 
 95  12
             handleStartDocument();
 96  
 
 97  
             // if the parser is at the start document, procees any comments or PIs
 98  12
             int event = staxStreamReader.getEventType();
 99  12
             if (event == XMLStreamConstants.START_DOCUMENT)
 100  
             {
 101  12
                 isDocument = true;
 102  12
                 event = staxStreamReader.next();
 103  32
                 while (event != XMLStreamConstants.START_ELEMENT)
 104  
                 {
 105  20
                     switch (event)
 106  
                     {
 107  
                         case XMLStreamConstants.COMMENT :
 108  4
                             handleComment();
 109  4
                             break;
 110  
                         case XMLStreamConstants.PROCESSING_INSTRUCTION :
 111  0
                             handlePI();
 112  
                             break;
 113  
                     }
 114  20
                     event = staxStreamReader.next();
 115  
                 };
 116  
             }
 117  
 
 118  12
             if (event != XMLStreamConstants.START_ELEMENT)
 119  0
                 throw new IllegalStateException("The current event is not START_ELEMENT\n but" + event);
 120  
 
 121  
             do
 122  
             {
 123  
                 // These are all of the events listed in the javadoc for
 124  
                 // XMLEvent.
 125  
                 // The spec only really describes 11 of them.
 126  6284
                 switch (event)
 127  
                 {
 128  
                     case XMLStreamConstants.START_ELEMENT :
 129  1564
                         depth++;
 130  1564
                         handleStartElement();
 131  1564
                         break;
 132  
                     case XMLStreamConstants.END_ELEMENT :
 133  1564
                         handleEndElement();
 134  1564
                         depth--;
 135  1564
                         break;
 136  
                     case XMLStreamConstants.CHARACTERS :
 137  3136
                         handleCharacters();
 138  3136
                         break;
 139  
                     case XMLStreamConstants.ENTITY_REFERENCE :
 140  0
                         handleEntityReference();
 141  0
                         break;
 142  
                     case XMLStreamConstants.PROCESSING_INSTRUCTION :
 143  0
                         handlePI();
 144  0
                         break;
 145  
                     case XMLStreamConstants.COMMENT :
 146  20
                         handleComment();
 147  20
                         break;
 148  
                     case XMLStreamConstants.DTD :
 149  0
                         handleDTD();
 150  0
                         break;
 151  
                     case XMLStreamConstants.ATTRIBUTE :
 152  0
                         handleAttribute();
 153  0
                         break;
 154  
                     case XMLStreamConstants.NAMESPACE :
 155  0
                         handleNamespace();
 156  0
                         break;
 157  
                     case XMLStreamConstants.CDATA :
 158  0
                         handleCDATA();
 159  0
                         break;
 160  
                     case XMLStreamConstants.ENTITY_DECLARATION :
 161  0
                         handleEntityDecl();
 162  0
                         break;
 163  
                     case XMLStreamConstants.NOTATION_DECLARATION :
 164  0
                         handleNotationDecl();
 165  0
                         break;
 166  
                     case XMLStreamConstants.SPACE :
 167  0
                         handleSpace();
 168  0
                         break;
 169  
                     default :
 170  0
                         throw new InternalError("processing event: " + event);
 171  
                 }
 172  
 
 173  6284
                 event = staxStreamReader.next();
 174  
             }
 175  6284
             while (depth != 0);
 176  
 
 177  
             // procees any remaining comments or PIs
 178  12
             if (isDocument)
 179  
             {
 180  20
                 while (event != XMLStreamConstants.END_DOCUMENT)
 181  
                 {
 182  8
                     switch (event)
 183  
                     {
 184  
                         case XMLStreamConstants.COMMENT :
 185  0
                             handleComment();
 186  0
                             break;
 187  
                         case XMLStreamConstants.PROCESSING_INSTRUCTION :
 188  0
                             handlePI();
 189  
                             break;
 190  
                     }
 191  8
                     event = staxStreamReader.next();
 192  
                 }
 193  
             }
 194  
 
 195  12
             handleEndDocument();
 196  
         }
 197  0
         catch (SAXException e)
 198  
         {
 199  0
             throw new XMLStreamException(e);
 200  12
         }
 201  12
     }
 202  
 
 203  
     protected void handleEndDocument() throws SAXException
 204  
     {
 205  12
         filter.endDocument();
 206  12
     }
 207  
 
 208  
     protected void handleStartDocument() throws SAXException
 209  
     {
 210  12
         final Location location = staxStreamReader.getLocation();
 211  12
         if (location != null)
 212  
         {
 213  12
             filter.setDocumentLocator(new Locator()
 214  
             {
 215  
                 public int getColumnNumber()
 216  
                 {
 217  0
                     return location.getColumnNumber();
 218  
                 }
 219  
 
 220  
                 public int getLineNumber()
 221  
                 {
 222  0
                     return location.getLineNumber();
 223  
                 }
 224  
 
 225  
                 public String getPublicId()
 226  
                 {
 227  0
                     return location.getPublicId();
 228  
                 }
 229  
 
 230  12
                 public String getSystemId()
 231  
                 {
 232  732
                     return location.getSystemId();
 233  
                 }
 234  
             });
 235  
         }
 236  
         else
 237  
         {
 238  0
             filter.setDocumentLocator(new DummyLocator());
 239  
         }
 240  12
         filter.startDocument();
 241  12
     }
 242  
 
 243  
     protected void handlePI() throws XMLStreamException
 244  
     {
 245  
         try
 246  
         {
 247  0
             filter.processingInstruction(staxStreamReader.getPITarget(), staxStreamReader.getPIData());
 248  
         }
 249  0
         catch (SAXException e)
 250  
         {
 251  0
             throw new XMLStreamException(e);
 252  0
         }
 253  0
     }
 254  
 
 255  
     protected void handleCharacters() throws XMLStreamException
 256  
     {
 257  3136
         char[] chars = staxStreamReader.getText().toCharArray();
 258  
 
 259  
         try
 260  
         {
 261  3136
             filter.characters(chars, 0, chars.length);
 262  
         }
 263  0
         catch (SAXException e)
 264  
         {
 265  0
             throw new XMLStreamException(e);
 266  3136
         }
 267  3136
     }
 268  
 
 269  
     protected void handleEndElement() throws XMLStreamException
 270  
     {
 271  1564
         QName qName = staxStreamReader.getName();
 272  
 
 273  
         try
 274  
         {
 275  
             // fire endElement
 276  1564
             String prefix = qName.getPrefix();
 277  
             String rawname;
 278  1564
             if (prefix == null || prefix.length() == 0)
 279  1564
                 rawname = qName.getLocalPart();
 280  
             else
 281  0
                 rawname = prefix + ':' + qName.getLocalPart();
 282  
 
 283  1564
             filter.endElement(qName.getNamespaceURI(), qName.getLocalPart(), rawname);
 284  
 
 285  
             // end namespace bindings
 286  1564
             int nsCount = staxStreamReader.getNamespaceCount();
 287  1568
             for (int i = nsCount - 1; i >= 0; i--)
 288  
             {
 289  4
                 String nsprefix = staxStreamReader.getNamespacePrefix(i);
 290  4
                 if (nsprefix == null)
 291  
                 { // true for default namespace
 292  4
                     nsprefix = "";
 293  
                 }
 294  4
                 filter.endPrefixMapping(nsprefix);
 295  
             }
 296  
         }
 297  0
         catch (SAXException e)
 298  
         {
 299  0
             throw new XMLStreamException(e);
 300  1564
         }
 301  1564
     }
 302  
 
 303  
     protected void handleStartElement() throws XMLStreamException
 304  
     {
 305  
 
 306  
         try
 307  
         {
 308  
             // start namespace bindings
 309  1564
             int nsCount = staxStreamReader.getNamespaceCount();
 310  1568
             for (int i = 0; i < nsCount; i++)
 311  
             {
 312  4
                 String uri = staxStreamReader.getNamespaceURI(i);
 313  4
                 if (uri == null)
 314  
                 {
 315  0
                     uri = "";
 316  
                 }
 317  4
                 String prefix = staxStreamReader.getNamespacePrefix(i);
 318  4
                 if (prefix == null)
 319  
                 { // true for default namespace
 320  4
                     prefix = "";
 321  
                 }
 322  4
                 filter.startPrefixMapping(prefix, uri);
 323  
             }
 324  
 
 325  
             // fire startElement
 326  1564
             QName qName = staxStreamReader.getName();
 327  1564
             String prefix = qName.getPrefix();
 328  
             String rawname;
 329  1564
             if (prefix == null || prefix.length() == 0)
 330  1564
                 rawname = qName.getLocalPart();
 331  
             else
 332  0
                 rawname = prefix + ':' + qName.getLocalPart();
 333  1564
             Attributes attrs = getAttributes();
 334  1564
             filter.startElement(qName.getNamespaceURI(), qName.getLocalPart(), rawname, attrs);
 335  
         }
 336  0
         catch (SAXException e)
 337  
         {
 338  0
             throw new XMLStreamException(e);
 339  1564
         }
 340  1564
     }
 341  
 
 342  
     /**
 343  
      * Get the attributes associated with the given START_ELEMENT or ATTRIBUTE
 344  
      * StAXevent.
 345  
      * 
 346  
      * @return the StAX attributes converted to an org.xml.sax.Attributes
 347  
      */
 348  
     protected Attributes getAttributes()
 349  
     {
 350  1564
         AttributesImpl attrs = new AttributesImpl();
 351  
 
 352  1564
         int eventType = staxStreamReader.getEventType();
 353  1564
         if (eventType != XMLStreamConstants.ATTRIBUTE && eventType != XMLStreamConstants.START_ELEMENT)
 354  
         {
 355  0
             throw new InternalError("getAttributes() attempting to process: " + eventType);
 356  
         }
 357  
 
 358  
         // Add namspace declarations if required
 359  1564
         if (filter.getNamespacePrefixes())
 360  
         {
 361  836
             for (int i = 0; i < staxStreamReader.getNamespaceCount(); i++)
 362  
             {
 363  4
                 String uri = staxStreamReader.getNamespaceURI(i);
 364  4
                 if (uri == null) uri = "";
 365  
 
 366  4
                 String prefix = staxStreamReader.getNamespacePrefix(i);
 367  4
                 if (prefix == null) prefix = "";
 368  
 
 369  4
                 String qName = "xmlns";
 370  4
                 if (prefix.length() == 0)
 371  
                 {
 372  4
                     prefix = qName;
 373  
                 }
 374  
                 else
 375  
                 {
 376  0
                     qName = qName + ':' + prefix;
 377  
                 }
 378  4
                 attrs.addAttribute("http://www.w3.org/2000/xmlns/", prefix, qName, "CDATA", uri);
 379  
             }
 380  
         }
 381  
 
 382  
         // gather non-namespace attrs
 383  1584
         for (int i = 0; i < staxStreamReader.getAttributeCount(); i++)
 384  
         {
 385  20
             String uri = staxStreamReader.getAttributeNamespace(i);
 386  20
             if (uri == null) uri = "";
 387  20
             String localName = staxStreamReader.getAttributeLocalName(i);
 388  20
             String prefix = staxStreamReader.getAttributePrefix(i);
 389  
             String qName;
 390  20
             if (prefix == null || prefix.length() == 0)
 391  20
                 qName = localName;
 392  
             else
 393  0
                 qName = prefix + ':' + localName;
 394  20
             String type = staxStreamReader.getAttributeType(i);
 395  20
             String value = staxStreamReader.getAttributeValue(i);
 396  
 
 397  20
             attrs.addAttribute(uri, localName, qName, type, value);
 398  
         }
 399  
 
 400  1564
         return attrs;
 401  
     }
 402  
 
 403  
     protected void handleNamespace()
 404  
     {
 405  
         // no-op ???
 406  
         // namespace events don't normally occur outside of a startElement
 407  
         // or endElement
 408  0
     }
 409  
 
 410  
     protected void handleAttribute()
 411  
     {
 412  
         // no-op ???
 413  
         // attribute events don't normally occur outside of a startElement
 414  
         // or endElement
 415  0
     }
 416  
 
 417  
     protected void handleDTD()
 418  
     {
 419  
         // no-op ???
 420  
         // it seems like we need to pass this info along, but how?
 421  0
     }
 422  
 
 423  
     protected void handleComment() throws XMLStreamException
 424  
     {
 425  24
         int textLength = staxStreamReader.getTextLength();
 426  24
         int textStart = staxStreamReader.getTextStart();
 427  24
         char[] chars = new char[textLength];
 428  
 
 429  24
         staxStreamReader.getTextCharacters(textStart, chars, 0, textLength);
 430  
 
 431  
         try
 432  
         {
 433  24
             filter.comment(chars, 0, textLength);
 434  
         }
 435  0
         catch (SAXException e)
 436  
         {
 437  0
             throw new XMLStreamException(e);
 438  24
         }
 439  24
     }
 440  
 
 441  
     protected void handleEntityReference()
 442  
     {
 443  
         // no-op ???
 444  0
     }
 445  
 
 446  
     protected void handleSpace()
 447  
     {
 448  
         // no-op ???
 449  
         // this event is listed in the javadoc, but not in the spec.
 450  0
     }
 451  
 
 452  
     protected void handleNotationDecl()
 453  
     {
 454  
         // no-op ???
 455  
         // this event is listed in the javadoc, but not in the spec.
 456  0
     }
 457  
 
 458  
     protected void handleEntityDecl()
 459  
     {
 460  
         // no-op ???
 461  
         // this event is listed in the javadoc, but not in the spec.
 462  0
     }
 463  
 
 464  
     protected void handleCDATA()
 465  
     {
 466  
         // no-op ???
 467  
         // this event is listed in the javadoc, but not in the spec.
 468  0
     }
 469  
 }