jdk/src/share/classes/javax/swing/text/AbstractWriter.java
author darcy
Thu, 27 Aug 2009 11:48:35 -0700
changeset 3709 e7cf22d025bb
parent 2 90ce3da70b43
child 5506 202f599c92aa
permissions -rw-r--r--
6876628: @throw instead of @throws in two ParagraphView classes Reviewed-by: peterz
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package javax.swing.text;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.Writer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.Enumeration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * AbstractWriter is an abstract class that actually
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * does the work of writing out the element tree
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * including the attributes.  In terms of how much is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * written out per line, the writer defaults to 100.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * But this value can be set by subclasses.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * @author Sunita Mani
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
public abstract class AbstractWriter {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
    private ElementIterator it;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
    private Writer out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
    private int indentLevel = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    private int indentSpace = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    private Document doc = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    private int maxLineLength = 100;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    private int currLength = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    private int startOffset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    private int endOffset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    // If (indentLevel * indentSpace) becomes >= maxLineLength, this will
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    // get incremened instead of indentLevel to avoid indenting going greater
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    // than line length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    private int offsetIndent = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
     * String used for end of line. If the Document has the property
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
     * EndOfLineStringProperty, it will be used for newlines. Otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
     * the System property line.separator will be used. The line separator
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
     * can also be set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    private String lineSeparator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
     * True indicates that when writing, the line can be split, false
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
     * indicates that even if the line is > than max line length it should
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
     * not be split.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    private boolean canWrapLines;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
     * True while the current line is empty. This will remain true after
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
     * indenting.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    private boolean isLineEmpty;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
     * Used when indenting. Will contain the spaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    private char[] indentChars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
     * Used when writing out a string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    private char[] tempChars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     * This is used in <code>writeLineSeparator</code> instead of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     * tempChars. If tempChars were used it would mean write couldn't invoke
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     * <code>writeLineSeparator</code> as it might have been passed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     * tempChars.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    private char[] newlineChars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
     * Used for writing text.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    private Segment segment;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * How the text packages models newlines.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * @see #getLineSeparator
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    protected static final char NEWLINE = '\n';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * Creates a new AbstractWriter.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * Initializes the ElementIterator with the default
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * root of the document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     * @param w a Writer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * @param doc a Document
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    protected AbstractWriter(Writer w, Document doc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        this(w, doc, 0, doc.getLength());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * Creates a new AbstractWriter.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * Initializes the ElementIterator with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * element passed in.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * @param w a Writer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     * @param doc an Element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     * @param pos The location in the document to fetch the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     *   content.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * @param len The amount to write out.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    protected AbstractWriter(Writer w, Document doc, int pos, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        this.doc = doc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        it = new ElementIterator(doc.getDefaultRootElement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        out = w;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        startOffset = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        endOffset = pos + len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        Object docNewline = doc.getProperty(DefaultEditorKit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                                       EndOfLineStringProperty);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        if (docNewline instanceof String) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            setLineSeparator((String)docNewline);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
            String newline = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
                newline = System.getProperty("line.separator");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            } catch (SecurityException se) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            if (newline == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                // Should not get here, but if we do it means we could not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                // find a newline string, use \n in this case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                newline = "\n";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            setLineSeparator(newline);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        canWrapLines = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * Creates a new AbstractWriter.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * Initializes the ElementIterator with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     * element passed in.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * @param w a Writer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     * @param root an Element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    protected AbstractWriter(Writer w, Element root) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        this(w, root, 0, root.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * Creates a new AbstractWriter.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * Initializes the ElementIterator with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     * element passed in.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     * @param w a Writer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     * @param root an Element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
     * @param pos The location in the document to fetch the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     *   content.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
     * @param len The amount to write out.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    protected AbstractWriter(Writer w, Element root, int pos, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        this.doc = root.getDocument();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        it = new ElementIterator(root);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        out = w;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        startOffset = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        endOffset = pos + len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        canWrapLines = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * Returns the first offset to be output.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    public int getStartOffset() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        return startOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     * Returns the last offset to be output.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    public int getEndOffset() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        return endOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     * Fetches the ElementIterator.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
     * @return the ElementIterator.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    protected ElementIterator getElementIterator() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        return it;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     * Returns the Writer that is used to output the content.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    protected Writer getWriter() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        return out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * Fetches the document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * @return the Document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    protected Document getDocument() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        return doc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * This method determines whether the current element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * is in the range specified.  When no range is specified,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * the range is initialized to be the entire document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * inRange() returns true if the range specified intersects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     * with the element's range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     * @param  next an Element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * @return boolean that indicates whether the element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     *         is in the range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    protected boolean inRange(Element next) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        int startOffset = getStartOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        int endOffset = getEndOffset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        if ((next.getStartOffset() >= startOffset &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
             next.getStartOffset()  < endOffset) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
            (startOffset >= next.getStartOffset() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
             startOffset < next.getEndOffset())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * This abstract method needs to be implemented
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * by subclasses.  Its responsibility is to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     * iterate over the elements and use the write()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     * methods to generate output in the desired format.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    abstract protected void write() throws IOException, BadLocationException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
     * Returns the text associated with the element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     * The assumption here is that the element is a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     * leaf element.  Throws a BadLocationException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     * when encountered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * @param     elem an <code>Element</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     * @exception BadLocationException if pos represents an invalid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     *            location within the document
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * @return    the text as a <code>String</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    protected String getText(Element elem) throws BadLocationException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        return doc.getText(elem.getStartOffset(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                           elem.getEndOffset() - elem.getStartOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
     * Writes out text.  If a range is specified when the constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     * is invoked, then only the appropriate range of text is written
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
     * out.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * @param     elem an Element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * @exception IOException on any I/O error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     * @exception BadLocationException if pos represents an invalid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     *            location within the document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    protected void text(Element elem) throws BadLocationException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                                             IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        int start = Math.max(getStartOffset(), elem.getStartOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        int end = Math.min(getEndOffset(), elem.getEndOffset());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        if (start < end) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            if (segment == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                segment = new Segment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            getDocument().getText(start, end - start, segment);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            if (segment.count > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                write(segment.array, segment.offset, segment.count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     * Enables subclasses to set the number of characters they
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
     * want written per line.   The default is 100.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     * @param l the maximum line length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    protected void setLineLength(int l) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        maxLineLength = l;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     * Returns the maximum line length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    protected int getLineLength() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        return maxLineLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * Sets the current line length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
    protected void setCurrentLineLength(int length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        currLength = length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        isLineEmpty = (currLength == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
     * Returns the current line length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
    protected int getCurrentLineLength() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        return currLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
     * Returns true if the current line should be considered empty. This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
     * is true when <code>getCurrentLineLength</code> == 0 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
     * <code>indent</code> has been invoked on an empty line.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    protected boolean isLineEmpty() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        return isLineEmpty;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     * Sets whether or not lines can be wrapped. This can be toggled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     * during the writing of lines. For example, outputting HTML might
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     * set this to false when outputting a quoted string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    protected void setCanWrapLines(boolean newValue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        canWrapLines = newValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
     * Returns whether or not the lines can be wrapped. If this is false
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
     * no lineSeparator's will be output.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    protected boolean getCanWrapLines() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        return canWrapLines;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     * Enables subclasses to specify how many spaces an indent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     * maps to. When indentation takes place, the indent level
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     * is multiplied by this mapping.  The default is 2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     * @param space an int representing the space to indent mapping.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    protected void setIndentSpace(int space) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        indentSpace = space;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     * Returns the amount of space to indent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    protected int getIndentSpace() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        return indentSpace;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * Sets the String used to reprsent newlines. This is initialized
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     * in the constructor from either the Document, or the System property
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     * line.separator.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    public void setLineSeparator(String value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        lineSeparator = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
     * Returns the string used to represent newlines.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    public String getLineSeparator() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        return lineSeparator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
     * Increments the indent level. If indenting would cause
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
     * <code>getIndentSpace()</code> *<code>getIndentLevel()</code> to be >
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
     * than <code>getLineLength()</code> this will not cause an indent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    protected void incrIndent() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        // Only increment to a certain point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        if (offsetIndent > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
            offsetIndent++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            if (++indentLevel * getIndentSpace() >= getLineLength()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
                offsetIndent++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
                --indentLevel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
     * Decrements the indent level.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    protected void decrIndent() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        if (offsetIndent > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
            --offsetIndent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            indentLevel--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * Returns the current indentation level. That is, the number of times
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * <code>incrIndent</code> has been invoked minus the number of times
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     * <code>decrIndent</code> has been invoked.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
    protected int getIndentLevel() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
        return indentLevel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     * Does indentation. The number of spaces written
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     * out is indent level times the space to map mapping. If the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     * line is empty, this will not make it so that the current line is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     * still considered empty.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
     * @exception IOException on any I/O error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    protected void indent() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        int max = getIndentLevel() * getIndentSpace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        if (indentChars == null || max > indentChars.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
            indentChars = new char[max];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
            for (int counter = 0; counter < max; counter++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                indentChars[counter] = ' ';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        int length = getCurrentLineLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        boolean wasEmpty = isLineEmpty();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        output(indentChars, 0, max);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        if (wasEmpty && length == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            isLineEmpty = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
     * Writes out a character. This is implemented to invoke
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
     * the <code>write</code> method that takes a char[].
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
     * @param     ch a char.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
     * @exception IOException on any I/O error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
    protected void write(char ch) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        if (tempChars == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            tempChars = new char[128];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        tempChars[0] = ch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        write(tempChars, 0, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
     * Writes out a string. This is implemented to invoke the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
     * <code>write</code> method that takes a char[].
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
     * @param     content a String.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
     * @exception IOException on any I/O error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
    protected void write(String content) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        if (content == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        int size = content.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        if (tempChars == null || tempChars.length < size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
            tempChars = new char[size];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        content.getChars(0, size, tempChars, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        write(tempChars, 0, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
     * Writes the line separator. This invokes <code>output</code> directly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
     * as well as setting the <code>lineLength</code> to 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    protected void writeLineSeparator() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        String newline = getLineSeparator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        int length = newline.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        if (newlineChars == null || newlineChars.length < length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            newlineChars = new char[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        newline.getChars(0, length, newlineChars, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        output(newlineChars, 0, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        setCurrentLineLength(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
     * All write methods call into this one. If <code>getCanWrapLines()</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
     * returns false, this will call <code>output</code> with each sequence
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
     * of <code>chars</code> that doesn't contain a NEWLINE, followed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
     * by a call to <code>writeLineSeparator</code>. On the other hand,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
     * if <code>getCanWrapLines()</code> returns true, this will split the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
     * string, as necessary, so <code>getLineLength</code> is honored.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
     * The only exception is if the current string contains no whitespace,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
     * and won't fit in which case the line length will exceed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
     * <code>getLineLength</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    protected void write(char[] chars, int startIndex, int length)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                   throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        if (!getCanWrapLines()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            // We can not break string, just track if a newline
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            // is in it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            int lastIndex = startIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            int endIndex = startIndex + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            int newlineIndex = indexOf(chars, NEWLINE, startIndex, endIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
            while (newlineIndex != -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                if (newlineIndex > lastIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                    output(chars, lastIndex, newlineIndex - lastIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                writeLineSeparator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                lastIndex = newlineIndex + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                newlineIndex = indexOf(chars, '\n', lastIndex, endIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            if (lastIndex < endIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                output(chars, lastIndex, endIndex - lastIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
            // We can break chars if the length exceeds maxLength.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
            int lastIndex = startIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
            int endIndex = startIndex + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
            int lineLength = getCurrentLineLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            int maxLength = getLineLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            while (lastIndex < endIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                int newlineIndex = indexOf(chars, NEWLINE, lastIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                                           endIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                boolean needsNewline = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
                boolean forceNewLine = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                lineLength = getCurrentLineLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                if (newlineIndex != -1 && (lineLength +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                              (newlineIndex - lastIndex)) < maxLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                    if (newlineIndex > lastIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                        output(chars, lastIndex, newlineIndex - lastIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                    lastIndex = newlineIndex + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                    forceNewLine = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
                else if (newlineIndex == -1 && (lineLength +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                                (endIndex - lastIndex)) < maxLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                    if (endIndex > lastIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                        output(chars, lastIndex, endIndex - lastIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                    lastIndex = endIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
                    // Need to break chars, find a place to split chars at,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
                    // from lastIndex to endIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                    // or maxLength - lineLength whichever is smaller
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                    int breakPoint = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                    int maxBreak = Math.min(endIndex - lastIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                                            maxLength - lineLength - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                    int counter = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
                    while (counter < maxBreak) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                        if (Character.isWhitespace(chars[counter +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                                                        lastIndex])) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                            breakPoint = counter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                        counter++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
                    if (breakPoint != -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
                        // Found a place to break at.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
                        breakPoint += lastIndex + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
                        output(chars, lastIndex, breakPoint - lastIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
                        lastIndex = breakPoint;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                        needsNewline = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
                    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
                        // No where good to break.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                        // find the next whitespace, or write out the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                        // whole string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
                            // maxBreak will be negative if current line too
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                            // long.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
                            counter = Math.max(0, maxBreak);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                            maxBreak = endIndex - lastIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                            while (counter < maxBreak) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
                                if (Character.isWhitespace(chars[counter +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                                                                lastIndex])) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                                    breakPoint = counter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
                                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                                counter++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
                            if (breakPoint == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
                                output(chars, lastIndex, endIndex - lastIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                                breakPoint = endIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
                            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
                                breakPoint += lastIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
                                if (chars[breakPoint] == NEWLINE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
                                    output(chars, lastIndex, breakPoint++ -
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
                                           lastIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                                forceNewLine = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
                                    output(chars, lastIndex, ++breakPoint -
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                                              lastIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
                                needsNewline = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                            lastIndex = breakPoint;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                if (forceNewLine || needsNewline || lastIndex < endIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
                    writeLineSeparator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
                    if (lastIndex < endIndex || !forceNewLine) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                        indent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
     * Writes out the set of attributes as " <name>=<value>"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
     * pairs. It throws an IOException when encountered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
     * @param     attr an AttributeSet.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     * @exception IOException on any I/O error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
    protected void writeAttributes(AttributeSet attr) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        Enumeration names = attr.getAttributeNames();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        while (names.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
            Object name = names.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            write(" " + name + "=" + attr.getAttribute(name));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
     * The last stop in writing out content. All the write methods eventually
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
     * make it to this method, which invokes <code>write</code> on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
     * Writer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
     * <p>This method also updates the line length based on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
     * <code>length</code>. If this is invoked to output a newline, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
     * current line length will need to be reset as will no longer be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
     * valid. If it is up to the caller to do this. Use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
     * <code>writeLineSeparator</code> to write out a newline, which will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
     * property update the current line length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    protected void output(char[] content, int start, int length)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                   throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
        getWriter().write(content, start, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        setCurrentLineLength(getCurrentLineLength() + length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
     * Support method to locate an occurence of a particular character.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
    private int indexOf(char[] chars, char sChar, int startIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
                        int endIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        while(startIndex < endIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
            if (chars[startIndex] == sChar) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
                return startIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
            startIndex++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
}