AbstractWriterpublic abstract class AbstractWriter extends Object AbstractWriter is an abstract class that actually
does the work of writing out the element tree
including the attributes. In terms of how much is
written out per line, the writer defaults to 100.
But this value can be set by subclasses. |
Fields Summary |
---|
private ElementIterator | it | private Writer | out | private int | indentLevel | private int | indentSpace | private Document | doc | private int | maxLineLength | private int | currLength | private int | startOffset | private int | endOffset | private int | offsetIndent | private String | lineSeparatorString used for end of line. If the Document has the property
EndOfLineStringProperty, it will be used for newlines. Otherwise
the System property line.separator will be used. The line separator
can also be set. | private boolean | canWrapLinesTrue indicates that when writing, the line can be split, false
indicates that even if the line is > than max line length it should
not be split. | private boolean | isLineEmptyTrue while the current line is empty. This will remain true after
indenting. | private char[] | indentCharsUsed when indenting. Will contain the spaces. | private char[] | tempCharsUsed when writing out a string. | private char[] | newlineCharsThis is used in writeLineSeparator instead of
tempChars. If tempChars were used it would mean write couldn't invoke
writeLineSeparator as it might have been passed
tempChars. | private Segment | segmentUsed for writing text. | protected static final char | NEWLINEHow the text packages models newlines. |
Constructors Summary |
---|
protected AbstractWriter(Writer w, Document doc)Creates a new AbstractWriter.
Initializes the ElementIterator with the default
root of the document.
this(w, doc, 0, doc.getLength());
| protected AbstractWriter(Writer w, Document doc, int pos, int len)Creates a new AbstractWriter.
Initializes the ElementIterator with the
element passed in.
this.doc = doc;
it = new ElementIterator(doc.getDefaultRootElement());
out = w;
startOffset = pos;
endOffset = pos + len;
Object docNewline = doc.getProperty(DefaultEditorKit.
EndOfLineStringProperty);
if (docNewline instanceof String) {
setLineSeparator((String)docNewline);
}
else {
String newline = null;
try {
newline = System.getProperty("line.separator");
} catch (SecurityException se) {}
if (newline == null) {
// Should not get here, but if we do it means we could not
// find a newline string, use \n in this case.
newline = "\n";
}
setLineSeparator(newline);
}
canWrapLines = true;
| protected AbstractWriter(Writer w, Element root)Creates a new AbstractWriter.
Initializes the ElementIterator with the
element passed in.
this(w, root, 0, root.getEndOffset());
| protected AbstractWriter(Writer w, Element root, int pos, int len)Creates a new AbstractWriter.
Initializes the ElementIterator with the
element passed in.
this.doc = root.getDocument();
it = new ElementIterator(root);
out = w;
startOffset = pos;
endOffset = pos + len;
canWrapLines = true;
|
Methods Summary |
---|
protected void | decrIndent()Decrements the indent level.
if (offsetIndent > 0) {
--offsetIndent;
}
else {
indentLevel--;
}
| protected boolean | getCanWrapLines()Returns whether or not the lines can be wrapped. If this is false
no lineSeparator's will be output.
return canWrapLines;
| protected int | getCurrentLineLength()Returns the current line length.
return currLength;
| protected javax.swing.text.Document | getDocument()Fetches the document.
return doc;
| protected javax.swing.text.ElementIterator | getElementIterator()Fetches the ElementIterator.
return it;
| public int | getEndOffset()Returns the last offset to be output.
return endOffset;
| protected int | getIndentLevel()Returns the current indentation level. That is, the number of times
incrIndent has been invoked minus the number of times
decrIndent has been invoked.
return indentLevel;
| protected int | getIndentSpace()Returns the amount of space to indent.
return indentSpace;
| protected int | getLineLength()Returns the maximum line length.
return maxLineLength;
| public java.lang.String | getLineSeparator()Returns the string used to represent newlines.
return lineSeparator;
| public int | getStartOffset()Returns the first offset to be output.
return startOffset;
| protected java.lang.String | getText(javax.swing.text.Element elem)Returns the text associated with the element.
The assumption here is that the element is a
leaf element. Throws a BadLocationException
when encountered.
return doc.getText(elem.getStartOffset(),
elem.getEndOffset() - elem.getStartOffset());
| protected java.io.Writer | getWriter()Returns the Writer that is used to output the content.
return out;
| protected boolean | inRange(javax.swing.text.Element next)This method determines whether the current element
is in the range specified. When no range is specified,
the range is initialized to be the entire document.
inRange() returns true if the range specified intersects
with the element's range.
int startOffset = getStartOffset();
int endOffset = getEndOffset();
if ((next.getStartOffset() >= startOffset &&
next.getStartOffset() < endOffset) ||
(startOffset >= next.getStartOffset() &&
startOffset < next.getEndOffset())) {
return true;
}
return false;
| protected void | incrIndent()Increments the indent level. If indenting would cause
getIndentSpace() *getIndentLevel() to be >
than getLineLength() this will not cause an indent.
// Only increment to a certain point.
if (offsetIndent > 0) {
offsetIndent++;
}
else {
if (++indentLevel * getIndentSpace() >= getLineLength()) {
offsetIndent++;
--indentLevel;
}
}
| protected void | indent()Does indentation. The number of spaces written
out is indent level times the space to map mapping. If the current
line is empty, this will not make it so that the current line is
still considered empty.
int max = getIndentLevel() * getIndentSpace();
if (indentChars == null || max > indentChars.length) {
indentChars = new char[max];
for (int counter = 0; counter < max; counter++) {
indentChars[counter] = ' ";
}
}
int length = getCurrentLineLength();
boolean wasEmpty = isLineEmpty();
output(indentChars, 0, max);
if (wasEmpty && length == 0) {
isLineEmpty = true;
}
| private int | indexOf(char[] chars, char sChar, int startIndex, int endIndex)Support method to locate an occurence of a particular character.
while(startIndex < endIndex) {
if (chars[startIndex] == sChar) {
return startIndex;
}
startIndex++;
}
return -1;
| protected boolean | isLineEmpty()Returns true if the current line should be considered empty. This
is true when getCurrentLineLength == 0 ||
indent has been invoked on an empty line.
return isLineEmpty;
| protected void | output(char[] content, int start, int length)The last stop in writing out content. All the write methods eventually
make it to this method, which invokes write on the
Writer.
This method also updates the line length based on
length . If this is invoked to output a newline, the
current line length will need to be reset as will no longer be
valid. If it is up to the caller to do this. Use
writeLineSeparator to write out a newline, which will
property update the current line length.
getWriter().write(content, start, length);
setCurrentLineLength(getCurrentLineLength() + length);
| protected void | setCanWrapLines(boolean newValue)Sets whether or not lines can be wrapped. This can be toggled
during the writing of lines. For example, outputting HTML might
set this to false when outputting a quoted string.
canWrapLines = newValue;
| protected void | setCurrentLineLength(int length)Sets the current line length.
currLength = length;
isLineEmpty = (currLength == 0);
| protected void | setIndentSpace(int space)Enables subclasses to specify how many spaces an indent
maps to. When indentation takes place, the indent level
is multiplied by this mapping. The default is 2.
indentSpace = space;
| protected void | setLineLength(int l)Enables subclasses to set the number of characters they
want written per line. The default is 100.
maxLineLength = l;
| public void | setLineSeparator(java.lang.String value)Sets the String used to reprsent newlines. This is initialized
in the constructor from either the Document, or the System property
line.separator.
lineSeparator = value;
| protected void | text(javax.swing.text.Element elem)Writes out text. If a range is specified when the constructor
is invoked, then only the appropriate range of text is written
out.
int start = Math.max(getStartOffset(), elem.getStartOffset());
int end = Math.min(getEndOffset(), elem.getEndOffset());
if (start < end) {
if (segment == null) {
segment = new Segment();
}
getDocument().getText(start, end - start, segment);
if (segment.count > 0) {
write(segment.array, segment.offset, segment.count);
}
}
| protected abstract void | write()This abstract method needs to be implemented
by subclasses. Its responsibility is to
iterate over the elements and use the write()
methods to generate output in the desired format.
| protected void | write(char ch)Writes out a character. This is implemented to invoke
the write method that takes a char[].
if (tempChars == null) {
tempChars = new char[128];
}
tempChars[0] = ch;
write(tempChars, 0, 1);
| protected void | write(java.lang.String content)Writes out a string. This is implemented to invoke the
write method that takes a char[].
if (content == null) {
return;
}
int size = content.length();
if (tempChars == null || tempChars.length < size) {
tempChars = new char[size];
}
content.getChars(0, size, tempChars, 0);
write(tempChars, 0, size);
| protected void | write(char[] chars, int startIndex, int length)All write methods call into this one. If getCanWrapLines()
returns false, this will call output with each sequence
of chars that doesn't contain a NEWLINE, followed
by a call to writeLineSeparator . On the other hand,
if getCanWrapLines() returns true, this will split the
string, as necessary, so getLineLength is honored.
The only exception is if the current string contains no whitespace,
and won't fit in which case the line length will exceed
getLineLength .
if (!getCanWrapLines()) {
// We can not break string, just track if a newline
// is in it.
int lastIndex = startIndex;
int endIndex = startIndex + length;
int newlineIndex = indexOf(chars, NEWLINE, startIndex, endIndex);
while (newlineIndex != -1) {
if (newlineIndex > lastIndex) {
output(chars, lastIndex, newlineIndex - lastIndex);
}
writeLineSeparator();
lastIndex = newlineIndex + 1;
newlineIndex = indexOf(chars, '\n", lastIndex, endIndex);
}
if (lastIndex < endIndex) {
output(chars, lastIndex, endIndex - lastIndex);
}
}
else {
// We can break chars if the length exceeds maxLength.
int lastIndex = startIndex;
int endIndex = startIndex + length;
int lineLength = getCurrentLineLength();
int maxLength = getLineLength();
while (lastIndex < endIndex) {
int newlineIndex = indexOf(chars, NEWLINE, lastIndex,
endIndex);
boolean needsNewline = false;
boolean forceNewLine = false;
lineLength = getCurrentLineLength();
if (newlineIndex != -1 && (lineLength +
(newlineIndex - lastIndex)) < maxLength) {
if (newlineIndex > lastIndex) {
output(chars, lastIndex, newlineIndex - lastIndex);
}
lastIndex = newlineIndex + 1;
forceNewLine = true;
}
else if (newlineIndex == -1 && (lineLength +
(endIndex - lastIndex)) < maxLength) {
if (endIndex > lastIndex) {
output(chars, lastIndex, endIndex - lastIndex);
}
lastIndex = endIndex;
}
else {
// Need to break chars, find a place to split chars at,
// from lastIndex to endIndex,
// or maxLength - lineLength whichever is smaller
int breakPoint = -1;
int maxBreak = Math.min(endIndex - lastIndex,
maxLength - lineLength - 1);
int counter = 0;
while (counter < maxBreak) {
if (Character.isWhitespace(chars[counter +
lastIndex])) {
breakPoint = counter;
}
counter++;
}
if (breakPoint != -1) {
// Found a place to break at.
breakPoint += lastIndex + 1;
output(chars, lastIndex, breakPoint - lastIndex);
lastIndex = breakPoint;
needsNewline = true;
}
else {
// No where good to break.
// find the next whitespace, or write out the
// whole string.
// maxBreak will be negative if current line too
// long.
counter = Math.max(0, maxBreak);
maxBreak = endIndex - lastIndex;
while (counter < maxBreak) {
if (Character.isWhitespace(chars[counter +
lastIndex])) {
breakPoint = counter;
break;
}
counter++;
}
if (breakPoint == -1) {
output(chars, lastIndex, endIndex - lastIndex);
breakPoint = endIndex;
}
else {
breakPoint += lastIndex;
if (chars[breakPoint] == NEWLINE) {
output(chars, lastIndex, breakPoint++ -
lastIndex);
forceNewLine = true;
}
else {
output(chars, lastIndex, ++breakPoint -
lastIndex);
needsNewline = true;
}
}
lastIndex = breakPoint;
}
}
if (forceNewLine || needsNewline || lastIndex < endIndex) {
writeLineSeparator();
if (lastIndex < endIndex || !forceNewLine) {
indent();
}
}
}
}
| protected void | writeAttributes(javax.swing.text.AttributeSet attr)Writes out the set of attributes as " ="
pairs. It throws an IOException when encountered.
Enumeration names = attr.getAttributeNames();
while (names.hasMoreElements()) {
Object name = names.nextElement();
write(" " + name + "=" + attr.getAttribute(name));
}
| protected void | writeLineSeparator()Writes the line separator. This invokes output directly
as well as setting the lineLength to 0.
String newline = getLineSeparator();
int length = newline.length();
if (newlineChars == null || newlineChars.length < length) {
newlineChars = new char[length];
}
newline.getChars(0, length, newlineChars, 0);
output(newlineChars, 0, length);
setCurrentLineLength(0);
|
|