Save This Page
Home » openjdk-7 » com.sun.xml.internal » txw2 » output » [javadoc | source]
    1   /*
    2    * Copyright 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   //@@3RD PARTY CODE@@
   26   
   27   // DataWriter.java - XML writer for data-oriented files.
   28   
   29   package com.sun.xml.internal.txw2.output;
   30   
   31   import org.xml.sax.Attributes;
   32   import org.xml.sax.SAXException;
   33   
   34   import java.io.Writer;
   35   import java.util.Stack;
   36   
   37   
   38   /**
   39    * Write data- or field-oriented XML.
   40    *
   41    * <p>This filter pretty-prints field-oriented XML without mixed content.
   42    * all added indentation and newlines will be passed on down
   43    * the filter chain (if any).</p>
   44    *
   45    * <p>In general, all whitespace in an XML document is potentially
   46    * significant, so a general-purpose XML writing tool like the
   47    * {@link XMLWriter} class cannot
   48    * add newlines or indentation.</p>
   49    *
   50    * <p>There is, however, a large class of XML documents where information
   51    * is strictly fielded: each element contains either character data
   52    * or other elements, but not both.  For this special case, it is possible
   53    * for a writing tool to provide automatic indentation and newlines
   54    * without requiring extra work from the user.  Note that this class
   55    * will likely not yield appropriate results for document-oriented
   56    * XML like XHTML pages, which mix character data and elements together.</p>
   57    *
   58    * <p>This writer will automatically place each start tag on a new line,
   59    * optionally indented if an indent step is provided (by default, there
   60    * is no indentation).  If an element contains other elements, the end
   61    * tag will also appear on a new line with leading indentation.  Consider,
   62    * for example, the following code:</p>
   63    *
   64    * <pre>
   65    * DataWriter w = new DataWriter();
   66    *
   67    * w.setIndentStep(2);
   68    * w.startDocument();
   69    * w.startElement("Person");
   70    * w.dataElement("name", "Jane Smith");
   71    * w.dataElement("date-of-birth", "1965-05-23");
   72    * w.dataElement("citizenship", "US");
   73    * w.endElement("Person");
   74    * w.endDocument();
   75    * </pre>
   76    *
   77    * <p>This code will produce the following document:</p>
   78    *
   79    * <pre>
   80    * &lt;?xml version="1.0" standalone="yes"?>
   81    *
   82    * &lt;Person>
   83    *   &lt;name>Jane Smith&lt;/name>
   84    *   &lt;date-of-birth>1965-05-23&lt;/date-of-birth>
   85    *   &lt;citizenship>US&lt;/citizenship>
   86    * &lt;/Person>
   87    * </pre>
   88    *
   89    * <p>This class inherits from {@link XMLWriter},
   90    * and provides all of the same support for Namespaces.</p>
   91    *
   92    * @since 1.0
   93    * @author David Megginson, david@megginson.com
   94    * @see XMLWriter
   95    */
   96   public class DataWriter extends XMLWriter
   97   {
   98   
   99   
  100   
  101       ////////////////////////////////////////////////////////////////////
  102       // Constructors.
  103       ////////////////////////////////////////////////////////////////////
  104   
  105   
  106       /**
  107        * Create a new data writer for the specified output.
  108        *
  109        * @param writer The character stream where the XML document
  110        *        will be written.
  111        * @param encoding
  112        *      If non-null string is specified, it is written as a part
  113        *      of the XML declaration.
  114        */
  115       public DataWriter ( Writer writer, String encoding, CharacterEscapeHandler _escapeHandler )
  116       {
  117           super(writer,encoding,_escapeHandler);
  118       }
  119   
  120   
  121       public DataWriter (Writer writer, String encoding ) {
  122           this( writer, encoding, DumbEscapeHandler.theInstance );
  123       }
  124   
  125       public DataWriter (Writer writer) {
  126           this( writer, null, DumbEscapeHandler.theInstance );
  127       }
  128   
  129   
  130   
  131       ////////////////////////////////////////////////////////////////////
  132       // Accessors and setters.
  133       ////////////////////////////////////////////////////////////////////
  134   
  135   
  136       /**
  137        * Return the current indent step.
  138        *
  139        * <p>Return the current indent step: each start tag will be
  140        * indented by this number of spaces times the number of
  141        * ancestors that the element has.</p>
  142        *
  143        * @return The number of spaces in each indentation step,
  144        *         or 0 or less for no indentation.
  145        * @see #setIndentStep(int)
  146        *
  147        * @deprecated
  148        *      Only return the length of the indent string.
  149        */
  150       public int getIndentStep ()
  151       {
  152           return indentStep.length();
  153       }
  154   
  155   
  156       /**
  157        * Set the current indent step.
  158        *
  159        * @param indentStep The new indent step (0 or less for no
  160        *        indentation).
  161        * @see #getIndentStep()
  162        *
  163        * @deprecated
  164        *      Should use the version that takes string.
  165        */
  166       public void setIndentStep (int indentStep)
  167       {
  168           StringBuilder s = new StringBuilder();
  169           for( ; indentStep>0; indentStep-- )   s.append(' ');
  170           setIndentStep(s.toString());
  171       }
  172   
  173       public void setIndentStep(String s) {
  174           this.indentStep = s;
  175       }
  176   
  177   
  178   
  179       ////////////////////////////////////////////////////////////////////
  180       // Override methods from XMLWriter.
  181       ////////////////////////////////////////////////////////////////////
  182   
  183   
  184       /**
  185        * Reset the writer so that it can be reused.
  186        *
  187        * <p>This method is especially useful if the writer failed
  188        * with an exception the last time through.</p>
  189        *
  190        * @see XMLWriter#reset()
  191        */
  192       public void reset ()
  193       {
  194           depth = 0;
  195           state = SEEN_NOTHING;
  196           stateStack = new Stack();
  197           super.reset();
  198       }
  199   
  200   
  201       /**
  202        * Write a start tag.
  203        *
  204        * <p>Each tag will begin on a new line, and will be
  205        * indented by the current indent step times the number
  206        * of ancestors that the element has.</p>
  207        *
  208        * <p>The newline and indentation will be passed on down
  209        * the filter chain through regular characters events.</p>
  210        *
  211        * @param uri The element's Namespace URI.
  212        * @param localName The element's local name.
  213        * @param qName The element's qualified (prefixed) name.
  214        * @param atts The element's attribute list.
  215        * @exception org.xml.sax.SAXException If there is an error
  216        *            writing the start tag, or if a filter further
  217        *            down the chain raises an exception.
  218        * @see XMLWriter#startElement(String, String, String, Attributes)
  219        */
  220       public void startElement (String uri, String localName,
  221                                 String qName, Attributes atts)
  222           throws SAXException
  223       {
  224           stateStack.push(SEEN_ELEMENT);
  225           state = SEEN_NOTHING;
  226           if (depth > 0) {
  227               super.characters("\n");
  228           }
  229           doIndent();
  230           super.startElement(uri, localName, qName, atts);
  231           depth++;
  232       }
  233   
  234   
  235       /**
  236        * Write an end tag.
  237        *
  238        * <p>If the element has contained other elements, the tag
  239        * will appear indented on a new line; otherwise, it will
  240        * appear immediately following whatever came before.</p>
  241        *
  242        * <p>The newline and indentation will be passed on down
  243        * the filter chain through regular characters events.</p>
  244        *
  245        * @param uri The element's Namespace URI.
  246        * @param localName The element's local name.
  247        * @param qName The element's qualified (prefixed) name.
  248        * @exception org.xml.sax.SAXException If there is an error
  249        *            writing the end tag, or if a filter further
  250        *            down the chain raises an exception.
  251        * @see XMLWriter#endElement(String, String, String)
  252        */
  253       public void endElement (String uri, String localName, String qName)
  254           throws SAXException
  255       {
  256           depth--;
  257           if (state == SEEN_ELEMENT) {
  258               super.characters("\n");
  259               doIndent();
  260           }
  261           super.endElement(uri, localName, qName);
  262           state = stateStack.pop();
  263       }
  264   
  265   
  266   //    /**
  267   //     * Write a empty element tag.
  268   //     *
  269   //     * <p>Each tag will appear on a new line, and will be
  270   //     * indented by the current indent step times the number
  271   //     * of ancestors that the element has.</p>
  272   //     *
  273   //     * <p>The newline and indentation will be passed on down
  274   //     * the filter chain through regular characters events.</p>
  275   //     *
  276   //     * @param uri The element's Namespace URI.
  277   //     * @param localName The element's local name.
  278   //     * @param qName The element's qualified (prefixed) name.
  279   //     * @param atts The element's attribute list.
  280   //     * @exception org.xml.sax.SAXException If there is an error
  281   //     *            writing the empty tag, or if a filter further
  282   //     *            down the chain raises an exception.
  283   //     * @see XMLWriter#emptyElement(String, String, String, Attributes)
  284   //     */
  285   //    public void emptyElement (String uri, String localName,
  286   //                              String qName, Attributes atts)
  287   //        throws SAXException
  288   //    {
  289   //        state = SEEN_ELEMENT;
  290   //        if (depth > 0) {
  291   //            super.characters("\n");
  292   //        }
  293   //        doIndent();
  294   //        super.emptyElement(uri, localName, qName, atts);
  295   //    }
  296   
  297   
  298       /**
  299        * Write a sequence of characters.
  300        *
  301        * @param ch The characters to write.
  302        * @param start The starting position in the array.
  303        * @param length The number of characters to use.
  304        * @exception org.xml.sax.SAXException If there is an error
  305        *            writing the characters, or if a filter further
  306        *            down the chain raises an exception.
  307        * @see XMLWriter#characters(char[], int, int)
  308        */
  309       public void characters (char ch[], int start, int length)
  310           throws SAXException
  311       {
  312           state = SEEN_DATA;
  313           super.characters(ch, start, length);
  314       }
  315   
  316       public void comment(char ch[], int start, int length) throws SAXException {
  317           if (depth > 0) {
  318               super.characters("\n");
  319           }
  320           doIndent();
  321           super.comment(ch,start,length);
  322       }
  323   
  324   
  325   
  326       ////////////////////////////////////////////////////////////////////
  327       // Internal methods.
  328       ////////////////////////////////////////////////////////////////////
  329   
  330   
  331       /**
  332        * Print indentation for the current level.
  333        *
  334        * @exception org.xml.sax.SAXException If there is an error
  335        *            writing the indentation characters, or if a filter
  336        *            further down the chain raises an exception.
  337        */
  338       private void doIndent ()
  339           throws SAXException
  340       {
  341           if (depth > 0) {
  342               char[] ch = indentStep.toCharArray();
  343               for( int i=0; i<depth; i++ )
  344                   characters(ch, 0, ch.length);
  345           }
  346       }
  347   
  348   
  349   
  350       ////////////////////////////////////////////////////////////////////
  351       // Constants.
  352       ////////////////////////////////////////////////////////////////////
  353   
  354       private final static Object SEEN_NOTHING = new Object();
  355       private final static Object SEEN_ELEMENT = new Object();
  356       private final static Object SEEN_DATA = new Object();
  357   
  358   
  359   
  360       ////////////////////////////////////////////////////////////////////
  361       // Internal state.
  362       ////////////////////////////////////////////////////////////////////
  363   
  364       private Object state = SEEN_NOTHING;
  365       private Stack stateStack = new Stack();
  366   
  367       private String indentStep = "";
  368       private int depth = 0;
  369   
  370   }
  371   
  372   // end of DataWriter.java

Save This Page
Home » openjdk-7 » com.sun.xml.internal » txw2 » output » [javadoc | source]