[jsword-svn] common/java/core/org/crosswire/common/xml s
jswordcvs at crosswire.org
jswordcvs at crosswire.org
Sat Mar 12 14:15:57 MST 2005
Update of /cvs/jsword/common/java/core/org/crosswire/common/xml
In directory www.crosswire.org:/tmp/cvs-serv1368/java/core/org/crosswire/common/xml
Modified Files:
XMLUtil.java
Added Files:
HTMLSerializingContentHandler.java
PrettySerializingContentHandler.java FormatType.java
Log Message:
Jira BD-28. Tidy and syntax highlighting of View Source.
--- NEW FILE: HTMLSerializingContentHandler.java ---
package org.crosswire.common.xml;
import java.io.Writer;
/**
* This class provides for the formatted and syntax highlighted
* serialization of a SAX stream to a <code>Writer</code>.
*
* <p><table border='1' cellPadding='3' cellSpacing='0'>
* <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
*
* Distribution Licence:<br />
* JSword is free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public License,
* version 2 as published by the Free Software Foundation.<br />
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.<br />
* The License is available on the internet
* <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, or by writing to:
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA<br />
* The copyright to this program is held by it's authors.
* </font></td></tr></table>
* @see gnu.gpl.Licence
* @author DM Smith [ dmsmith555 at gmail dot com]
* @version $Id: HTMLSerializingContentHandler.java,v 1.1 2005/03/12 21:15:55 dmsmith Exp $
*/
public class HTMLSerializingContentHandler extends PrettySerializingContentHandler
{
/**
* A formatting serializer that does not add whitespace to the document.
* This uses a StringWriter and the toString method will return its content.
*/
public HTMLSerializingContentHandler()
{
super();
}
/**
* A formatting serializer that adds whitespace to the document
* according to the specified <code>FormatType</code>. This uses
* a StringWriter and the toString method will return its content.
*
* @param theFormat the formatting to use
*/
public HTMLSerializingContentHandler(FormatType theFormat)
{
super(theFormat);
}
/**
* A formatting serializer that adds whitespace to the document
* according to the specified <code>FormatType</code>. As the document
* is serialized it is written to the provided <code>Writer</code>.
*
* @param theFormat the formatting to use
* @param theWriter the writer to use
*/
public HTMLSerializingContentHandler(FormatType theFormat, Writer theWriter)
{
super(theFormat, theWriter);
}
protected String decorateTagName(String tagName)
{
StringBuffer buf = new StringBuffer();
buf.append("<font class='tag'>"); //$NON-NLS-1$
buf.append(super.decorateTagName(tagName));
buf.append("</font>"); //$NON-NLS-1$
return buf.toString();
}
/* (non-Javadoc)
* @see org.crosswire.common.xml.PrettySerializingContentHandler#decorateAttributeName(java.lang.String)
*/
protected String decorateAttributeName(String attrName)
{
StringBuffer buf = new StringBuffer();
buf.append("<font class='attr'>"); //$NON-NLS-1$
buf.append(super.decorateAttributeName(attrName));
buf.append("</font>"); //$NON-NLS-1$
return buf.toString();
}
/* (non-Javadoc)
* @see org.crosswire.common.xml.PrettySerializingContentHandler#decorateAttributeValue(java.lang.String)
*/
protected String decorateAttributeValue(String attrValue)
{
StringBuffer buf = new StringBuffer();
buf.append("<font class='value'>"); //$NON-NLS-1$
buf.append(super.decorateAttributeValue(attrValue));
buf.append("</font>"); //$NON-NLS-1$
return buf.toString();
}
/* (non-Javadoc)
* @see org.crosswire.common.xml.PrettySerializingContentHandler#decorateCharacters(java.lang.String)
*/
protected String decorateCharacters(String characters)
{
StringBuffer buf = new StringBuffer();
buf.append("<font class='text'>"); //$NON-NLS-1$
buf.append(XMLUtil.escape(super.decorateCharacters(characters)).replaceAll("\n", "<br>")); //$NON-NLS-1$ //$NON-NLS-2$
buf.append("</font>"); //$NON-NLS-1$
return buf.toString();
}
/* (non-Javadoc)
* @see org.crosswire.common.xml.PrettySerializingContentHandler#decorateIndent(int)
*/
protected String decorateIndent(int indentLevel)
{
StringBuffer buf = new StringBuffer();
buf.append("<font class='indent'>"); //$NON-NLS-1$
buf.append(super.decorateIndent(indentLevel).replaceAll("\t"," ")); //$NON-NLS-1$ //$NON-NLS-2$
buf.append("</font>"); //$NON-NLS-1$
return buf.toString();
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startDocument()
*/
public void startDocument()
{
StringBuffer buf = new StringBuffer();
// Note: we should be using SPAN here but Sun's Java does not support styling it.
// Also, it introduces whitespace between the span and the text.
buf.append("FONT.tag { color : #666699; font-weight: bold; }\n"); //$NON-NLS-1$
buf.append("FONT.attr { color : #669966; font-weight: bold; }\n"); //$NON-NLS-1$
buf.append("FONT.value { color : #669966; font-style: italic; }\n"); //$NON-NLS-1$
buf.append("FONT.indent { }\n"); //$NON-NLS-1$
buf.append("FONT.text { background : yellow; }\n"); //$NON-NLS-1$
write("<html><head><style type='text/css'>\n"); //$NON-NLS-1$
write(buf.toString());
write("</style></head><body>\n"); //$NON-NLS-1$
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endDocument()
*/
public void endDocument()
{
write("</body></head>"); //$NON-NLS-1$
}
/* (non-Javadoc)
* @see org.crosswire.common.xml.PrettySerializingContentHandler#getEmptyTagEnd()
*/
protected String getEmptyTagEnd()
{
return XMLUtil.escape(super.getEmptyTagEnd());
}
/* (non-Javadoc)
* @see org.crosswire.common.xml.PrettySerializingContentHandler#getEndTagStart()
*/
protected String getEndTagStart()
{
return XMLUtil.escape(super.getEndTagStart());
}
/* (non-Javadoc)
* @see org.crosswire.common.xml.PrettySerializingContentHandler#getPIEnd()
*/
protected String getPIEnd()
{
return XMLUtil.escape(super.getPIEnd());
}
/* (non-Javadoc)
* @see org.crosswire.common.xml.PrettySerializingContentHandler#getPIStart()
*/
protected String getPIStart()
{
return XMLUtil.escape(super.getPIStart());
}
/* (non-Javadoc)
* @see org.crosswire.common.xml.PrettySerializingContentHandler#getTagEnd()
*/
protected String getTagEnd()
{
return XMLUtil.escape(super.getTagEnd());
}
/* (non-Javadoc)
* @see org.crosswire.common.xml.PrettySerializingContentHandler#getTagStart()
*/
protected String getTagStart()
{
return XMLUtil.escape(super.getTagStart());
}
/* (non-Javadoc)
* @see org.crosswire.common.xml.PrettySerializingContentHandler#getNewline()
*/
protected String getNewline()
{
return "<br>"; //$NON-NLS-1$
}
}
--- NEW FILE: FormatType.java ---
package org.crosswire.common.xml;
import java.io.Serializable;
/**
* The PrettySerializingContentHandler uses a FormatType to control its output.
*
* <p><table border='1' cellPadding='3' cellSpacing='0'>
* <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
*
* Distribution Licence:<br />
* JSword is free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public License,
* version 2 as published by the Free Software Foundation.<br />
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.<br />
* The License is available on the internet
* <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, or by writing to:
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA<br />
* The copyright to this program is held by it's authors.
* </font></td></tr></table>
* @see gnu.gpl.Licence
* @author DM Smith [dmsmith555 at gmail dot com]
* @version $Id: FormatType.java,v 1.1 2005/03/12 21:15:55 dmsmith Exp $
*/
public final class FormatType implements Serializable
{
public static final FormatType AS_IS = new FormatType("AS_IS", false, false, false); //$NON-NLS-1$
public static final FormatType ANALYSIS = new FormatType("ANALYSIS", true, false, false); //$NON-NLS-1$
public static final FormatType CLASSIC = new FormatType("CLASSIC", true, false, true); //$NON-NLS-1$
public static final FormatType ANALYSIS_INDENT = new FormatType("ANALYSIS_INDENT", true, true, false); //$NON-NLS-1$
public static final FormatType CLASSIC_INDENT = new FormatType("CLASSIC_INDENT", true, true, true); //$NON-NLS-1$
/**
* Simple ctor
*/
public FormatType(String aName, boolean displayNewlines, boolean doIndenting, boolean classicLines)
{
name = aName;
multiline = displayNewlines;
// the following are true only if we add newlines.
indented = doIndenting && multiline;
classic = classicLines && multiline;
analytic = !classicLines && multiline;
}
/**
* Whether newlines are introduced into the document.
* @return true if newlines are added to the document
*/
public boolean isMultiline()
{
return multiline;
}
/**
* Whether indents are introduced into the document.
* @return true if indents are added to the document
*/
public boolean isIndented()
{
return indented;
}
/**
* Whether added whitespace is inside tags. Note, this does
* not change the document.
* @return true if whitespace is added inside tags of document
*/
public boolean isAnalytic()
{
return analytic;
}
/**
* Whether added whitespace is between tags. Note, this does
* change the document as whitespace is added to either side of
* existing text.
* @return true if whitespace is added inside tags of document
*/
public boolean isClassic()
{
return classic;
}
/**
* Get an integer representation for this FormatType
*/
public int toInteger()
{
for (int i = 0; i < VALUES.length; i++)
{
if (equals(VALUES[i]))
{
return i;
}
}
// cannot get here
assert false;
return -1;
}
/**
* Lookup method to convert from a String
*/
public static FormatType fromString(String name)
{
for (int i = 0; i < VALUES.length; i++)
{
FormatType obj = VALUES[i];
if (obj.name.equalsIgnoreCase(name))
{
return obj;
}
}
// cannot get here
assert false;
return null;
}
/**
* Lookup method to convert from an integer
*/
public static FormatType fromInteger(int i)
{
return VALUES[i];
}
/**
* Prevent subclasses from overriding canonical identity based Object methods
* @see java.lang.Object#equals(java.lang.Object)
*/
public final boolean equals(Object o)
{
return super.equals(o);
}
/**
* Prevent subclasses from overriding canonical identity based Object methods
* @see java.lang.Object#hashCode()
*/
public final int hashCode()
{
return super.hashCode();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString()
{
return name;
}
/**
* The name of the FormatType
*/
private String name;
private boolean indented;
private boolean multiline;
private boolean analytic;
private boolean classic;
// Support for serialization
private static int nextObj;
private final int obj = nextObj++;
Object readResolve()
{
return VALUES[obj];
}
private static final FormatType[] VALUES =
{
AS_IS,
ANALYSIS,
CLASSIC,
ANALYSIS_INDENT,
CLASSIC_INDENT,
};
/**
* Serialization ID
*/
private static final long serialVersionUID = 3544385916136142129L;
}
--- NEW FILE: PrettySerializingContentHandler.java ---
package org.crosswire.common.xml;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
/**
* This class provides for the formatted serialization of a SAX stream
* to a <code>Writer</code>.
*
* <p><table border='1' cellPadding='3' cellSpacing='0'>
* <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
*
* Distribution Licence:<br />
* JSword is free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public License,
* version 2 as published by the Free Software Foundation.<br />
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.<br />
* The License is available on the internet
* <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, or by writing to:
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA<br />
* The copyright to this program is held by it's authors.
* </font></td></tr></table>
* @see gnu.gpl.Licence
* @author DM Smith [dmsmith555 at gmail dot com]
* @version $Id: PrettySerializingContentHandler.java,v 1.1 2005/03/12 21:15:55 dmsmith Exp $
*/
public class PrettySerializingContentHandler implements ContentHandler
{
/**
* A formatting serializer that does not add whitespace to the document.
* This uses a StringWriter and the toString method will return its content.
*/
public PrettySerializingContentHandler()
{
this(FormatType.AS_IS);
}
/**
* A formatting serializer that adds whitespace to the document
* according to the specified <code>FormatType</code>. This uses
* a StringWriter and the toString method will return its content.
*
* @param theFormat the formatting to use
*/
public PrettySerializingContentHandler(FormatType theFormat)
{
this(theFormat, null);
}
/**
* A formatting serializer that adds whitespace to the document
* according to the specified <code>FormatType</code>. As the document
* is serialized it is written to the provided <code>Writer</code>.
*
* @param theFormat the formatting to use
* @param theWriter the writer to use
*/
public PrettySerializingContentHandler(FormatType theFormat, Writer theWriter)
{
formatting = theFormat;
writer = theWriter == null ? new StringWriter() : theWriter;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString()
{
return writer.toString();
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
*/
public void setDocumentLocator(Locator locator)
{
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startDocument()
*/
public void startDocument()
{
//write("<?xml version=\"1.0\"?>");
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endDocument()
*/
public void endDocument()
{
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
*/
public void startPrefixMapping(String prefix, String uri)
{
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
*/
public void endPrefixMapping(String prefix)
{
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
public void startElement(String uri, String localname, String qname, Attributes attrs)
{
if (depth > 0)
{
handlePending();
}
write(getTagStart());
write(decorateTagName(localname));
for (int i = 0; i < attrs.getLength(); i++)
{
write(' ');
write(decorateAttributeName(attrs.getLocalName(i)));
write("='"); //$NON-NLS-1$
write(decorateAttributeValue(XMLUtil.escape(attrs.getValue(i))));
write('\'');
}
pendingEndTag = true;
depth++;
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
*/
public void endElement(String uri, String localname, String qname)
{
depth--;
if (pendingEndTag)
{
if (formatting.isAnalytic() && depth > 0)
{
emitWhitespace(depth - 1);
}
write(getEmptyTagEnd());
}
else
{
if (formatting.isClassic())
{
emitWhitespace(depth);
}
write(getEndTagStart());
write(decorateTagName(localname));
if (formatting.isAnalytic())
{
emitWhitespace(depth);
}
write(getTagEnd());
}
pendingEndTag = false;
lookingForChars = false;
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
*/
public void characters(char[] chars, int start, int length)
{
if (!lookingForChars)
{
handlePending();
}
String s = new String(chars, start, length);
write(decorateCharacters(s));
lookingForChars = true;
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
*/
public void ignorableWhitespace(char[] chars, int start, int length)
{
characters(chars, start, length);
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
*/
public void processingInstruction(String target, String data)
{
handlePending();
write(getPIStart());
write(target);
write(' ');
write(decorateCharacters(data));
write(getPIEnd());
if (formatting.isMultiline())
{
write(getNewline());
}
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
*/
public void skippedEntity(String name)
{
}
protected String getTagStart()
{
return "<"; //$NON-NLS-1$
}
protected String getTagEnd()
{
return ">"; //$NON-NLS-1$
}
protected String getEmptyTagEnd()
{
return "/>"; //$NON-NLS-1$
}
protected String getEndTagStart()
{
return "</"; //$NON-NLS-1$
}
protected String getPIStart()
{
return "<!"; //$NON-NLS-1$
}
protected String getPIEnd()
{
return "!>"; //$NON-NLS-1$
}
protected String getNewline()
{
return "\n"; //$NON-NLS-1$
}
protected String decorateTagName(String tagName)
{
return tagName;
}
protected String decorateAttributeName(String attrName)
{
return attrName;
}
protected String decorateAttributeValue(String attrValue)
{
return attrValue;
}
protected String decorateCharacters(String characters)
{
return characters;
}
protected String decorateIndent(int indentLevel)
{
return new String(indentation, 0, indentLevel).intern();
}
protected void write(String obj)
{
try
{
writer.write(obj);
}
catch (IOException e)
{
e.printStackTrace();
}
}
protected void write(char obj)
{
try
{
writer.write(obj);
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void handlePending()
{
if (pendingEndTag)
{
pendingEndTag = false;
if (formatting.isAnalytic())
{
emitWhitespace(depth);
}
write(getTagEnd());
}
if (formatting.isClassic())
{
emitWhitespace(depth);
}
lookingForChars = false;
}
private void emitWhitespace(int indentLevel)
{
write(getNewline());
if (formatting.isIndented())
{
write(decorateIndent(indentLevel));
}
}
/**
* This allows for rapid output of whitespace.
*/
static private char[] indentation =
{
'\t', '\t', '\t', '\t', '\t',
'\t', '\t', '\t', '\t', '\t',
'\t', '\t', '\t', '\t', '\t',
'\t', '\t', '\t', '\t', '\t',
'\t', '\t', '\t', '\t', '\t',
'\t', '\t', '\t', '\t', '\t'
};
/**
* The depth is incremented on each startElement and decremented on each endElement.
* This is used to output the indentation.
*/
private int depth;
/**
* It is possible that characters(...) will be called for adjacent pieces of text.
* Often this is due to entities in the text. This will allow for these to be
* joined back together.
*/
private boolean lookingForChars;
/**
* One of the difficulties in SAX parsing is that it does not retain state.
* Even for an empty tag, it calls startElement and endElement. This allows
* for making empty elements to have the empty tag notation: <tag/>.
*/
private boolean pendingEndTag;
private FormatType formatting;
private Writer writer;
}
Index: XMLUtil.java
===================================================================
RCS file: /cvs/jsword/common/java/core/org/crosswire/common/xml/XMLUtil.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** XMLUtil.java 28 Feb 2005 02:21:30 -0000 1.8
--- XMLUtil.java 12 Mar 2005 21:15:55 -0000 1.9
***************
*** 11,14 ****
--- 11,15 ----
import org.jdom.input.SAXBuilder;
import org.xml.sax.Attributes;
+ import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
***************
*** 71,75 ****
public static String writeToString(SAXEventProvider provider) throws SAXException
{
! SerializingContentHandler ser = new SerializingContentHandler();
provider.provideSAXEvents(ser);
return ser.toString();
--- 72,76 ----
public static String writeToString(SAXEventProvider provider) throws SAXException
{
! ContentHandler ser = new PrettySerializingContentHandler();
provider.provideSAXEvents(ser);
return ser.toString();
***************
*** 348,352 ****
// So we have the end of the tag, delete it ...
! //DataPolice.report("disguarding tag: " + working.substring(lt, i + 1));
working = working.substring(0, lt) + working.substring(i + 1);
}
--- 349,353 ----
// So we have the end of the tag, delete it ...
! //DataPolice.report("discarding tag: " + working.substring(lt, i + 1));
working = working.substring(0, lt) + working.substring(i + 1);
}
More information about the jsword-svn
mailing list