diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/javax/swing/text/html/HTMLWriter.java | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/javax/swing/text/html/HTMLWriter.java')
-rw-r--r-- | libjava/classpath/javax/swing/text/html/HTMLWriter.java | 1088 |
1 files changed, 1088 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/text/html/HTMLWriter.java b/libjava/classpath/javax/swing/text/html/HTMLWriter.java new file mode 100644 index 000000000..55d25ccbb --- /dev/null +++ b/libjava/classpath/javax/swing/text/html/HTMLWriter.java @@ -0,0 +1,1088 @@ +/* HTMLWriter.java -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.swing.text.html; + +import gnu.java.lang.CPStringBuilder; + +import java.io.IOException; +import java.io.Writer; + +import java.util.Enumeration; +import java.util.HashSet; + +import javax.swing.ComboBoxModel; + +import javax.swing.text.AbstractWriter; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.Element; +import javax.swing.text.StyleConstants; + +import javax.swing.text.html.HTML; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.Option; + +/** + * HTMLWriter, + * A Writer for HTMLDocuments. + * + * @author David Fu (fchoong at netbeans.jp) + */ + +public class HTMLWriter + extends AbstractWriter +{ + /** + * We keep a reference of the writer passed by the construct. + */ + private Writer outWriter = null; + + /** + * We keep a reference of the HTMLDocument passed by the construct. + */ + private HTMLDocument htmlDoc = null; + + /** + * Used to keep track of which embedded has been written out. + */ + private HashSet<HTML.Tag> openEmbeddedTagHashSet = null; + + private String new_line_str = "" + NEWLINE; + + private char[] html_entity_char_arr = {'<', '>', '&', '"'}; + + private String[] html_entity_escape_str_arr = {"<", ">", "&", + """}; + + // variables used to output Html Fragment + private int doc_pos = -1; + private int doc_len = -1; + private int doc_offset_remaining = -1; + private int doc_len_remaining = -1; + private HashSet<Element> htmlFragmentParentHashSet = null; + private Element startElem = null; + private Element endElem = null; + private boolean fg_pass_start_elem = false; + private boolean fg_pass_end_elem = false; + + /** + * Constructs a HTMLWriter. + * + * @param writer writer to write output to + * @param doc the HTMLDocument to output + */ + public HTMLWriter(Writer writer, HTMLDocument doc) + { + super(writer, doc); + outWriter = writer; + htmlDoc = doc; + openEmbeddedTagHashSet = new HashSet<HTML.Tag>(); + } // public HTMLWriter(Writer writer, HTMLDocument doc) + + /** + * Constructs a HTMLWriter which outputs a Html Fragment. + * + * @param writer <code>Writer</code> to write output to + * @param doc the <code>javax.swing.text.html.HTMLDocument</code> + * to output + * @param pos position to start outputing the document + * @param len amount to output the document + */ + public HTMLWriter(Writer writer, HTMLDocument doc, int pos, int len) + { + super(writer, doc, pos, len); + outWriter = writer; + htmlDoc = doc; + openEmbeddedTagHashSet = new HashSet<HTML.Tag>(); + + doc_pos = pos; + doc_offset_remaining = pos; + doc_len = len; + doc_len_remaining = len; + htmlFragmentParentHashSet = new HashSet<Element>(); + } // public HTMLWriter(Writer writer, HTMLDocument doc, int pos, int len) + + /** + * Call this method to start outputing HTML. + * + * @throws IOException on any I/O exceptions + * @throws BadLocationException if a pos is not a valid position in the + * html doc element + */ + public void write() + throws IOException, BadLocationException + { + Element rootElem = htmlDoc.getDefaultRootElement(); + + if (doc_pos == -1 && doc_len == -1) + { + // Normal traversal. + traverse(rootElem); + } // if(doc_pos == -1 && doc_len == -1) + else + { + // Html fragment traversal. + if (doc_pos == -1 || doc_len == -1) + throw new BadLocationException("Bad Location(" + + doc_pos + ", " + doc_len + ")", doc_pos); + + startElem = htmlDoc.getCharacterElement(doc_pos); + + int start_offset = startElem.getStartOffset(); + + // Positions before start_offset will not be traversed, and thus + // will not be counted. + if (start_offset > 0) + doc_offset_remaining = doc_offset_remaining - start_offset; + + Element tempParentElem = startElem; + + while ((tempParentElem = tempParentElem.getParentElement()) != null) + { + if (!htmlFragmentParentHashSet.contains(tempParentElem)) + htmlFragmentParentHashSet.add(tempParentElem); + } // while((tempParentElem = tempParentElem.getParentElement()) + // != null) + + // NOTE: 20061030 - fchoong - the last index should not be included. + endElem = htmlDoc.getCharacterElement(doc_pos + doc_len - 1); + + tempParentElem = endElem; + + while ((tempParentElem = tempParentElem.getParentElement()) != null) + { + if (!htmlFragmentParentHashSet.contains(tempParentElem)) + htmlFragmentParentHashSet.add(tempParentElem); + } // while((tempParentElem = tempParentElem.getParentElement()) + // != null) + + traverseHtmlFragment(rootElem); + + } // else + + // NOTE: close out remaining open embeded tags. + HTML.Tag[] tag_arr = + openEmbeddedTagHashSet.toArray(new HTML.Tag[openEmbeddedTagHashSet.size()]); + + for (int i = 0; i < tag_arr.length; i++) + { + writeRaw("</" + tag_arr[i].toString() + ">"); + } // for(int i = 0; i < tag_arr.length; i++) + + } // public void write() throws IOException, BadLocationException + + /** + * Writes all the attributes in the attrSet, except for attrbutes with + * keys of <code>javax.swing.text.html.HTML.Tag</code>, + * <code>javax.swing.text.StyleConstants</code> or + * <code>javax.swing.text.html.HTML.Attribute.ENDTAG</code>. + * + * @param attrSet attrSet to write out + * + * @throws IOException on any I/O exceptions + */ + protected void writeAttributes(AttributeSet attrSet) + throws IOException + { + Enumeration<?> attrNameEnum = attrSet.getAttributeNames(); + + while (attrNameEnum.hasMoreElements()) + { + Object key = attrNameEnum.nextElement(); + Object value = attrSet.getAttribute(key); + + // HTML.Attribute.ENDTAG is an instance, not a class. + if (!((key instanceof HTML.Tag) || (key instanceof StyleConstants) + || (key == HTML.Attribute.ENDTAG))) + { + if (key == HTML.Attribute.SELECTED) + writeRaw(" selected"); + else if (key == HTML.Attribute.CHECKED) + writeRaw(" checked"); + else + writeRaw(" " + key + "=\"" + value + "\""); + } // if(!((key instanceof HTML.Tag) || (key instanceof + // StyleConstants) || (key == HTML.Attribute.ENDTAG))) + } // while(attrNameEnum.hasMoreElements()) + + } // protected void writeAttributes(AttributeSet attrSet) throws IOException + + /** + * Writes out an empty tag. i.e. a tag without any child elements. + * + * @param paramElem the element to output as an empty tag + * + * @throws IOException on any I/O exceptions + * @throws BadLocationException if a pos is not a valid position in the + * html doc element + */ + protected void emptyTag(Element paramElem) + throws IOException, BadLocationException + { + String elem_name = paramElem.getName(); + AttributeSet attrSet = paramElem.getAttributes(); + + writeRaw("<" + elem_name); + writeAttributes(attrSet); + writeRaw(">"); + + if (isBlockTag(attrSet)) + { + writeRaw("</" + elem_name + ">"); + } // if(isBlockTag(attrSet)) + + } // protected void emptyTag(Element paramElem) + // throws IOException, BadLocationException + + /** + * Determines if it is a block tag or not. + * + * @param attrSet the attrSet of the element + * + * @return <code>true</code> if it is a block tag + * <code>false</code> if it is a not block tag + */ + protected boolean isBlockTag(AttributeSet attrSet) + { + return ((HTML.Tag) + attrSet.getAttribute(StyleConstants.NameAttribute)).isBlock(); + } // protected boolean isBlockTag(AttributeSet attrSet) + + /** + * Writes out a start tag. Synthesized elements are skipped. + * + * @param paramElem the element to output as a start tag + * @throws IOException on any I/O exceptions + * @throws BadLocationException if a pos is not a valid position in the + * html doc element + */ + protected void startTag(Element paramElem) + throws IOException, BadLocationException + { + // NOTE: Sysnthesized elements do no call this method at all. + String elem_name = paramElem.getName(); + AttributeSet attrSet = paramElem.getAttributes(); + + indent(); + writeRaw("<" + elem_name); + writeAttributes(attrSet); + writeRaw(">"); + writeLineSeparator(); // Extra formatting to look more like the RI. + incrIndent(); + + } // protected void startTag(Element paramElem) + // throws IOException, BadLocationException + + /** + * Writes out the contents of a textarea. + * + * @param attrSet the attrSet of the element to output as a text area + * @throws IOException on any I/O exceptions + * @throws BadLocationException if a pos is not a valid position in the + * html doc element + */ + protected void textAreaContent(AttributeSet attrSet) + throws IOException, BadLocationException + { + writeLineSeparator(); // Extra formatting to look more like the RI. + indent(); + writeRaw("<textarea"); + writeAttributes(attrSet); + writeRaw(">"); + + Document tempDocument = + (Document) attrSet.getAttribute(StyleConstants.ModelAttribute); + + writeRaw(tempDocument.getText(0, tempDocument.getLength())); + indent(); + writeRaw("</textarea>"); + + } // protected void textAreaContent(AttributeSet attrSet) + // throws IOException, BadLocationException + + /** + * Writes out text, within the appropriate range if it is specified. + * + * @param paramElem the element to output as a text + * @throws IOException on any I/O exceptions + * @throws BadLocationException if a pos is not a valid position in the + * html doc element + */ + protected void text(Element paramElem) + throws IOException, BadLocationException + { + int offset = paramElem.getStartOffset(); + int len = paramElem.getEndOffset() - paramElem.getStartOffset(); + String txt_value = htmlDoc.getText(offset, len); + + writeContent(txt_value); + + } // protected void text(Element paramElem) + // throws IOException, BadLocationException + + /** + * Writes out the contents of a select element. + * + * @param attrSet the attrSet of the element to output as a select box + * + * @throws IOException on any I/O exceptions + */ + protected void selectContent(AttributeSet attrSet) + throws IOException + { + writeLineSeparator(); // Extra formatting to look more like the RI. + indent(); + writeRaw("<select"); + writeAttributes(attrSet); + writeRaw(">"); + incrIndent(); + writeLineSeparator(); // extra formatting to look more like the RI. + + ComboBoxModel comboBoxModel = + (ComboBoxModel) attrSet.getAttribute(StyleConstants.ModelAttribute); + + for (int i = 0; i < comboBoxModel.getSize(); i++) + { + writeOption((Option) comboBoxModel.getElementAt(i)); + } // for(int i = 0; i < comboBoxModel.getSize(); i++) + + decrIndent(); + indent(); + writeRaw("</select>"); + + } // protected void selectContent(AttributeSet attrSet) throws IOException + + /** + * Writes out the contents of an option element. + * + * @param option the option object to output as a select option + * + * @throws IOException on any I/O exceptions + */ + protected void writeOption(Option option) + throws IOException + { + indent(); + writeRaw("<option"); + writeAttributes(option.getAttributes()); + writeRaw(">"); + + writeContent(option.getLabel()); + + writeRaw("</option>"); + writeLineSeparator(); // extra formatting to look more like the RI. + + } // protected void writeOption(Option option) throws IOException + + /** + * Writes out an end tag. + * + * @param paramElem the element to output as an end tag + * + * @throws IOException on any I/O exceptions + */ + protected void endTag(Element paramElem) + throws IOException + { + String elem_name = paramElem.getName(); + + //writeLineSeparator(); // Extra formatting to look more like the RI. + decrIndent(); + indent(); + writeRaw("</" + elem_name + ">"); + writeLineSeparator(); // Extra formatting to look more like the RI. + + } // protected void endTag(Element paramElem) throws IOException + + /** + * Writes out the comment. + * + * @param paramElem the element to output as a comment + */ + protected void comment(Element paramElem) + throws IOException, BadLocationException + { + AttributeSet attrSet = paramElem.getAttributes(); + + String comment_str = (String) attrSet.getAttribute(HTML.Attribute.COMMENT); + + writeRaw("<!--" + comment_str + "-->"); + + } // protected void comment(Element paramElem) + // throws IOException, BadLocationException + + /** + * Determines if element is a synthesized + * <code>javax.swing.text.Element</code> or not. + * + * @param element the element to test + * + * @return <code>true</code> if it is a synthesized element, + * <code>false</code> if it is a not synthesized element + */ + protected boolean synthesizedElement(Element element) + { + AttributeSet attrSet = element.getAttributes(); + Object tagType = attrSet.getAttribute(StyleConstants.NameAttribute); + + if (tagType == HTML.Tag.CONTENT || tagType == HTML.Tag.COMMENT + || tagType == HTML.Tag.IMPLIED) + return true; + else + return false; + } // protected boolean synthesizedElement(Element element) + + /** + * Determines if + * <code>javax.swing.text.StyleConstants.NameAttribute</code> + * matches tag or not. + * + * @param attrSet the <code>javax.swing.text.AttributeSet</code> of + * element to be matched + * @param tag the HTML.Tag to match + * + * @return <code>true</code> if it matches, + * <code>false</code> if it does not match + */ + protected boolean matchNameAttribute(AttributeSet attrSet, HTML.Tag tag) + { + Object tagType = attrSet.getAttribute(StyleConstants.NameAttribute); + + if (tagType == tag) + return true; + else + return false; + } // protected boolean matchNameAttribute(AttributeSet attrSet, + // HTML.Tag tag) + + /** + * Writes out an embedded tag. The tags not already in + * openEmbededTagHashSet will written out. + * + * @param attrSet the <code>javax.swing.text.AttributeSet</code> of + * the element to write out + * + * @throws IOException on any I/O exceptions + */ + protected void writeEmbeddedTags(AttributeSet attrSet) + throws IOException + { + Enumeration<?> attrNameEnum = attrSet.getAttributeNames(); + + while (attrNameEnum.hasMoreElements()) + { + Object key = attrNameEnum.nextElement(); + Object value = attrSet.getAttribute(key); + + if (key instanceof HTML.Tag) + { + if (!openEmbeddedTagHashSet.contains(key)) + { + writeRaw("<" + key); + writeAttributes((AttributeSet) value); + writeRaw(">"); + openEmbeddedTagHashSet.add((HTML.Tag) key); + } // if(!openEmbededTagHashSet.contains(key)) + } // if(key instanceof HTML.Tag) + } // while(attrNameEnum.hasMoreElements()) + + } // protected void writeEmbeddedTags(AttributeSet attrSet) + // throws IOException + + /** + * Closes out an unwanted embedded tag. The tags from the + * openEmbededTagHashSet not found in attrSet will be written out. + * + * @param attrSet the AttributeSet of the element to write out + * + * @throws IOException on any I/O exceptions + */ + protected void closeOutUnwantedEmbeddedTags(AttributeSet attrSet) + throws IOException + { + HTML.Tag[] tag_arr = + openEmbeddedTagHashSet.toArray(new HTML.Tag[openEmbeddedTagHashSet.size()]); + + for (int i = 0; i < tag_arr.length; i++) + { + HTML.Tag key = tag_arr[i]; + + if (!attrSet.isDefined(key)) + { + writeRaw("</" + key.toString() + ">"); + openEmbeddedTagHashSet.remove(key); + } // if(!attrSet.isDefined(key)) + } // for(int i = 0; i < tag_arr.length; i++) + + } // protected void closeOutUnwantedEmbeddedTags(AttributeSet attrSet) + // throws IOException + + /** + * Writes out a line separator. Overwrites the parent to write out a new + * line. + * + * @throws IOException on any I/O exceptions. + */ + protected void writeLineSeparator() + throws IOException + { + writeRaw(new_line_str); + } // protected void writeLineSeparator() throws IOException + + /** + * Write to the writer. Character entites such as <, > + * are escaped appropriately. + * + * @param chars char array to write out + * @param off offset + * @param len length + * + * @throws IOException on any I/O exceptions + */ + protected void output(char[] chars, int off, int len) + throws IOException + { + CPStringBuilder strBuffer = new CPStringBuilder(); + + for (int i = 0; i < chars.length; i++) + { + if (isCharHtmlEntity(chars[i])) + strBuffer.append(escapeCharHtmlEntity(chars[i])); + else + strBuffer.append(chars[i]); + } // for(int i = 0; i < chars.length; i++) + + writeRaw(strBuffer.toString()); + + } // protected void output(char[] chars, int off, int len) + // throws IOException + + //------------------------------------------------------------------------- + // private methods + + /** + * The main method used to traverse through the elements. + * + * @param paramElem element to traverse + * + * @throws IOException on any I/O exceptions + */ + private void traverse(Element paramElem) + throws IOException, BadLocationException + { + Element currElem = paramElem; + + AttributeSet attrSet = currElem.getAttributes(); + + closeOutUnwantedEmbeddedTags(attrSet); + + // handle the tag + if (synthesizedElement(paramElem)) + { + if (matchNameAttribute(attrSet, HTML.Tag.CONTENT)) + { + writeEmbeddedTags(attrSet); + text(currElem); + } // if(matchNameAttribute(attrSet, HTML.Tag.CONTENT)) + else if (matchNameAttribute(attrSet, HTML.Tag.COMMENT)) + { + comment(currElem); + } // else if(matchNameAttribute(attrSet, HTML.Tag.COMMENT)) + else if (matchNameAttribute(attrSet, HTML.Tag.IMPLIED)) + { + int child_elem_count = currElem.getElementCount(); + + if (child_elem_count > 0) + { + for (int i = 0; i < child_elem_count; i++) + { + Element childElem = paramElem.getElement(i); + + traverse(childElem); + + } // for(int i = 0; i < child_elem_count; i++) + } // if(child_elem_count > 0) + } // else if(matchNameAttribute(attrSet, HTML.Tag.IMPLIED)) + } // if(synthesizedElement(paramElem)) + else + { + // NOTE: 20061030 - fchoong - title is treated specially here. + // based on RI behavior. + if (matchNameAttribute(attrSet, HTML.Tag.TITLE)) + { + boolean fg_is_end_tag = false; + Enumeration<?> attrNameEnum = attrSet.getAttributeNames(); + + while (attrNameEnum.hasMoreElements()) + { + Object key = attrNameEnum.nextElement(); + Object value = attrSet.getAttribute(key); + + if (key == HTML.Attribute.ENDTAG && value.equals("true")) + fg_is_end_tag = true; + } // while(attrNameEnum.hasMoreElements()) + + if (fg_is_end_tag) + writeRaw("</title>"); + else + { + indent(); + writeRaw("<title>"); + + String title_str = + (String) htmlDoc.getProperty(HTMLDocument.TitleProperty); + + if (title_str != null) + writeContent(title_str); + + } // else + } // if(matchNameAttribute(attrSet, HTML.Tag.TITLE)) + else if (matchNameAttribute(attrSet, HTML.Tag.PRE)) + { + // We pursue more stringent formating here. + attrSet = paramElem.getAttributes(); + + indent(); + writeRaw("<pre"); + writeAttributes(attrSet); + writeRaw(">"); + + int child_elem_count = currElem.getElementCount(); + + for (int i = 0; i < child_elem_count; i++) + { + Element childElem = paramElem.getElement(i); + + traverse(childElem); + + } // for(int i = 0; i < child_elem_count; i++) + + writeRaw("</pre>"); + + } // else if(matchNameAttribute(attrSet, HTML.Tag.PRE)) + else if (matchNameAttribute(attrSet, HTML.Tag.SELECT)) + { + selectContent(attrSet); + } // else if(matchNameAttribute(attrSet, HTML.Tag.SELECT)) + else if (matchNameAttribute(attrSet, HTML.Tag.TEXTAREA)) + { + textAreaContent(attrSet); + } // else if(matchNameAttribute(attrSet, HTML.Tag.TEXTAREA)) + else + { + int child_elem_count = currElem.getElementCount(); + + if (child_elem_count > 0) + { + startTag(currElem); + + for (int i = 0; i < child_elem_count; i++) + { + Element childElem = paramElem.getElement(i); + + traverse(childElem); + + } // for(int i = 0; i < child_elem_count; i++) + + endTag(currElem); + + } // if(child_elem_count > 0) + else + { + emptyTag(currElem); + } // else + } // else + } // else + + } // private void traverse(Element paramElem) + // throws IOException, BadLocationException + + /** + * The method used to traverse through a html fragment. + * + * @param paramElem element to traverse + * + * @throws IOException on any I/O exceptions + */ + private void traverseHtmlFragment(Element paramElem) + throws IOException, BadLocationException + { + // NOTE: This method is similar to traverse(Element paramElem) + Element currElem = paramElem; + + boolean fg_is_fragment_parent_elem = false; + boolean fg_is_start_and_end_elem = false; + + if (htmlFragmentParentHashSet.contains(paramElem)) + fg_is_fragment_parent_elem = true; + + if (paramElem == startElem) + fg_pass_start_elem = true; + + if (paramElem == startElem && paramElem == endElem) + fg_is_start_and_end_elem = true; + + AttributeSet attrSet = currElem.getAttributes(); + + closeOutUnwantedEmbeddedTags(attrSet); + + if (fg_is_fragment_parent_elem || (fg_pass_start_elem + && fg_pass_end_elem == false) || fg_is_start_and_end_elem) + { + // handle the tag + if (synthesizedElement(paramElem)) + { + if (matchNameAttribute(attrSet, HTML.Tag.CONTENT)) + { + writeEmbeddedTags(attrSet); + + int content_offset = paramElem.getStartOffset(); + int content_length = currElem.getEndOffset() - content_offset; + + if (doc_offset_remaining > 0) + { + if (content_length > doc_offset_remaining) + { + int split_len = content_length; + + split_len = split_len - doc_offset_remaining; + + if (split_len > doc_len_remaining) + split_len = doc_len_remaining; + + // we need to split it. + String txt_value = htmlDoc.getText(content_offset + + doc_offset_remaining, split_len); + + writeContent(txt_value); + + doc_offset_remaining = 0; // the offset is used up. + doc_len_remaining = doc_len_remaining - split_len; + } // if(content_length > doc_offset_remaining) + else + { + // doc_offset_remaining is greater than the entire + // length of content + doc_offset_remaining = doc_offset_remaining + - content_length; + } // else + } // if(doc_offset_remaining > 0) + else if (content_length <= doc_len_remaining) + { + // we can fit the entire content. + text(currElem); + doc_len_remaining = doc_len_remaining - content_length; + } // else if(content_length <= doc_len_remaining) + else + { + // we need to split it. + String txt_value = htmlDoc.getText(content_offset, + doc_len_remaining); + + writeContent(txt_value); + + doc_len_remaining = 0; + } // else + + } // if(matchNameAttribute(attrSet, HTML.Tag.CONTENT)) + else if (matchNameAttribute(attrSet, HTML.Tag.COMMENT)) + { + comment(currElem); + } // else if(matchNameAttribute(attrSet, HTML.Tag.COMMENT)) + else if (matchNameAttribute(attrSet, HTML.Tag.IMPLIED)) + { + int child_elem_count = currElem.getElementCount(); + + if (child_elem_count > 0) + { + for (int i = 0; i < child_elem_count; i++) + { + Element childElem = paramElem.getElement(i); + + traverseHtmlFragment(childElem); + + } // for(int i = 0; i < child_elem_count; i++) + } // if(child_elem_count > 0) + } // else if(matchNameAttribute(attrSet, HTML.Tag.IMPLIED)) + } // if(synthesizedElement(paramElem)) + else + { + // NOTE: 20061030 - fchoong - the isLeaf() condition seems to + // generate the closest behavior to the RI. + if (paramElem.isLeaf()) + { + if (doc_offset_remaining > 0) + { + doc_offset_remaining--; + } // if(doc_offset_remaining > 0) + else if (doc_len_remaining > 0) + { + doc_len_remaining--; + } // else if(doc_len_remaining > 0) + } // if(paramElem.isLeaf()) + + // NOTE: 20061030 - fchoong - title is treated specially here. + // based on RI behavior. + if (matchNameAttribute(attrSet, HTML.Tag.TITLE)) + { + boolean fg_is_end_tag = false; + Enumeration<?> attrNameEnum = attrSet.getAttributeNames(); + + while (attrNameEnum.hasMoreElements()) + { + Object key = attrNameEnum.nextElement(); + Object value = attrSet.getAttribute(key); + + if (key == HTML.Attribute.ENDTAG && value.equals("true")) + fg_is_end_tag = true; + } // while(attrNameEnum.hasMoreElements()) + + if (fg_is_end_tag) + writeRaw("</title>"); + else + { + indent(); + writeRaw("<title>"); + + String title_str = + (String) htmlDoc.getProperty(HTMLDocument.TitleProperty); + + if (title_str != null) + writeContent(title_str); + + } // else + } // if(matchNameAttribute(attrSet, HTML.Tag.TITLE)) + else if (matchNameAttribute(attrSet, HTML.Tag.PRE)) + { + // We pursue more stringent formating here. + attrSet = paramElem.getAttributes(); + + indent(); + writeRaw("<pre"); + writeAttributes(attrSet); + writeRaw(">"); + + int child_elem_count = currElem.getElementCount(); + + for (int i = 0; i < child_elem_count; i++) + { + Element childElem = paramElem.getElement(i); + + traverseHtmlFragment(childElem); + + } // for(int i = 0; i < child_elem_count; i++) + + writeRaw("</pre>"); + + } // else if(matchNameAttribute(attrSet, HTML.Tag.PRE)) + else if (matchNameAttribute(attrSet, HTML.Tag.SELECT)) + { + selectContent(attrSet); + } // else if(matchNameAttribute(attrSet, HTML.Tag.SELECT)) + else if (matchNameAttribute(attrSet, HTML.Tag.TEXTAREA)) + { + textAreaContent(attrSet); + } // else if(matchNameAttribute(attrSet, HTML.Tag.TEXTAREA)) + else + { + int child_elem_count = currElem.getElementCount(); + + if (child_elem_count > 0) + { + startTag(currElem); + + for (int i = 0; i < child_elem_count; i++) + { + Element childElem = paramElem.getElement(i); + + traverseHtmlFragment(childElem); + + } // for(int i = 0; i < child_elem_count; i++) + + endTag(currElem); + + } // if(child_elem_count > 0) + else + { + emptyTag(currElem); + } // else + } // else + } // else + + } // if(fg_is_fragment_parent_elem || (fg_pass_start_elem + // && fg_pass_end_elem == false) || fg_is_start_and_end_elem) + + if (paramElem == endElem) + fg_pass_end_elem = true; + + } // private void traverseHtmlFragment(Element paramElem) + // throws IOException, BadLocationException + + /** + * Write to the writer without any modifications. + * + * @param param_str the str to write out + * + * @throws IOException on any I/O exceptions + */ + private void writeRaw(String param_str) + throws IOException + { + super.output(param_str.toCharArray(), 0, param_str.length()); + } // private void writeRaw(char[] chars, int off, int len) + // throws IOException + + /** + * Write to the writer, escaping HTML character entitie where neccessary. + * + * @param param_str the str to write out + * + * @throws IOException on any I/O exceptions + */ + private void writeContent(String param_str) + throws IOException + { + char[] str_char_arr = param_str.toCharArray(); + + if (hasHtmlEntity(param_str)) + output(str_char_arr, 0, str_char_arr.length); + else + super.output(str_char_arr, 0, str_char_arr.length); + + } // private void writeContent(String param_str) throws IOException + + /** + * Use this for debugging. Writes out all attributes regardless of type. + * + * @param attrSet the <code>javax.swing.text.AttributeSet</code> to + * write out + * + * @throws IOException on any I/O exceptions + */ + private void writeAllAttributes(AttributeSet attrSet) + throws IOException + { + Enumeration<?> attrNameEnum = attrSet.getAttributeNames(); + + while (attrNameEnum.hasMoreElements()) + { + Object key = attrNameEnum.nextElement(); + Object value = attrSet.getAttribute(key); + + writeRaw(" " + key + "=\"" + value + "\""); + writeRaw(" " + key.getClass().toString() + "=\"" + + value.getClass().toString() + "\""); + } // while(attrNameEnum.hasMoreElements()) + + } // private void writeAllAttributes(AttributeSet attrSet) + // throws IOException + + /** + * Tests if the str contains any html entities. + * + * @param param_str the str to test + * + * @return <code>true</code> if it has a html entity + * <code>false</code> if it does not have a html entity + */ + private boolean hasHtmlEntity(String param_str) + { + boolean ret_bool = false; + + for (int i = 0; i < html_entity_char_arr.length; i++) + { + if (param_str.indexOf(html_entity_char_arr[i]) != -1) + { + ret_bool = true; + break; + } // if(param_str.indexOf(html_entity_char_arr[i]) != -1) + } // for(int i = 0; i < html_entity_char_arr.length; i++) + + return ret_bool; + } // private boolean hasHtmlEntity(String param_str) + + /** + * Tests if the char is a html entities. + * + * @param param_char the char to test + * + * @return <code>true</code> if it is a html entity + * <code>false</code> if it is not a html entity. + */ + private boolean isCharHtmlEntity(char param_char) + { + boolean ret_bool = false; + + for (int i = 0; i < html_entity_char_arr.length; i++) + { + if (param_char == html_entity_char_arr[i]) + { + ret_bool = true; + break; + } // if(param_char == html_entity_char_arr[i]) + } // for(int i = 0; i < html_entity_char_arr.length; i++) + + return ret_bool; + } // private boolean hasHtmlEntity(String param_str) + + /** + * Escape html entities. + * + * @param param_char the char to escape + * + * @return escaped html entity. Original char is returned as a str if is + * is not a html entity + */ + private String escapeCharHtmlEntity(char param_char) + { + String ret_str = "" + param_char; + + for (int i = 0; i < html_entity_char_arr.length; i++) + { + if (param_char == html_entity_char_arr[i]) + { + ret_str = html_entity_escape_str_arr[i]; + break; + } // if(param_char == html_entity_char_arr[i]) + } // for(int i = 0; i < html_entity_char_arr.length; i++) + + return ret_str; + } // private String escapeCharHtmlEntity(char param_char) + +} // public class HTMLWriter extends AbstractWriter |