Code Search for Developers
 
 
  

HTMLWriter.html from PeerWriter at Krugle


Show HTMLWriter.html syntax highlighted

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /><title>HTMLWriter xref</title>
<link type="text/css" rel="stylesheet" href="../../../stylesheet.css" />
</head>
<body>
<div id="overview"><a href="../../../../apidocs/org/dom4j/io/HTMLWriter.html">View Javadoc</a></div><pre>

<a name="1" href="#1">1</a>   <em class="comment">/*</em>
<a name="2" href="#2">2</a>   <em class="comment"> * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.</em>
<a name="3" href="#3">3</a>   <em class="comment"> *</em>
<a name="4" href="#4">4</a>   <em class="comment"> * This software is open source.</em>
<a name="5" href="#5">5</a>   <em class="comment"> * See the bottom of this file for the licence.</em>
<a name="6" href="#6">6</a>   <em class="comment"> */</em>
<a name="7" href="#7">7</a>   
<a name="8" href="#8">8</a>   <strong>package</strong> <a href="../../../org/dom4j/io/package-summary.html">org.dom4j.io</a>;
<a name="9" href="#9">9</a>   
<a name="10" href="#10">10</a>  <strong>import</strong> java.io.IOException;
<a name="11" href="#11">11</a>  <strong>import</strong> java.io.OutputStream;
<a name="12" href="#12">12</a>  <strong>import</strong> java.io.StringWriter;
<a name="13" href="#13">13</a>  <strong>import</strong> java.io.UnsupportedEncodingException;
<a name="14" href="#14">14</a>  <strong>import</strong> java.io.Writer;
<a name="15" href="#15">15</a>  <strong>import</strong> java.util.HashSet;
<a name="16" href="#16">16</a>  <strong>import</strong> java.util.Iterator;
<a name="17" href="#17">17</a>  <strong>import</strong> java.util.Set;
<a name="18" href="#18">18</a>  <strong>import</strong> java.util.Stack;
<a name="19" href="#19">19</a>  
<a name="20" href="#20">20</a>  <strong>import</strong> org.dom4j.Document;
<a name="21" href="#21">21</a>  <strong>import</strong> org.dom4j.DocumentHelper;
<a name="22" href="#22">22</a>  <strong>import</strong> org.dom4j.Element;
<a name="23" href="#23">23</a>  <strong>import</strong> org.dom4j.Entity;
<a name="24" href="#24">24</a>  <strong>import</strong> org.dom4j.Node;
<a name="25" href="#25">25</a>  
<a name="26" href="#26">26</a>  <strong>import</strong> org.xml.sax.SAXException;
<a name="27" href="#27">27</a>  
<a name="28" href="#28">28</a>  <em>/**<em>*</em></em>
<a name="29" href="#29">29</a>  <em> * &lt;p></em>
<a name="30" href="#30">30</a>  <em> * &lt;code>HTMLWriter&lt;/code> takes a DOM4J tree and formats it to a stream as</em>
<a name="31" href="#31">31</a>  <em> * HTML. This formatter is similar to XMLWriter but it outputs the text of CDATA</em>
<a name="32" href="#32">32</a>  <em> * and Entity sections rather than the serialised format as in XML, it has an</em>
<a name="33" href="#33">33</a>  <em> * XHTML mode, it retains whitespace in certain elements such as &amp;lt;PRE&amp;gt;,</em>
<a name="34" href="#34">34</a>  <em> * and it supports certain elements which have no corresponding close tag such</em>
<a name="35" href="#35">35</a>  <em> * as for &amp;lt;BR&amp;gt; and &amp;lt;P&amp;gt;.</em>
<a name="36" href="#36">36</a>  <em> * &lt;/p></em>
<a name="37" href="#37">37</a>  <em> * </em>
<a name="38" href="#38">38</a>  <em> * &lt;p></em>
<a name="39" href="#39">39</a>  <em> * The OutputFormat passed in to the constructor is checked for isXHTML() and</em>
<a name="40" href="#40">40</a>  <em> * isExpandEmptyElements(). See {@link OutputFormat OutputFormat}for details.</em>
<a name="41" href="#41">41</a>  <em> * Here are the rules for &lt;b>this class &lt;/b> based on an OutputFormat, "format",</em>
<a name="42" href="#42">42</a>  <em> * passed in to the constructor: &lt;br/>&lt;br/></em>
<a name="43" href="#43">43</a>  <em> * </em>
<a name="44" href="#44">44</a>  <em> * &lt;ul></em>
<a name="45" href="#45">45</a>  <em> * &lt;li>If an element is in {@link #getOmitElementCloseSet()</em>
<a name="46" href="#46">46</a>  <em> * getOmitElementCloseSet}, then it is treated specially:</em>
<a name="47" href="#47">47</a>  <em> * </em>
<a name="48" href="#48">48</a>  <em> * &lt;ul></em>
<a name="49" href="#49">49</a>  <em> * &lt;li>It never expands, since some browsers treat this as two separate</em>
<a name="50" href="#50">50</a>  <em> * Horizontal Rules: &amp;lt;HR&amp;gt;&amp;lt;/HR&amp;gt;&lt;/li></em>
<a name="51" href="#51">51</a>  <em> * &lt;li>If {@link org.dom4j.io.OutputFormat#isXHTML() format.isXHTML()}, then</em>
<a name="52" href="#52">52</a>  <em> * it has a space before the closing single-tag slash, since Netscape 4.x-</em>
<a name="53" href="#53">53</a>  <em> * treats this: &amp;lt;HR /&amp;gt; as an element named "HR" with an attribute named</em>
<a name="54" href="#54">54</a>  <em> * "/", but that's better than when it refuses to recognize this: &amp;lt;hr/&amp;gt;</em>
<a name="55" href="#55">55</a>  <em> * which it thinks is an element named "HR/".&lt;/li></em>
<a name="56" href="#56">56</a>  <em> * &lt;/ul></em>
<a name="57" href="#57">57</a>  <em> * </em>
<a name="58" href="#58">58</a>  <em> * &lt;/li></em>
<a name="59" href="#59">59</a>  <em> * &lt;li>If {@link org.dom4j.io.OutputFormat#isXHTML() format.isXHTML()}, all</em>
<a name="60" href="#60">60</a>  <em> * elements must have either a close element, or be a closed single tag.&lt;/li></em>
<a name="61" href="#61">61</a>  <em> * &lt;li>If {@link org.dom4j.io.OutputFormat#isExpandEmptyElements()</em>
<a name="62" href="#62">62</a>  <em> * format.isExpandEmptyElements()}() is true, all elements are expanded except</em>
<a name="63" href="#63">63</a>  <em> * as above.&lt;/li></em>
<a name="64" href="#64">64</a>  <em> * &lt;/ul></em>
<a name="65" href="#65">65</a>  <em> * </em>
<a name="66" href="#66">66</a>  <em> * &lt;b>Examples &lt;/b></em>
<a name="67" href="#67">67</a>  <em> * &lt;/p></em>
<a name="68" href="#68">68</a>  <em> * </em>
<a name="69" href="#69">69</a>  <em> * &lt;p></em>
<a name="70" href="#70">70</a>  <em> * &lt;/p></em>
<a name="71" href="#71">71</a>  <em> * </em>
<a name="72" href="#72">72</a>  <em> * &lt;p></em>
<a name="73" href="#73">73</a>  <em> * If isXHTML == true, CDATA sections look like this:</em>
<a name="74" href="#74">74</a>  <em> * </em>
<a name="75" href="#75">75</a>  <em> * &lt;PRE></em>
<a name="76" href="#76">76</a>  <em> * </em>
<a name="77" href="#77">77</a>  <em> * &lt;b>&amp;lt;myelement&amp;gt;&amp;lt;![CDATA[My data]]&amp;gt;&amp;lt;/myelement&amp;gt; &lt;/b></em>
<a name="78" href="#78">78</a>  <em> * </em>
<a name="79" href="#79">79</a>  <em> * &lt;/PRE></em>
<a name="80" href="#80">80</a>  <em> * </em>
<a name="81" href="#81">81</a>  <em> * Otherwise, they look like this:</em>
<a name="82" href="#82">82</a>  <em> * </em>
<a name="83" href="#83">83</a>  <em> * &lt;PRE></em>
<a name="84" href="#84">84</a>  <em> * </em>
<a name="85" href="#85">85</a>  <em> * &lt;b>&amp;lt;myelement&amp;gt;My data&amp;lt;/myelement&amp;gt; &lt;/b></em>
<a name="86" href="#86">86</a>  <em> * </em>
<a name="87" href="#87">87</a>  <em> * &lt;/PRE></em>
<a name="88" href="#88">88</a>  <em> * </em>
<a name="89" href="#89">89</a>  <em> * &lt;/p></em>
<a name="90" href="#90">90</a>  <em> * </em>
<a name="91" href="#91">91</a>  <em> * &lt;p></em>
<a name="92" href="#92">92</a>  <em> * Basically, {@link OutputFormat.isXHTML() OutputFormat.isXHTML()} ==</em>
<a name="93" href="#93">93</a>  <em> * &lt;code>true&lt;/code> will produce valid XML, while {@link</em>
<a name="94" href="#94">94</a>  <em> * org.dom4j.io.OutputFormat#isExpandEmptyElements()</em>
<a name="95" href="#95">95</a>  <em> * format.isExpandEmptyElements()} determines whether empty elements are</em>
<a name="96" href="#96">96</a>  <em> * expanded if isXHTML is true, excepting the special HTML single tags.</em>
<a name="97" href="#97">97</a>  <em> * &lt;/p></em>
<a name="98" href="#98">98</a>  <em> * </em>
<a name="99" href="#99">99</a>  <em> * &lt;p></em>
<a name="100" href="#100">100</a> <em> * Also, HTMLWriter handles tags whose contents should be preformatted, that is,</em>
<a name="101" href="#101">101</a> <em> * whitespace-preserved. By default, this set includes the tags &amp;lt;PRE&amp;gt;,</em>
<a name="102" href="#102">102</a> <em> * &amp;lt;SCRIPT&amp;gt;, &amp;lt;STYLE&amp;gt;, and &amp;lt;TEXTAREA&amp;gt;, case insensitively. It</em>
<a name="103" href="#103">103</a> <em> * does not include &amp;lt;IFRAME&amp;gt;. Other tags, such as &amp;lt;CODE&amp;gt;,</em>
<a name="104" href="#104">104</a> <em> * &amp;lt;KBD&amp;gt;, &amp;lt;TT&amp;gt;, &amp;lt;VAR&amp;gt;, are usually rendered in a different</em>
<a name="105" href="#105">105</a> <em> * font in most browsers, but don't preserve whitespace, so they also don't</em>
<a name="106" href="#106">106</a> <em> * appear in the default list. HTML Comments are always whitespace-preserved.</em>
<a name="107" href="#107">107</a> <em> * However, the parser you use may store comments with linefeed-only text nodes</em>
<a name="108" href="#108">108</a> <em> * (\n) even if your platform uses another line.separator character, and</em>
<a name="109" href="#109">109</a> <em> * HTMLWriter outputs Comment nodes exactly as the DOM is set up by the parser.</em>
<a name="110" href="#110">110</a> <em> * See examples and discussion here: {@link#setPreformattedTags(java.util.Set)</em>
<a name="111" href="#111">111</a> <em> * setPreformattedTags}</em>
<a name="112" href="#112">112</a> <em> * &lt;/p></em>
<a name="113" href="#113">113</a> <em> * </em>
<a name="114" href="#114">114</a> <em> * &lt;p></em>
<a name="115" href="#115">115</a> <em> * &lt;b>Examples &lt;/b></em>
<a name="116" href="#116">116</a> <em> * &lt;/p></em>
<a name="117" href="#117">117</a> <em> * &lt;blockquote></em>
<a name="118" href="#118">118</a> <em> * &lt;p></em>
<a name="119" href="#119">119</a> <em> * &lt;b>Pretty Printing &lt;/b></em>
<a name="120" href="#120">120</a> <em> * &lt;/p></em>
<a name="121" href="#121">121</a> <em> * </em>
<a name="122" href="#122">122</a> <em> * &lt;p></em>
<a name="123" href="#123">123</a> <em> * This example shows how to pretty print a string containing a valid HTML</em>
<a name="124" href="#124">124</a> <em> * document to a string. You can also just call the static methods of this</em>
<a name="125" href="#125">125</a> <em> * class: &lt;br></em>
<a name="126" href="#126">126</a> <em> * {@link #prettyPrintHTML(String) prettyPrintHTML(String)}or &lt;br></em>
<a name="127" href="#127">127</a> <em> * {@link #prettyPrintHTML(String,boolean,boolean,boolean,boolean)</em>
<a name="128" href="#128">128</a> <em> * prettyPrintHTML(String,boolean,boolean,boolean,boolean)} or, &lt;br></em>
<a name="129" href="#129">129</a> <em> * {@link #prettyPrintXHTML(String) prettyPrintXHTML(String)}for XHTML (note</em>
<a name="130" href="#130">130</a> <em> * the X)</em>
<a name="131" href="#131">131</a> <em> * &lt;/p></em>
<a name="132" href="#132">132</a> <em> * </em>
<a name="133" href="#133">133</a> <em> * &lt;pre></em>
<a name="134" href="#134">134</a> <em> * String testPrettyPrint(String html) {</em>
<a name="135" href="#135">135</a> <em> *     StringWriter sw = new StringWriter();</em>
<a name="136" href="#136">136</a> <em> *     OutputFormat format = OutputFormat.createPrettyPrint();</em>
<a name="137" href="#137">137</a> <em> *     // These are the default values for createPrettyPrint,</em>
<a name="138" href="#138">138</a> <em> *     // so you needn't set them:</em>
<a name="139" href="#139">139</a> <em> *     // format.setNewlines(true);</em>
<a name="140" href="#140">140</a> <em> *     // format.setTrimText(true);&amp;lt;/font&amp;gt;</em>
<a name="141" href="#141">141</a> <em> *     format.setXHTML(true);</em>
<a name="142" href="#142">142</a> <em> *     HTMLWriter writer = new HTMLWriter(sw, format);</em>
<a name="143" href="#143">143</a> <em> *     Document document = DocumentHelper.parseText(html);</em>
<a name="144" href="#144">144</a> <em> *     writer.write(document);</em>
<a name="145" href="#145">145</a> <em> *     writer.flush();</em>
<a name="146" href="#146">146</a> <em> *     return sw.toString();</em>
<a name="147" href="#147">147</a> <em> * }</em>
<a name="148" href="#148">148</a> <em> * &lt;/pre></em>
<a name="149" href="#149">149</a> <em> * </em>
<a name="150" href="#150">150</a> <em> * &lt;p></em>
<a name="151" href="#151">151</a> <em> * This example shows how to create a "squeezed" document, but one that will</em>
<a name="152" href="#152">152</a> <em> * work in browsers even if the browser line length is limited. No newlines are</em>
<a name="153" href="#153">153</a> <em> * included, no extra whitespace at all, except where it it required by</em>
<a name="154" href="#154">154</a> <em> * {@link #setPreformattedTags(java.util.Set) setPreformattedTags}.</em>
<a name="155" href="#155">155</a> <em> * &lt;/p></em>
<a name="156" href="#156">156</a> <em> * </em>
<a name="157" href="#157">157</a> <em> * &lt;pre></em>
<a name="158" href="#158">158</a> <em> * String testCrunch(String html) {</em>
<a name="159" href="#159">159</a> <em> *     StringWriter sw = new StringWriter();</em>
<a name="160" href="#160">160</a> <em> *     OutputFormat format = OutputFormat.createPrettyPrint();</em>
<a name="161" href="#161">161</a> <em> *     format.setNewlines(false);</em>
<a name="162" href="#162">162</a> <em> *     format.setTrimText(true);</em>
<a name="163" href="#163">163</a> <em> *     format.setIndent(&amp;quot;&amp;quot;);</em>
<a name="164" href="#164">164</a> <em> *     format.setXHTML(true);</em>
<a name="165" href="#165">165</a> <em> *     format.setExpandEmptyElements(false);</em>
<a name="166" href="#166">166</a> <em> *     format.setNewLineAfterNTags(20);</em>
<a name="167" href="#167">167</a> <em> *     org.dom4j.io.HTMLWriter writer = new HTMLWriter(sw, format);</em>
<a name="168" href="#168">168</a> <em> *     org.dom4j.Document document = DocumentHelper.parseText(html);</em>
<a name="169" href="#169">169</a> <em> *     writer.write(document);</em>
<a name="170" href="#170">170</a> <em> *     writer.flush();</em>
<a name="171" href="#171">171</a> <em> *     return sw.toString();</em>
<a name="172" href="#172">172</a> <em> * }</em>
<a name="173" href="#173">173</a> <em> * &lt;/pre></em>
<a name="174" href="#174">174</a> <em> * </em>
<a name="175" href="#175">175</a> <em> * &lt;/blockquote></em>
<a name="176" href="#176">176</a> <em> * </em>
<a name="177" href="#177">177</a> <em> * @author &lt;a href="<a href="mailto:james.strachan@metastuff.com" target="alexandria_uri">mailto:james.strachan@metastuff.com</a>">James Strachan &lt;/a></em>
<a name="178" href="#178">178</a> <em> * @author Laramie Crocker</em>
<a name="179" href="#179">179</a> <em> * @version $Revision: 1.1 $</em>
<a name="180" href="#180">180</a> <em> */</em>
<a name="181" href="#181">181</a> <strong>public</strong> <strong>class</strong> <a href="../../../org/dom4j/io/HTMLWriter.html">HTMLWriter</a> <strong>extends</strong> <a href="../../../org/dom4j/io/XMLWriter.html">XMLWriter</a> {
<a name="182" href="#182">182</a>     <strong>private</strong> <strong>static</strong> String lineSeparator = System.getProperty(<span class="string">"line.separator"</span>);
<a name="183" href="#183">183</a> 
<a name="184" href="#184">184</a>     <strong>protected</strong> <strong>static</strong> <strong>final</strong> HashSet DEFAULT_PREFORMATTED_TAGS;
<a name="185" href="#185">185</a> 
<a name="186" href="#186">186</a>     <strong>static</strong> {
<a name="187" href="#187">187</a>         <em class="comment">// If you change this list, update the javadoc examples, above in the</em>
<a name="188" href="#188">188</a>         <em class="comment">// class javadoc, in writeElement, and in setPreformattedTags().</em>
<a name="189" href="#189">189</a>         DEFAULT_PREFORMATTED_TAGS = <strong>new</strong> HashSet();
<a name="190" href="#190">190</a>         DEFAULT_PREFORMATTED_TAGS.add(<span class="string">"PRE"</span>);
<a name="191" href="#191">191</a>         DEFAULT_PREFORMATTED_TAGS.add(<span class="string">"SCRIPT"</span>);
<a name="192" href="#192">192</a>         DEFAULT_PREFORMATTED_TAGS.add(<span class="string">"STYLE"</span>);
<a name="193" href="#193">193</a>         DEFAULT_PREFORMATTED_TAGS.add(<span class="string">"TEXTAREA"</span>);
<a name="194" href="#194">194</a>     }
<a name="195" href="#195">195</a> 
<a name="196" href="#196">196</a>     <strong>protected</strong> <strong>static</strong> <strong>final</strong> <a href="../../../org/dom4j/io/OutputFormat.html">OutputFormat</a> DEFAULT_HTML_FORMAT;
<a name="197" href="#197">197</a> 
<a name="198" href="#198">198</a>     <strong>static</strong> {
<a name="199" href="#199">199</a>         DEFAULT_HTML_FORMAT = <strong>new</strong> <a href="../../../org/dom4j/io/OutputFormat.html">OutputFormat</a>(<span class="string">"  "</span>, <strong>true</strong>);
<a name="200" href="#200">200</a>         DEFAULT_HTML_FORMAT.setTrimText(<strong>true</strong>);
<a name="201" href="#201">201</a>         DEFAULT_HTML_FORMAT.setSuppressDeclaration(<strong>true</strong>);
<a name="202" href="#202">202</a>     }
<a name="203" href="#203">203</a> 
<a name="204" href="#204">204</a>     <strong>private</strong> Stack formatStack = <strong>new</strong> Stack();
<a name="205" href="#205">205</a> 
<a name="206" href="#206">206</a>     <strong>private</strong> String lastText = <span class="string">""</span>;
<a name="207" href="#207">207</a> 
<a name="208" href="#208">208</a>     <strong>private</strong> <strong>int</strong> tagsOuput = 0;
<a name="209" href="#209">209</a> 
<a name="210" href="#210">210</a>     <em class="comment">// legal values are 0+, but -1 signifies lazy initialization.</em>
<a name="211" href="#211">211</a>     <strong>private</strong> <strong>int</strong> newLineAfterNTags = -1;
<a name="212" href="#212">212</a> 
<a name="213" href="#213">213</a>     <strong>private</strong> HashSet preformattedTags = DEFAULT_PREFORMATTED_TAGS;
<a name="214" href="#214">214</a> 
<a name="215" href="#215">215</a>     <em>/**<em>*</em></em>
<a name="216" href="#216">216</a> <em>     * Used to store the qualified element names which should have no close</em>
<a name="217" href="#217">217</a> <em>     * element tag</em>
<a name="218" href="#218">218</a> <em>     */</em>
<a name="219" href="#219">219</a>     <strong>private</strong> HashSet omitElementCloseSet;
<a name="220" href="#220">220</a> 
<a name="221" href="#221">221</a>     <strong>public</strong> <a href="../../../org/dom4j/io/HTMLWriter.html">HTMLWriter</a>(Writer writer) {
<a name="222" href="#222">222</a>         <strong>super</strong>(writer, DEFAULT_HTML_FORMAT);
<a name="223" href="#223">223</a>     }
<a name="224" href="#224">224</a> 
<a name="225" href="#225">225</a>     <strong>public</strong> <a href="../../../org/dom4j/io/HTMLWriter.html">HTMLWriter</a>(Writer writer, <a href="../../../org/dom4j/io/OutputFormat.html">OutputFormat</a> format) {
<a name="226" href="#226">226</a>         <strong>super</strong>(writer, format);
<a name="227" href="#227">227</a>     }
<a name="228" href="#228">228</a> 
<a name="229" href="#229">229</a>     <strong>public</strong> <a href="../../../org/dom4j/io/HTMLWriter.html">HTMLWriter</a>() throws UnsupportedEncodingException {
<a name="230" href="#230">230</a>         <strong>super</strong>(DEFAULT_HTML_FORMAT);
<a name="231" href="#231">231</a>     }
<a name="232" href="#232">232</a> 
<a name="233" href="#233">233</a>     <strong>public</strong> <a href="../../../org/dom4j/io/HTMLWriter.html">HTMLWriter</a>(<a href="../../../org/dom4j/io/OutputFormat.html">OutputFormat</a> format) throws UnsupportedEncodingException {
<a name="234" href="#234">234</a>         <strong>super</strong>(format);
<a name="235" href="#235">235</a>     }
<a name="236" href="#236">236</a> 
<a name="237" href="#237">237</a>     <strong>public</strong> <a href="../../../org/dom4j/io/HTMLWriter.html">HTMLWriter</a>(OutputStream out) throws UnsupportedEncodingException {
<a name="238" href="#238">238</a>         <strong>super</strong>(out, DEFAULT_HTML_FORMAT);
<a name="239" href="#239">239</a>     }
<a name="240" href="#240">240</a> 
<a name="241" href="#241">241</a>     <strong>public</strong> <a href="../../../org/dom4j/io/HTMLWriter.html">HTMLWriter</a>(OutputStream out, <a href="../../../org/dom4j/io/OutputFormat.html">OutputFormat</a> format)
<a name="242" href="#242">242</a>             throws UnsupportedEncodingException {
<a name="243" href="#243">243</a>         <strong>super</strong>(out, format);
<a name="244" href="#244">244</a>     }
<a name="245" href="#245">245</a> 
<a name="246" href="#246">246</a>     <strong>public</strong> <strong>void</strong> startCDATA() throws SAXException {
<a name="247" href="#247">247</a>     }
<a name="248" href="#248">248</a> 
<a name="249" href="#249">249</a>     <strong>public</strong> <strong>void</strong> endCDATA() throws SAXException {
<a name="250" href="#250">250</a>     }
<a name="251" href="#251">251</a> 
<a name="252" href="#252">252</a>     <em class="comment">// Overloaded methods</em>
<a name="253" href="#253">253</a>     <em class="comment">// added isXHTML() stuff so you get the CDATA brackets if you desire.</em>
<a name="254" href="#254">254</a>     <strong>protected</strong> <strong>void</strong> writeCDATA(String text) throws IOException {
<a name="255" href="#255">255</a>         <em class="comment">// XXX: Should we escape entities?</em>
<a name="256" href="#256">256</a>         <em class="comment">// writer.write( escapeElementEntities( text ) );</em>
<a name="257" href="#257">257</a>         <strong>if</strong> (getOutputFormat().isXHTML()) {
<a name="258" href="#258">258</a>             <strong>super</strong>.writeCDATA(text);
<a name="259" href="#259">259</a>         } <strong>else</strong> {
<a name="260" href="#260">260</a>             writer.write(text);
<a name="261" href="#261">261</a>         }
<a name="262" href="#262">262</a> 
<a name="263" href="#263">263</a>         lastOutputNodeType = Node.CDATA_SECTION_NODE;
<a name="264" href="#264">264</a>     }
<a name="265" href="#265">265</a> 
<a name="266" href="#266">266</a>     <strong>protected</strong> <strong>void</strong> writeEntity(<a href="../../../org/dom4j/Entity.html">Entity</a> entity) throws IOException {
<a name="267" href="#267">267</a>         writer.write(entity.getText());
<a name="268" href="#268">268</a>         lastOutputNodeType = Node.ENTITY_REFERENCE_NODE;
<a name="269" href="#269">269</a>     }
<a name="270" href="#270">270</a> 
<a name="271" href="#271">271</a>     <strong>protected</strong> <strong>void</strong> writeDeclaration() throws IOException {
<a name="272" href="#272">272</a>     }
<a name="273" href="#273">273</a> 
<a name="274" href="#274">274</a>     <strong>protected</strong> <strong>void</strong> writeString(String text) throws IOException {
<a name="275" href="#275">275</a>         <em class="comment">/*</em>
<a name="276" href="#276">276</a> <em class="comment">         * DOM stores \n at the end of text nodes that are newlines. This is</em>
<a name="277" href="#277">277</a> <em class="comment">         * significant if we are in a PRE section. However, we only want to</em>
<a name="278" href="#278">278</a> <em class="comment">         * output the system line.separator, not \n. This is a little brittle,</em>
<a name="279" href="#279">279</a> <em class="comment">         * but this function appears to be called with these lineseparators as a</em>
<a name="280" href="#280">280</a> <em class="comment">         * separate TEXT_NODE. If we are in a preformatted section, output the</em>
<a name="281" href="#281">281</a> <em class="comment">         * right line.separator, otherwise ditch. If the single \n character is</em>
<a name="282" href="#282">282</a> <em class="comment">         * not the text, then do the super thing to output the text.</em>
<a name="283" href="#283">283</a> <em class="comment">         * </em>
<a name="284" href="#284">284</a> <em class="comment">         * Also, we store the last text that was not a \n since it may be used</em>
<a name="285" href="#285">285</a> <em class="comment">         * by writeElement in this class to line up preformatted tags.</em>
<a name="286" href="#286">286</a> <em class="comment">         */</em>
<a name="287" href="#287">287</a>         <strong>if</strong> (text.equals(<span class="string">"\n"</span>)) {
<a name="288" href="#288">288</a>             <strong>if</strong> (!formatStack.empty()) {
<a name="289" href="#289">289</a>                 <strong>super</strong>.writeString(lineSeparator);
<a name="290" href="#290">290</a>             }
<a name="291" href="#291">291</a> 
<a name="292" href="#292">292</a>             <strong>return</strong>;
<a name="293" href="#293">293</a>         }
<a name="294" href="#294">294</a> 
<a name="295" href="#295">295</a>         lastText = text;
<a name="296" href="#296">296</a> 
<a name="297" href="#297">297</a>         <strong>if</strong> (formatStack.empty()) {
<a name="298" href="#298">298</a>             <strong>super</strong>.writeString(text.trim());
<a name="299" href="#299">299</a>         } <strong>else</strong> {
<a name="300" href="#300">300</a>             <strong>super</strong>.writeString(text);
<a name="301" href="#301">301</a>         }
<a name="302" href="#302">302</a>     }
<a name="303" href="#303">303</a> 
<a name="304" href="#304">304</a>     <em>/**<em>*</em></em>
<a name="305" href="#305">305</a> <em>     * Overriden method to not close certain element names to avoid wierd</em>
<a name="306" href="#306">306</a> <em>     * behaviour from browsers for versions up to 5.x</em>
<a name="307" href="#307">307</a> <em>     * </em>
<a name="308" href="#308">308</a> <em>     * @param qualifiedName</em>
<a name="309" href="#309">309</a> <em>     *            DOCUMENT ME!</em>
<a name="310" href="#310">310</a> <em>     * </em>
<a name="311" href="#311">311</a> <em>     * @throws IOException</em>
<a name="312" href="#312">312</a> <em>     *             DOCUMENT ME!</em>
<a name="313" href="#313">313</a> <em>     */</em>
<a name="314" href="#314">314</a>     <strong>protected</strong> <strong>void</strong> writeClose(String qualifiedName) throws IOException {
<a name="315" href="#315">315</a>         <strong>if</strong> (!omitElementClose(qual<strong>if</strong>iedName)) {
<a name="316" href="#316">316</a>             <strong>super</strong>.writeClose(qualifiedName);
<a name="317" href="#317">317</a>         }
<a name="318" href="#318">318</a>     }
<a name="319" href="#319">319</a> 
<a name="320" href="#320">320</a>     <strong>protected</strong> <strong>void</strong> writeEmptyElementClose(String qualifiedName)
<a name="321" href="#321">321</a>             throws IOException {
<a name="322" href="#322">322</a>         <strong>if</strong> (getOutputFormat().isXHTML()) {
<a name="323" href="#323">323</a>             <em class="comment">// xhtml, always check with format object whether to expand or not.</em>
<a name="324" href="#324">324</a>             <strong>if</strong> (omitElementClose(qual<strong>if</strong>iedName)) {
<a name="325" href="#325">325</a>                 <em class="comment">// it was a special omit tag, do it the XHTML way: "&lt;br/>",</em>
<a name="326" href="#326">326</a>                 <em class="comment">// ignoring the expansion option, since &lt;br>&lt;/br> is OK XML,</em>
<a name="327" href="#327">327</a>                 <em class="comment">// but produces twice the linefeeds desired in the browser.</em>
<a name="328" href="#328">328</a>                 <em class="comment">// for netscape 4.7, though all are fine with it, write a space</em>
<a name="329" href="#329">329</a>                 <em class="comment">// before the close slash.</em>
<a name="330" href="#330">330</a>                 writer.write(<span class="string">" />"</span>);
<a name="331" href="#331">331</a>             } <strong>else</strong> {
<a name="332" href="#332">332</a>                 <strong>super</strong>.writeEmptyElementClose(qualifiedName);
<a name="333" href="#333">333</a>             }
<a name="334" href="#334">334</a>         } <strong>else</strong> {
<a name="335" href="#335">335</a>             <em class="comment">// html, not xhtml</em>
<a name="336" href="#336">336</a>             <strong>if</strong> (omitElementClose(qual<strong>if</strong>iedName)) {
<a name="337" href="#337">337</a>                 <em class="comment">// it was a special omit tag, do it the old html way: "&lt;br>".</em>
<a name="338" href="#338">338</a>                 writer.write(<span class="string">">"</span>);
<a name="339" href="#339">339</a>             } <strong>else</strong> {
<a name="340" href="#340">340</a>                 <em class="comment">// it was NOT a special omit tag, check with format object</em>
<a name="341" href="#341">341</a>                 <em class="comment">// whether to expand or not.</em>
<a name="342" href="#342">342</a>                 <strong>super</strong>.writeEmptyElementClose(qualifiedName);
<a name="343" href="#343">343</a>             }
<a name="344" href="#344">344</a>         }
<a name="345" href="#345">345</a>     }
<a name="346" href="#346">346</a> 
<a name="347" href="#347">347</a>     <strong>protected</strong> <strong>boolean</strong> omitElementClose(String qualifiedName) {
<a name="348" href="#348">348</a>         <strong>return</strong> internalGetOmitElementCloseSet().contains(
<a name="349" href="#349">349</a>                 qualifiedName.toUpperCase());
<a name="350" href="#350">350</a>     }
<a name="351" href="#351">351</a> 
<a name="352" href="#352">352</a>     <strong>private</strong> HashSet internalGetOmitElementCloseSet() {
<a name="353" href="#353">353</a>         <strong>if</strong> (omitElementCloseSet == <strong>null</strong>) {
<a name="354" href="#354">354</a>             omitElementCloseSet = <strong>new</strong> HashSet();
<a name="355" href="#355">355</a>             loadOmitElementCloseSet(omitElementCloseSet);
<a name="356" href="#356">356</a>         }
<a name="357" href="#357">357</a> 
<a name="358" href="#358">358</a>         <strong>return</strong> omitElementCloseSet;
<a name="359" href="#359">359</a>     }
<a name="360" href="#360">360</a> 
<a name="361" href="#361">361</a>     <em class="comment">// If you change this, change the javadoc for getOmitElementCloseSet.</em>
<a name="362" href="#362">362</a>     <strong>protected</strong> <strong>void</strong> loadOmitElementCloseSet(Set set) {
<a name="363" href="#363">363</a>         set.add(<span class="string">"AREA"</span>);
<a name="364" href="#364">364</a>         set.add(<span class="string">"BASE"</span>);
<a name="365" href="#365">365</a>         set.add(<span class="string">"BR"</span>);
<a name="366" href="#366">366</a>         set.add(<span class="string">"COL"</span>);
<a name="367" href="#367">367</a>         set.add(<span class="string">"HR"</span>);
<a name="368" href="#368">368</a>         set.add(<span class="string">"IMG"</span>);
<a name="369" href="#369">369</a>         set.add(<span class="string">"INPUT"</span>);
<a name="370" href="#370">370</a>         set.add(<span class="string">"LINK"</span>);
<a name="371" href="#371">371</a>         set.add(<span class="string">"META"</span>);
<a name="372" href="#372">372</a>         set.add(<span class="string">"P"</span>);
<a name="373" href="#373">373</a>         set.add(<span class="string">"PARAM"</span>);
<a name="374" href="#374">374</a>     }
<a name="375" href="#375">375</a> 
<a name="376" href="#376">376</a>     <em class="comment">// let the people see the set, but not modify it.</em>
<a name="377" href="#377">377</a> 
<a name="378" href="#378">378</a>     <em>/**<em>*</em></em>
<a name="379" href="#379">379</a> <em>     * A clone of the Set of elements that can have their close-tags omitted. By</em>
<a name="380" href="#380">380</a> <em>     * default it should be "AREA", "BASE", "BR", "COL", "HR", "IMG", "INPUT",</em>
<a name="381" href="#381">381</a> <em>     * "LINK", "META", "P", "PARAM"</em>
<a name="382" href="#382">382</a> <em>     * </em>
<a name="383" href="#383">383</a> <em>     * @return A clone of the Set.</em>
<a name="384" href="#384">384</a> <em>     */</em>
<a name="385" href="#385">385</a>     <strong>public</strong> Set getOmitElementCloseSet() {
<a name="386" href="#386">386</a>         <strong>return</strong> (Set) (internalGetOmitElementCloseSet().clone());
<a name="387" href="#387">387</a>     }
<a name="388" href="#388">388</a> 
<a name="389" href="#389">389</a>     <em>/**<em>*</em></em>
<a name="390" href="#390">390</a> <em>     * To use the empty set, pass an empty Set, or null:</em>
<a name="391" href="#391">391</a> <em>     * </em>
<a name="392" href="#392">392</a> <em>     * &lt;pre></em>
<a name="393" href="#393">393</a> <em>     * </em>
<a name="394" href="#394">394</a> <em>     * </em>
<a name="395" href="#395">395</a> <em>     *       setOmitElementCloseSet(new HashSet());</em>
<a name="396" href="#396">396</a> <em>     *     or</em>
<a name="397" href="#397">397</a> <em>     *       setOmitElementCloseSet(null);</em>
<a name="398" href="#398">398</a> <em>     * </em>
<a name="399" href="#399">399</a> <em>     *  </em>
<a name="400" href="#400">400</a> <em>     * &lt;/pre></em>
<a name="401" href="#401">401</a> <em>     * </em>
<a name="402" href="#402">402</a> <em>     * @param newSet</em>
<a name="403" href="#403">403</a> <em>     *            DOCUMENT ME!</em>
<a name="404" href="#404">404</a> <em>     */</em>
<a name="405" href="#405">405</a>     <strong>public</strong> <strong>void</strong> setOmitElementCloseSet(Set newSet) {
<a name="406" href="#406">406</a>         <em class="comment">// resets, and safely empties it out if newSet is null.</em>
<a name="407" href="#407">407</a>         omitElementCloseSet = <strong>new</strong> HashSet();
<a name="408" href="#408">408</a> 
<a name="409" href="#409">409</a>         <strong>if</strong> (newSet != <strong>null</strong>) {
<a name="410" href="#410">410</a>             omitElementCloseSet = <strong>new</strong> HashSet();
<a name="411" href="#411">411</a> 
<a name="412" href="#412">412</a>             Object aTag;
<a name="413" href="#413">413</a>             Iterator iter = newSet.iterator();
<a name="414" href="#414">414</a> 
<a name="415" href="#415">415</a>             <strong>while</strong> (iter.hasNext()) {
<a name="416" href="#416">416</a>                 aTag = iter.next();
<a name="417" href="#417">417</a> 
<a name="418" href="#418">418</a>                 <strong>if</strong> (aTag != <strong>null</strong>) {
<a name="419" href="#419">419</a>                     omitElementCloseSet.add(aTag.toString().toUpperCase());
<a name="420" href="#420">420</a>                 }
<a name="421" href="#421">421</a>             }
<a name="422" href="#422">422</a>         }
<a name="423" href="#423">423</a>     }
<a name="424" href="#424">424</a> 
<a name="425" href="#425">425</a>     <em>/**<em>*</em></em>
<a name="426" href="#426">426</a> <em>     * @see #setPreformattedTags(java.util.Set) setPreformattedTags</em>
<a name="427" href="#427">427</a> <em>     */</em>
<a name="428" href="#428">428</a>     <strong>public</strong> Set getPreformattedTags() {
<a name="429" href="#429">429</a>         <strong>return</strong> (Set) (preformattedTags.clone());
<a name="430" href="#430">430</a>     }
<a name="431" href="#431">431</a> 
<a name="432" href="#432">432</a>     <em>/**<em>*</em></em>
<a name="433" href="#433">433</a> <em>     * &lt;p></em>
<a name="434" href="#434">434</a> <em>     * Override the default set, which includes PRE, SCRIPT, STYLE, and</em>
<a name="435" href="#435">435</a> <em>     * TEXTAREA, case insensitively.</em>
<a name="436" href="#436">436</a> <em>     * &lt;/p></em>
<a name="437" href="#437">437</a> <em>     * </em>
<a name="438" href="#438">438</a> <em>     * &lt;p></em>
<a name="439" href="#439">439</a> <em>     * &lt;b>Setting Preformatted Tags &lt;/b></em>
<a name="440" href="#440">440</a> <em>     * &lt;/p></em>
<a name="441" href="#441">441</a> <em>     * </em>
<a name="442" href="#442">442</a> <em>     * &lt;p></em>
<a name="443" href="#443">443</a> <em>     * Pass in a Set of Strings, one for each tag name that should be treated</em>
<a name="444" href="#444">444</a> <em>     * like a PRE tag. You may pass in null or an empty Set to assign the empty</em>
<a name="445" href="#445">445</a> <em>     * set, in which case no tags will be treated as preformatted, except that</em>
<a name="446" href="#446">446</a> <em>     * HTML Comments will continue to be preformatted. If a tag is included in</em>
<a name="447" href="#447">447</a> <em>     * the set of preformatted tags, all whitespace within the tag will be</em>
<a name="448" href="#448">448</a> <em>     * preserved, including whitespace on the same line preceding the close tag.</em>
<a name="449" href="#449">449</a> <em>     * This will generally make the close tag not line up with the start tag,</em>
<a name="450" href="#450">450</a> <em>     * but it preserves the intention of the whitespace within the tag.</em>
<a name="451" href="#451">451</a> <em>     * &lt;/p></em>
<a name="452" href="#452">452</a> <em>     * </em>
<a name="453" href="#453">453</a> <em>     * &lt;p></em>
<a name="454" href="#454">454</a> <em>     * The browser considers leading whitespace before the close tag to be</em>
<a name="455" href="#455">455</a> <em>     * significant, but leading whitespace before the open tag to be</em>
<a name="456" href="#456">456</a> <em>     * insignificant. For example, if the HTML author doesn't put the close</em>
<a name="457" href="#457">457</a> <em>     * TEXTAREA tag flush to the left margin, then the TEXTAREA control in the</em>
<a name="458" href="#458">458</a> <em>     * browser will have spaces on the last line inside the control. This may be</em>
<a name="459" href="#459">459</a> <em>     * the HTML author's intent. Similarly, in a PRE, the browser treats a</em>
<a name="460" href="#460">460</a> <em>     * flushed left close PRE tag as different from a close tag with leading</em>
<a name="461" href="#461">461</a> <em>     * whitespace. Again, this must be left up to the HTML author.</em>
<a name="462" href="#462">462</a> <em>     * &lt;/p></em>
<a name="463" href="#463">463</a> <em>     * </em>
<a name="464" href="#464">464</a> <em>     * &lt;p></em>
<a name="465" href="#465">465</a> <em>     * &lt;b>Examples &lt;/b></em>
<a name="466" href="#466">466</a> <em>     * &lt;/p></em>
<a name="467" href="#467">467</a> <em>     * &lt;blockquote></em>
<a name="468" href="#468">468</a> <em>     * &lt;p></em>
<a name="469" href="#469">469</a> <em>     * Here is an example of how you can set the PreformattedTags list using</em>
<a name="470" href="#470">470</a> <em>     * setPreformattedTags to include IFRAME, as well as the default set, if you</em>
<a name="471" href="#471">471</a> <em>     * have an instance of this class named myHTMLWriter:</em>
<a name="472" href="#472">472</a> <em>     * </em>
<a name="473" href="#473">473</a> <em>     * &lt;pre></em>
<a name="474" href="#474">474</a> <em>     * Set current = myHTMLWriter.getPreformattedTags();</em>
<a name="475" href="#475">475</a> <em>     * current.add(&amp;quot;IFRAME&amp;quot;);</em>
<a name="476" href="#476">476</a> <em>     * myHTMLWriter.setPreformattedTags(current);</em>
<a name="477" href="#477">477</a> <em>     * </em>
<a name="478" href="#478">478</a> <em>     * //The set is now &amp;lt;b&amp;gt;PRE, SCRIPT, STYLE, TEXTAREA, IFRAME&amp;lt;/b&amp;gt;</em>
<a name="479" href="#479">479</a> <em>     * </em>
<a name="480" href="#480">480</a> <em>     * </em>
<a name="481" href="#481">481</a> <em>     * &lt;/pre></em>
<a name="482" href="#482">482</a> <em>     * </em>
<a name="483" href="#483">483</a> <em>     * Similarly, you can simply replace it with your own:</em>
<a name="484" href="#484">484</a> <em>     * </em>
<a name="485" href="#485">485</a> <em>     * &lt;pre></em>
<a name="486" href="#486">486</a> <em>     * </em>
<a name="487" href="#487">487</a> <em>     * </em>
<a name="488" href="#488">488</a> <em>     *       HashSet newset = new HashSet();</em>
<a name="489" href="#489">489</a> <em>     *       newset.add(&amp;quot;PRE&amp;quot;);</em>
<a name="490" href="#490">490</a> <em>     *       newset.add(&amp;quot;TEXTAREA&amp;quot;);</em>
<a name="491" href="#491">491</a> <em>     *       myHTMLWriter.setPreformattedTags(newset);</em>
<a name="492" href="#492">492</a> <em>     * </em>
<a name="493" href="#493">493</a> <em>     *       //The set is now &amp;lt;b&amp;gt;{PRE, TEXTAREA}&amp;lt;/b&amp;gt;</em>
<a name="494" href="#494">494</a> <em>     * </em>
<a name="495" href="#495">495</a> <em>     *  </em>
<a name="496" href="#496">496</a> <em>     * &lt;/pre></em>
<a name="497" href="#497">497</a> <em>     * </em>
<a name="498" href="#498">498</a> <em>     * You can remove all tags from the preformatted tags list, with an empty</em>
<a name="499" href="#499">499</a> <em>     * set, like this:</em>
<a name="500" href="#500">500</a> <em>     * </em>
<a name="501" href="#501">501</a> <em>     * &lt;pre></em>
<a name="502" href="#502">502</a> <em>     * </em>
<a name="503" href="#503">503</a> <em>     * </em>
<a name="504" href="#504">504</a> <em>     *       myHTMLWriter.setPreformattedTags(new HashSet());</em>
<a name="505" href="#505">505</a> <em>     * </em>
<a name="506" href="#506">506</a> <em>     *       //The set is now &amp;lt;b&amp;gt;{}&amp;lt;/b&amp;gt;</em>
<a name="507" href="#507">507</a> <em>     * </em>
<a name="508" href="#508">508</a> <em>     *  </em>
<a name="509" href="#509">509</a> <em>     * &lt;/pre></em>
<a name="510" href="#510">510</a> <em>     * </em>
<a name="511" href="#511">511</a> <em>     * or with null, like this:</em>
<a name="512" href="#512">512</a> <em>     * </em>
<a name="513" href="#513">513</a> <em>     * &lt;pre></em>
<a name="514" href="#514">514</a> <em>     * </em>
<a name="515" href="#515">515</a> <em>     * </em>
<a name="516" href="#516">516</a> <em>     *       myHTMLWriter.setPreformattedTags(null);</em>
<a name="517" href="#517">517</a> <em>     * </em>
<a name="518" href="#518">518</a> <em>     *       //The set is now &amp;lt;b&amp;gt;{}&amp;lt;/b&amp;gt;</em>
<a name="519" href="#519">519</a> <em>     * </em>
<a name="520" href="#520">520</a> <em>     *  </em>
<a name="521" href="#521">521</a> <em>     * &lt;/pre></em>
<a name="522" href="#522">522</a> <em>     * </em>
<a name="523" href="#523">523</a> <em>     * &lt;/p></em>
<a name="524" href="#524">524</a> <em>     * &lt;/blockquote></em>
<a name="525" href="#525">525</a> <em>     * </em>
<a name="526" href="#526">526</a> <em>     * @param newSet</em>
<a name="527" href="#527">527</a> <em>     *            DOCUMENT ME!</em>
<a name="528" href="#528">528</a> <em>     */</em>
<a name="529" href="#529">529</a>     <strong>public</strong> <strong>void</strong> setPreformattedTags(Set newSet) {
<a name="530" href="#530">530</a>         <em class="comment">// no fancy merging, just set it, assuming they did a</em>
<a name="531" href="#531">531</a>         <em class="comment">// getExcludeTrimTags() first if they wanted to preserve the default</em>
<a name="532" href="#532">532</a>         <em class="comment">// set.</em>
<a name="533" href="#533">533</a>         <em class="comment">// resets, and safely empties it out if newSet is null.</em>
<a name="534" href="#534">534</a>         preformattedTags = <strong>new</strong> HashSet();
<a name="535" href="#535">535</a> 
<a name="536" href="#536">536</a>         <strong>if</strong> (newSet != <strong>null</strong>) {
<a name="537" href="#537">537</a>             Object aTag;
<a name="538" href="#538">538</a>             Iterator iter = newSet.iterator();
<a name="539" href="#539">539</a> 
<a name="540" href="#540">540</a>             <strong>while</strong> (iter.hasNext()) {
<a name="541" href="#541">541</a>                 aTag = iter.next();
<a name="542" href="#542">542</a> 
<a name="543" href="#543">543</a>                 <strong>if</strong> (aTag != <strong>null</strong>) {
<a name="544" href="#544">544</a>                     preformattedTags.add(aTag.toString().toUpperCase());
<a name="545" href="#545">545</a>                 }
<a name="546" href="#546">546</a>             }
<a name="547" href="#547">547</a>         }
<a name="548" href="#548">548</a>     }
<a name="549" href="#549">549</a> 
<a name="550" href="#550">550</a>     <em>/**<em>*</em></em>
<a name="551" href="#551">551</a> <em>     * DOCUMENT ME!</em>
<a name="552" href="#552">552</a> <em>     * </em>
<a name="553" href="#553">553</a> <em>     * @param qualifiedName</em>
<a name="554" href="#554">554</a> <em>     *            DOCUMENT ME!</em>
<a name="555" href="#555">555</a> <em>     * </em>
<a name="556" href="#556">556</a> <em>     * @return true if the qualifiedName passed in matched (case-insensitively)</em>
<a name="557" href="#557">557</a> <em>     *         a tag in the preformattedTags set, or false if not found or if</em>
<a name="558" href="#558">558</a> <em>     *         the set is empty or null.</em>
<a name="559" href="#559">559</a> <em>     * </em>
<a name="560" href="#560">560</a> <em>     * @see #setPreformattedTags(java.util.Set) setPreformattedTags</em>
<a name="561" href="#561">561</a> <em>     */</em>
<a name="562" href="#562">562</a>     <strong>public</strong> <strong>boolean</strong> isPreformattedTag(String qualifiedName) {
<a name="563" href="#563">563</a>         <em class="comment">// A null set implies that the user called setPreformattedTags(null),</em>
<a name="564" href="#564">564</a>         <em class="comment">// which means they want no tags to be preformatted.</em>
<a name="565" href="#565">565</a>         <strong>return</strong> (preformattedTags != <strong>null</strong>)
<a name="566" href="#566">566</a>                 &amp;&amp; (preformattedTags.contains(qualifiedName.toUpperCase()));
<a name="567" href="#567">567</a>     }
<a name="568" href="#568">568</a> 
<a name="569" href="#569">569</a>     <em>/**<em>*</em></em>
<a name="570" href="#570">570</a> <em>     * This override handles any elements that should not remove whitespace,</em>
<a name="571" href="#571">571</a> <em>     * such as &amp;lt;PRE&amp;gt;, &amp;lt;SCRIPT&amp;gt;, &amp;lt;STYLE&amp;gt;, and &amp;lt;TEXTAREA&amp;gt;.</em>
<a name="572" href="#572">572</a> <em>     * Note: the close tags won't line up with the open tag, but we can't alter</em>
<a name="573" href="#573">573</a> <em>     * that. See javadoc note at setPreformattedTags.</em>
<a name="574" href="#574">574</a> <em>     * </em>
<a name="575" href="#575">575</a> <em>     * @param element</em>
<a name="576" href="#576">576</a> <em>     *            DOCUMENT ME!</em>
<a name="577" href="#577">577</a> <em>     * </em>
<a name="578" href="#578">578</a> <em>     * @throws IOException</em>
<a name="579" href="#579">579</a> <em>     *             When the stream could not be written to.</em>
<a name="580" href="#580">580</a> <em>     * </em>
<a name="581" href="#581">581</a> <em>     * @see #setPreformattedTags(java.util.Set) setPreformattedTags</em>
<a name="582" href="#582">582</a> <em>     */</em>
<a name="583" href="#583">583</a>     <strong>protected</strong> <strong>void</strong> writeElement(<a href="../../../org/dom4j/Element.html">Element</a> element) throws IOException {
<a name="584" href="#584">584</a>         <strong>if</strong> (newLineAfterNTags == -1) { <em class="comment">// lazy initialization check</em>
<a name="585" href="#585">585</a>             lazyInitNewLinesAfterNTags();
<a name="586" href="#586">586</a>         }
<a name="587" href="#587">587</a> 
<a name="588" href="#588">588</a>         <strong>if</strong> (newLineAfterNTags > 0) {
<a name="589" href="#589">589</a>             <strong>if</strong> ((tagsOuput > 0) &amp;&amp; ((tagsOuput % newLineAfterNTags) == 0)) {
<a name="590" href="#590">590</a>                 <strong>super</strong>.writer.write(lineSeparator);
<a name="591" href="#591">591</a>             }
<a name="592" href="#592">592</a>         }
<a name="593" href="#593">593</a> 
<a name="594" href="#594">594</a>         tagsOuput++;
<a name="595" href="#595">595</a> 
<a name="596" href="#596">596</a>         String qualifiedName = element.getQualifiedName();
<a name="597" href="#597">597</a>         String saveLastText = lastText;
<a name="598" href="#598">598</a>         <strong>int</strong> size = element.nodeCount();
<a name="599" href="#599">599</a> 
<a name="600" href="#600">600</a>         <strong>if</strong> (isPreformattedTag(qual<strong>if</strong>iedName)) {
<a name="601" href="#601">601</a>             <a href="../../../org/dom4j/io/OutputFormat.html">OutputFormat</a> currentFormat = getOutputFormat();
<a name="602" href="#602">602</a>             <strong>boolean</strong> saveNewlines = currentFormat.isNewlines();
<a name="603" href="#603">603</a>             <strong>boolean</strong> saveTrimText = currentFormat.isTrimText();
<a name="604" href="#604">604</a>             String currentIndent = currentFormat.getIndent();
<a name="605" href="#605">605</a> 
<a name="606" href="#606">606</a>             <em class="comment">// You could have nested PREs, or SCRIPTS within PRE... etc.,</em>
<a name="607" href="#607">607</a>             <em class="comment">// therefore use push and pop.</em>
<a name="608" href="#608">608</a>             formatStack.push(<strong>new</strong> FormatState(saveNewlines, saveTrimText,
<a name="609" href="#609">609</a>                     currentIndent));
<a name="610" href="#610">610</a> 
<a name="611" href="#611">611</a>             <strong>try</strong> {
<a name="612" href="#612">612</a>                 <em class="comment">// do this manually, since it won't be done while outputting</em>
<a name="613" href="#613">613</a>                 <em class="comment">// the tag.</em>
<a name="614" href="#614">614</a>                 <strong>super</strong>.writePrintln();
<a name="615" href="#615">615</a> 
<a name="616" href="#616">616</a>                 <strong>if</strong> ((saveLastText.trim().length() == 0)
<a name="617" href="#617">617</a>                         &amp;&amp; (currentIndent != <strong>null</strong>)
<a name="618" href="#618">618</a>                         &amp;&amp; (currentIndent.length() > 0)) {
<a name="619" href="#619">619</a>                     <em class="comment">// We are indenting, but we want to line up with the close</em>
<a name="620" href="#620">620</a>                     <em class="comment">// tag. lastText was the indent (whitespace, no \n) before</em>
<a name="621" href="#621">621</a>                     <em class="comment">// the preformatted start tag. So write it out instead of</em>
<a name="622" href="#622">622</a>                     <em class="comment">// the current indent level. This makes it line up with its</em>
<a name="623" href="#623">623</a>                     <em class="comment">// close tag.</em>
<a name="624" href="#624">624</a>                     <strong>super</strong>.writer.write(justSpaces(saveLastText));
<a name="625" href="#625">625</a>                 }
<a name="626" href="#626">626</a> 
<a name="627" href="#627">627</a>                 <em class="comment">// actually, newlines are handled in this class by writeString,</em>
<a name="628" href="#628">628</a>                 <em class="comment">// depending on if the stack is empty.</em>
<a name="629" href="#629">629</a>                 currentFormat.setNewlines(false);
<a name="630" href="#630">630</a>                 currentFormat.setTrimText(false);
<a name="631" href="#631">631</a>                 currentFormat.setIndent(<span class="string">""</span>);
<a name="632" href="#632">632</a> 
<a name="633" href="#633">633</a>                 <em class="comment">// This line is the recursive one:</em>
<a name="634" href="#634">634</a>                 <strong>super</strong>.writeElement(element);
<a name="635" href="#635">635</a>             } <strong>finally</strong> {
<a name="636" href="#636">636</a>                 FormatState state = (FormatState) formatStack.pop();
<a name="637" href="#637">637</a>                 currentFormat.setNewlines(state.isNewlines());
<a name="638" href="#638">638</a>                 currentFormat.setTrimText(state.isTrimText());
<a name="639" href="#639">639</a>                 currentFormat.setIndent(state.getIndent());
<a name="640" href="#640">640</a>             }
<a name="641" href="#641">641</a>         } <strong>else</strong> {
<a name="642" href="#642">642</a>             <strong>super</strong>.writeElement(element);
<a name="643" href="#643">643</a>         }
<a name="644" href="#644">644</a>     }
<a name="645" href="#645">645</a> 
<a name="646" href="#646">646</a>     <strong>private</strong> String justSpaces(String text) {
<a name="647" href="#647">647</a>         <strong>int</strong> size = text.length();
<a name="648" href="#648">648</a>         StringBuffer res = <strong>new</strong> StringBuffer(size);
<a name="649" href="#649">649</a>         <strong>char</strong> c;
<a name="650" href="#650">650</a> 
<a name="651" href="#651">651</a>         <strong>for</strong> (<strong>int</strong> i = 0; i &lt; size; i++) {
<a name="652" href="#652">652</a>             c = text.charAt(i);
<a name="653" href="#653">653</a> 
<a name="654" href="#654">654</a>             <strong>switch</strong> (c) {
<a name="655" href="#655">655</a>                 <strong>case</strong> '\r':
<a name="656" href="#656">656</a>                 <strong>case</strong> '\n':
<a name="657" href="#657">657</a> 
<a name="658" href="#658">658</a>                     <strong>continue</strong>;
<a name="659" href="#659">659</a> 
<a name="660" href="#660">660</a>                 <strong>default</strong>:
<a name="661" href="#661">661</a>                     res.append(c);
<a name="662" href="#662">662</a>             }
<a name="663" href="#663">663</a>         }
<a name="664" href="#664">664</a> 
<a name="665" href="#665">665</a>         <strong>return</strong> res.toString();
<a name="666" href="#666">666</a>     }
<a name="667" href="#667">667</a> 
<a name="668" href="#668">668</a>     <strong>private</strong> <strong>void</strong> lazyInitNewLinesAfterNTags() {
<a name="669" href="#669">669</a>         <strong>if</strong> (getOutputFormat().isNewlines()) {
<a name="670" href="#670">670</a>             <em class="comment">// don't bother, newlines are going to happen anyway.</em>
<a name="671" href="#671">671</a>             newLineAfterNTags = 0;
<a name="672" href="#672">672</a>         } <strong>else</strong> {
<a name="673" href="#673">673</a>             newLineAfterNTags = getOutputFormat().getNewLineAfterNTags();
<a name="674" href="#674">674</a>         }
<a name="675" href="#675">675</a>     }
<a name="676" href="#676">676</a> 
<a name="677" href="#677">677</a>     <em class="comment">// Convenience methods, static, with bunch-o-defaults</em>
<a name="678" href="#678">678</a> 
<a name="679" href="#679">679</a>     <em>/**<em>*</em></em>
<a name="680" href="#680">680</a> <em>     * Convenience method to just get a String result.</em>
<a name="681" href="#681">681</a> <em>     * </em>
<a name="682" href="#682">682</a> <em>     * @param html</em>
<a name="683" href="#683">683</a> <em>     *            DOCUMENT ME!</em>
<a name="684" href="#684">684</a> <em>     * </em>
<a name="685" href="#685">685</a> <em>     * @return a pretty printed String from the source string, preserving</em>
<a name="686" href="#686">686</a> <em>     *         whitespace in the defaultPreformattedTags set, and leaving the</em>
<a name="687" href="#687">687</a> <em>     *         close tags off of the default omitElementCloseSet set. Use one of</em>
<a name="688" href="#688">688</a> <em>     *         the write methods if you want stream output.</em>
<a name="689" href="#689">689</a> <em>     * </em>
<a name="690" href="#690">690</a> <em>     * @throws java.io.IOException</em>
<a name="691" href="#691">691</a> <em>     * @throws java.io.UnsupportedEncodingException</em>
<a name="692" href="#692">692</a> <em>     * @throws org.dom4j.DocumentException</em>
<a name="693" href="#693">693</a> <em>     */</em>
<a name="694" href="#694">694</a>     <strong>public</strong> <strong>static</strong> String prettyPrintHTML(String html)
<a name="695" href="#695">695</a>             throws java.io.IOException, java.io.UnsupportedEncodingException,
<a name="696" href="#696">696</a>             org.dom4j.DocumentException {
<a name="697" href="#697">697</a>         <strong>return</strong> prettyPrintHTML(html, <strong>true</strong>, <strong>true</strong>, false, <strong>true</strong>);
<a name="698" href="#698">698</a>     }
<a name="699" href="#699">699</a> 
<a name="700" href="#700">700</a>     <em>/**<em>*</em></em>
<a name="701" href="#701">701</a> <em>     * Convenience method to just get a String result, but &lt;b>As XHTML &lt;/b>.</em>
<a name="702" href="#702">702</a> <em>     * </em>
<a name="703" href="#703">703</a> <em>     * @param html</em>
<a name="704" href="#704">704</a> <em>     *            DOCUMENT ME!</em>
<a name="705" href="#705">705</a> <em>     * </em>
<a name="706" href="#706">706</a> <em>     * @return a pretty printed String from the source string, preserving</em>
<a name="707" href="#707">707</a> <em>     *         whitespace in the defaultPreformattedTags set, but conforming to</em>
<a name="708" href="#708">708</a> <em>     *         XHTML: no close tags are omitted (though if empty, they will be</em>
<a name="709" href="#709">709</a> <em>     *         converted to XHTML empty tags: &amp;lt;HR/&amp;gt; Use one of the write</em>
<a name="710" href="#710">710</a> <em>     *         methods if you want stream output.</em>
<a name="711" href="#711">711</a> <em>     * </em>
<a name="712" href="#712">712</a> <em>     * @throws java.io.IOException</em>
<a name="713" href="#713">713</a> <em>     * @throws java.io.UnsupportedEncodingException</em>
<a name="714" href="#714">714</a> <em>     * @throws org.dom4j.DocumentException</em>
<a name="715" href="#715">715</a> <em>     */</em>
<a name="716" href="#716">716</a>     <strong>public</strong> <strong>static</strong> String prettyPrintXHTML(String html)
<a name="717" href="#717">717</a>             throws java.io.IOException, java.io.UnsupportedEncodingException,
<a name="718" href="#718">718</a>             org.dom4j.DocumentException {
<a name="719" href="#719">719</a>         <strong>return</strong> prettyPrintHTML(html, <strong>true</strong>, <strong>true</strong>, <strong>true</strong>, false);
<a name="720" href="#720">720</a>     }
<a name="721" href="#721">721</a> 
<a name="722" href="#722">722</a>     <em>/**<em>*</em></em>
<a name="723" href="#723">723</a> <em>     * DOCUMENT ME!</em>
<a name="724" href="#724">724</a> <em>     * </em>
<a name="725" href="#725">725</a> <em>     * @param html</em>
<a name="726" href="#726">726</a> <em>     *            DOCUMENT ME!</em>
<a name="727" href="#727">727</a> <em>     * @param newlines</em>
<a name="728" href="#728">728</a> <em>     *            DOCUMENT ME!</em>
<a name="729" href="#729">729</a> <em>     * @param trim</em>
<a name="730" href="#730">730</a> <em>     *            DOCUMENT ME!</em>
<a name="731" href="#731">731</a> <em>     * @param isXHTML</em>
<a name="732" href="#732">732</a> <em>     *            DOCUMENT ME!</em>
<a name="733" href="#733">733</a> <em>     * @param expandEmpty</em>
<a name="734" href="#734">734</a> <em>     *            DOCUMENT ME!</em>
<a name="735" href="#735">735</a> <em>     * </em>
<a name="736" href="#736">736</a> <em>     * @return a pretty printed String from the source string, preserving</em>
<a name="737" href="#737">737</a> <em>     *         whitespace in the defaultPreformattedTags set, and leaving the</em>
<a name="738" href="#738">738</a> <em>     *         close tags off of the default omitElementCloseSet set. This</em>
<a name="739" href="#739">739</a> <em>     *         override allows you to specify various formatter options. Use one</em>
<a name="740" href="#740">740</a> <em>     *         of the write methods if you want stream output.</em>
<a name="741" href="#741">741</a> <em>     * </em>
<a name="742" href="#742">742</a> <em>     * @throws java.io.IOException</em>
<a name="743" href="#743">743</a> <em>     * @throws java.io.UnsupportedEncodingException</em>
<a name="744" href="#744">744</a> <em>     * @throws org.dom4j.DocumentException</em>
<a name="745" href="#745">745</a> <em>     */</em>
<a name="746" href="#746">746</a>     <strong>public</strong> <strong>static</strong> String prettyPrintHTML(String html, <strong>boolean</strong> newlines,
<a name="747" href="#747">747</a>             <strong>boolean</strong> trim, <strong>boolean</strong> isXHTML, <strong>boolean</strong> expandEmpty)
<a name="748" href="#748">748</a>             throws java.io.IOException, java.io.UnsupportedEncodingException,
<a name="749" href="#749">749</a>             org.dom4j.DocumentException {
<a name="750" href="#750">750</a>         StringWriter sw = <strong>new</strong> StringWriter();
<a name="751" href="#751">751</a>         <a href="../../../org/dom4j/io/OutputFormat.html">OutputFormat</a> format = OutputFormat.createPrettyPrint();
<a name="752" href="#752">752</a>         format.setNewlines(newlines);
<a name="753" href="#753">753</a>         format.setTrimText(trim);
<a name="754" href="#754">754</a>         format.setXHTML(isXHTML);
<a name="755" href="#755">755</a>         format.setExpandEmptyElements(expandEmpty);
<a name="756" href="#756">756</a> 
<a name="757" href="#757">757</a>         <a href="../../../org/dom4j/io/HTMLWriter.html">HTMLWriter</a> writer = <strong>new</strong> <a href="../../../org/dom4j/io/HTMLWriter.html">HTMLWriter</a>(sw, format);
<a name="758" href="#758">758</a>         <a href="../../../org/dom4j/Document.html">Document</a> document = DocumentHelper.parseText(html);
<a name="759" href="#759">759</a>         writer.write(document);
<a name="760" href="#760">760</a>         writer.flush();
<a name="761" href="#761">761</a> 
<a name="762" href="#762">762</a>         <strong>return</strong> sw.toString();
<a name="763" href="#763">763</a>     }
<a name="764" href="#764">764</a> 
<a name="765" href="#765">765</a>     <em class="comment">// Allows us to the current state of the format in this struct on the</em>
<a name="766" href="#766">766</a>     <em class="comment">// formatStack.</em>
<a name="767" href="#767">767</a>     <strong>private</strong> <strong>class</strong> FormatState {
<a name="768" href="#768">768</a>         <strong>private</strong> <strong>boolean</strong> newlines = false;
<a name="769" href="#769">769</a> 
<a name="770" href="#770">770</a>         <strong>private</strong> <strong>boolean</strong> trimText = false;
<a name="771" href="#771">771</a> 
<a name="772" href="#772">772</a>         <strong>private</strong> String indent = <span class="string">""</span>;
<a name="773" href="#773">773</a> 
<a name="774" href="#774">774</a>         <strong>public</strong> FormatState(<strong>boolean</strong> newLines, <strong>boolean</strong> trimText, String indent) {
<a name="775" href="#775">775</a>             <strong>this</strong>.newlines = newLines;
<a name="776" href="#776">776</a>             <strong>this</strong>.trimText = trimText;
<a name="777" href="#777">777</a>             <strong>this</strong>.indent = indent;
<a name="778" href="#778">778</a>         }
<a name="779" href="#779">779</a> 
<a name="780" href="#780">780</a>         <strong>public</strong> <strong>boolean</strong> isNewlines() {
<a name="781" href="#781">781</a>             <strong>return</strong> newlines;
<a name="782" href="#782">782</a>         }
<a name="783" href="#783">783</a> 
<a name="784" href="#784">784</a>         <strong>public</strong> <strong>boolean</strong> isTrimText() {
<a name="785" href="#785">785</a>             <strong>return</strong> trimText;
<a name="786" href="#786">786</a>         }
<a name="787" href="#787">787</a> 
<a name="788" href="#788">788</a>         <strong>public</strong> String getIndent() {
<a name="789" href="#789">789</a>             <strong>return</strong> indent;
<a name="790" href="#790">790</a>         }
<a name="791" href="#791">791</a>     }
<a name="792" href="#792">792</a> }
<a name="793" href="#793">793</a> 
<a name="794" href="#794">794</a> <em class="comment">/*</em>
<a name="795" href="#795">795</a> <em class="comment"> * &lt;html> &lt;head> &lt;title>My Title &lt;/title> &lt;style> .foo { text-align: Right; }</em>
<a name="796" href="#796">796</a> <em class="comment"> * &lt;/style> &lt;script> function mojo(){ return "bar"; } &lt;/script> &lt;script</em>
<a name="797" href="#797">797</a> <em class="comment"> * language="JavaScript"> &lt;!-- //this is the canonical javascript hiding.</em>
<a name="798" href="#798">798</a> <em class="comment"> * function foo(){ return "foo"; } //--> &lt;/script> &lt;/head> &lt;!-- this is a</em>
<a name="799" href="#799">799</a> <em class="comment"> * comment --> &lt;body bgcolor="#A4BFDD" mojo="&amp;amp;"> entities: &amp;#160; &amp;amp;</em>
<a name="800" href="#800">800</a> <em class="comment"> * &amp;quot; &amp;lt; &amp;gt; %23 &lt;p>&lt;/p> &lt;mojo> &lt;/mojo> &lt;foo /> &lt;table border="1"> &lt;tr></em>
<a name="801" href="#801">801</a> <em class="comment"> * &lt;td>&lt;pre> line0 &lt;hr /> line1 &lt;b>line2, should line up, indent-wise &lt;/b> line</em>
<a name="802" href="#802">802</a> <em class="comment"> * 3 line 4 &lt;/pre>&lt;/td>&lt;td>&lt;/td>&lt;/tr> &lt;/table> &lt;myCDATAElement> &lt;![CDATA[My</em>
<a name="803" href="#803">803</a> <em class="comment"> * data]]> &lt;/myCDATAElement> &lt;/body> &lt;/html></em>
<a name="804" href="#804">804</a> <em class="comment"> */</em>
<a name="805" href="#805">805</a> 
<a name="806" href="#806">806</a> <em class="comment">/*</em>
<a name="807" href="#807">807</a> <em class="comment"> * Redistribution and use of this software and associated documentation</em>
<a name="808" href="#808">808</a> <em class="comment"> * ("Software"), with or without modification, are permitted provided that the</em>
<a name="809" href="#809">809</a> <em class="comment"> * following conditions are met:</em>
<a name="810" href="#810">810</a> <em class="comment"> * </em>
<a name="811" href="#811">811</a> <em class="comment"> * 1. Redistributions of source code must retain copyright statements and</em>
<a name="812" href="#812">812</a> <em class="comment"> * notices. Redistributions must also contain a copy of this document.</em>
<a name="813" href="#813">813</a> <em class="comment"> * </em>
<a name="814" href="#814">814</a> <em class="comment"> * 2. Redistributions in binary form must reproduce the above copyright notice,</em>
<a name="815" href="#815">815</a> <em class="comment"> * this list of conditions and the following disclaimer in the documentation</em>
<a name="816" href="#816">816</a> <em class="comment"> * and/or other materials provided with the distribution.</em>
<a name="817" href="#817">817</a> <em class="comment"> * </em>
<a name="818" href="#818">818</a> <em class="comment"> * 3. The name "DOM4J" must not be used to endorse or promote products derived</em>
<a name="819" href="#819">819</a> <em class="comment"> * from this Software without prior written permission of MetaStuff, Ltd. For</em>
<a name="820" href="#820">820</a> <em class="comment"> * written permission, please contact dom4j-info@metastuff.com.</em>
<a name="821" href="#821">821</a> <em class="comment"> * </em>
<a name="822" href="#822">822</a> <em class="comment"> * 4. Products derived from this Software may not be called "DOM4J" nor may</em>
<a name="823" href="#823">823</a> <em class="comment"> * "DOM4J" appear in their names without prior written permission of MetaStuff,</em>
<a name="824" href="#824">824</a> <em class="comment"> * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.</em>
<a name="825" href="#825">825</a> <em class="comment"> * </em>
<a name="826" href="#826">826</a> <em class="comment"> * 5. Due credit should be given to the DOM4J Project - <a href="http://www.dom4j.org" target="alexandria_uri">http://www.dom4j.org</a></em>
<a name="827" href="#827">827</a> <em class="comment"> * </em>
<a name="828" href="#828">828</a> <em class="comment"> * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND</em>
<a name="829" href="#829">829</a> <em class="comment"> * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE</em>
<a name="830" href="#830">830</a> <em class="comment"> * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE</em>
<a name="831" href="#831">831</a> <em class="comment"> * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE</em>
<a name="832" href="#832">832</a> <em class="comment"> * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR</em>
<a name="833" href="#833">833</a> <em class="comment"> * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF</em>
<a name="834" href="#834">834</a> <em class="comment"> * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS</em>
<a name="835" href="#835">835</a> <em class="comment"> * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN</em>
<a name="836" href="#836">836</a> <em class="comment"> * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)</em>
<a name="837" href="#837">837</a> <em class="comment"> * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE</em>
<a name="838" href="#838">838</a> <em class="comment"> * POSSIBILITY OF SUCH DAMAGE.</em>
<a name="839" href="#839">839</a> <em class="comment"> * </em>
<a name="840" href="#840">840</a> <em class="comment"> * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.</em>
<a name="841" href="#841">841</a> <em class="comment"> */</em>
</pre>
<hr/><div id="footer">This page was automatically generated by <a href="http://maven.apache.org/">Maven</a></div></body>
</html>





See more files for this project here

PeerWriter

PeerWriter is a collaborative text editor. Multiple peers can edit the same document while they see overall changes in real-time. PeerWriter is based on a decentralized infrastructure, using a non-locking concurrency protocol ensuring global consistency.

Project homepage: http://sourceforge.net/projects/peerwriter
Programming language(s): Java,XML
License: gpl2

  DOMReader.html
  DOMWriter.html
  DispatchHandler.html
  DocumentInputSource.html
  DocumentResult.html
  DocumentSource.html
  ElementModifier.html
  ElementStack.html
  HTMLWriter.html
  JAXPHelper.html
  OutputFormat.html
  PruningDispatchHandler.html
  PruningElementStack.html
  SAXContentHandler.html
  SAXEventRecorder.html
  SAXHelper.html
  SAXModifier.html
  SAXModifyContentHandler.html
  SAXModifyElementHandler.html
  SAXModifyException.html
  SAXModifyReader.html
  SAXReader.html
  SAXValidator.html
  SAXWriter.html
  STAXEventReader.html
  STAXEventWriter.html
  XMLResult.html
  XMLWriter.html
  XPP3Reader.html
  XPPReader.html
  package-frame.html
  package-summary.html