/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* $Id: ToHTMLStream.java,v 1.2.4.1 2005/09/15 08:15:26 suresh_emailid Exp $
*/
/**
* This serializer takes a series of SAX or
* SAX-like events and writes its output
* to the given stream.
*
* This class is not a public API, it is public
* because it is used from another package.
*
* @xsl.usage internal
*/
{
/** This flag is set while receiving events from the DTD */
protected boolean m_inDTD = false;
/** True if the current element is a block element. (seems like
* this needs to be a stack. -sb). */
private boolean m_inBlockElem = false;
/**
* Map that tells which XML characters should have special treatment, and it
* provides character to entity name lookup.
*/
// new CharInfo(CharInfo.HTML_ENTITIES_RESOURCE);
/** A digital search trie for fast, case insensitive lookup of ElemDesc objects. */
static {
}
// HTML 4.0 loose DTD
"FRAME",
"ISINDEX",
"APPLET",
// HTML 4.0 strict DTD
"SUP",
"SUB",
"SPAN",
"BDO",
"BR",
new ElemDesc(
0
"ADDRESS",
new ElemDesc(
0
"DIV",
new ElemDesc(
0
"MAP",
new ElemDesc(
"AREA",
"LINK",
new ElemDesc(
"IMG",
new ElemDesc(
0
"OBJECT",
new ElemDesc(
0
"HR",
new ElemDesc(
0
"P",
new ElemDesc(
0
"H1",
"H2",
"H3",
"H4",
"H5",
"H6",
"PRE",
"Q",
"BLOCKQUOTE",
new ElemDesc(
0
"DL",
new ElemDesc(
0
"OL",
"UL",
"INPUT",
new ElemDesc(
"SELECT",
"TEXTAREA",
"FIELDSET",
"BUTTON",
"TABLE",
new ElemDesc(
0
"COL",
"HEAD",
"BASE",
"META",
new ElemDesc(
"STYLE",
new ElemDesc(
"SCRIPT",
new ElemDesc(
0
"NOSCRIPT",
new ElemDesc(
0
// From "John Ky" <hand@syd.speednet.com.au
// Transitional Document Type Definition ()
// file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/sgml/loosedtd.html#basefont
// file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/present/graphics.html#edef-STRIKE
// file:///C:/Documents%20and%20Settings/sboag.BOAG600E/My%20Documents/html/present/graphics.html#edef-U
// From "John Ky" <hand@syd.speednet.com.au
// HTML 4.0, section 16.5
"IFRAME",
new ElemDesc(
0
// Netscape 4 extension
"LAYER",
new ElemDesc(
0
// Netscape 4 extension
"ILAYER",
new ElemDesc(
0
// NOW FOR ATTRIBUTE INFORMATION . . .
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// Attribution to: "Voytenko, Dimitry" <DVoytenko@SECTORBASE.COM>
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// HTML 4.0, section 16.5
// ----------------------------------------------
// Netscape 4 extension
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// Netscape 4 extension
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// ----------------------------------------------
// The nowrap attribute of a tr element is both
// a Netscape and Internet-Explorer extension
// ----------------------------------------------
}
/**
* Dummy element for elements not found.
*/
/** True if URLs should be specially escaped with the %xx form. */
private boolean m_specialEscapeURLs = true;
/** True if the META tag should be omitted. */
private boolean m_omitMetaTag = false;
/**
* Tells if the formatter should use special URL escaping.
*
* @param bool True if URLs should be specially escaped with the %xx form.
*/
{
}
/**
* Tells if the formatter should omit the META tag.
*
* @param bool True if the META tag should be omitted.
*/
{
}
/**
* Specifies an output format for this serializer. It the
* serializer has already been associated with an output format,
* it will switch to the new format. This method should not be
* called while the serializer is in the process of serializing
* a document.
*
* This method can be called multiple times before starting
* the serialization of a particular result-tree. In principle
* all serialization parameters can be changed, with the exception
* of method="html" (it must be method="html" otherwise we
* shouldn't even have a ToHTMLStream object here!)
*
* @param format The output format or serialzation parameters
* to use.
*/
{
format);
format);
super.setOutputFormat(format);
}
/**
* Tells if the formatter should use special URL escaping.
*
* @return True if URLs should be specially escaped with the %xx form.
*/
private final boolean getSpecialEscapeURLs()
{
return m_specialEscapeURLs;
}
/**
* Tells if the formatter should omit the META tag.
*
* @return True if the META tag should be omitted.
*/
private final boolean getOmitMetaTag()
{
return m_omitMetaTag;
}
/**
* Get a description of the given element.
*
* @param name non-null name of element, case insensitive.
*
* @return non-null reference to ElemDesc, which may be m_dummy if no
* element description matches the given name.
*/
{
/* this method used to return m_dummy when name was null
* but now it doesn't check and and requires non-null name.
*/
return m_dummy;
}
/**
* A Trie that is just a copy of the "static" one.
* We need this one to be able to use the faster, but not thread-safe
* method Trie.get2(name)
*/
/**
* Calls to this method could be replaced with calls to
* getElemDesc(name), but this one should be faster.
*/
{
return m_dummy;
}
/**
* Default constructor.
*/
public ToHTMLStream()
{
super();
// initialize namespaces
m_prefixMap = new NamespaceMappings();
}
/** The name of the current element. */
// private String m_currentElementName = null;
/**
* Receive notification of the beginning of a document.
*
* @throws org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
*
* @throws org.xml.sax.SAXException
*/
{
super.startDocumentInternal();
m_needToCallStartDocument = false;
m_needToOutputDocTypeDecl = true;
m_startNewLine = false;
setOmitXMLDeclaration(true);
if (true == m_needToOutputDocTypeDecl)
{
{
try
{
if (null != doctypePublic)
{
}
if (null != doctypeSystem)
{
if (null == doctypePublic)
else
}
}
catch(IOException e)
{
throw new SAXException(e);
}
}
}
m_needToOutputDocTypeDecl = false;
}
/**
* Receive notification of the end of a document.
*
* @throws org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
*
* @throws org.xml.sax.SAXException
*/
{
flushPending();
if (m_doIndent && !m_isprevtext)
{
try
{
}
catch(IOException e)
{
throw new SAXException(e);
}
}
flushWriter();
super.fireEndDoc();
}
/**
* Receive notification of the beginning of an element.
*
*
* @param namespaceURI
* @param localName
* @param name The element type name.
* @param atts The attributes attached to the element, if any.
* @throws org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
* @see #endElement
* @see org.xml.sax.AttributeList
*/
public void startElement(
{
// clean up any pending things first
{
elemContext.m_startTagOpen = false;
}
else if (m_cdataTagOpen)
{
closeCDATA();
m_cdataTagOpen = false;
}
else if (m_needToCallStartDocument)
{
m_needToCallStartDocument = false;
}
// if this element has a namespace then treat it like XML
{
return;
}
try
{
// getElemDesc2(name) is faster than getElemDesc(name)
// deal with indentation issues first
if (m_doIndent)
{
if (m_ispreserve)
m_ispreserve = false;
else if (
&& (!m_inBlockElem
|| isBlockElement) /* && !isWhiteSpaceSensitive */
)
{
m_startNewLine = true;
indent();
}
}
// save any attributes for later processing
m_isprevtext = false;
{
// an optimization for elements which are expected
// to be empty.
/* XSLTC sometimes calls namespaceAfterStartElement()
* so we need to remember the name
*/
return;
}
else
{
}
{
// This is the <HEAD> element, do some special processing
elemContext.m_startTagOpen = false;
if (!m_omitMetaTag)
{
if (m_doIndent)
indent();
}
}
}
catch (IOException e)
{
throw new SAXException(e);
}
}
/**
* Receive notification of the end of an element.
*
*
* @param namespaceURI
* @param localName
* @param name The element type name
* @throws org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
*/
public final void endElement(
final String namespaceURI,
{
// deal with any pending issues
if (m_cdataTagOpen)
closeCDATA();
// if the element has a namespace, treat it like XML, not HTML
{
return;
}
try
{
// deal with any indentation issues
if (m_doIndent)
{
boolean shouldIndent = false;
if (m_ispreserve)
{
m_ispreserve = false;
}
{
m_startNewLine = true;
shouldIndent = true;
}
}
if (!elemContext.m_startTagOpen)
{
}
else
{
// the start-tag open when this method was called,
// so we need to process it now.
super.fireStartElem(name);
// the starting tag was still open when we received this endElement() call
// so we need to process any gathered attributes NOW, before they go away.
if (nAttrs > 0)
{
// clear attributes object for re-use with next element
}
if (!elemEmpty)
{
// if (shouldIndent)
// writer.write('>');
// indent(m_currentIndent);
}
else
{
}
}
// clean up because the element has ended
m_ispreserve = true;
m_isprevtext = false;
// fire off the end element event
super.fireEndElem(name);
// OPTIMIZE-EMPTY
if (elemEmpty)
{
// a quick exit if the HTML element had no children.
// This block of code can be removed if the corresponding block of code
// in startElement() also labeled with "OPTIMIZE-EMPTY" is also removed
return;
}
// some more clean because the element has ended.
if (!elemContext.m_startTagOpen)
{
m_preserves.pop();
}
// m_isRawStack.pop();
}
catch (IOException e)
{
throw new SAXException(e);
}
}
/**
* Process an attribute.
* @param writer The writer to write the processed output to.
* @param name The name of the attribute.
* @param value The value of the attribute.
* @param elemDesc The description of the HTML element
* that has this attribute.
*
* @throws org.xml.sax.SAXException
*/
protected void processAttribute(
throws IOException
{
{
}
else
{
// %REVIEW% %OPT%
// Two calls to single-char write may NOT
// be more efficient than one to string-write...
else
}
}
/**
* Tell if a character is an ASCII digit.
*/
private boolean isASCIIDigit(char c)
{
return (c >= '0' && c <= '9');
}
/**
* Make an integer into an HH hex value.
* Does no checking on the size of the input, since this
* is only meant to be used locally by writeAttrURI.
*
* @param i must be a value less than 255.
*
* @return should be a two character string.
*/
{
if (s.length() == 1)
{
s = "0" + s;
}
return s;
}
/**
* Dmitri Ilyin: Makes sure if the String is HH encoded sign.
* @param str must be 2 characters long
*
* @return true or false
*/
{
boolean sign = true;
try
{
}
catch (NumberFormatException e)
{
sign = false;
}
return sign;
}
/**
* Write the specified <var>string</var> after substituting non ASCII characters,
* with <CODE>%HH</CODE>, where HH is the hex of the byte value.
*
* @param string String to convert to XML format.
* @param doURLEscaping True if we should try to encode as
*
* @throws org.xml.sax.SAXException if a bad surrogate pair is detected.
*/
public void writeAttrURI(
throws IOException
{
// http://www.ietf.org/rfc/rfc2396.txt says:
// A URI is always in an "escaped" form, since escaping or unescaping a
// completed URI might change its semantics. Normally, the only time
// escape encodings can safely be made is when the URI is being created
// from its component parts; each component may have its own set of
// characters that are reserved, so only the mechanism responsible for
// generating or interpreting that component can determine whether or
// not escaping a character will change its semantics. Likewise, a URI
// must be separated into its components before the escaped characters
// within those components can be safely decoded.
//
// ...So we do our best to do limited escaping of the URL, without
// causing damage. If the URL is already properly escaped, in theory, this
// function should not change the string value.
{
}
final char[] chars = m_attrBuff;
int cleanStart = 0;
int cleanLength = 0;
char ch = 0;
for (int i = 0; i < end; i++)
{
{
if (cleanLength > 0)
{
cleanLength = 0;
}
if (doURLEscaping)
{
// Encode UTF16 to UTF8.
// Reference is Unicode, A Primer, by Tony Graham.
// Page 92.
// Note that Kay doesn't escape 0x20...
// if(ch == 0x20) // Not sure about this... -sb
// {
// writer.write(ch);
// }
// else
if (ch <= 0x7F)
{
}
else if (ch <= 0x7FF)
{
// Clear low 6 bits before rotate, put high 4 bits in low byte,
// and set two high bits.
// First 6 bits, + high bit
}
{
// I'm sure this can be done in 3 instructions, but I choose
// to try and do it exactly like it is done in the book, at least
// until we are sure this is totally clean. I don't think performance
// is a big issue with this particular function, though I could be
// wrong. Also, the stuff below clearly does more masking than
// it needs to do.
// Clear high 6 bits.
// Middle 4 bits (wwww) + 1
// "Note that the value of wwww from the high surrogate bit pattern
// is incremented to make the uuuuu bit pattern in the scalar value
// so the surrogate pair don't address the BMP."
// next 4 bits
// low 2 bits
// Get low surrogate character.
// Clear high 6 bits.
// put the middle 4 bits into the bottom of yyyyyy (byte 3)
// bottom 6 bits.
int byte2 =
}
else
{
// middle 6 bits
// First 6 bits, + high bit
}
}
else if (escapingNotNeeded(ch))
{
}
else
{
}
// In this character range we have first written out any previously accumulated
// "clean" characters, then processed the current more complicated character,
// which may have incremented "i".
// We now we reset the next possible clean character.
cleanStart = i + 1;
}
// Since http://www.ietf.org/rfc/rfc2396.txt refers to the URI grammar as
// not allowing quotes in the URI proper syntax, nor in the fragment
// identifier, we believe that it's OK to double escape quotes.
else if (ch == '"')
{
// If the character is a '%' number number, try to avoid double-escaping.
// There is a question if this is legal behavior.
// Dmitri Ilyin: to check if '%' number number is invalid. It must be checked if %xx is a sign, that would be encoded
// The encoded signes are in Hex form. So %xx my be in form %3C that is "<" sign. I will try to change here a little.
// if( ((i+2) < len) && isASCIIDigit(stringArray[i+1]) && isASCIIDigit(stringArray[i+2]) )
// We are no longer escaping '%'
if (cleanLength > 0)
{
cleanLength = 0;
}
// Mike Kay encodes this as ", so he may know something I don't?
if (doURLEscaping)
else
// We have written out any clean characters, then the escaped '%' and now we
// We now we reset the next possible clean character.
cleanStart = i + 1;
}
else if (ch == '&')
{
// HTML 4.01 reads, "Authors should use "&" (ASCII decimal 38)
// instead of "&" to avoid confusion with the beginning of a character
// reference (entity reference open delimiter).
if (cleanLength > 0)
{
cleanLength = 0;
}
cleanStart = i + 1;
}
else
{
// no processing for this character, just count how
// many characters in a row that we have that need no processing
cleanLength++;
}
}
// are there any clean characters at the end of the array
// that we haven't processed yet?
if (cleanLength > 1)
{
// if the whole string can be written out as-is do so
// otherwise write out the clean chars at the end of the
// array
if (cleanStart == 0)
else
}
else if (cleanLength == 1)
{
// a little optimization for 1 clean character
// (we could have let the previous if(...) handle them all)
}
}
/**
* Writes the specified <var>string</var> after substituting <VAR>specials</VAR>,
* and UTF-16 surrogates for character references <CODE>&#xnn</CODE>.
*
* @param string String to convert to XML format.
* @param encoding CURRENTLY NOT IMPLEMENTED.
*
* @throws org.xml.sax.SAXException
*/
public void writeAttrString(
throws IOException
{
{
}
final char[] chars = m_attrBuff;
int cleanStart = 0;
int cleanLength = 0;
char ch = 0;
for (int i = 0; i < end; i++)
{
// System.out.println("SPECIALSSIZE: "+SPECIALSSIZE);
// System.out.println("ch: "+(int)ch);
// System.out.println("m_maxCharacter: "+(int)m_maxCharacter);
// System.out.println("m_attrCharsMap[ch]: "+(int)m_attrCharsMap[ch]);
{
cleanLength++;
}
{
cleanLength++; // no escaping in this case, as specified in 15.2
}
else if (
{
cleanLength++; // no escaping in this case, as specified in 15.2
}
else
{
if (cleanLength > 0)
{
cleanLength = 0;
}
if (i != pos)
{
i = pos - 1;
}
else
{
{
i++; // two input characters processed
// this increments by one and the for()
// loop itself increments by another one.
}
// The next is kind of a hack to keep from escaping in the case
// of Shift_JIS and the like.
/*
else if ((ch < m_maxCharacter) && (m_maxCharacter == 0xFFFF)
&& (ch != 160))
{
writer.write(ch); // no escaping in this case
}
else
*/
if (null != outputStringForChar)
{
}
else if (escapingNotNeeded(ch))
{
}
else
{
}
}
cleanStart = i + 1;
}
} // end of for()
// are there any clean characters at the end of the array
// that we haven't processed yet?
if (cleanLength > 1)
{
// if the whole string can be written out as-is do so
// otherwise write out the clean chars at the end of the
// array
if (cleanStart == 0)
else
}
else if (cleanLength == 1)
{
// a little optimization for 1 clean character
// (we could have let the previous if(...) handle them all)
}
}
/**
* Receive notification of character data.
*
* <p>The Parser will call this method to report each chunk of
* character data. SAX parsers may return all contiguous character
* data in a single chunk, or they may split it into several
* chunks; however, all of the characters in any single event
* must come from the same external entity, so that the Locator
* provides useful information.</p>
*
* <p>The application must not attempt to read from the array
* outside of the specified range.</p>
*
* <p>Note that some parsers will report whitespace using the
* ignorableWhitespace() method rather than this one (validating
* parsers must do so).</p>
*
* @param chars The characters from the XML document.
* @param start The start position in the array.
* @param length The number of characters to read from the array.
* @throws org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
* @see #ignorableWhitespace
* @see org.xml.sax.Locator
*
* @throws org.xml.sax.SAXException
*/
{
if (m_elemContext.m_isRaw)
{
try
{
{
m_elemContext.m_startTagOpen = false;
}
m_ispreserve = true;
// With m_ispreserve just set true it looks like shouldIndent()
// will always return false, so drop any possible indentation.
// if (shouldIndent())
// indent();
// writer.write("<![CDATA[");
// writer.write(chars, start, length);
// writer.write("]]>");
// time to generate characters event
return;
}
catch (IOException ioe)
{
null),
ioe);
//"IO error", ioe);
}
}
else
{
}
}
/**
* Receive notification of cdata.
*
* <p>The Parser will call this method to report each chunk of
* character data. SAX parsers may return all contiguous character
* data in a single chunk, or they may split it into several
* chunks; however, all of the characters in any single event
* must come from the same external entity, so that the Locator
* provides useful information.</p>
*
* <p>The application must not attempt to read from the array
* outside of the specified range.</p>
*
* <p>Note that some parsers will report whitespace using the
* ignorableWhitespace() method rather than this one (validating
* parsers must do so).</p>
*
* @param ch The characters from the XML document.
* @param start The start position in the array.
* @param length The number of characters to read from the array.
* @throws org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
* @see #ignorableWhitespace
* @see org.xml.sax.Locator
*
* @throws org.xml.sax.SAXException
*/
{
{
try
{
{
m_elemContext.m_startTagOpen = false;
}
m_ispreserve = true;
if (shouldIndent())
indent();
// writer.write(ch, start, length);
}
catch (IOException ioe)
{
null),
ioe);
//"IO error", ioe);
}
}
else
{
}
}
/**
* Receive notification of a processing instruction.
*
* @param target The processing instruction target.
* @param data The processing instruction data, or null if
* none was supplied.
* @throws org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
*
* @throws org.xml.sax.SAXException
*/
{
// Process any pending starDocument and startElement first.
flushPending();
// Use a fairly nasty hack to tell if the next node is supposed to be
// unescaped text.
{
}
{
}
else
{
try
{
{
m_elemContext.m_startTagOpen = false;
}
else if (m_needToCallStartDocument)
if (shouldIndent())
indent();
//writer.write("<?" + target);
//writer.write(data + ">"); // different from XML
// Always output a newline char if not inside of an
// element. The whitespace is not significant in that
// case.
m_startNewLine = true;
}
catch(IOException e)
{
throw new SAXException(e);
}
}
// now generate the PI event
}
/**
* Receive notivication of a entityReference.
*
* @param name non-null reference to entity name string.
*
* @throws org.xml.sax.SAXException
*/
{
try
{
} catch(IOException e)
{
throw new SAXException(e);
}
}
/**
* @see ExtendedContentHandler#endElement(String)
*/
{
}
/**
* Process the attributes, which means to write out the currently
* collected attributes to the writer. The attributes are not
* cleared by this method
*
* @param writer the writer to write processed attributes to.
* @param nAttrs the number of attributes in m_attributes
* to be processed
*
* @throws org.xml.sax.SAXException
*/
throws IOException,SAXException
{
/*
* process the collected attributes
*/
for (int i = 0; i < nAttrs; i++)
{
m_attributes.getQName(i),
m_attributes.getValue(i),
}
}
/**
* For the enclosing elements starting tag write out out any attributes
* followed by ">"
*
*@throws org.xml.sax.SAXException
*/
{
try
{
// finish processing attributes, time to fire off the start element event
if (nAttrs>0)
{
// clear attributes object for re-use with next element
}
/* whether Xalan or XSLTC, we have the prefix mappings now, so
* lets determine if the current element is specified in the cdata-
* section-elements list.
*/
if (m_cdataSectionElements != null)
if (m_doIndent)
{
m_isprevtext = false;
}
}
catch(IOException e)
{
throw new SAXException(e);
}
}
/**
* Initialize the serializer with the specified output stream and output
* format. Must be called before calling any of the serialize methods.
*
* @param output The output stream to use
* @param format The output format
* @throws UnsupportedEncodingException The encoding specified in the
* output format is not supported
*/
throws UnsupportedEncodingException
{
{
}
}
/**
* Specifies an output stream to which the document should be
* serialized. This method should not be called while the
* serializer is in the process of serializing a document.
* <p>
* The encoding specified in the output properties is used, or
* if no encoding was specified, the default for the selected
* output method.
*
* @param output The output stream
*/
{
try
{
else
}
catch (UnsupportedEncodingException uee)
{
// Should have been warned in init, I guess...
}
}
/**
* is indicated after the element was started with a
* startElement() and before and endElement().
* startPrefixMapping(prefix,uri) would be used before the
* startElement() call.
* @param uri the URI of the namespace
* @param prefix the prefix associated with the given URI.
*
* @see ExtendedContentHandler#namespaceAfterStartElement(String, String)
*/
throws SAXException
{
// hack for XSLTC with finding URI for default namespace
{
{
// the elements URI is not known yet, and it
// doesn't have a prefix, and we are currently
// setting the uri for prefix "", so we have
// the uri for the element... lets remember it
}
}
}
throws SAXException
{
m_inDTD = true;
}
/**
* Report the end of DTD declarations.
* @throws org.xml.sax.SAXException The application may raise an exception.
* @see #startDTD
*/
{
m_inDTD = false;
/* for ToHTMLStream the DOCTYPE is entirely output in the
* startDocumentInternal() method, so don't do anything here
*/
}
/**
* This method does nothing.
*/
public void attributeDecl(
throws SAXException
{
// The internal DTD subset is not serialized by the ToHTMLStream serializer
}
/**
* This method does nothing.
*/
{
// The internal DTD subset is not serialized by the ToHTMLStream serializer
}
/**
* This method does nothing.
*/
throws SAXException
{
// The internal DTD subset is not serialized by the ToHTMLStream serializer
}
/**
* This method does nothing.
*/
public void externalEntityDecl(
throws SAXException
{
// The internal DTD subset is not serialized by the ToHTMLStream serializer
}
/**
* This method is used to add an attribute to the currently open element.
* The caller has guaranted that this attribute is unique, which means that it
* not been seen before and will not be seen again.
*
* @param name the qualified name of the attribute
* @param value the value of the attribute which can contain only
* ASCII printable characters characters in the range 32 to 127 inclusive.
* @param flags the bit values of this integer give optimization information.
*/
throws SAXException
{
try
{
{
// "flags" has indicated that the characters
// '>' '<' '&' and '"' are not in the value and
// m_htmlcharInfo has recorded that there are no other
// entities in the range 0 to 127 so we write out the
// value directly
}
else if (
{
}
else
{
{
}
else
{
}
}
} catch (IOException e) {
throw new SAXException(e);
}
}
throws SAXException
{
// The internal DTD subset is not serialized by the ToHTMLStream serializer
if (m_inDTD)
return;
}
public boolean reset()
{
if (!ret)
return false;
return true;
}
private void initToHTMLStream()
{
// m_elementDesc = null;
m_inBlockElem = false;
m_inDTD = false;
// m_isRawStack.clear();
m_omitMetaTag = false;
m_specialEscapeURLs = true;
}
static class Trie
{
/**
* A digital search trie for 7-bit ASCII text
* The API is a subset of java.util.Hashtable
* The key must be a 7-bit ASCII string
* The value may be any Java Object
* One can get an object stored in a trie from its key,
* but the search is either case sensitive or case
* insensitive to the characters in the key, and this
* choice of sensitivity or insensitivity is made when
* the Trie is created, before any objects are put in it.
*
* This class is a copy of the one in com.sun.org.apache.xml.internal.utils.
* It exists to cut the serializers dependancy on that package.
*
* @xsl.usage internal
*/
/** Size of the m_nextChar array. */
/** The root node of the tree. */
/** helper buffer to convert Strings to char arrays */
/** true if the search for an object is lower case only with the key */
private final boolean m_lowerCaseOnly;
/**
* Construct the trie that has a case insensitive search.
*/
public Trie()
{
m_lowerCaseOnly = false;
}
/**
* Construct the trie given the desired case sensitivity with the key.
* @param lowerCaseOnly true if the search keys are to be loser case only,
* not case insensitive.
*/
{
}
/**
* Put an object into the trie for lookup.
*
* @param key must be a 7-bit ASCII string
* @param value any java object.
*
* @return The old object that matched key, or null.
*/
{
{
// make the biggest buffer ever needed in get(String)
m_charBuffer = new char[len];
}
for (int i = 0; i < len; i++)
{
{
}
else
{
for (; i < len; i++)
{
if (m_lowerCaseOnly)
{
// put this value into the tree only with a lower case key
}
else
{
// put this value into the tree with a case insensitive key
}
}
break;
}
}
return ret;
}
/**
* Get an object that matches the key.
*
* @param key must be a 7-bit ASCII string
*
* @return The object that matches the key, or null.
*/
{
/* If the name is too long, we won't find it, this also keeps us
* from overflowing m_charBuffer
*/
return null;
switch (len) // optimize the look up based on the number of chars
{
// case 0 looks silly, but the generated bytecode runs
// faster for lookup of elements of length 2 with this in
// and a fair bit faster. Don't know why.
case 0 :
{
return null;
}
case 1 :
{
if (ch < ALPHA_SIZE)
{
}
return null;
}
// comment out case 2 because the default is faster
// case 2 :
// {
// final char ch0 = key.charAt(0);
// final char ch1 = key.charAt(1);
// if (ch0 < ALPHA_SIZE && ch1 < ALPHA_SIZE)
// {
// node = node.m_nextChar[ch0];
// if (node != null)
// {
//
// if (ch1 < ALPHA_SIZE)
// {
// node = node.m_nextChar[ch1];
// if (node != null)
// return node.m_Value;
// }
// }
// }
// return null;
// }
default :
{
for (int i = 0; i < len; i++)
{
// A thread-safe way to loop over the characters
if (ALPHA_SIZE <= ch)
{
// the key is not 7-bit ASCII so we won't find it here
return null;
}
return null;
}
}
}
}
/**
* The node representation for the trie.
* @xsl.usage internal
*/
private class Node
{
/**
* Constructor, creates a Node[ALPHA_SIZE].
*/
Node()
{
}
/** The next nodes. */
/** The value. */
}
/**
* Construct the trie from another Trie.
* Both the existing Trie and this new one share the same table for
* lookup, and it is assumed that the table is fully populated and
* not changing anymore.
*
* @param existingTrie the Trie that this one is a copy of.
*/
{
// copy some fields from the existing Trie into this one.
// get a buffer just big enough to hold the longest key in the table.
m_charBuffer = new char[max];
}
/**
* Get an object that matches the key.
* This method is faster than get(), but is not thread-safe.
*
* @param key must be a 7-bit ASCII string
*
* @return The object that matches the key, or null.
*/
{
/* If the name is too long, we won't find it, this also keeps us
* from overflowing m_charBuffer
*/
return null;
switch (len) // optimize the look up based on the number of chars
{
// case 0 looks silly, but the generated bytecode runs
// faster for lookup of elements of length 2 with this in
// and a fair bit faster. Don't know why.
case 0 :
{
return null;
}
case 1 :
{
if (ch < ALPHA_SIZE)
{
}
return null;
}
default :
{
/* Copy string into array. This is not thread-safe because
* it modifies the contents of m_charBuffer. If multiple
* threads were to use this Trie they all would be
* using this same array (not good). So this
* method is not thread-safe, but it is faster because
* converting to a char[] and looping over elements of
* the array is faster than a String's charAt(i).
*/
for (int i = 0; i < len; i++)
{
final char ch = m_charBuffer[i];
if (ALPHA_SIZE <= ch)
{
// the key is not 7-bit ASCII so we won't find it here
return null;
}
return null;
}
}
}
}
/**
* Get the length of the longest key used in the table.
*/
public int getLongestKeyLength()
{
return m_charBuffer.length;
}
}
}