Save This Page
Home » openjdk-7 » com.sun.org.apache.xalan » internal » xsltc » trax » [javadoc | source]
    1   /*
    2    * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package com.sun.org.apache.xalan.internal.xsltc.trax;
   27   
   28   import java.io.IOException;
   29   import java.util.Iterator;
   30   
   31   import org.xml.sax.Attributes;
   32   import org.xml.sax.ContentHandler;
   33   import org.xml.sax.DTDHandler;
   34   import org.xml.sax.EntityResolver;
   35   import org.xml.sax.ErrorHandler;
   36   import org.xml.sax.InputSource;
   37   import org.xml.sax.Locator;
   38   import org.xml.sax.SAXException;
   39   import org.xml.sax.SAXNotRecognizedException;
   40   import org.xml.sax.SAXNotSupportedException;
   41   import org.xml.sax.XMLReader;
   42   import org.xml.sax.ext.LexicalHandler;
   43   import org.xml.sax.helpers.AttributesImpl;
   44   import org.xml.sax.ext.Locator2;
   45   import com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl;
   46   
   47   import javax.xml.namespace.QName;
   48   import javax.xml.stream.XMLEventReader;
   49   import javax.xml.stream.XMLStreamConstants;
   50   import javax.xml.stream.XMLStreamException;
   51   import javax.xml.stream.events.Attribute;
   52   import javax.xml.stream.events.Characters;
   53   import javax.xml.stream.events.EndElement;
   54   import javax.xml.stream.events.Namespace;
   55   import javax.xml.stream.events.ProcessingInstruction;
   56   import javax.xml.stream.events.StartElement;
   57   import javax.xml.stream.events.XMLEvent;
   58   import javax.xml.stream.events.StartDocument;
   59   
   60   
   61   /**
   62    * @author Suresh Kumar
   63    * @author Sunitha Reddy
   64    * @since 1.6
   65    */
   66   public class StAXEvent2SAX implements XMLReader, Locator {
   67   
   68       //private final static String EMPTYSTRING = "";
   69       //private static final String XMLNS_PREFIX = "xmlns";
   70   
   71       // StAX event source
   72       private final XMLEventReader staxEventReader;
   73   
   74       //private Node _dom = null;
   75       private ContentHandler _sax = null;
   76       private LexicalHandler _lex = null;
   77       private SAXImpl _saxImpl = null;
   78       //private Hashtable _nsPrefixes = new Hashtable();
   79       private String version = null;
   80       private String encoding = null;
   81   
   82   
   83       public StAXEvent2SAX(XMLEventReader staxCore) {
   84           staxEventReader = staxCore;
   85       }
   86   
   87       public ContentHandler getContentHandler() {
   88           return _sax;
   89       }
   90   
   91       public void setContentHandler(ContentHandler handler) throws
   92           NullPointerException
   93       {
   94           _sax = handler;
   95           if (handler instanceof LexicalHandler) {
   96               _lex = (LexicalHandler) handler;
   97           }
   98   
   99           if (handler instanceof SAXImpl) {
  100               _saxImpl = (SAXImpl)handler;
  101           }
  102       }
  103   
  104   
  105       public void parse(InputSource unused) throws IOException, SAXException {
  106          try {
  107               bridge();
  108           } catch (XMLStreamException e) {
  109               throw new SAXException(e);
  110           }
  111       }
  112   
  113   
  114       //Main Work Starts Here.
  115       public void parse() throws IOException, SAXException, XMLStreamException {
  116           bridge();
  117       }
  118   
  119   
  120       /*  public void parse() throws IOException, SAXException {
  121           if (_dom != null) {
  122               boolean isIncomplete =
  123                   (_dom.getNodeType() != org.w3c.dom.Node.DOCUMENT_NODE);
  124   
  125               if (isIncomplete) {
  126                   _sax.startDocument();
  127                   parse(_dom);
  128                   _sax.endDocument();
  129               }
  130               else {
  131                   parse(_dom);
  132               }
  133           }
  134       }
  135       */
  136   
  137       /*
  138        * @see StAXReaderToContentHandler#bridge()
  139        */
  140       private void bridge() throws XMLStreamException {
  141   
  142           try {
  143               // remembers the nest level of elements to know when we are done.
  144               int depth=0;
  145               boolean startedAtDocument = false;
  146   
  147               XMLEvent event = staxEventReader.peek();
  148   
  149               if (!event.isStartDocument() && !event.isStartElement()) {
  150                   throw new IllegalStateException();
  151               }
  152   
  153               if (event.getEventType() == XMLStreamConstants.START_DOCUMENT){
  154                   startedAtDocument = true;
  155                   version = ((StartDocument)event).getVersion();
  156                   if (((StartDocument)event).encodingSet())
  157                       encoding = ((StartDocument)event).getCharacterEncodingScheme();
  158                   event=staxEventReader.nextEvent(); // that gets the one we peeked at
  159                   event=staxEventReader.nextEvent(); // that really gets the next one
  160               }
  161   
  162               handleStartDocument(event);
  163   
  164               // Handle the prolog: http://www.w3.org/TR/REC-xml/#NT-prolog
  165               while (event.getEventType() != XMLStreamConstants.START_ELEMENT) {
  166                   switch (event.getEventType()) {
  167                       case XMLStreamConstants.CHARACTERS :
  168                           handleCharacters(event.asCharacters());
  169                           break;
  170                       case XMLStreamConstants.PROCESSING_INSTRUCTION :
  171                           handlePI((ProcessingInstruction)event);
  172                           break;
  173                       case XMLStreamConstants.COMMENT :
  174                           handleComment();
  175                           break;
  176                       case XMLStreamConstants.DTD :
  177                           handleDTD();
  178                           break;
  179                       case XMLStreamConstants.SPACE :
  180                           handleSpace();
  181                           break;
  182                       default :
  183                           throw new InternalError("processing prolog event: " + event);
  184                   }
  185                   event=staxEventReader.nextEvent();
  186               }
  187   
  188               // Process the (document) element
  189               do {
  190                   // These are all of the events listed in the javadoc for
  191                   // XMLEvent.
  192                   // The spec only really describes 11 of them.
  193                   switch (event.getEventType()) {
  194                       case XMLStreamConstants.START_ELEMENT :
  195                           depth++;
  196                           handleStartElement(event.asStartElement());
  197                           break;
  198                       case XMLStreamConstants.END_ELEMENT :
  199                           handleEndElement(event.asEndElement());
  200                           depth--;
  201                           break;
  202                       case XMLStreamConstants.CHARACTERS :
  203                           handleCharacters(event.asCharacters());
  204                           break;
  205                       case XMLStreamConstants.ENTITY_REFERENCE :
  206                           handleEntityReference();
  207                           break;
  208                       case XMLStreamConstants.PROCESSING_INSTRUCTION :
  209                           handlePI((ProcessingInstruction)event);
  210                           break;
  211                       case XMLStreamConstants.COMMENT :
  212                           handleComment();
  213                           break;
  214                       case XMLStreamConstants.DTD :
  215                           handleDTD();
  216                           break;
  217                       case XMLStreamConstants.ATTRIBUTE :
  218                           handleAttribute();
  219                           break;
  220                       case XMLStreamConstants.NAMESPACE :
  221                           handleNamespace();
  222                           break;
  223                       case XMLStreamConstants.CDATA :
  224                           handleCDATA();
  225                           break;
  226                       case XMLStreamConstants.ENTITY_DECLARATION :
  227                           handleEntityDecl();
  228                           break;
  229                       case XMLStreamConstants.NOTATION_DECLARATION :
  230                           handleNotationDecl();
  231                           break;
  232                       case XMLStreamConstants.SPACE :
  233                           handleSpace();
  234                           break;
  235                       default :
  236                           throw new InternalError("processing event: " + event);
  237                   }
  238   
  239                   event=staxEventReader.nextEvent();
  240               } while (depth!=0);
  241   
  242               if (startedAtDocument) {
  243                   // Handle the Misc (http://www.w3.org/TR/REC-xml/#NT-Misc) that can follow the document element
  244                   while (event.getEventType() != XMLStreamConstants.END_DOCUMENT) {
  245                       switch (event.getEventType()) {
  246                           case XMLStreamConstants.CHARACTERS :
  247                               handleCharacters(event.asCharacters());
  248                               break;
  249                           case XMLStreamConstants.PROCESSING_INSTRUCTION :
  250                               handlePI((ProcessingInstruction)event);
  251                               break;
  252                           case XMLStreamConstants.COMMENT :
  253                               handleComment();
  254                               break;
  255                           case XMLStreamConstants.SPACE :
  256                               handleSpace();
  257                               break;
  258                           default :
  259                               throw new InternalError("processing misc event after document element: " + event);
  260                       }
  261                       event=staxEventReader.nextEvent();
  262                   }
  263               }
  264   
  265               handleEndDocument();
  266           } catch (SAXException e) {
  267               throw new XMLStreamException(e);
  268           }
  269       }
  270   
  271   
  272       private void handleEndDocument() throws SAXException {
  273           _sax.endDocument();
  274       }
  275   
  276       private void handleStartDocument(final XMLEvent event) throws SAXException {
  277           _sax.setDocumentLocator(new Locator2() {
  278               public int getColumnNumber() {
  279                   return event.getLocation().getColumnNumber();
  280               }
  281               public int getLineNumber() {
  282                   return event.getLocation().getLineNumber();
  283               }
  284               public String getPublicId() {
  285                   return event.getLocation().getPublicId();
  286               }
  287               public String getSystemId() {
  288                   return event.getLocation().getSystemId();
  289               }
  290               public String getXMLVersion(){
  291                   return version;
  292               }
  293               public String getEncoding(){
  294                   return encoding;
  295               }
  296   
  297           });
  298           _sax.startDocument();
  299       }
  300   
  301       private void handlePI(ProcessingInstruction event)
  302           throws XMLStreamException {
  303           try {
  304               _sax.processingInstruction(
  305                   event.getTarget(),
  306                   event.getData());
  307           } catch (SAXException e) {
  308               throw new XMLStreamException(e);
  309           }
  310       }
  311   
  312       private void handleCharacters(Characters event) throws XMLStreamException {
  313           try {
  314               _sax.characters(
  315                   event.getData().toCharArray(),
  316                   0,
  317                   event.getData().length());
  318           } catch (SAXException e) {
  319               throw new XMLStreamException(e);
  320           }
  321       }
  322   
  323       private void handleEndElement(EndElement event) throws XMLStreamException {
  324           QName qName = event.getName();
  325   
  326           //construct prefix:localName from qName
  327           String qname = "";
  328           if (qName.getPrefix() != null && qName.getPrefix().trim().length() != 0){
  329               qname = qName.getPrefix() + ":";
  330           }
  331           qname += qName.getLocalPart();
  332   
  333           try {
  334               // fire endElement
  335               _sax.endElement(
  336                   qName.getNamespaceURI(),
  337                   qName.getLocalPart(),
  338                   qname);
  339   
  340               // end namespace bindings
  341               for( Iterator i = event.getNamespaces(); i.hasNext();) {
  342                   String prefix = (String)i.next();
  343                   if( prefix == null ) { // true for default namespace
  344                       prefix = "";
  345                   }
  346                   _sax.endPrefixMapping(prefix);
  347               }
  348           } catch (SAXException e) {
  349               throw new XMLStreamException(e);
  350           }
  351       }
  352   
  353       private void handleStartElement(StartElement event)
  354           throws XMLStreamException {
  355           try {
  356               // start namespace bindings
  357               for (Iterator i = event.getNamespaces(); i.hasNext();) {
  358                   String prefix = ((Namespace)i.next()).getPrefix();
  359                   if (prefix == null) { // true for default namespace
  360                       prefix = "";
  361                   }
  362                   _sax.startPrefixMapping(
  363                       prefix,
  364                       event.getNamespaceURI(prefix));
  365               }
  366   
  367               // fire startElement
  368               QName qName = event.getName();
  369               String prefix = qName.getPrefix();
  370               String rawname;
  371               if (prefix == null || prefix.length() == 0) {
  372                   rawname = qName.getLocalPart();
  373               } else {
  374                   rawname = prefix + ':' + qName.getLocalPart();
  375               }
  376   
  377               Attributes saxAttrs = getAttributes(event);
  378               _sax.startElement(
  379                   qName.getNamespaceURI(),
  380                   qName.getLocalPart(),
  381                   rawname,
  382                   saxAttrs);
  383           } catch (SAXException e) {
  384               throw new XMLStreamException(e);
  385           }
  386       }
  387   
  388       /**
  389        * Get the attributes associated with the given START_ELEMENT StAXevent.
  390        *
  391        * @return the StAX attributes converted to an org.xml.sax.Attributes
  392        */
  393       private Attributes getAttributes(StartElement event) {
  394           AttributesImpl attrs = new AttributesImpl();
  395   
  396           if ( !event.isStartElement() ) {
  397               throw new InternalError(
  398                   "getAttributes() attempting to process: " + event);
  399           }
  400   
  401           // in SAX, namespace declarations are not part of attributes by default.
  402           // (there's a property to control that, but as far as we are concerned
  403           // we don't use it.) So don't add xmlns:* to attributes.
  404   
  405           // gather non-namespace attrs
  406           for (Iterator i = event.getAttributes(); i.hasNext();) {
  407               Attribute staxAttr = (javax.xml.stream.events.Attribute)i.next();
  408   
  409               String uri = staxAttr.getName().getNamespaceURI();
  410               if (uri == null) {
  411                   uri = "";
  412               }
  413               String localName = staxAttr.getName().getLocalPart();
  414               String prefix = staxAttr.getName().getPrefix();
  415               String qName;
  416               if (prefix == null || prefix.length() == 0) {
  417                   qName = localName;
  418               } else {
  419                   qName = prefix + ':' + localName;
  420               }
  421               String type = staxAttr.getDTDType();
  422               String value = staxAttr.getValue();
  423   
  424               attrs.addAttribute(uri, localName, qName, type, value);
  425           }
  426   
  427           return attrs;
  428       }
  429   
  430       private void handleNamespace() {
  431           // no-op ???
  432           // namespace events don't normally occur outside of a startElement
  433           // or endElement
  434       }
  435   
  436       private void handleAttribute() {
  437           // no-op ???
  438           // attribute events don't normally occur outside of a startElement
  439           // or endElement
  440       }
  441   
  442       private void handleDTD() {
  443           // no-op ???
  444           // it seems like we need to pass this info along, but how?
  445       }
  446   
  447       private void handleComment() {
  448           // no-op ???
  449       }
  450   
  451       private void handleEntityReference() {
  452           // no-op ???
  453       }
  454   
  455       private void handleSpace() {
  456           // no-op ???
  457           // this event is listed in the javadoc, but not in the spec.
  458       }
  459   
  460       private void handleNotationDecl() {
  461           // no-op ???
  462           // this event is listed in the javadoc, but not in the spec.
  463       }
  464   
  465       private void handleEntityDecl() {
  466           // no-op ???
  467           // this event is listed in the javadoc, but not in the spec.
  468       }
  469   
  470       private void handleCDATA() {
  471           // no-op ???
  472           // this event is listed in the javadoc, but not in the spec.
  473       }
  474   
  475   
  476       /**
  477        * This class is only used internally so this method should never
  478        * be called.
  479        */
  480       public DTDHandler getDTDHandler() {
  481           return null;
  482       }
  483   
  484       /**
  485        * This class is only used internally so this method should never
  486        * be called.
  487        */
  488       public ErrorHandler getErrorHandler() {
  489           return null;
  490       }
  491   
  492       /**
  493        * This class is only used internally so this method should never
  494        * be called.
  495        */
  496       public boolean getFeature(String name) throws SAXNotRecognizedException,
  497           SAXNotSupportedException
  498       {
  499           return false;
  500       }
  501   
  502       /**
  503        * This class is only used internally so this method should never
  504        * be called.
  505        */
  506       public void setFeature(String name, boolean value) throws
  507           SAXNotRecognizedException, SAXNotSupportedException
  508       {
  509       }
  510   
  511       /**
  512        * This class is only used internally so this method should never
  513        * be called.
  514        */
  515       public void parse(String sysId) throws IOException, SAXException {
  516           throw new IOException("This method is not yet implemented.");
  517       }
  518   
  519       /**
  520        * This class is only used internally so this method should never
  521        * be called.
  522        */
  523       public void setDTDHandler(DTDHandler handler) throws NullPointerException {
  524       }
  525   
  526       /**
  527        * This class is only used internally so this method should never
  528        * be called.
  529        */
  530       public void setEntityResolver(EntityResolver resolver) throws
  531           NullPointerException
  532       {
  533       }
  534   
  535       /**
  536        * This class is only used internally so this method should never
  537        * be called.
  538        */
  539       public EntityResolver getEntityResolver() {
  540           return null;
  541       }
  542   
  543       /**
  544        * This class is only used internally so this method should never
  545        * be called.
  546        */
  547       public void setErrorHandler(ErrorHandler handler) throws
  548           NullPointerException
  549       {
  550       }
  551   
  552       /**
  553        * This class is only used internally so this method should never
  554        * be called.
  555        */
  556       public void setProperty(String name, Object value) throws
  557           SAXNotRecognizedException, SAXNotSupportedException {
  558       }
  559   
  560       /**
  561        * This class is only used internally so this method should never
  562        * be called.
  563        */
  564       public Object getProperty(String name) throws SAXNotRecognizedException,
  565           SAXNotSupportedException
  566       {
  567           return null;
  568       }
  569   
  570       /**
  571        * This class is only used internally so this method should never
  572        * be called.
  573        */
  574       public int getColumnNumber() {
  575           return 0;
  576       }
  577   
  578       /**
  579        * This class is only used internally so this method should never
  580        * be called.
  581        */
  582       public int getLineNumber() {
  583           return 0;
  584       }
  585   
  586       /**
  587        * This class is only used internally so this method should never
  588        * be called.
  589        */
  590       public String getPublicId() {
  591           return null;
  592       }
  593   
  594       /**
  595        * This class is only used internally so this method should never
  596        * be called.
  597        */
  598       public String getSystemId() {
  599           return null;
  600       }
  601   }

Save This Page
Home » openjdk-7 » com.sun.org.apache.xalan » internal » xsltc » trax » [javadoc | source]