jaxp/src/com/sun/org/apache/xml/internal/serialize/BaseMarkupSerializer.java
changeset 23777 ce87cedb71cf
parent 12457 c348e06f0e82
child 25834 aba3efbf4ec5
equal deleted inserted replaced
23776:e517d680b5cf 23777:ce87cedb71cf
     1 /*
     1 /*
     2  * reserved comment block
     2  * reserved comment block
     3  * DO NOT REMOVE OR ALTER!
     3  * DO NOT REMOVE OR ALTER!
     4  */
     4  */
     5 /*
     5 /*
     6  * Copyright 1999-2002,2004,2005 The Apache Software Foundation.
     6  * Licensed to the Apache Software Foundation (ASF) under one or more
     7  *
     7  * contributor license agreements.  See the NOTICE file distributed with
     8  * Licensed under the Apache License, Version 2.0 (the "License");
     8  * this work for additional information regarding copyright ownership.
     9  * you may not use this file except in compliance with the License.
     9  * The ASF licenses this file to You under the Apache License, Version 2.0
    10  * You may obtain a copy of the License at
    10  * (the "License"); you may not use this file except in compliance with
       
    11  * the License.  You may obtain a copy of the License at
    11  *
    12  *
    12  *      http://www.apache.org/licenses/LICENSE-2.0
    13  *      http://www.apache.org/licenses/LICENSE-2.0
    13  *
    14  *
    14  * Unless required by applicable law or agreed to in writing, software
    15  * Unless required by applicable law or agreed to in writing, software
    15  * distributed under the License is distributed on an "AS IS" BASIS,
    16  * distributed under the License is distributed on an "AS IS" BASIS,
    16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    17  * See the License for the specific language governing permissions and
    18  * See the License for the specific language governing permissions and
    18  * limitations under the License.
    19  * limitations under the License.
    19  */
    20  */
    20 
       
    21 
    21 
    22 // Sep 14, 2000:
    22 // Sep 14, 2000:
    23 //  Fixed comments to preserve whitespaces and add a line break
    23 //  Fixed comments to preserve whitespaces and add a line break
    24 //  when indenting. Reported by Gervase Markham <gerv@gerv.net>
    24 //  when indenting. Reported by Gervase Markham <gerv@gerv.net>
    25 // Sep 14, 2000:
    25 // Sep 14, 2000:
    55 
    55 
    56 import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl;
    56 import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl;
    57 import com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl;
    57 import com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl;
    58 import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
    58 import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
    59 import com.sun.org.apache.xerces.internal.util.XMLChar;
    59 import com.sun.org.apache.xerces.internal.util.XMLChar;
    60 import org.w3c.dom.DOMImplementation;
    60 import org.w3c.dom.DOMError;
       
    61 import org.w3c.dom.DOMErrorHandler;
    61 import org.w3c.dom.Document;
    62 import org.w3c.dom.Document;
    62 import org.w3c.dom.DocumentFragment;
    63 import org.w3c.dom.DocumentFragment;
    63 import org.w3c.dom.DocumentType;
    64 import org.w3c.dom.DocumentType;
    64 import org.w3c.dom.DOMError;
       
    65 import org.w3c.dom.DOMErrorHandler;
       
    66 import org.w3c.dom.Element;
    65 import org.w3c.dom.Element;
    67 import org.w3c.dom.Entity;
       
    68 import org.w3c.dom.NamedNodeMap;
       
    69 import org.w3c.dom.Node;
    66 import org.w3c.dom.Node;
    70 import org.w3c.dom.Notation;
       
    71 import org.w3c.dom.ls.LSException;
    67 import org.w3c.dom.ls.LSException;
    72 import org.w3c.dom.ls.LSSerializerFilter;
    68 import org.w3c.dom.ls.LSSerializerFilter;
    73 import org.w3c.dom.traversal.NodeFilter;
    69 import org.w3c.dom.traversal.NodeFilter;
    74 import org.xml.sax.ContentHandler;
    70 import org.xml.sax.ContentHandler;
    75 import org.xml.sax.DTDHandler;
    71 import org.xml.sax.DTDHandler;
   124  * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
   120  * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
   125  * @author <a href="mailto:rahul.srivastava@sun.com">Rahul Srivastava</a>
   121  * @author <a href="mailto:rahul.srivastava@sun.com">Rahul Srivastava</a>
   126  * @author Elena Litani, IBM
   122  * @author Elena Litani, IBM
   127  * @author Sunitha Reddy, Sun Microsystems
   123  * @author Sunitha Reddy, Sun Microsystems
   128  * @see Serializer
   124  * @see Serializer
   129  * @see LSSerializer
   125  * @see org.w3c.dom.ls.LSSerializer
   130  */
   126  */
   131 public abstract class BaseMarkupSerializer
   127 public abstract class BaseMarkupSerializer
   132     implements ContentHandler, DocumentHandler, LexicalHandler,
   128     implements ContentHandler, DocumentHandler, LexicalHandler,
   133                DTDHandler, DeclHandler, DOMSerializer, Serializer
   129                DTDHandler, DeclHandler, DOMSerializer, Serializer
   134 {
   130 {
   335         fCurrentNode = null;
   331         fCurrentNode = null;
   336         fStrBuffer.setLength(0);
   332         fStrBuffer.setLength(0);
   337         return true;
   333         return true;
   338     }
   334     }
   339 
   335 
       
   336     protected void cleanup() {
       
   337         fCurrentNode = null;
       
   338     }
   340 
   339 
   341     protected void prepare()
   340     protected void prepare()
   342         throws IOException
   341         throws IOException
   343     {
   342     {
   344         if ( _prepared )
   343         if ( _prepared )
   407         throws IOException
   406         throws IOException
   408     {
   407     {
   409         reset();
   408         reset();
   410         prepare();
   409         prepare();
   411         serializeNode( elem );
   410         serializeNode( elem );
       
   411         cleanup();
   412         _printer.flush();
   412         _printer.flush();
   413         if ( _printer.getException() != null )
   413         if ( _printer.getException() != null )
   414             throw _printer.getException();
   414             throw _printer.getException();
   415     }
   415     }
   416 
   416 
   436     /**
   436     /**
   437      * Serializes the DOM document fragmnt using the previously specified
   437      * Serializes the DOM document fragmnt using the previously specified
   438      * writer and output format. Throws an exception only if
   438      * writer and output format. Throws an exception only if
   439      * an I/O exception occured while serializing.
   439      * an I/O exception occured while serializing.
   440      *
   440      *
   441      * @param elem The element to serialize
   441      * @param frag The document fragment to serialize
   442      * @throws IOException An I/O exception occured while
   442      * @throws IOException An I/O exception occured while
   443      *   serializing
   443      *   serializing
   444      */
   444      */
   445     public void serialize( DocumentFragment frag )
   445     public void serialize( DocumentFragment frag )
   446         throws IOException
   446         throws IOException
   447     {
   447     {
   448         reset();
   448         reset();
   449         prepare();
   449         prepare();
   450         serializeNode( frag );
   450         serializeNode( frag );
       
   451         cleanup();
   451         _printer.flush();
   452         _printer.flush();
   452         if ( _printer.getException() != null )
   453         if ( _printer.getException() != null )
   453             throw _printer.getException();
   454             throw _printer.getException();
   454     }
   455     }
   455 
   456 
   468     {
   469     {
   469         reset();
   470         reset();
   470         prepare();
   471         prepare();
   471         serializeNode( doc );
   472         serializeNode( doc );
   472         serializePreRoot();
   473         serializePreRoot();
       
   474         cleanup();
   473         _printer.flush();
   475         _printer.flush();
   474         if ( _printer.getException() != null )
   476         if ( _printer.getException() != null )
   475             throw _printer.getException();
   477             throw _printer.getException();
   476     }
   478     }
   477 
   479 
   528                     continue;
   530                     continue;
   529                 }
   531                 }
   530                 if (!XMLChar.isValid(ch)) {
   532                 if (!XMLChar.isValid(ch)) {
   531                     // check if it is surrogate
   533                     // check if it is surrogate
   532                     if (++index < end) {
   534                     if (++index < end) {
   533                         surrogates(ch, chars[index]);
   535                         surrogates(ch, chars[index],true);
   534                     }
   536                     }
   535                     else {
   537                     else {
   536                         fatalError("The character '"+(char)ch+"' is an invalid XML character");
   538                         fatalError("The character '"+ch+"' is an invalid XML character");
   537                     }
   539                     }
   538                     continue;
   540                     continue;
   539                 } else {
   541                 }
   540                     if ( ( ch >= ' ' && _encodingInfo.isPrintable((char)ch) && ch != 0xF7 ) ||
   542                 if ( ( ch >= ' ' && _encodingInfo.isPrintable(ch) && ch != 0x7F ) ||
   541                         ch == '\n' || ch == '\r' || ch == '\t' ) {
   543                     ch == '\n' || ch == '\r' || ch == '\t' ) {
   542                         _printer.printText((char)ch);
   544                     _printer.printText(ch);
   543                     } else {
   545                 }
   544                         // The character is not printable -- split CDATA section
   546                 else {
   545                         _printer.printText("]]>&#x");
   547                     // The character is not printable -- split CDATA section
   546                         _printer.printText(Integer.toHexString(ch));
   548                     _printer.printText("]]>&#x");
   547                         _printer.printText(";<![CDATA[");
   549                     _printer.printText(Integer.toHexString(ch));
   548                     }
   550                     _printer.printText(";<![CDATA[");
   549                 }
   551                 }
   550             }
   552             }
   551             _printer.setNextIndent( saveIndent );
   553             _printer.setNextIndent( saveIndent );
   552 
   554 
   553         } else {
   555         } else {
  1193             serializeElement( (Element) node );
  1195             serializeElement( (Element) node );
  1194             break;
  1196             break;
  1195         }
  1197         }
  1196         case Node.DOCUMENT_NODE : {
  1198         case Node.DOCUMENT_NODE : {
  1197             DocumentType      docType;
  1199             DocumentType      docType;
  1198             DOMImplementation domImpl;
       
  1199             NamedNodeMap      map;
       
  1200             Entity            entity;
       
  1201             Notation          notation;
       
  1202             int               i;
       
  1203 
  1200 
  1204             serializeDocument();
  1201             serializeDocument();
  1205 
  1202 
  1206             // If there is a document type, use the SAX events to
  1203             // If there is a document type, use the SAX events to
  1207             // serialize it.
  1204             // serialize it.
  1208             docType = ( (Document) node ).getDoctype();
  1205             docType = ( (Document) node ).getDoctype();
  1209             if (docType != null) {
  1206             if (docType != null) {
  1210                 // DOM Level 2 (or higher)
  1207                 // DOM Level 2 (or higher)
  1211                 domImpl = ( (Document) node ).getImplementation();
       
  1212                 try {
  1208                 try {
  1213                     String internal;
  1209                     String internal;
  1214 
  1210 
  1215                     _printer.enterDTD();
  1211                     _printer.enterDTD();
  1216                     _docTypePublicId = docType.getPublicId();
  1212                     _docTypePublicId = docType.getPublicId();
  1370      * If the element was just opened, the opening tag is closed and
  1366      * If the element was just opened, the opening tag is closed and
  1371      * will be matched to a closing tag. Returns the current element
  1367      * will be matched to a closing tag. Returns the current element
  1372      * state with <tt>empty</tt> and <tt>afterElement</tt> set to false.
  1368      * state with <tt>empty</tt> and <tt>afterElement</tt> set to false.
  1373      *
  1369      *
  1374      * @return The current element state
  1370      * @return The current element state
  1375      * @throws IOException An I/O exception occured while
  1371      * @throws IOException An I/O exception occurred while
  1376      *   serializing
  1372      *   serializing
  1377      */
  1373      */
  1378     protected ElementState content()
  1374     protected ElementState content()
  1379         throws IOException
  1375         throws IOException
  1380     {
  1376     {
  1413      * for that purpose as well. White space handling is determined by the
  1409      * for that purpose as well. White space handling is determined by the
  1414      * current element state. In addition, the output format can dictate
  1410      * current element state. In addition, the output format can dictate
  1415      * whether the text is printed as CDATA or unescaped.
  1411      * whether the text is printed as CDATA or unescaped.
  1416      *
  1412      *
  1417      * @param text The text to print
  1413      * @param text The text to print
  1418      * @param unescaped True is should print unescaped
       
  1419      * @throws IOException An I/O exception occured while
  1414      * @throws IOException An I/O exception occured while
  1420      *   serializing
  1415      *   serializing
  1421      */
  1416      */
  1422     protected void characters( String text )
  1417     protected void characters( String text )
  1423         throws IOException
  1418         throws IOException
  1428         // Check if text should be print as CDATA section or unescaped
  1423         // Check if text should be print as CDATA section or unescaped
  1429         // based on elements listed in the output format (the element
  1424         // based on elements listed in the output format (the element
  1430         // state) or whether we are inside a CDATA section or entity.
  1425         // state) or whether we are inside a CDATA section or entity.
  1431 
  1426 
  1432         if ( state.inCData || state.doCData ) {
  1427         if ( state.inCData || state.doCData ) {
  1433             int          index;
       
  1434             int          saveIndent;
       
  1435 
       
  1436             // Print a CDATA section. The text is not escaped, but ']]>'
  1428             // Print a CDATA section. The text is not escaped, but ']]>'
  1437             // appearing in the code must be identified and dealt with.
  1429             // appearing in the code must be identified and dealt with.
  1438             // The contents of a text node is considered space preserving.
  1430             // The contents of a text node is considered space preserving.
  1439             if ( ! state.inCData ) {
  1431             if ( ! state.inCData ) {
  1440                 _printer.printText("<![CDATA[");
  1432                 _printer.printText("<![CDATA[");
  1441                 state.inCData = true;
  1433                 state.inCData = true;
  1442             }
  1434             }
  1443             saveIndent = _printer.getNextIndent();
  1435             int saveIndent = _printer.getNextIndent();
  1444             _printer.setNextIndent( 0 );
  1436             _printer.setNextIndent( 0 );
  1445             printCDATAText( text);
  1437             printCDATAText( text);
  1446             _printer.setNextIndent( saveIndent );
  1438             _printer.setNextIndent( saveIndent );
  1447 
  1439 
  1448         } else {
  1440         } else {
  1541                             // issue fatal error
  1533                             // issue fatal error
  1542                             modifyDOMError(msg, DOMError.SEVERITY_FATAL_ERROR, "wf-invalid-character", fCurrentNode);
  1534                             modifyDOMError(msg, DOMError.SEVERITY_FATAL_ERROR, "wf-invalid-character", fCurrentNode);
  1543                             fDOMErrorHandler.handleError(fDOMError);
  1535                             fDOMErrorHandler.handleError(fDOMError);
  1544                             throw new LSException(LSException.SERIALIZE_ERR, msg);
  1536                             throw new LSException(LSException.SERIALIZE_ERR, msg);
  1545                         }
  1537                         }
  1546                         else {
  1538                         // issue error
  1547                             // issue error
  1539                         modifyDOMError(msg, DOMError.SEVERITY_ERROR, "cdata-section-not-splitted", fCurrentNode);
  1548                             modifyDOMError(msg, DOMError.SEVERITY_ERROR, "cdata-section-not-splitted", fCurrentNode);
  1540                         if (!fDOMErrorHandler.handleError(fDOMError)) {
  1549                             if (!fDOMErrorHandler.handleError(fDOMError)) {
  1541                             throw new LSException(LSException.SERIALIZE_ERR, msg);
  1550                                 throw new LSException(LSException.SERIALIZE_ERR, msg);
       
  1551                             }
       
  1552                         }
  1542                         }
  1553                     } else {
  1543                     } else {
  1554                         // issue warning
  1544                         // issue warning
  1555                         String msg =
  1545                         String msg =
  1556                             DOMMessageFormatter.formatMessage(
  1546                             DOMMessageFormatter.formatMessage(
  1571             }
  1561             }
  1572 
  1562 
  1573             if (!XMLChar.isValid(ch)) {
  1563             if (!XMLChar.isValid(ch)) {
  1574                 // check if it is surrogate
  1564                 // check if it is surrogate
  1575                 if (++index <length) {
  1565                 if (++index <length) {
  1576                     surrogates(ch, text.charAt(index));
  1566                     surrogates(ch, text.charAt(index),true);
  1577                 }
  1567                 }
  1578                 else {
  1568                 else {
  1579                     fatalError("The character '"+(char)ch+"' is an invalid XML character");
  1569                     fatalError("The character '"+ch+"' is an invalid XML character");
  1580                 }
  1570                 }
  1581                 continue;
  1571                 continue;
  1582             } else {
  1572             }
  1583                 if ( ( ch >= ' ' && _encodingInfo.isPrintable((char)ch) && ch != 0xF7 ) ||
  1573             if ( ( ch >= ' ' && _encodingInfo.isPrintable(ch) && ch != 0x7F ) ||
  1584                      ch == '\n' || ch == '\r' || ch == '\t' ) {
  1574                  ch == '\n' || ch == '\r' || ch == '\t' ) {
  1585                     _printer.printText((char)ch);
  1575                 _printer.printText(ch);
  1586                 } else {
  1576             }
  1587 
  1577             else {
  1588                     // The character is not printable -- split CDATA section
  1578 
  1589                     _printer.printText("]]>&#x");
  1579                 // The character is not printable -- split CDATA section
  1590                     _printer.printText(Integer.toHexString(ch));
  1580                 _printer.printText("]]>&#x");
  1591                     _printer.printText(";<![CDATA[");
  1581                 _printer.printText(Integer.toHexString(ch));
  1592                 }
  1582                 _printer.printText(";<![CDATA[");
  1593             }
  1583             }
  1594         }
  1584         }
  1595     }
  1585     }
  1596 
  1586 
  1597 
  1587 
  1598     protected void surrogates(int high, int low) throws IOException{
  1588     protected void surrogates(int high, int low, boolean inContent) throws IOException{
  1599         if (XMLChar.isHighSurrogate(high)) {
  1589         if (XMLChar.isHighSurrogate(high)) {
  1600             if (!XMLChar.isLowSurrogate(low)) {
  1590             if (!XMLChar.isLowSurrogate(low)) {
  1601                 //Invalid XML
  1591                 //Invalid XML
  1602                 fatalError("The character '"+(char)low+"' is an invalid XML character");
  1592                 fatalError("The character '"+(char)low+"' is an invalid XML character");
  1603             }
  1593             }
  1606                 if (!XMLChar.isValid(supplemental)) {
  1596                 if (!XMLChar.isValid(supplemental)) {
  1607                     //Invalid XML
  1597                     //Invalid XML
  1608                     fatalError("The character '"+(char)supplemental+"' is an invalid XML character");
  1598                     fatalError("The character '"+(char)supplemental+"' is an invalid XML character");
  1609                 }
  1599                 }
  1610                 else {
  1600                 else {
  1611                     if (content().inCData ) {
  1601                     if (inContent && content().inCData) {
  1612                         _printer.printText("]]>&#x");
  1602                         _printer.printText("]]>&#x");
  1613                         _printer.printText(Integer.toHexString(supplemental));
  1603                         _printer.printText(Integer.toHexString(supplemental));
  1614                         _printer.printText(";<![CDATA[");
  1604                         _printer.printText(";<![CDATA[");
  1615                     }
  1605                     }
  1616                     else {
  1606                     else {
  1631      * for each new line. If spaces are not preserved, the text is
  1621      * for each new line. If spaces are not preserved, the text is
  1632      * broken at space boundaries if longer than the line width;
  1622      * broken at space boundaries if longer than the line width;
  1633      * Multiple spaces are printed as such, but spaces at beginning
  1623      * Multiple spaces are printed as such, but spaces at beginning
  1634      * of line are removed.
  1624      * of line are removed.
  1635      *
  1625      *
  1636      * @param text The text to print
  1626      * @param chars The text to print
       
  1627      * @param start The start offset
       
  1628      * @param length The number of characters
  1637      * @param preserveSpace Space preserving flag
  1629      * @param preserveSpace Space preserving flag
  1638      * @param unescaped Print unescaped
  1630      * @param unescaped Print unescaped
  1639      */
  1631      */
  1640     protected void printText( char[] chars, int start, int length,
  1632     protected void printText( char[] chars, int start, int length,
  1641                                     boolean preserveSpace, boolean unescaped )
  1633                                     boolean preserveSpace, boolean unescaped )
  1642         throws IOException
  1634         throws IOException
  1643     {
  1635     {
  1644         int index;
       
  1645         char ch;
       
  1646 
  1636 
  1647         if ( preserveSpace ) {
  1637         if ( preserveSpace ) {
  1648             // Preserving spaces: the text must print exactly as it is,
  1638             // Preserving spaces: the text must print exactly as it is,
  1649             // without breaking when spaces appear in the text and without
  1639             // without breaking when spaces appear in the text and without
  1650             // consolidating spaces. If a line terminator is used, a line
  1640             // consolidating spaces. If a line terminator is used, a line
  1651             // break will occur.
  1641             // break will occur.
  1652             while ( length-- > 0 ) {
  1642             while ( length-- > 0 ) {
  1653                 ch = chars[ start ];
  1643                 char ch = chars[ start ];
  1654                 ++start;
  1644                 ++start;
  1655                 if ( ch == '\n' || ch == '\r' || unescaped )
  1645                 if ( ch == '\n' || ch == '\r' || unescaped ) {
  1656                     _printer.printText( ch );
  1646                     _printer.printText( ch );
  1657                 else
  1647                 }
       
  1648                 else {
  1658                     printEscaped( ch );
  1649                     printEscaped( ch );
       
  1650                 }
  1659             }
  1651             }
  1660         } else {
  1652         } else {
  1661             // Not preserving spaces: print one part at a time, and
  1653             // Not preserving spaces: print one part at a time, and
  1662             // use spaces between parts to break them into different
  1654             // use spaces between parts to break them into different
  1663             // lines. Spaces at beginning of line will be stripped
  1655             // lines. Spaces at beginning of line will be stripped
  1664             // by printing mechanism. Line terminator is treated
  1656             // by printing mechanism. Line terminator is treated
  1665             // no different than other text part.
  1657             // no different than other text part.
  1666             while ( length-- > 0 ) {
  1658             while ( length-- > 0 ) {
  1667                 ch = chars[ start ];
  1659                 char ch = chars[ start ];
  1668                 ++start;
  1660                 ++start;
  1669                 if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' )
  1661                 if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' ) {
  1670                     _printer.printSpace();
  1662                     _printer.printSpace();
  1671                 else if ( unescaped )
  1663                 }
       
  1664                 else if ( unescaped ) {
  1672                     _printer.printText( ch );
  1665                     _printer.printText( ch );
  1673                 else
  1666                 }
       
  1667                 else {
  1674                     printEscaped( ch );
  1668                     printEscaped( ch );
       
  1669                 }
  1675             }
  1670             }
  1676         }
  1671         }
  1677     }
  1672     }
  1678 
  1673 
  1679 
  1674 
  1701             // lines. Spaces at beginning of line will be stripped
  1696             // lines. Spaces at beginning of line will be stripped
  1702             // by printing mechanism. Line terminator is treated
  1697             // by printing mechanism. Line terminator is treated
  1703             // no different than other text part.
  1698             // no different than other text part.
  1704             for ( index = 0 ; index < text.length() ; ++index ) {
  1699             for ( index = 0 ; index < text.length() ; ++index ) {
  1705                 ch = text.charAt( index );
  1700                 ch = text.charAt( index );
  1706                 if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' )
  1701                 if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' ) {
  1707                     _printer.printSpace();
  1702                     _printer.printSpace();
  1708                 else if ( unescaped )
  1703                 }
       
  1704                 else if ( unescaped ) {
  1709                     _printer.printText( ch );
  1705                     _printer.printText( ch );
  1710                 else
  1706                 }
       
  1707                 else {
  1711                     printEscaped( ch );
  1708                     printEscaped( ch );
       
  1709                 }
  1712             }
  1710             }
  1713         }
  1711         }
  1714     }
  1712     }
  1715 
  1713 
  1716 
  1714 
  1749         charRef = getEntityRef( ch );
  1747         charRef = getEntityRef( ch );
  1750         if ( charRef != null ) {
  1748         if ( charRef != null ) {
  1751             _printer.printText( '&' );
  1749             _printer.printText( '&' );
  1752             _printer.printText( charRef );
  1750             _printer.printText( charRef );
  1753             _printer.printText( ';' );
  1751             _printer.printText( ';' );
  1754         } else if ( ( ch >= ' ' && _encodingInfo.isPrintable((char)ch) && ch != 0xF7 ) ||
  1752         } else if ( ( ch >= ' ' && _encodingInfo.isPrintable((char)ch) && ch != 0x7F ) ||
  1755                     ch == '\n' || ch == '\r' || ch == '\t' ) {
  1753                     ch == '\n' || ch == '\r' || ch == '\t' ) {
  1756             // Non printables are below ASCII space but not tab or line
  1754             // Non printables are below ASCII space but not tab or line
  1757             // terminator, ASCII delete, or above a certain Unicode threshold.
  1755             // terminator, ASCII delete, or above a certain Unicode threshold.
  1758             if (ch < 0x10000) {
  1756             if (ch < 0x10000) {
  1759                 _printer.printText((char)ch );
  1757                 _printer.printText((char)ch );
  1870      */
  1868      */
  1871     protected ElementState leaveElementState()
  1869     protected ElementState leaveElementState()
  1872     {
  1870     {
  1873         if ( _elementStateCount > 0 ) {
  1871         if ( _elementStateCount > 0 ) {
  1874             /*Corrected by David Blondeau (blondeau@intalio.com)*/
  1872             /*Corrected by David Blondeau (blondeau@intalio.com)*/
  1875                 _prefixes = null;
  1873             _prefixes = null;
  1876                 //_prefixes = _elementStates[ _elementStateCount ].prefixes;
  1874             //_prefixes = _elementStates[ _elementStateCount ].prefixes;
  1877             -- _elementStateCount;
  1875             -- _elementStateCount;
  1878             return _elementStates[ _elementStateCount ];
  1876             return _elementStates[ _elementStateCount ];
  1879         } else {
  1877         }
  1880             String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.SERIALIZER_DOMAIN, "Internal", null);
  1878         String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.SERIALIZER_DOMAIN, "Internal", null);
  1881             throw new IllegalStateException(msg);
  1879         throw new IllegalStateException(msg);
  1882         }
       
  1883     }
  1880     }
  1884 
  1881 
  1885 
  1882 
  1886     /**
  1883     /**
  1887      * Returns true if in the state of the document.
  1884      * Returns true if in the state of the document.
  1888      * Returns true before entering any element and after
  1885      * Returns true before entering any element and after
  1889      * leaving the root element.
  1886      * leaving the root element.
  1890      *
  1887      *
  1891      * @return True if in the state of the document
  1888      * @return True if in the state of the document
  1892      */
  1889      */
  1893     protected boolean isDocumentState()
  1890     protected boolean isDocumentState() {
  1894     {
       
  1895         return _elementStateCount == 0;
  1891         return _elementStateCount == 0;
  1896     }
  1892     }
  1897 
  1893 
       
  1894     /** Clears document state. **/
       
  1895     final void clearDocumentState() {
       
  1896         _elementStateCount = 0;
       
  1897     }
  1898 
  1898 
  1899     /**
  1899     /**
  1900      * Returns the namespace prefix for the specified URI.
  1900      * Returns the namespace prefix for the specified URI.
  1901      * If the URI has been mapped to a prefix, returns the
  1901      * If the URI has been mapped to a prefix, returns the
  1902      * prefix, otherwise returns null.
  1902      * prefix, otherwise returns null.
  1911         if ( _prefixes != null ) {
  1911         if ( _prefixes != null ) {
  1912             prefix = (String) _prefixes.get( namespaceURI );
  1912             prefix = (String) _prefixes.get( namespaceURI );
  1913             if ( prefix != null )
  1913             if ( prefix != null )
  1914                 return prefix;
  1914                 return prefix;
  1915         }
  1915         }
  1916         if ( _elementStateCount == 0 )
  1916         if ( _elementStateCount == 0 ) {
  1917             return null;
  1917             return null;
  1918         else {
  1918         }
  1919             for ( int i = _elementStateCount ; i > 0 ; --i ) {
  1919         for ( int i = _elementStateCount ; i > 0 ; --i ) {
  1920                 if ( _elementStates[ i ].prefixes != null ) {
  1920             if ( _elementStates[ i ].prefixes != null ) {
  1921                     prefix = (String) _elementStates[ i ].prefixes.get( namespaceURI );
  1921                 prefix = (String) _elementStates[ i ].prefixes.get( namespaceURI );
  1922                     if ( prefix != null )
  1922                 if ( prefix != null )
  1923                         return prefix;
  1923                     return prefix;
  1924                 }
       
  1925             }
  1924             }
  1926         }
  1925         }
  1927         return null;
  1926         return null;
  1928     }
  1927     }
  1929 
  1928