Coverage Report - org.mule.module.xml.stax.XMLStreamReaderToContentHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
XMLStreamReaderToContentHandler
0%
0/166
0%
0/76
3.591
XMLStreamReaderToContentHandler$1
0%
0/5
N/A
3.591
 
 1  
 /* $Id$
 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  0
     {
 78  0
         staxStreamReader = staxCore;
 79  
 
 80  0
         this.filter = filter;
 81  0
     }
 82  
 
 83  
     public void bridge() throws XMLStreamException
 84  
     {
 85  
         try
 86  
         {
 87  
             // remembers the nest level of elements to know when we are done.
 88  0
             int depth = 0;
 89  0
             boolean isDocument = false;
 90  
 
 91  0
             handleStartDocument();
 92  
 
 93  
             // if the parser is at the start document, procees any comments or PIs
 94  0
             int event = staxStreamReader.getEventType();
 95  0
             if (event == XMLStreamConstants.START_DOCUMENT)
 96  
             {
 97  0
                 isDocument = true;
 98  0
                 event = staxStreamReader.next();
 99  0
                 while (event != XMLStreamConstants.START_ELEMENT)
 100  
                 {
 101  0
                     switch (event)
 102  
                     {
 103  
                         case XMLStreamConstants.COMMENT :
 104  0
                             handleComment();
 105  0
                             break;
 106  
                         case XMLStreamConstants.PROCESSING_INSTRUCTION :
 107  0
                             handlePI();
 108  
                             break;
 109  
                     }
 110  0
                     event = staxStreamReader.next();
 111  
                 }
 112  
             }
 113  
 
 114  0
             if (event != XMLStreamConstants.START_ELEMENT)
 115  0
                 throw new IllegalStateException("The current event is not START_ELEMENT\n but" + event);
 116  
 
 117  
             do
 118  
             {
 119  
                 // These are all of the events listed in the javadoc for
 120  
                 // XMLEvent.
 121  
                 // The spec only really describes 11 of them.
 122  0
                 switch (event)
 123  
                 {
 124  
                     case XMLStreamConstants.START_ELEMENT :
 125  0
                         depth++;
 126  0
                         handleStartElement();
 127  0
                         break;
 128  
                     case XMLStreamConstants.END_ELEMENT :
 129  0
                         handleEndElement();
 130  0
                         depth--;
 131  0
                         break;
 132  
                     case XMLStreamConstants.CHARACTERS :
 133  0
                         handleCharacters();
 134  0
                         break;
 135  
                     case XMLStreamConstants.ENTITY_REFERENCE :
 136  0
                         handleEntityReference();
 137  0
                         break;
 138  
                     case XMLStreamConstants.PROCESSING_INSTRUCTION :
 139  0
                         handlePI();
 140  0
                         break;
 141  
                     case XMLStreamConstants.COMMENT :
 142  0
                         handleComment();
 143  0
                         break;
 144  
                     case XMLStreamConstants.DTD :
 145  0
                         handleDTD();
 146  0
                         break;
 147  
                     case XMLStreamConstants.ATTRIBUTE :
 148  0
                         handleAttribute();
 149  0
                         break;
 150  
                     case XMLStreamConstants.NAMESPACE :
 151  0
                         handleNamespace();
 152  0
                         break;
 153  
                     case XMLStreamConstants.CDATA :
 154  0
                         handleCDATA();
 155  0
                         break;
 156  
                     case XMLStreamConstants.ENTITY_DECLARATION :
 157  0
                         handleEntityDecl();
 158  0
                         break;
 159  
                     case XMLStreamConstants.NOTATION_DECLARATION :
 160  0
                         handleNotationDecl();
 161  0
                         break;
 162  
                     case XMLStreamConstants.SPACE :
 163  0
                         handleSpace();
 164  0
                         break;
 165  
                     default :
 166  0
                         throw new InternalError("processing event: " + event);
 167  
                 }
 168  
 
 169  0
                 event = staxStreamReader.next();
 170  
             }
 171  0
             while (depth != 0);
 172  
 
 173  
             // procees any remaining comments or PIs
 174  0
             if (isDocument)
 175  
             {
 176  0
                 while (event != XMLStreamConstants.END_DOCUMENT)
 177  
                 {
 178  0
                     switch (event)
 179  
                     {
 180  
                         case XMLStreamConstants.COMMENT :
 181  0
                             handleComment();
 182  0
                             break;
 183  
                         case XMLStreamConstants.PROCESSING_INSTRUCTION :
 184  0
                             handlePI();
 185  
                             break;
 186  
                     }
 187  0
                     event = staxStreamReader.next();
 188  
                 }
 189  
             }
 190  
 
 191  0
             handleEndDocument();
 192  
         }
 193  0
         catch (SAXException e)
 194  
         {
 195  0
             throw new XMLStreamException(e);
 196  0
         }
 197  0
     }
 198  
 
 199  
     protected void handleEndDocument() throws SAXException
 200  
     {
 201  0
         filter.endDocument();
 202  0
     }
 203  
 
 204  
     protected void handleStartDocument() throws SAXException
 205  
     {
 206  0
         final Location location = staxStreamReader.getLocation();
 207  0
         if (location != null)
 208  
         {
 209  0
             filter.setDocumentLocator(new Locator()
 210  0
             {
 211  
                 public int getColumnNumber()
 212  
                 {
 213  0
                     return location.getColumnNumber();
 214  
                 }
 215  
 
 216  
                 public int getLineNumber()
 217  
                 {
 218  0
                     return location.getLineNumber();
 219  
                 }
 220  
 
 221  
                 public String getPublicId()
 222  
                 {
 223  0
                     return location.getPublicId();
 224  
                 }
 225  
 
 226  
                 public String getSystemId()
 227  
                 {
 228  0
                     return location.getSystemId();
 229  
                 }
 230  
             });
 231  
         }
 232  
         else
 233  
         {
 234  0
             filter.setDocumentLocator(new DummyLocator());
 235  
         }
 236  0
         filter.startDocument();
 237  0
     }
 238  
 
 239  
     protected void handlePI() throws XMLStreamException
 240  
     {
 241  
         try
 242  
         {
 243  0
             filter.processingInstruction(staxStreamReader.getPITarget(), staxStreamReader.getPIData());
 244  
         }
 245  0
         catch (SAXException e)
 246  
         {
 247  0
             throw new XMLStreamException(e);
 248  0
         }
 249  0
     }
 250  
 
 251  
     protected void handleCharacters() throws XMLStreamException
 252  
     {
 253  0
         char[] chars = staxStreamReader.getText().toCharArray();
 254  
 
 255  
         try
 256  
         {
 257  0
             filter.characters(chars, 0, chars.length);
 258  
         }
 259  0
         catch (SAXException e)
 260  
         {
 261  0
             throw new XMLStreamException(e);
 262  0
         }
 263  0
     }
 264  
 
 265  
     protected void handleEndElement() throws XMLStreamException
 266  
     {
 267  0
         QName qName = staxStreamReader.getName();
 268  
 
 269  
         try
 270  
         {
 271  
             // fire endElement
 272  0
             String prefix = qName.getPrefix();
 273  
             String rawname;
 274  0
             if (prefix == null || prefix.length() == 0)
 275  0
                 rawname = qName.getLocalPart();
 276  
             else
 277  0
                 rawname = prefix + ':' + qName.getLocalPart();
 278  
 
 279  0
             filter.endElement(qName.getNamespaceURI(), qName.getLocalPart(), rawname);
 280  
 
 281  
             // end namespace bindings
 282  0
             int nsCount = staxStreamReader.getNamespaceCount();
 283  0
             for (int i = nsCount - 1; i >= 0; i--)
 284  
             {
 285  0
                 String nsprefix = staxStreamReader.getNamespacePrefix(i);
 286  0
                 if (nsprefix == null)
 287  
                 { // true for default namespace
 288  0
                     nsprefix = "";
 289  
                 }
 290  0
                 filter.endPrefixMapping(nsprefix);
 291  
             }
 292  
         }
 293  0
         catch (SAXException e)
 294  
         {
 295  0
             throw new XMLStreamException(e);
 296  0
         }
 297  0
     }
 298  
 
 299  
     protected void handleStartElement() throws XMLStreamException
 300  
     {
 301  
 
 302  
         try
 303  
         {
 304  
             // start namespace bindings
 305  0
             int nsCount = staxStreamReader.getNamespaceCount();
 306  0
             for (int i = 0; i < nsCount; i++)
 307  
             {
 308  0
                 String uri = staxStreamReader.getNamespaceURI(i);
 309  0
                 if (uri == null)
 310  
                 {
 311  0
                     uri = "";
 312  
                 }
 313  0
                 String prefix = staxStreamReader.getNamespacePrefix(i);
 314  0
                 if (prefix == null)
 315  
                 { // true for default namespace
 316  0
                     prefix = "";
 317  
                 }
 318  0
                 filter.startPrefixMapping(prefix, uri);
 319  
             }
 320  
 
 321  
             // fire startElement
 322  0
             QName qName = staxStreamReader.getName();
 323  0
             String prefix = qName.getPrefix();
 324  
             String rawname;
 325  0
             if (prefix == null || prefix.length() == 0)
 326  0
                 rawname = qName.getLocalPart();
 327  
             else
 328  0
                 rawname = prefix + ':' + qName.getLocalPart();
 329  0
             Attributes attrs = getAttributes();
 330  0
             filter.startElement(qName.getNamespaceURI(), qName.getLocalPart(), rawname, attrs);
 331  
         }
 332  0
         catch (SAXException e)
 333  
         {
 334  0
             throw new XMLStreamException(e);
 335  0
         }
 336  0
     }
 337  
 
 338  
     /**
 339  
      * Get the attributes associated with the given START_ELEMENT or ATTRIBUTE
 340  
      * StAXevent.
 341  
      * 
 342  
      * @return the StAX attributes converted to an org.xml.sax.Attributes
 343  
      */
 344  
     protected Attributes getAttributes()
 345  
     {
 346  0
         AttributesImpl attrs = new AttributesImpl();
 347  
 
 348  0
         int eventType = staxStreamReader.getEventType();
 349  0
         if (eventType != XMLStreamConstants.ATTRIBUTE && eventType != XMLStreamConstants.START_ELEMENT)
 350  
         {
 351  0
             throw new InternalError("getAttributes() attempting to process: " + eventType);
 352  
         }
 353  
 
 354  
         // Add namspace declarations if required
 355  0
         if (filter.getNamespacePrefixes())
 356  
         {
 357  0
             for (int i = 0; i < staxStreamReader.getNamespaceCount(); i++)
 358  
             {
 359  0
                 String uri = staxStreamReader.getNamespaceURI(i);
 360  0
                 if (uri == null) uri = "";
 361  
 
 362  0
                 String prefix = staxStreamReader.getNamespacePrefix(i);
 363  0
                 if (prefix == null) prefix = "";
 364  
 
 365  0
                 String qName = "xmlns";
 366  0
                 if (prefix.length() == 0)
 367  
                 {
 368  0
                     prefix = qName;
 369  
                 }
 370  
                 else
 371  
                 {
 372  0
                     qName = qName + ':' + prefix;
 373  
                 }
 374  0
                 attrs.addAttribute("http://www.w3.org/2000/xmlns/", prefix, qName, "CDATA", uri);
 375  
             }
 376  
         }
 377  
 
 378  
         // gather non-namespace attrs
 379  0
         for (int i = 0; i < staxStreamReader.getAttributeCount(); i++)
 380  
         {
 381  0
             String uri = staxStreamReader.getAttributeNamespace(i);
 382  0
             if (uri == null) uri = "";
 383  0
             String localName = staxStreamReader.getAttributeLocalName(i);
 384  0
             String prefix = staxStreamReader.getAttributePrefix(i);
 385  
             String qName;
 386  0
             if (prefix == null || prefix.length() == 0)
 387  0
                 qName = localName;
 388  
             else
 389  0
                 qName = prefix + ':' + localName;
 390  0
             String type = staxStreamReader.getAttributeType(i);
 391  0
             String value = staxStreamReader.getAttributeValue(i);
 392  
 
 393  0
             attrs.addAttribute(uri, localName, qName, type, value);
 394  
         }
 395  
 
 396  0
         return attrs;
 397  
     }
 398  
 
 399  
     protected void handleNamespace()
 400  
     {
 401  
         // no-op ???
 402  
         // namespace events don't normally occur outside of a startElement
 403  
         // or endElement
 404  0
     }
 405  
 
 406  
     protected void handleAttribute()
 407  
     {
 408  
         // no-op ???
 409  
         // attribute events don't normally occur outside of a startElement
 410  
         // or endElement
 411  0
     }
 412  
 
 413  
     protected void handleDTD()
 414  
     {
 415  
         // no-op ???
 416  
         // it seems like we need to pass this info along, but how?
 417  0
     }
 418  
 
 419  
     protected void handleComment() throws XMLStreamException
 420  
     {
 421  0
         char[] chars = staxStreamReader.getText().toCharArray();
 422  
         
 423  
         try
 424  
         {
 425  0
             filter.comment(chars, 0, chars.length);
 426  
         }
 427  0
         catch (SAXException e)
 428  
         {
 429  0
             throw new XMLStreamException(e);
 430  0
         }
 431  0
     }
 432  
 
 433  
     protected void handleEntityReference()
 434  
     {
 435  
         // no-op ???
 436  0
     }
 437  
 
 438  
     protected void handleSpace()
 439  
     {
 440  
         // no-op ???
 441  
         // this event is listed in the javadoc, but not in the spec.
 442  0
     }
 443  
 
 444  
     protected void handleNotationDecl()
 445  
     {
 446  
         // no-op ???
 447  
         // this event is listed in the javadoc, but not in the spec.
 448  0
     }
 449  
 
 450  
     protected void handleEntityDecl()
 451  
     {
 452  
         // no-op ???
 453  
         // this event is listed in the javadoc, but not in the spec.
 454  0
     }
 455  
 
 456  
     protected void handleCDATA() throws XMLStreamException
 457  
     {
 458  0
         char[] chars = staxStreamReader.getText().toCharArray();
 459  
 
 460  
         try
 461  
         {
 462  0
             filter.startCDATA();
 463  0
             filter.characters(chars, 0, chars.length);
 464  0
             filter.endCDATA();
 465  
         }
 466  0
         catch(SAXException e)
 467  
         {
 468  0
             throw new XMLStreamException(e);
 469  0
         }
 470  0
     }
 471  
 }