Coverage Report - org.mule.module.xml.stax.ReversibleXMLStreamReader
 
Classes in this File Line Coverage Branch Coverage Complexity
ReversibleXMLStreamReader
32%
69/213
18%
32/174
3.565
 
 1  
 /*
 2  
  * $Id$
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.module.xml.stax;
 12  
 
 13  
 import java.util.ArrayList;
 14  
 import java.util.List;
 15  
 
 16  
 import javanet.staxutils.events.AttributeEvent;
 17  
 import javanet.staxutils.events.CDataEvent;
 18  
 import javanet.staxutils.events.CharactersEvent;
 19  
 import javanet.staxutils.events.CommentEvent;
 20  
 import javanet.staxutils.events.EndDocumentEvent;
 21  
 import javanet.staxutils.events.EndElementEvent;
 22  
 import javanet.staxutils.events.NamespaceEvent;
 23  
 import javanet.staxutils.events.StartDocumentEvent;
 24  
 import javanet.staxutils.events.StartElementEvent;
 25  
 
 26  
 import javax.xml.namespace.NamespaceContext;
 27  
 import javax.xml.namespace.QName;
 28  
 import javax.xml.stream.Location;
 29  
 import javax.xml.stream.XMLStreamConstants;
 30  
 import javax.xml.stream.XMLStreamException;
 31  
 import javax.xml.stream.XMLStreamReader;
 32  
 import javax.xml.stream.events.Attribute;
 33  
 import javax.xml.stream.events.Namespace;
 34  
 import javax.xml.stream.events.XMLEvent;
 35  
 
 36  
 public class ReversibleXMLStreamReader extends DelegateXMLStreamReader
 37  
 {
 38  
     private List events;
 39  
     private XMLEvent current;
 40  
     private int replayIndex;
 41  4
     private boolean tracking = false;
 42  4
     private boolean replay = false;
 43  
     
 44  
     public ReversibleXMLStreamReader(XMLStreamReader reader)
 45  
     {
 46  4
         super(reader);
 47  4
     }
 48  
 
 49  
     public int nextTag() throws XMLStreamException
 50  
     {
 51  0
         int eventType = next();
 52  
         while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace())
 53  
                || (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
 54  
                || eventType == XMLStreamConstants.SPACE
 55  
                || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
 56  0
                || eventType == XMLStreamConstants.COMMENT)
 57  
         {
 58  0
             eventType = next();
 59  
         }
 60  0
         if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT)
 61  
         {
 62  0
             throw new XMLStreamException("expected start or end tag", getLocation());
 63  
         }
 64  0
         return eventType;
 65  
     }
 66  
 
 67  
     public void reset()
 68  
     {
 69  6
         replay = true;
 70  6
         replayIndex = 0;
 71  6
         current = null;
 72  6
     }
 73  
 
 74  
     public boolean isTracking()
 75  
     {
 76  0
         return tracking;
 77  
     }
 78  
 
 79  
     public void setTracking(boolean tracking)
 80  
     {
 81  4
         this.tracking = tracking;
 82  
         
 83  4
         if (tracking)
 84  
         {
 85  4
             replayIndex = 0;
 86  
             
 87  4
             if (events == null)
 88  
             {
 89  4
                 events = new ArrayList();
 90  
             }
 91  
         }
 92  4
     }
 93  
 
 94  
     public int next() throws XMLStreamException
 95  
     {
 96  
         int event;
 97  
 
 98  44
         if (replay)
 99  
         {
 100  22
             if (replayIndex == events.size())
 101  
             {
 102  2
                 replay = false;
 103  2
                 event = super.next();
 104  
             }
 105  
             else
 106  
             {
 107  20
                 event = getReplayEvent();
 108  
             }
 109  
         }
 110  
         else
 111  
         {
 112  22
             event = super.next();
 113  
         }
 114  
         
 115  44
         if (tracking && !replay) 
 116  
         {
 117  24
             capture(event);
 118  
         }
 119  
 
 120  44
         return event;
 121  
     }
 122  
 
 123  
     private int getReplayEvent()
 124  
     {
 125  20
         current = (XMLEvent) events.get(replayIndex);
 126  20
         replayIndex++;
 127  
 
 128  20
         return current.getEventType();
 129  
     }
 130  
 
 131  
     /**
 132  
      * Capture the current event;
 133  
      * 
 134  
      * @param event
 135  
      */
 136  
     private void capture(int event)
 137  
     {
 138  24
         switch (event)
 139  
         {
 140  
             case XMLStreamConstants.START_DOCUMENT :
 141  0
                 events.add(new StartDocumentEvent(getEncoding(), new Boolean(isStandalone()), getVersion(),
 142  
                     getLocation()));
 143  0
                 break;
 144  
             case XMLStreamConstants.END_DOCUMENT :
 145  4
                 events.add(new EndDocumentEvent(getLocation()));
 146  4
                 break;
 147  
             case XMLStreamConstants.START_ELEMENT :
 148  4
                 events.add(createStartElementEvent());
 149  4
                 break;
 150  
             case XMLStreamConstants.END_ELEMENT :
 151  4
                 events.add(new EndElementEvent(getName(), getNamespaces().iterator(), getLocation()));
 152  4
                 break;
 153  
             case XMLStreamConstants.CDATA :
 154  0
                 events.add(new CDataEvent(getText(), getLocation()));
 155  0
                 break;
 156  
             case XMLStreamConstants.CHARACTERS :
 157  4
                 events.add(new CharactersEvent(getText(), getLocation()));
 158  4
                 break;
 159  
             case XMLStreamConstants.COMMENT :
 160  0
                 events.add(new CommentEvent(getText(), getLocation()));
 161  0
                 break;
 162  
             case XMLStreamConstants.DTD :
 163  0
                 break;
 164  
             case XMLStreamConstants.ENTITY_DECLARATION :
 165  0
                 break;
 166  
             case XMLStreamConstants.ENTITY_REFERENCE :
 167  0
                 break;
 168  
             case XMLStreamConstants.NOTATION_DECLARATION :
 169  0
                 break;
 170  
             case XMLStreamConstants.PROCESSING_INSTRUCTION :
 171  0
                 break;
 172  
             case XMLStreamConstants.SPACE :
 173  
                 break;
 174  
         }
 175  24
     }
 176  
 
 177  
     private StartElementEvent createStartElementEvent()
 178  
     {
 179  4
         List attributes = new ArrayList();
 180  4
         for (int i = 0; i < getAttributeCount(); i++)
 181  
         {
 182  0
             attributes.add(new AttributeEvent(getAttributeName(i), getAttributeValue(i)));
 183  
         }
 184  
 
 185  4
         return new StartElementEventX(getName(), attributes, getNamespaces(),
 186  
             createContext(), getLocation(), null);
 187  
     }
 188  
 
 189  
     private NamespaceContext createContext()
 190  
     {
 191  4
         MapNamespaceContext ctx = new MapNamespaceContext();
 192  
 
 193  4
         for (int i = 0; i < getNamespaceCount(); i++)
 194  
         {
 195  0
             ctx.addNamespace(getNamespacePrefix(i), getNamespaceURI(i));
 196  
         }
 197  
 
 198  4
         return ctx;
 199  
     }
 200  
 
 201  
     private List getNamespaces()
 202  
     {
 203  8
         List namespaces = new ArrayList();
 204  8
         for (int i = 0; i < getNamespaceCount(); i++)
 205  
         {
 206  0
             namespaces.add(new NamespaceEvent(getNamespacePrefix(i), getNamespaceURI(i), getLocation()));
 207  
         }
 208  8
         return namespaces;
 209  
     }
 210  
 
 211  
     public String getElementText() throws XMLStreamException
 212  
     {
 213  0
         if (getEventType() != XMLStreamConstants.START_ELEMENT)
 214  
         {
 215  0
             throw new XMLStreamException("parser must be on START_ELEMENT to read next text", getLocation());
 216  
         }
 217  
 
 218  0
         int eventType = next();
 219  0
         StringBuffer buf = new StringBuffer();
 220  0
         while (eventType != XMLStreamConstants.END_ELEMENT)
 221  
         {
 222  0
             if (eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA
 223  
                 || eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.ENTITY_REFERENCE)
 224  
             {
 225  0
                 buf.append(getText());
 226  
             }
 227  0
             else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
 228  
                      || eventType == XMLStreamConstants.COMMENT)
 229  
             {
 230  
                 // skipping
 231  
             }
 232  0
             else if (eventType == XMLStreamConstants.END_DOCUMENT)
 233  
             {
 234  0
                 throw new XMLStreamException("unexpected end of document when reading element text content");
 235  
             }
 236  0
             else if (eventType == XMLStreamConstants.START_ELEMENT)
 237  
             {
 238  0
                 throw new XMLStreamException("element text content may not contain START_ELEMENT",
 239  
                     getLocation());
 240  
             }
 241  
             else
 242  
             {
 243  0
                 throw new XMLStreamException("Unexpected event type " + eventType, getLocation());
 244  
             }
 245  0
             eventType = next();
 246  
         }
 247  0
         return buf.toString();
 248  
 
 249  
     }
 250  
 
 251  
     public int getAttributeCount()
 252  
     {
 253  4
         if (replay)
 254  
         {
 255  0
             return ((StartElementEventX) current).getAttributeList().size();
 256  
         }
 257  
         else
 258  
         {
 259  4
             return super.getAttributeCount();
 260  
         }
 261  
     }
 262  
 
 263  
     public String getAttributeLocalName(int i)
 264  
     {
 265  
 
 266  0
         if (replay)
 267  
         {
 268  0
             Attribute att = (Attribute) ((StartElementEventX) current).getAttributeList().get(i);
 269  0
             return att.getName().getLocalPart();
 270  
         }
 271  
         else 
 272  
         {
 273  0
             return super.getAttributeLocalName(i);
 274  
         }
 275  
     }
 276  
 
 277  
     public QName getAttributeName(int i)
 278  
     {
 279  
 
 280  0
         if (replay)
 281  
         {
 282  0
             Attribute att = (Attribute) ((StartElementEventX) current).getAttributeList().get(i);
 283  0
             return att.getName();
 284  
         }
 285  
         else
 286  
         {
 287  0
             return super.getAttributeName(i);
 288  
         }
 289  
     }
 290  
 
 291  
     public String getAttributeNamespace(int i)
 292  
     {
 293  
 
 294  0
         if (replay)
 295  
         {
 296  0
             Attribute att = (Attribute) ((StartElementEventX) current).getAttributeList().get(i);
 297  0
             return att.getName().getNamespaceURI();
 298  
         }
 299  
         else
 300  
         {
 301  0
             return super.getAttributeNamespace(i);
 302  
         }
 303  
     }
 304  
 
 305  
     public String getAttributePrefix(int i)
 306  
     {
 307  0
         if (replay)
 308  
         {
 309  0
             Attribute att = (Attribute) ((StartElementEventX) current).getAttributeList().get(i);
 310  0
             return att.getName().getPrefix();
 311  
         }
 312  
         else
 313  
         {
 314  0
             return super.getAttributePrefix(i);
 315  
         }
 316  
     }
 317  
 
 318  
     public String getAttributeType(int i)
 319  
     {
 320  0
         if (replay)
 321  
         {
 322  0
             Attribute att = (Attribute) ((StartElementEventX) current).getAttributeList().get(i);
 323  0
             return att.getDTDType();
 324  
         }
 325  
         else
 326  
         {
 327  0
             return super.getAttributeType(i);
 328  
         }
 329  
     }
 330  
 
 331  
     public String getAttributeValue(int i)
 332  
     {
 333  0
         if (replay)
 334  
         {
 335  0
             Attribute att = (Attribute) ((StartElementEventX) current).getAttributeList().get(i);
 336  0
             return att.getValue();
 337  
         }
 338  
         else
 339  
         {
 340  0
             return super.getAttributeValue(i);
 341  
         }
 342  
     }
 343  
 
 344  
     public String getAttributeValue(String ns, String local)
 345  
     {
 346  0
         if (replay)
 347  
         {
 348  0
             Attribute att = ((StartElementEventX) current).getAttributeByName(new QName(ns, local));
 349  0
             if (att != null)
 350  
             {
 351  0
                 return att.getValue();
 352  
             }
 353  
             else
 354  
             {
 355  0
                 return null;
 356  
             }
 357  
         }
 358  
         else
 359  
         {
 360  0
             return super.getAttributeValue(ns, local);
 361  
         }
 362  
     }
 363  
 
 364  
     public int getEventType()
 365  
     {
 366  0
         if (replay)
 367  
         {
 368  0
             if (current == null)
 369  
             {
 370  0
                 return START_DOCUMENT;
 371  
             }
 372  0
             return current.getEventType();
 373  
         }
 374  
         else
 375  
         {
 376  0
             return super.getEventType();
 377  
         }
 378  
     }
 379  
 
 380  
     public String getLocalName()
 381  
     {
 382  2
         if (replay)
 383  
         {
 384  2
             if (isStartElement())
 385  
             {
 386  2
                 return ((StartElementEventX) current).getName().getLocalPart();
 387  
             }
 388  
             else 
 389  
             {
 390  0
                 return ((EndElementEvent) current).getName().getLocalPart();
 391  
             }
 392  
         }
 393  
         else
 394  
         {
 395  0
             return super.getLocalName();
 396  
         }
 397  
     }
 398  
 
 399  
     public Location getLocation()
 400  
     {
 401  16
         if (replay)
 402  
         {
 403  0
             return current.getLocation();
 404  
         }
 405  
         else
 406  
         {
 407  16
             return super.getLocation();
 408  
         }
 409  
     }
 410  
 
 411  
     public QName getName()
 412  
     {
 413  14
         if (replay)
 414  
         {
 415  4
             if (isStartElement())
 416  
             {
 417  4
                 return ((StartElementEventX) current).getName();
 418  
             }
 419  
             else 
 420  
             {
 421  0
                 return ((EndElementEvent) current).getName();
 422  
             }
 423  
         }
 424  
         else
 425  
         {
 426  10
             return super.getName();
 427  
         }
 428  
     }
 429  
 
 430  
     public NamespaceContext getNamespaceContext()
 431  
     {
 432  0
         if (replay)
 433  
         {
 434  0
             return ((StartElementEventX) current).getNamespaceContext();
 435  
         }
 436  
         else
 437  
         {
 438  0
             return super.getNamespaceContext();
 439  
         }
 440  
     }
 441  
 
 442  
     public int getNamespaceCount()
 443  
     {
 444  12
         if (replay)
 445  
         {
 446  0
             return ((StartElementEventX) current).getNamespaceList().size();
 447  
         }
 448  
         else
 449  
         {
 450  12
             return super.getNamespaceCount();
 451  
         }
 452  
     }
 453  
 
 454  
     public String getNamespacePrefix(int arg0)
 455  
     {
 456  0
         if (replay)
 457  
         {
 458  0
             Namespace ns = (Namespace) ((StartElementEventX) current).getNamespaceList().get(arg0);
 459  
             
 460  0
             return ns.getPrefix();
 461  
         }
 462  
         else
 463  
         {
 464  0
             return super.getNamespacePrefix(arg0);
 465  
         }
 466  
     }
 467  
 
 468  
     public String getNamespaceURI()
 469  
     {
 470  2
         if (replay)
 471  
         {
 472  2
             if (isStartElement())
 473  
             {
 474  2
                 return ((StartElementEventX) current).getName().getNamespaceURI();
 475  
             }
 476  
             else 
 477  
             {
 478  0
                 return ((EndElementEvent) current).getName().getNamespaceURI();
 479  
             }
 480  
         }
 481  
         else
 482  
         {
 483  0
             return super.getNamespaceURI();
 484  
         }
 485  
     }
 486  
 
 487  
     public String getNamespaceURI(int arg0)
 488  
     {
 489  0
         if (replay)
 490  
         {
 491  0
             Namespace ns = (Namespace) ((StartElementEventX) current).getNamespaceList().get(arg0);
 492  
             
 493  0
             return ns.getNamespaceURI();
 494  
         }
 495  
         else
 496  
         {
 497  0
             return super.getNamespaceURI(arg0);
 498  
         }
 499  
     }
 500  
 
 501  
     public String getNamespaceURI(String prefix)
 502  
     {
 503  0
         if (replay)
 504  
         {
 505  0
             return ((StartElementEventX) current).getNamespaceURI(prefix);
 506  
         }
 507  
         else
 508  
         {
 509  0
             return super.getNamespaceURI(prefix);
 510  
         }
 511  
     }
 512  
 
 513  
     public String getPIData()
 514  
     {
 515  0
         if (replay)
 516  
         {
 517  0
             return null;
 518  
         }
 519  
         else
 520  
         {
 521  0
             return super.getPIData();
 522  
         }
 523  
     }
 524  
 
 525  
     public String getPITarget()
 526  
     {
 527  0
         if (replay)
 528  
         {
 529  0
             return null;
 530  
         }
 531  
         else
 532  
         {
 533  0
             return super.getPITarget();
 534  
         }
 535  
     }
 536  
 
 537  
     public String getPrefix()
 538  
     {
 539  2
         if (replay)
 540  
         {
 541  2
             if (isStartElement())
 542  
             {
 543  2
                 return ((StartElementEventX) current).getName().getPrefix();
 544  
             }
 545  
             else 
 546  
             {
 547  0
                 return ((EndElementEvent) current).getName().getPrefix();
 548  
             }
 549  
         }
 550  
         else
 551  
         {
 552  0
             return super.getPrefix();
 553  
         }
 554  
     }
 555  
 
 556  
     public String getText()
 557  
     {
 558  10
         if (replay)
 559  
         {
 560  4
             return ((CharactersEvent) current).getData();
 561  
         }
 562  
         else
 563  
         {
 564  6
             return super.getText();
 565  
         }
 566  
     }
 567  
 
 568  
     public char[] getTextCharacters()
 569  
     {
 570  0
         if (replay)
 571  
         {
 572  0
             return ((CharactersEvent) current).getData().toCharArray();
 573  
         }
 574  
         else
 575  
         {
 576  0
             return super.getTextCharacters();
 577  
         }
 578  
     }
 579  
 
 580  
     public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException
 581  
     {
 582  0
         if (replay)
 583  
         {
 584  0
             char[] src = getText().toCharArray();
 585  
 
 586  0
             if (sourceStart + length >= src.length) {
 587  0
                 length = src.length - sourceStart;
 588  
             }
 589  
 
 590  0
             for (int i = 0; i < length; i++) {
 591  0
                 target[targetStart + i] = src[i + sourceStart];
 592  
             }
 593  
 
 594  0
             return length;
 595  
         }
 596  
         else
 597  
         {
 598  0
             return super.getTextCharacters(sourceStart, target, targetStart, length);
 599  
         }
 600  
     }
 601  
 
 602  
     public int getTextLength()
 603  
     {
 604  0
         if (replay)
 605  
         {
 606  0
             return getText().length();
 607  
         }
 608  
         else
 609  
         {
 610  0
             return super.getTextLength();
 611  
         }
 612  
     }
 613  
 
 614  
     public int getTextStart()
 615  
     {
 616  0
         if (replay)
 617  
         {
 618  0
             return 0;
 619  
         }
 620  
         else
 621  
         {
 622  0
             return super.getTextStart();
 623  
         }
 624  
     }
 625  
 
 626  
     public boolean hasName()
 627  
     {
 628  0
         if (replay)
 629  
         {
 630  0
             return isStartElement() || isEndElement();
 631  
         }
 632  
         else
 633  
         {
 634  0
             return super.hasName();
 635  
         }
 636  
     }
 637  
 
 638  
     public boolean hasNext() throws XMLStreamException
 639  
     {
 640  0
         if (replay)
 641  
         {
 642  0
             if (replayIndex == events.size()) 
 643  
             {
 644  0
                 return super.hasNext();
 645  
             }
 646  
             else
 647  
             {
 648  0
                 return true;
 649  
             }
 650  
         }
 651  
         else
 652  
         {
 653  0
             return super.hasNext();
 654  
         }
 655  
     }
 656  
 
 657  
     public boolean hasText()
 658  
     {
 659  0
         if (replay)
 660  
         {
 661  0
             int event = getEventType();
 662  0
             return event == CHARACTERS || event == DTD
 663  
                 || event == ENTITY_REFERENCE || event == COMMENT || event == SPACE;
 664  
         }
 665  
         else
 666  
         {
 667  0
             return super.hasText();
 668  
         }
 669  
     }
 670  
 
 671  
     public boolean isAttributeSpecified(int i)
 672  
     {
 673  0
         if (replay)
 674  
         {
 675  0
             Attribute attr = (Attribute) ((StartElementEventX) current).getAttributeList().get(i);
 676  0
             return attr.isSpecified();
 677  
         }
 678  
         else
 679  
         {
 680  0
             return super.isAttributeSpecified(i);
 681  
         }
 682  
     }
 683  
 
 684  
     public boolean isCharacters()
 685  
     {
 686  0
         if (replay)
 687  
         {
 688  0
             return current.isCharacters();
 689  
         }
 690  
         else
 691  
         {
 692  0
             return super.isCharacters();
 693  
         }
 694  
     }
 695  
 
 696  
     public boolean isEndElement()
 697  
     {
 698  0
         if (replay)
 699  
         {
 700  0
             return current.isEndElement();
 701  
         }
 702  
         else
 703  
         {
 704  0
             return super.isEndElement();
 705  
         }
 706  
     }
 707  
 
 708  
 
 709  
     public boolean isStartElement()
 710  
     {
 711  10
         if (replay)
 712  
         {
 713  10
             return current.isStartElement();
 714  
         }
 715  
         else
 716  
         {
 717  0
             return super.isStartElement();
 718  
         }
 719  
     }
 720  
 
 721  
     public boolean isWhiteSpace()
 722  
     {
 723  0
         if (replay)
 724  
         {
 725  0
             return current.getEventType() == SPACE;
 726  
         }
 727  
         else
 728  
         {
 729  0
             return super.isWhiteSpace();
 730  
         }
 731  
     }
 732  
 
 733  
 }