sboag 00/10/12 17:34:49
Modified: java/src makexslt4j
java/src/org/apache/xalan/processor ProcessorCharacters.java
StylesheetHandler.java
java/src/org/apache/xalan/stree SourceTreeHandler.java
java/src/org/apache/xalan/templates ElemAttribute.java
ElemElement.java ElemLiteralResult.java
ElemTemplateElement.java
java/src/org/apache/xalan/transformer ResultTreeHandler.java
TransformerImpl.java
java/src/org/apache/xml/serialize/transition
BaseMarkupSerializer.java
java/src/org/apache/xpath/functions FuncNormalizeSpace.java
Added: java/src/org/apache/xalan/transformer
ClonerToResultTree.java QueuedEvents.java
QueuedSAXEvent.java QueuedStartDocument.java
QueuedStartElement.java SerializerSwitcher.java
java/src/org/apache/xalan/utils XMLCharacterRecognizer.java
Log:
Major rewrite of ResultTreeHandler class, to make it more understandable, and
to fix the bug where prefix events were not being generated correctly.
Several bugs related to whitespace before the XML decl were fixed in the
process.
Also, fixed bug where string conversion of result tree fragments were being
done with the XML serializer, instead of the Text serializer.
Revision Changes Path
1.19 +6 -0 xml-xalan/java/src/makexslt4j
Index: makexslt4j
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/makexslt4j,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- makexslt4j 2000/10/11 03:36:01 1.18
+++ makexslt4j 2000/10/13 00:34:44 1.19
@@ -199,6 +199,11 @@
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)transformer$(PATHSEP)TransformerClient.java
\
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)transformer$(PATHSEP)TreeWalker2Result.java
\
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)transformer$(PATHSEP)XSLInfiniteLoopException.java
\
+
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)transformer$(PATHSEP)QueuedSAXEvent.java
\
+
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)transformer$(PATHSEP)QueuedStartDocument.java
\
+
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)transformer$(PATHSEP)QueuedStartElement.java
\
+
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)transformer$(PATHSEP)QueuedEvents.java
\
+
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)transformer$(PATHSEP)SerializerSwitcher.java
\
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)utils$(PATHSEP)AttList.java \
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)utils$(PATHSEP)BoolStack.java \
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)utils$(PATHSEP)DefaultErrorHandler.java
\
@@ -229,6 +234,7 @@
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)utils$(PATHSEP)WrongParserException.java
\
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)utils$(PATHSEP)NodeConsumer.java \
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)utils$(PATHSEP)WrappedRuntimeException.java
\
+
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)utils$(PATHSEP)XMLCharacterRecognizer.java
\
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)xslt$(PATHSEP)Process.java \
org$(PATHSEP)apache$(PATHSEP)xalan$(PATHSEP)xslt$(PATHSEP)StylesheetSpec.java \
trax$(PATHSEP)Examples.java \
1.3 +3 -45
xml-xalan/java/src/org/apache/xalan/processor/ProcessorCharacters.java
Index: ProcessorCharacters.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/processor/ProcessorCharacters.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ProcessorCharacters.java 2000/08/08 00:27:17 1.2
+++ ProcessorCharacters.java 2000/10/13 00:34:45 1.3
@@ -62,6 +62,7 @@
import org.apache.xalan.templates.ElemTextLiteral;
import org.apache.xalan.templates.ElemTemplateElement;
import org.apache.xalan.templates.Constants;
+import org.apache.xalan.utils.XMLCharacterRecognizer;
/**
* This class processes character events for a XSLT template element.
@@ -82,7 +83,8 @@
int nChars = m_accumulator.length();
if((nChars > 0) &&
- ((null != m_xslTextElement) || !isWhiteSpace(m_accumulator)))
+ ((null != m_xslTextElement)
+ || !XMLCharacterRecognizer.isWhiteSpace(m_accumulator)))
{
ElemTextLiteral elem = new ElemTextLiteral();
elem.setDOMBackPointer(handler.getOriginatingNode());
@@ -100,50 +102,6 @@
parent.appendChild(elem);
}
m_accumulator.setLength(0);
- }
-
- /**
- * Returns whether the specified <var>ch</var> conforms to the XML 1.0
definition
- * of whitespace. Refer to <A
href="http://www.w3.org/TR/1998/REC-xml-19980210#NT-S">
- * the definition of <CODE>S</CODE></A> for details.
- * @param ch Character to check as XML whitespace.
- * @return =true if <var>ch</var> is XML whitespace; otherwise
=false.
- */
- public static boolean isSpace(char ch)
- {
- return (ch == 0x20) || (ch == 0x09) || (ch == 0xD) || (ch == 0xA);
- }
-
- /**
- * Tell if the string is whitespace.
- * @param string String to be trimmed.
- * @return The trimmed string.
- */
- public static boolean isWhiteSpace(char ch[], int start, int length)
- {
- int end = start+length;
- for(int s = start; s < end; s++)
- {
- if (!isSpace(ch[s]))
- return false;
- }
- return true;
- }
-
- /**
- * Tell if the string is whitespace.
- * @param string String to be trimmed.
- * @return The trimmed string.
- */
- public static boolean isWhiteSpace(StringBuffer buf)
- {
- int n = buf.length();
- for(int i = 0; i < n; i++)
- {
- if (!isSpace(buf.charAt(i)))
- return false;
- }
- return true;
}
1.11 +3 -16
xml-xalan/java/src/org/apache/xalan/processor/StylesheetHandler.java
Index: StylesheetHandler.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/processor/StylesheetHandler.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- StylesheetHandler.java 2000/10/11 03:36:04 1.10
+++ StylesheetHandler.java 2000/10/13 00:34:45 1.11
@@ -64,6 +64,7 @@
import org.apache.xalan.templates.Stylesheet;
import org.apache.xalan.templates.ElemUnknown;
import org.apache.xalan.utils.NodeConsumer;
+import org.apache.xalan.utils.XMLCharacterRecognizer;
import trax.ProcessorException;
import trax.TemplatesBuilder;
import trax.Templates;
@@ -522,21 +523,7 @@
this.popProcessor();
m_nsSupport.popContext();
}
-
- /**
- * Tell if the given character array is whitespace.
- */
- private boolean isWhitespaceArray(char ch[], int start, int length)
- {
- int n = start+length;
- for(int i = start; i < n; i++)
- {
- if(!Character.isWhitespace(ch[i]))
- return false;
- }
- return true;
- }
-
+
/**
* Receive notification of character data inside an element.
*
@@ -561,7 +548,7 @@
if(null == elemProcessor)
{
// If it's whitespace, just ignore it, otherwise flag an error.
- if(!isWhitespaceArray(ch, start, length))
+ if(!XMLCharacterRecognizer.isWhiteSpace(ch, start, length))
error("Non-whitespace text is not allowed in this position in the
stylesheet!", null);
}
else
1.11 +2 -18
xml-xalan/java/src/org/apache/xalan/stree/SourceTreeHandler.java
Index: SourceTreeHandler.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/stree/SourceTreeHandler.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- SourceTreeHandler.java 2000/10/09 23:25:17 1.10
+++ SourceTreeHandler.java 2000/10/13 00:34:45 1.11
@@ -4,6 +4,7 @@
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.apache.xalan.utils.DOMBuilder;
+import org.apache.xalan.utils.XMLCharacterRecognizer;
import org.apache.xpath.XPathContext;
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xalan.templates.StylesheetRoot;
@@ -293,23 +294,6 @@
}
/**
- * Tell if the given character array is whitespace.
- */
- private boolean isWhitespaceArray(char ch[], int start, int length)
- {
- synchronized (getSynchObject())
- {
- int n = start+length;
- for(int i = start; i < n; i++)
- {
- if(!Character.isWhitespace(ch[i]))
- return false;
- }
- }
- return true;
- }
-
- /**
* Implement the characters event.
*/
public void characters (char ch[], int start, int length)
@@ -317,7 +301,7 @@
{
synchronized (getSynchObject())
{
- if(isWhitespaceArray(ch, start, length) && getShouldStripWhitespace())
+ if(XMLCharacterRecognizer.isWhiteSpace(ch, start, length) &&
getShouldStripWhitespace())
return;
if(m_isCData)
1.4 +3 -3
xml-xalan/java/src/org/apache/xalan/templates/ElemAttribute.java
Index: ElemAttribute.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemAttribute.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ElemAttribute.java 2000/09/29 18:03:35 1.3
+++ ElemAttribute.java 2000/10/13 00:34:46 1.4
@@ -165,7 +165,7 @@
// If they are trying to add an attribute when there isn't an
// element pending, it is an error.
- if(null == rhandler.getPendingElementName())
+ if(!rhandler.isElementPending())
{
transformer.getMsgMgr().warn(XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_NAME, new
Object[]{origAttrName});
return;
@@ -193,7 +193,7 @@
if(null == prefix)
{
prefix = rhandler.getNewUniqueNSPrefix();
- rhandler.startPrefixMapping(prefix, attrNameSpace);
+ rhandler.startPrefixMapping(prefix, attrNameSpace, false);
}
// add the prefix to the attribute name.
attrName = (prefix + ":"+QName.getLocalPart(attrName));
@@ -206,7 +206,7 @@
String prefix = QName.getPrefixFromXMLNSDecl(origAttrName);
String ns = rhandler.getURI(prefix);
if(null == ns)
- rhandler.startPrefixMapping(prefix, val);
+ rhandler.startPrefixMapping(prefix, val, false);
return;
}
// Note we are using original attribute name for these tests.
1.4 +5 -3
xml-xalan/java/src/org/apache/xalan/templates/ElemElement.java
Index: ElemElement.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemElement.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ElemElement.java 2000/10/02 15:33:15 1.3
+++ ElemElement.java 2000/10/13 00:34:46 1.4
@@ -239,6 +239,9 @@
}
}
+ // Add namespace declarations.
+ executeNSDecls(transformer);
+
rhandler.startElement(elemNameSpace, QName.getLocalPart(elemName),
elemName);
if(null != prefix)
{
@@ -250,16 +253,15 @@
// excluded because transformer.m_pendingElementName will be null.
super.execute(transformer, sourceNode, mode);
- // Add namespace declarations.
- executeNSDecls(transformer);
-
transformer.executeChildTemplates(this, sourceNode, mode);
// Now end the element if name was valid
if(null != elemName && null != ns)
{
rhandler.endElement("", "", elemName);
+ unexecuteNSDecls(transformer);
}
+
}
}
1.7 +6 -4
xml-xalan/java/src/org/apache/xalan/templates/ElemLiteralResult.java
Index: ElemLiteralResult.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemLiteralResult.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ElemLiteralResult.java 2000/09/20 23:33:10 1.6
+++ ElemLiteralResult.java 2000/10/13 00:34:46 1.7
@@ -407,16 +407,16 @@
{
ResultTreeHandler rhandler = transformer.getResultTreeHandler();
+ // Add namespace declarations.
+ executeNSDecls(transformer);
+
rhandler.startElement(getNamespace(), getLocalName(), getRawName());
// Process any possible attributes from xsl:use-attribute-sets first
super.execute(transformer, sourceNode, mode);
//xsl:version, excludeResultPrefixes???
-
- // Add namespace declarations.
- executeNSDecls(transformer);
-
+
// Process the list of avts next
if(null != m_avts)
{
@@ -444,7 +444,9 @@
// Now process all the elements in this subtree
// TODO: Process m_extensionElementPrefixes && m_attributeSetsNames
transformer.executeChildTemplates(this, sourceNode, mode);
+
rhandler.endElement (getNamespace(), getLocalName(), getRawName());
+ unexecuteNSDecls(transformer);
}
/** Compiling templates requires that we be able to list the AVTs
1.13 +21 -1
xml-xalan/java/src/org/apache/xalan/templates/ElemTemplateElement.java
Index: ElemTemplateElement.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemTemplateElement.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- ElemTemplateElement.java 2000/10/11 03:36:10 1.12
+++ ElemTemplateElement.java 2000/10/13 00:34:46 1.13
@@ -748,7 +748,7 @@
child.resolvePrefixTables();
}
}
-
+
/**
* Send startPrefixMapping events to the result tree handler
* for all declared prefix mappings in the stylesheet.
@@ -767,6 +767,26 @@
}
}
}
+
+ /**
+ * Send startPrefixMapping events to the result tree handler
+ * for all declared prefix mappings in the stylesheet.
+ */
+ void unexecuteNSDecls(TransformerImpl transformer)
+ throws SAXException
+ {
+ ResultTreeHandler rhandler = transformer.getResultTreeHandler();
+ int n = m_prefixTable.size();
+ for(int i = 0; i < n; i++)
+ {
+ XMLNSDecl decl = (XMLNSDecl)m_prefixTable.elementAt(i);
+ if(!decl.getIsExcluded())
+ {
+ rhandler.endPrefixMapping(decl.getPrefix());
+ }
+ }
+ }
+
/**
* Parent node.
1.16 +434 -684
xml-xalan/java/src/org/apache/xalan/transformer/ResultTreeHandler.java
Index: ResultTreeHandler.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/ResultTreeHandler.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- ResultTreeHandler.java 2000/10/03 20:12:31 1.15
+++ ResultTreeHandler.java 2000/10/13 00:34:47 1.16
@@ -55,39 +55,40 @@
* <http://www.apache.org/>.
*/
package org.apache.xalan.transformer;
-
-import org.w3c.dom.*;
-import java.util.Stack;
+
import java.util.Enumeration;
-import java.io.Writer;
-import java.io.OutputStream;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.ext.LexicalHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.Attributes;
-import org.xml.sax.helpers.NamespaceSupport;
-import org.apache.xalan.utils.DOMBuilder;
-import org.apache.xalan.utils.TreeWalker;
-import org.apache.xalan.utils.MutableAttrListImpl;
-import org.apache.xalan.utils.StringToStringTable;
-import org.apache.xalan.utils.QName;
-import org.apache.xalan.res.XSLTErrorResources;
-import org.apache.xalan.templates.Constants;
+
import org.apache.xalan.templates.Stylesheet;
import org.apache.xalan.templates.StylesheetRoot;
-import org.apache.xalan.templates.ElemTemplateElement;
-import org.apache.xalan.templates.OutputFormatExtended;
-import serialize.SerializerFactory;
-import serialize.OutputFormat;
-import serialize.Method;
+
+import org.apache.xalan.trace.TraceManager;
import org.apache.xalan.trace.GenerateEvent;
+
+import org.apache.xalan.utils.MutableAttrListImpl;
+import org.apache.xalan.utils.QName;
+import org.apache.xalan.utils.TreeWalker;
+import org.apache.xalan.utils.ObjectPool;
+import org.apache.xalan.utils.XMLCharacterRecognizer;
+
+import org.apache.xpath.DOMHelper;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.XPathContext;
-import org.apache.xpath.DOMHelper;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.NamedNodeMap;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.NamespaceSupport;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
import serialize.SerializerHandler;
-import serialize.Serializer;
/**
* This class is a layer between the direct calls to the result
@@ -98,366 +99,47 @@
* the attributes have to be fully collected before you
* can call startElement.
*/
-public class ResultTreeHandler
+public class ResultTreeHandler extends QueuedEvents
implements ContentHandler, SerializerHandler, LexicalHandler
{
/**
* Create a new result tree handler. The real content
- * handler will be the ContentHandler of the transformer.
- */
- public ResultTreeHandler(TransformerImpl transformer)
- {
- m_transformer = transformer;
- }
-
- /**
- * Create a new result tree handler. The real content
* handler will be the ContentHandler passed as an argument.
*/
public ResultTreeHandler(TransformerImpl transformer,
ContentHandler realHandler)
{
m_transformer = transformer;
+ m_tracer = transformer.getTraceManager();
m_contentHandler = realHandler;
- }
+ m_cloner = new ClonerToResultTree(transformer, this);
- /**
- * Given a result tree fragment, walk the tree and
- * output it to the result stream.
- */
- public void outputResultTreeFragment(XObject obj,
- XPathContext support)
- throws SAXException
- {
- DocumentFragment docFrag = obj.rtree(support);
- NodeList nl = docFrag.getChildNodes();
- int nChildren = nl.getLength();
- TreeWalker tw = new TreeWalker(this);
- for(int i = 0; i < nChildren; i++)
- {
- flushPending(); // I think.
- tw.traverse(nl.item(i));
- }
- }
-
- /**
- * Clone an element with or without children.
- * TODO: Fix or figure out node clone failure!
- * the error condition is severe enough to halt processing.
- */
- public void cloneToResultTree(Stylesheet stylesheetTree, Node node,
- boolean shouldCloneWithChildren,
- boolean overrideStrip,
- boolean shouldCloneAttributes)
- throws SAXException
- {
- boolean stripWhiteSpace = false;
- XPathContext xctxt = this.m_transformer.getXPathContext();
- DOMHelper dhelper = xctxt.getDOMHelper();
-
- switch(node.getNodeType())
- {
- case Node.TEXT_NODE:
- {
- // If stripWhiteSpace is false, then take this as an override and
- // just preserve the space, otherwise use the XSL whitespace rules.
- if(!overrideStrip)
- {
- // stripWhiteSpace = isLiteral ? true :
shouldStripSourceNode(node);
- stripWhiteSpace = false;
- }
- Text tx = (Text)node;
- String data = null;
- // System.out.println("stripWhiteSpace = "+stripWhiteSpace+",
"+tx.getData());
- if(stripWhiteSpace)
- {
- if(!dhelper.isIgnorableWhitespace(tx))
- {
- data = tx.getData();
- if((null != data) && (0 == data.trim().length()))
- {
- data = null;
- }
- }
- }
- else
- {
- Node parent = node.getParentNode();
- if(null != parent)
- {
- if( Node.DOCUMENT_NODE != parent.getNodeType())
- {
- data = tx.getData();
- if((null != data) && (0 == data.length()))
- {
- data = null;
- }
- }
- }
- else
- {
- data = tx.getData();
- if((null != data) && (0 == data.length()))
- {
- data = null;
- }
- }
- }
-
- if(null != data)
- {
- // TODO: Hack around the issue of comments next to literals.
- // This would be, when a comment is present, the whitespace
- // after the comment must be added to the literal. The
- // parser should do this, but XML4J doesn't seem to.
- // <foo>some lit text
- // <!-- comment -->
- // </foo>
- // Loop through next siblings while they are comments, then,
- // if the node after that is a ignorable text node, append
- // it to the text node just added.
- if(dhelper.isIgnorableWhitespace(tx))
- {
- ignorableWhitespace(data.toCharArray(), 0, data.length());
- }
- else
- {
- characters(data.toCharArray(), 0, data.length());
- }
- }
- }
- break;
- case Node.DOCUMENT_NODE:
- // Can't clone a document, but refrain from throwing an error
- // so that copy-of will work
- break;
- case Node.ELEMENT_NODE:
- {
- Attributes atts;
- if(shouldCloneAttributes)
- {
- addAttributes( node );
- processNSDecls(node);
- }
- String ns = dhelper.getNamespaceOfNode(node);
- String localName = dhelper.getLocalNameOfNode(node);
- startElement (ns, localName, node.getNodeName());
- }
- break;
- case Node.CDATA_SECTION_NODE:
- {
- String data = ((CDATASection)node).getData();
- cdata(data.toCharArray(), 0, data.length());
- }
- break;
- case Node.ATTRIBUTE_NODE:
- {
- String ns = dhelper.getNamespaceOfNode(node);
- String localName = dhelper.getLocalNameOfNode(node);
- addAttribute(ns, localName, node.getNodeName(), "CDATA",
- ((Attr)node).getValue());
- }
- break;
- case Node.COMMENT_NODE:
- {
- comment(((Comment)node).getData());
- }
- break;
- case Node.DOCUMENT_FRAGMENT_NODE:
- {
-
- m_transformer.getMsgMgr().error(null, node,
XSLTErrorResources.ER_NO_CLONE_OF_DOCUMENT_FRAG); //"No clone of a document
fragment!");
- }
- break;
- case Node.ENTITY_REFERENCE_NODE:
- {
- EntityReference er = (EntityReference)node;
- entityReference(er.getNodeName());
- }
- break;
- case Node.PROCESSING_INSTRUCTION_NODE:
- {
- ProcessingInstruction pi = (ProcessingInstruction)node;
- processingInstruction(pi.getTarget(), pi.getData());
- }
- break;
- default:
-
m_transformer.getMsgMgr().error(XSLTErrorResources.ER_CANT_CREATE_ITEM, new
Object[] {node.getNodeName()}); //"Can not create item in result tree:
"+node.getNodeName());
- }
-
- } // end cloneToResultTree function
-
-
-
- /**
- * Check to see if the output prefix should be excluded.
- */
- private String excludePrefix(String name)
- {
- if(null != m_stylesheetRoot) // Just extra defensive
- {
- int indexOfNSSep = name.indexOf(':');
- if(indexOfNSSep > 0)
- {
- String prefix = name.substring(0, indexOfNSSep);
- if(m_stylesheetRoot.containsExcludeResultPrefix(prefix))
- name = name.substring(indexOfNSSep+1);
- }
- }
- return name;
- }
-
-
- /**
- * Flush the pending element.
- */
- public void flushPending()
- throws SAXException
- {
// The stylesheet is set at a rather late stage, so I do
// this here, though it would probably be better done elsewhere.
- if((null == m_stylesheetRoot) && (null != m_transformer))
+ if(null != m_transformer)
m_stylesheetRoot = m_transformer.getStylesheet();
-
- if(!m_foundStartDoc && (null != m_pendingElementName))
- {
- if(null != m_stylesheetRoot && !m_stylesheetRoot.isOutputMethodSet())
- {
- if(m_pendingElementName.equalsIgnoreCase("html")
- && (null == m_nsSupport.getURI("")))
- {
- OutputFormat oformat = m_stylesheetRoot.getOutputFormat();
- oformat.setMethod(Method.HTML);
- try
- {
- Serializer oldSerializer = m_transformer.getSerializer();
- if(null != oldSerializer)
- {
- Serializer serializer =
SerializerFactory.getSerializer(oformat);
- Writer writer = oldSerializer.getWriter();
- if(null != writer)
- serializer.setWriter(writer);
- else
- {
- OutputStream os = serializer.getOutputStream();
- if(null != os)
- serializer.setOutputStream(os);
- }
- m_transformer.setSerializer(serializer);
- ContentHandler ch = serializer.asContentHandler();
- m_transformer.setContentHandler(ch);
- m_contentHandler = ch;
- }
- }
- catch(java.io.IOException e)
- {
- throw new SAXException(e);
- }
- }
- }
- }
- // System.out.println("m_pendingStartDoc: "+m_pendingStartDoc);
- // System.out.println("m_haveDocContent: "+m_haveDocContent);
- if (!m_foundStartDoc && m_haveDocContent)
- {
- startDocument();
- m_haveDocContent = true;
- }
-
- if (m_pendingStartDoc && m_haveDocContent)
- {
- m_pendingStartDoc = false;
- getContentHandler().startDocument();
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_STARTDOCUMENT));
- }
-
-// if((null != m_pendingElementName) && m_haveDocContent)
- if (null != m_pendingElementName)
- {
- /*
- if(null != m_stylesheetRoot.getCDataSectionElems())
- {
- if(isCDataResultElem(m_pendingElementName))
- {
- m_cdataStack.push(TRUE);
- }
- else
- {
- m_cdataStack.push(FALSE);
- }
- }
- */
- if(!m_nsDeclsHaveBeenAdded)
- addNSDeclsToAttrs();
- // System.out.print("Calling start element:
"+m_pendingElementName+"... ");
- // System.out.print(" on: "+getContentHandler()+"... ");
- // System.out.flush();
- getContentHandler().startElement(m_pendingElementNS,
- m_pendingElementLName,
- m_pendingElementName,
- m_pendingAttributes);
- // System.out.println("Done calling start element:
"+m_pendingElementLName);
- // System.out.flush();
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_STARTELEMENT,
-
m_pendingElementName, m_pendingAttributes));
- clearPendingElement();
- }
- }
-
- /**
- * To fullfill the FormatterListener interface... not action
- * for the moment.
- */
- public void setDocumentLocator (Locator locator)
- {
+ pushDocumentEvent(); // not pending yet.
}
- public boolean getFoundStartDoc() { return m_foundStartDoc; }
/**
- * Flag to indicate whether or not our startDocument() method has been
called.
- */
- private boolean m_foundStartDoc = false;
-
- public boolean getFoundEndDoc() { return m_foundEndDoc; }
- private boolean m_foundEndDoc = false;
-
- /**
* Bottleneck the startDocument event.
*/
public void startDocument ()
throws SAXException
{
- // m_uniqueNSValue = 0;
- m_foundStartDoc = true;
- m_pendingStartDoc = true;
- m_haveDocContent = false;
- // m_flistener.startDocument();
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_STARTDOCUMENT));
- ContentHandler chandler = getContentHandler();
- if((null != chandler)
- && (chandler instanceof TransformerClient))
- {
- ((TransformerClient)chandler).setTransformState(m_transformer);
- }
}
/**
- * Bottleneck the endDocument event.
+ * Bottleneck the endDocument event. This may be called
+ * more than once in order to make sure the pending start
+ * document is called.
*/
public void endDocument ()
throws SAXException
{
- m_foundEndDoc = true;
- m_haveDocContent = true;
- flushPending();
- getContentHandler().endDocument();
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_ENDDOCUMENT));
- // m_variableStacks.popCurrentContext();
+ flushPending(EVT_ENDDOCUMENT);
+ getQueuedDocAtBottom().flushEnd();
}
/**
@@ -468,18 +150,9 @@
public void startElement (String ns, String localName, String name)
throws SAXException
{
- flushPending();
- m_nsSupport.pushContext();
- setPendingElementName (ns, localName, name);
- m_haveDocContent = true;
- if (ns != null && ns.length() > 0)
- {
- int index;
- String prefix = (index = name.indexOf(":"))< 0 ? "" :
name.substring(0, index);
- startPrefixMapping ( prefix, ns);
- }
+ startElement (ns, localName, name, null);
}
-
+
/**
* Bottleneck the startElement event. This is used to "pend" an
* element, so that attributes can still be added to it before
@@ -489,18 +162,15 @@
Attributes atts)
throws SAXException
{
- flushPending();
- m_nsSupport.pushContext();
- m_pendingAttributes.clear(); // Is this needed?? -sb
- m_pendingAttributes.addAttributes(atts);
- setPendingElementName (ns, localName, name);
- m_haveDocContent = true;
- if (ns != null && ns.length() > 0)
- {
- int index;
- String prefix = (index = name.indexOf(":"))< 0 ? "" :
name.substring(0, index);
- startPrefixMapping ( prefix, ns);
- }
+ checkForSerializerSwitch(ns, localName);
+ flushPending(EVT_STARTELEMENT);
+ if(!m_nsContextPushed)
+ m_nsSupport.pushContext();
+
+ ensurePrefixIsDeclared(ns, localName);
+
+ // getQueuedElem().setPending(ns, localName, name, atts);
+ this.pushElementEvent(ns, localName, name, atts);
}
/**
@@ -509,45 +179,107 @@
public void endElement (String ns, String localName, String name)
throws SAXException
{
- // name = excludePrefix(name);
- flushPending();
- getContentHandler().endElement(ns, localName, name);
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_ENDELEMENT,
- name,
(Attributes)null));
- // if(null != m_stylesheetRoot.getCDataSectionElems())
- // m_cdataStack.pop();
+ flushPending(EVT_ENDELEMENT);
+ QueuedStartElement qse = getQueuedElem();
+ qse.flushEnd();
+ sendEndPrefixMappings();
+ popEvent();
+
m_nsSupport.popContext();
}
+
+ boolean m_nsContextPushed = false;
+
+ /**
+ * Begin the scope of a prefix-URI Namespace mapping.
+ *
+ * <p>The information from this event is not necessary for
+ * normal Namespace processing: the SAX XML reader will
+ * automatically replace prefixes for element and attribute
+ * names when the http://xml.org/sax/features/namespaces
+ * feature is true (the default).</p>
+ *
+ * <p>There are cases, however, when applications need to
+ * use prefixes in character data or in attribute values,
+ * where they cannot safely be expanded automatically; the
+ * start/endPrefixMapping event supplies the information
+ * to the application to expand prefixes in those contexts
+ * itself, if necessary.</p>
+ *
+ * <p>Note that start/endPrefixMapping events are not
+ * guaranteed to be properly nested relative to each-other:
+ * all startPrefixMapping events will occur before the
+ * corresponding startElement event, and all endPrefixMapping
+ * events will occur after the corresponding endElement event,
+ * but their order is not guaranteed.</p>
+ *
+ * @param prefix The Namespace prefix being declared.
+ * @param uri The Namespace URI the prefix is mapped to.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ * @see #endPrefixMapping
+ * @see #startElement
+ */
+ public void startPrefixMapping (String prefix, String uri)
+ throws SAXException
+ {
+ startPrefixMapping (prefix, uri, true);
+ }
+
+ public void startPrefixMapping (String prefix, String uri, boolean
shouldFlush)
+ throws SAXException
+ {
+ if(shouldFlush)
+ flushPending(EVT_STARTPREFIXMAPPING);
+ if(!m_nsContextPushed)
+ {
+ m_nsSupport.pushContext();
+ m_nsContextPushed = true;
+ }
+
+ String existingURI = m_nsSupport.getURI(prefix);
+ if((null == existingURI) || !existingURI.equals(uri))
+ {
+ m_nsSupport.declarePrefix(prefix, uri);
+ }
+ }
+
/**
+ * End the scope of a prefix-URI mapping.
+ *
+ * <p>See startPrefixMapping for details. This event will
+ * always occur after the corresponding endElement event,
+ * but the order of endPrefixMapping events is not otherwise
+ * guaranteed.</p>
+ *
+ * @param prefix The prefix that was being mapping.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ * @see #startPrefixMapping
+ * @see #endElement
+ */
+ public void endPrefixMapping (String prefix)
+ throws SAXException
+ {
+ }
+
+ /**
* Bottleneck the characters event.
*/
public void characters (char ch[], int start, int length)
throws SAXException
{
- if(!m_haveDocContent)
- {
- int n = ch.length;
- for(int i = 0; i < n; i++)
- {
- // todo: isSpaceChar doesn't seem to be recognizing 0x0A. (??) -sb
- if(!Character.isSpaceChar(ch[i]))
- {
- m_haveDocContent = true;
- break;
- }
- }
- }
- if(m_haveDocContent)
- {
- flushPending();
- }
+ QueuedStartDocument qsd = getQueuedDoc();
+ if((null != qsd) && qsd.isPending()
+ && XMLCharacterRecognizer.isWhiteSpace(ch, start, length))
+ return;
+ flushPending(EVT_CHARACTERS);
getContentHandler().characters(ch, start, length);
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_CHARACTERS,
- ch,
start, length));
+ m_tracer.fireGenerateEvent(new GenerateEvent(m_transformer,
+
GenerateEvent.EVENTTYPE_CHARACTERS,
+ ch, start, length));
}
/**
@@ -556,14 +288,16 @@
public void ignorableWhitespace (char ch[], int start, int length)
throws SAXException
{
- if(m_haveDocContent)
- {
- flushPending();
- getContentHandler().ignorableWhitespace(ch, start, length);
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_IGNORABLEWHITESPACE,
- ch, start, length));
- }
+ QueuedStartDocument qsd = getQueuedDoc();
+ if((null != qsd) && qsd.isPending()
+ && XMLCharacterRecognizer.isWhiteSpace(ch, start, length))
+ return;
+
+ flushPending(EVT_IGNORABLEWHITESPACE);
+ getContentHandler().ignorableWhitespace(ch, start, length);
+ m_tracer.fireGenerateEvent(new GenerateEvent(m_transformer,
+
GenerateEvent.EVENTTYPE_IGNORABLEWHITESPACE,
+ ch, start, length));
}
/**
@@ -572,12 +306,11 @@
public void processingInstruction (String target, String data)
throws SAXException
{
- m_haveDocContent = true;
- flushPending();
+ flushPending(EVT_PROCESSINGINSTRUCTION);
getContentHandler().processingInstruction(target, data);
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_PI,
- target, data));
+ m_tracer.fireGenerateEvent(new GenerateEvent(m_transformer,
+ GenerateEvent.EVENTTYPE_PI,
+ target, data));
}
/**
@@ -585,15 +318,14 @@
*/
public void comment(String data) throws SAXException
{
- m_haveDocContent = true;
- flushPending();
+ flushPending(EVT_COMMENT);
if(getContentHandler() instanceof LexicalHandler)
{
((LexicalHandler)getContentHandler()).comment(data.toCharArray(), 0,
data.length());
}
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_COMMENT,
- data));
+ m_tracer.fireGenerateEvent(new GenerateEvent(m_transformer,
+
GenerateEvent.EVENTTYPE_COMMENT,
+ data));
}
/**
@@ -601,15 +333,14 @@
*/
public void comment(char ch[], int start, int length) throws SAXException
{
- m_haveDocContent = true;
- flushPending();
+ flushPending(EVT_COMMENT);
if(getContentHandler() instanceof LexicalHandler)
{
((LexicalHandler)getContentHandler()).comment(ch, start, length);
}
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_COMMENT,
- new String(ch, start,
length)));
+ m_tracer.fireGenerateEvent(new GenerateEvent(m_transformer,
+
GenerateEvent.EVENTTYPE_COMMENT,
+ new String(ch, start,
length)));
}
@@ -618,16 +349,15 @@
*/
public void entityReference(String name) throws SAXException
{
- m_haveDocContent = true;
- flushPending();
+ flushPending(EVT_ENTITYREF);
if(getContentHandler() instanceof LexicalHandler)
{
((LexicalHandler)getContentHandler()).startEntity(name);
((LexicalHandler)getContentHandler()).endEntity(name);
}
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_ENTITYREF,
- name));
+ m_tracer.fireGenerateEvent(new GenerateEvent(m_transformer,
+
GenerateEvent.EVENTTYPE_ENTITYREF,
+ name));
}
/**
@@ -635,8 +365,7 @@
*/
public void startEntity(String name) throws SAXException
{
- m_haveDocContent = true;
- flushPending();
+ flushPending(EVT_STARTENTITY);
if(getContentHandler() instanceof LexicalHandler)
{
((LexicalHandler)getContentHandler()).startEntity(name);
@@ -648,15 +377,14 @@
*/
public void endEntity(String name) throws SAXException
{
- m_haveDocContent = true;
- flushPending();
+ flushPending(EVT_ENDENTITY);
if(getContentHandler() instanceof LexicalHandler)
{
((LexicalHandler)getContentHandler()).endEntity(name);
}
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_ENTITYREF,
- name));
+ m_tracer.fireGenerateEvent(new GenerateEvent(m_transformer,
+
GenerateEvent.EVENTTYPE_ENTITYREF,
+ name));
}
/**
@@ -664,7 +392,7 @@
*/
public void startDTD(String s1, String s2, String s3) throws SAXException
{
- flushPending();
+ flushPending(EVT_STARTDTD);
if(getContentHandler() instanceof LexicalHandler)
{
((LexicalHandler)getContentHandler()).startDTD(s1, s2, s3);
@@ -676,13 +404,13 @@
*/
public void endDTD() throws SAXException
{
- flushPending();
+ flushPending(EVT_ENDDTD);
if(getContentHandler() instanceof LexicalHandler)
{
((LexicalHandler)getContentHandler()).endDTD();
}
}
-
+
/**
* Starts an un-escaping section. All characters printed within an
* un-escaping section are printed as is, without escaping special
@@ -695,7 +423,7 @@
public void startNonEscaping()
throws SAXException
{
- flushPending();
+ flushPending(EVT_STARTNONESCAPING);
if(getContentHandler() instanceof SerializerHandler)
{
((SerializerHandler)getContentHandler()).startNonEscaping();
@@ -710,7 +438,7 @@
public void endNonEscaping()
throws SAXException
{
- flushPending();
+ flushPending(EVT_ENDNONESCAPING);
if(getContentHandler() instanceof SerializerHandler)
{
((SerializerHandler)getContentHandler()).endNonEscaping();
@@ -730,7 +458,7 @@
public void startPreserving()
throws SAXException
{
- flushPending();
+ flushPending(EVT_STARTPRESERVING);
if(getContentHandler() instanceof SerializerHandler)
{
((SerializerHandler)getContentHandler()).startPreserving();
@@ -746,7 +474,7 @@
public void endPreserving()
throws SAXException
{
- flushPending();
+ flushPending(EVT_ENDENDPRESERVING);
if(getContentHandler() instanceof SerializerHandler)
{
((SerializerHandler)getContentHandler()).endPreserving();
@@ -758,7 +486,7 @@
*/
public void startCDATA() throws SAXException
{
- flushPending();
+ flushPending(EVT_STARTCDATA);
if(getContentHandler() instanceof LexicalHandler)
{
((LexicalHandler)getContentHandler()).startCDATA();
@@ -770,68 +498,13 @@
*/
public void endCDATA() throws SAXException
{
- flushPending();
+ flushPending(EVT_ENDCDATA);
if(getContentHandler() instanceof LexicalHandler)
{
((LexicalHandler)getContentHandler()).endCDATA();
}
}
-
- /**
- * Bottleneck the cdata event.
- */
- public void cdata (char ch[], int start, int length)
- throws SAXException
- {
- m_haveDocContent = true;
- flushPending();
- /*
- if((null != m_stylesheetRoot.getCDataSectionElems()) &&
- !m_cdataStack.isEmpty() && (m_cdataStack.peek() == TRUE))
- {
- // boolean isLexH = (getContentHandler() instanceof LexicalHandler);
-
- if(getContentHandler() instanceof LexicalHandler)
- ((LexicalHandler)getContentHandler()).startCDATA();
-
- getContentHandler().characters(ch, start, length);
-
- if(getContentHandler() instanceof LexicalHandler)
- ((LexicalHandler)getContentHandler()).endCDATA();
-
- if(null != m_traceListeners)
- fireGenerateEvent(new GenerateEvent(m_transformer,
- GenerateEvent.EVENTTYPE_CDATA,
- ch, start, length));
- }
- else
- */
- {
- getContentHandler().characters(ch, start, length);
- m_transformer.getTraceManager().fireGenerateEvent(new
GenerateEvent(m_transformer,
-
GenerateEvent.EVENTTYPE_CHARACTERS,
- ch, start, length));
- }
-
- /*
- if(getContentHandler() instanceof FormatterListener)
- {
- ((FormatterListener)getContentHandler()).cdata(ch, start, length);
- }
- else
- {
- // Bad but I think it's better than dropping it.
- getContentHandler().characters(ch, start, length);
- }
- ((FormatterListener)getContentHandler()).cdata(ch, start, length);
- if(null != m_traceListeners)
- fireGenerateEvent(new GenerateEvent(this,
- GenerateEvent.EVENTTYPE_CDATA,
- ch, start, length));
- }
- */
- }
-
+
/**
* Receive notification of a skipped entity.
*
@@ -855,12 +528,158 @@
}
/**
+ * Flush the pending element.
+ */
+ public void flushPending()
+ throws SAXException
+ {
+ flushPending(EVT_NODE);
+ }
+
+ /**
+ * Flush the pending element.
+ */
+ public void flushPending(int type)
+ throws SAXException
+ {
+ QueuedStartElement qe = getQueuedElem();
+ QueuedStartDocument qdab = getQueuedDocAtBottom();
+
+ if ((type != EVT_STARTPREFIXMAPPING) && qdab.isPending())
+ {
+ qdab.flush();
+ }
+
+ if ((null != qe) && qe.isPending())
+ {
+ if(!qe.nsDeclsHaveBeenAdded())
+ addNSDeclsToAttrs();
+
+ sendStartPrefixMappings();
+ qe.flush();
+ m_nsContextPushed = false;
+ }
+ }
+
+ /**
+ * Given a result tree fragment, walk the tree and
+ * output it to the result stream.
+ */
+ public void outputResultTreeFragment(XObject obj,
+ XPathContext support)
+ throws SAXException
+ {
+ DocumentFragment docFrag = obj.rtree(support);
+ NodeList nl = docFrag.getChildNodes();
+ int nChildren = nl.getLength();
+ TreeWalker tw = new TreeWalker(this);
+ for(int i = 0; i < nChildren; i++)
+ {
+ flushPending(EVT_NODE); // I think.
+ tw.traverse(nl.item(i));
+ }
+ }
+
+ /**
+ * Clone an element with or without children.
+ */
+ public void cloneToResultTree(Stylesheet stylesheetTree, Node node,
+ boolean shouldCloneWithChildren,
+ boolean overrideStrip,
+ boolean shouldCloneAttributes)
+ throws SAXException
+ {
+ m_cloner.cloneToResultTree(stylesheetTree, node,
+ shouldCloneWithChildren,
+ overrideStrip,
+ shouldCloneAttributes);
+ }
+
+ /**
+ * To fullfill the FormatterListener interface... no action
+ * for the moment.
+ */
+ public void setDocumentLocator (Locator locator)
+ {
+ }
+
+ /**
+ * This function checks to make sure a given prefix is really
+ * declared. It might not be, because it may be an excluded prefix.
+ * If it's not, it still needs to be declared at this point.
+ * TODO: This needs to be done at an earlier stage in the game... -sb
+ */
+ void ensurePrefixIsDeclared(String ns, String localName)
+ throws SAXException
+ {
+ if (ns != null && ns.length() > 0)
+ {
+ int index;
+ String prefix = (index = localName.indexOf(":"))< 0 ? null :
localName.substring(0, index);
+ if(null != prefix)
+ {
+ String foundURI = m_nsSupport.getURI(prefix);
+ if((null == foundURI) || !foundURI.equals(ns))
+ startPrefixMapping ( prefix, ns, false);
+ }
+ }
+ }
+
+ /**
+ * Add the attributes that have been declared to the attribute list.
+ * (Seems like I shouldn't have to do this...)
+ */
+ protected void sendStartPrefixMappings()
+ throws SAXException
+ {
+ Enumeration prefixes = m_nsSupport.getDeclaredPrefixes();
+ ContentHandler handler = getContentHandler();
+ while (prefixes.hasMoreElements())
+ {
+ String prefix = (String)prefixes.nextElement();
+ handler.startPrefixMapping(prefix, m_nsSupport.getURI(prefix));
+ }
+ }
+
+ /**
+ * Add the attributes that have been declared to the attribute list.
+ * (Seems like I shouldn't have to do this...)
+ */
+ protected void sendEndPrefixMappings()
+ throws SAXException
+ {
+ Enumeration prefixes = m_nsSupport.getDeclaredPrefixes();
+ ContentHandler handler = getContentHandler();
+
+ while (prefixes.hasMoreElements())
+ {
+ String prefix = (String)prefixes.nextElement();
+ handler.endPrefixMapping(prefix);
+ }
+ }
+
+ /**
+ * Check to see if we should switch serializers based on the
+ * first output element being an HTML element.
+ */
+ private void checkForSerializerSwitch(String ns, String localName)
+ throws SAXException
+ {
+ QueuedStartDocument qdab = getQueuedDocAtBottom();
+ if(qdab.isPending())
+ {
+ SerializerSwitcher.switchSerializerIfHTML(m_transformer, ns,
localName);
+ }
+ }
+
+ /**
* Add the attributes that have been declared to the attribute list.
* (Seems like I shouldn't have to do this...)
*/
protected void addNSDeclsToAttrs()
{
Enumeration prefixes = m_nsSupport.getDeclaredPrefixes();
+ QueuedStartElement qe = getQueuedElem();
while (prefixes.hasMoreElements())
{
String prefix = (String)prefixes.nextElement();
@@ -874,15 +693,11 @@
else
name="xmlns:"+prefix;
- // System.out.println("Adding xmlns: "+name);
-
- // System.out.println("calling addAttribute(null, null, "+name+",
'CDATA', "+
- // m_nsSupport.getURI(prefix)+");");
- m_pendingAttributes.addAttribute("http://www.w3.org/2000/xmlns/",
- prefix,
- name, "CDATA",
m_nsSupport.getURI(prefix));
+ qe.addAttribute("http://www.w3.org/2000/xmlns/",
+ prefix,
+ name, "CDATA", m_nsSupport.getURI(prefix));
}
- m_nsDeclsHaveBeenAdded = true;
+ qe.setNSDeclsHaveBeenAdded(true);
}
/**
@@ -922,7 +737,7 @@
}
}
}
-
+
/**
* Given a prefix, return the namespace,
*/
@@ -946,75 +761,8 @@
}
return null;
}
-
- /**
- * Begin the scope of a prefix-URI Namespace mapping.
- *
- * <p>The information from this event is not necessary for
- * normal Namespace processing: the SAX XML reader will
- * automatically replace prefixes for element and attribute
- * names when the http://xml.org/sax/features/namespaces
- * feature is true (the default).</p>
- *
- * <p>There are cases, however, when applications need to
- * use prefixes in character data or in attribute values,
- * where they cannot safely be expanded automatically; the
- * start/endPrefixMapping event supplies the information
- * to the application to expand prefixes in those contexts
- * itself, if necessary.</p>
- *
- * <p>Note that start/endPrefixMapping events are not
- * guaranteed to be properly nested relative to each-other:
- * all startPrefixMapping events will occur before the
- * corresponding startElement event, and all endPrefixMapping
- * events will occur after the corresponding endElement event,
- * but their order is not guaranteed.</p>
- *
- * @param prefix The Namespace prefix being declared.
- * @param uri The Namespace URI the prefix is mapped to.
- * @exception org.xml.sax.SAXException The client may throw
- * an exception during processing.
- * @see #endPrefixMapping
- * @see #startElement
- */
- public void startPrefixMapping (String prefix, String uri)
- throws SAXException
- {
- // System.out.println("startPrefixMapping("+prefix+", "+uri+")");
- String existingURI = m_nsSupport.getURI(prefix);
- if((null == existingURI) || !existingURI.equals(uri))
- {
- m_nsSupport.declarePrefix(prefix, uri);
- getContentHandler().startPrefixMapping(prefix, uri);
- }
- }
-
- /**
- * End the scope of a prefix-URI mapping.
- *
- * <p>See startPrefixMapping for details. This event will
- * always occur after the corresponding endElement event,
- * but the order of endPrefixMapping events is not otherwise
- * guaranteed.</p>
- *
- * @param prefix The prefix that was being mapping.
- * @exception org.xml.sax.SAXException The client may throw
- * an exception during processing.
- * @see #startPrefixMapping
- * @see #endElement
- */
- public void endPrefixMapping (String prefix)
- throws SAXException
- {
- getContentHandler().endPrefixMapping(prefix);
- }
/**
- * Use the SAX2 helper class to track result namespaces.
- */
- private NamespaceSupport m_nsSupport = new NamespaceSupport();
-
- /**
* Get the NamespaceSupport object.
*/
public NamespaceSupport getNamespaceSupport()
@@ -1022,22 +770,18 @@
return m_nsSupport;
}
- /**
- * The transformer object.
- */
- private TransformerImpl m_transformer;
-
/**
- * The content handler. May be null, in which
- * case, we'll defer to the content handler in the
- * transformer.
+ * Override QueuedEvents#initQSE.
*/
- private ContentHandler m_contentHandler;
+ protected void initQSE(QueuedSAXEvent qse)
+ {
+ qse.setContentHandler(m_contentHandler);
+ qse.setTransformer(m_transformer);
+ qse.setTraceManager(m_tracer);
+ }
/**
- * Return the current content handler, which may be a content
- * handler stored in this object, or it may delegate to the
- * content handler in the transformer.
+ * Return the current content handler.
*
* @return The current content handler, or null if none
* has been registered.
@@ -1045,21 +789,22 @@
*/
public ContentHandler getContentHandler()
{
- return (null == m_contentHandler)
- ? m_transformer.getContentHandler() : m_contentHandler;
+ return m_contentHandler;
}
-
- /**
- * The root of a linked set of stylesheets.
- */
- private StylesheetRoot m_stylesheetRoot = null;
-
/**
- * This is used whenever a unique namespace is needed.
+ * Set the current content handler.
+ *
+ * @return The current content handler, or null if none
+ * has been registered.
+ * @see #getContentHandler
*/
- private int m_uniqueNSValue = 0;
-
+ public void setContentHandler(ContentHandler ch)
+ {
+ m_contentHandler = ch;
+ reInitEvents();
+ }
+
/**
* Get a unique namespace value.
*/
@@ -1067,9 +812,7 @@
{
return m_uniqueNSValue++;
}
-
- private static final String S_NAMESPACEPREFIX = "ns";
-
+
/**
* Get new unique namespace prefix.
*/
@@ -1077,81 +820,8 @@
{
return S_NAMESPACEPREFIX+String.valueOf(getUniqueNSValue());
}
-
- /**
- * Flag to indicate that we have some document content since the last
- * call to startDocument()
- */
- private boolean m_haveDocContent = false;
-
- /**
- * The pending element, namespace, and local name.
- */
- private String m_pendingElementName;
- private String m_pendingElementNS;
- private String m_pendingElementLName;
/**
- * Set the pending element name. We have to delay the call to
- * m_flistener.startElement(name, atts) because of the
- * xsl:attribute and xsl:copy calls. In other words,
- * the attributes have to be fully collected before you
- * can call startElement.
- */
- private void setPendingElementName (String ns, String localName, String
name)
- {
- m_pendingElementName = name;
- m_pendingElementNS = ns;
- m_pendingElementLName = localName;
- }
-
- /**
- * Get the pending element name. We have to delay the call to
- * m_flistener.startElement(name, atts) because of the
- * xsl:attribute and xsl:copy calls. In other words,
- * the attributes have to be fully collected before you
- * can call startElement.
- */
- public String getPendingElementName()
- {
- return m_pendingElementName;
- }
-
- /**
- * Clear the pending element values. This needs to be called
- * after the real startElement event is sent to the listener.
- */
- private void clearPendingElement()
- {
- m_pendingAttributes.clear();
- m_nsDeclsHaveBeenAdded = false;
- m_pendingElementName = null;
- m_pendingElementNS = null;
- m_pendingElementLName = null;
- }
-
- /**
- * Flag to tell if a call to getContentHandler().startDocument is pending.
- */
- private boolean m_pendingStartDoc = false;
-
- /**
- * The pending attributes. We have to delay the call to
- * m_flistener.startElement(name, atts) because of the
- * xsl:attribute and xsl:copy calls. In other words,
- * the attributes have to be fully collected before you
- * can call startElement.
- */
- private MutableAttrListImpl m_pendingAttributes = new
MutableAttrListImpl();
-
- /**
- * Flag to try and get the xmlns decls to the attribute list
- * before other attributes are added.
- */
- private boolean m_nsDeclsHaveBeenAdded = false;
-
-
- /**
* Get the pending attributes. We have to delay the call to
* m_flistener.startElement(name, atts) because of the
* xsl:attribute and xsl:copy calls. In other words,
@@ -1160,7 +830,7 @@
*/
public MutableAttrListImpl getPendingAttributes()
{
- return m_pendingAttributes;
+ return getQueuedElem().getAttrs();
}
/**
@@ -1184,10 +854,14 @@
*/
public void addAttribute (String uri, String localName, String rawName,
String type, String value)
+ throws SAXException
{
- if(!m_nsDeclsHaveBeenAdded)
+ QueuedStartElement qe = getQueuedElem();
+ if(!qe.nsDeclsHaveBeenAdded())
addNSDeclsToAttrs();
- m_pendingAttributes.addAttribute(uri, localName, rawName, type, value);
+
+ ensurePrefixIsDeclared(uri, localName);
+ qe.addAttribute(uri, localName, rawName, type, value);
}
/**
@@ -1219,5 +893,81 @@
addAttribute((Attr)nnm.item(i));
}
}
+
+ /**
+ * Tell if an element is pending, to be output to the result tree.
+ */
+ public boolean isElementPending()
+ {
+ QueuedStartElement qse = getQueuedElem();
+ return (null != qse) ? qse.isPending() : false;
+ }
+
+ /**
+ * Use the SAX2 helper class to track result namespaces.
+ */
+ private NamespaceSupport m_nsSupport = new NamespaceSupport();
+
+ /**
+ * The transformer object.
+ */
+ private TransformerImpl m_transformer;
+
+ /**
+ * The content handler. May be null, in which
+ * case, we'll defer to the content handler in the
+ * transformer.
+ */
+ private ContentHandler m_contentHandler;
+
+ /**
+ * The root of a linked set of stylesheets.
+ */
+ private StylesheetRoot m_stylesheetRoot = null;
+
+ /**
+ * This is used whenever a unique namespace is needed.
+ */
+ private int m_uniqueNSValue = 0;
+
+ private static final String S_NAMESPACEPREFIX = "ns";
+
+ /**
+ * This class clones nodes to the result tree.
+ */
+ private ClonerToResultTree m_cloner;
+
+ /**
+ * Trace manager for debug support.
+ */
+ private TraceManager m_tracer;
+
+
+ // These are passed to flushPending, to help it decide if it
+ // should really flush.
+ private static final int EVT_SETDOCUMENTLOCATOR = 1;
+ private static final int EVT_STARTDOCUMENT = 2;
+ private static final int EVT_ENDDOCUMENT = 3;
+ private static final int EVT_STARTPREFIXMAPPING = 4;
+ private static final int EVT_ENDPREFIXMAPPING = 5;
+ private static final int EVT_STARTELEMENT = 6;
+ private static final int EVT_ENDELEMENT = 7;
+ private static final int EVT_CHARACTERS = 8;
+ private static final int EVT_IGNORABLEWHITESPACE = 9;
+ private static final int EVT_PROCESSINGINSTRUCTION = 10;
+ private static final int EVT_SKIPPEDENTITY = 11;
+ private static final int EVT_COMMENT = 12;
+ private static final int EVT_ENTITYREF = 13;
+ private static final int EVT_STARTENTITY = 14;
+ private static final int EVT_ENDENTITY = 15;
+ private static final int EVT_STARTDTD = 16;
+ private static final int EVT_ENDDTD = 17;
+ private static final int EVT_STARTNONESCAPING = 18;
+ private static final int EVT_ENDNONESCAPING = 19;
+ private static final int EVT_STARTPRESERVING = 20;
+ private static final int EVT_ENDENDPRESERVING = 21;
+ private static final int EVT_STARTCDATA = 22;
+ private static final int EVT_ENDCDATA = 23;
+ private static final int EVT_NODE = 24;
}
1.31 +64 -22
xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java
Index: TransformerImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- TransformerImpl.java 2000/10/09 23:25:20 1.30
+++ TransformerImpl.java 2000/10/13 00:34:47 1.31
@@ -204,7 +204,7 @@
m_currentNodes = new Stack();
m_currentMatchTemplates = new Stack();
m_currentMatchNodes = new Stack();
- m_resultTreeHandler = new ResultTreeHandler(this);
+ m_resultTreeHandler = null;
m_keyManager = new KeyManager();
m_attrSetStack = null;
m_countersTable = null;
@@ -319,6 +319,7 @@
reader.parse( xmlSource );
}
+
// Kick off the parse. When the ContentHandler gets
// the startDocument event, it will call transformNode( node ).
// reader.parse( xmlSource );
@@ -336,6 +337,11 @@
else
throw new trax.TransformException(e);
}
+ else if(null != m_resultTreeHandler)
+ {
+ m_resultTreeHandler.endDocument();
+ }
+
}
catch(org.apache.xalan.utils.WrappedRuntimeException wre)
{
@@ -658,10 +664,9 @@
// ===========
this.transformNode(null, null, node, null);
- if((null != m_resultTreeHandler) &&
!m_resultTreeHandler.getFoundEndDoc())
+ if(null != m_resultTreeHandler)
{
m_resultTreeHandler.endDocument();
- this.m_resultTreeHandler.flushPending();
}
}
catch(SAXException se)
@@ -1019,6 +1024,7 @@
// = SerializerFactory.getSerializerFactory("text");
sw = new StringWriter();
OutputFormat format = new OutputFormat();
+ format.setMethod("text");
format.setPreserveSpace(true);
Serializer serializer = SerializerFactory.getSerializer(format);
serializer.setWriter(sw);
@@ -1037,9 +1043,6 @@
// Do the transformation of the child elements.
executeChildTemplates(elem, sourceNode, mode);
- // Make sure everything is flushed!
- this.m_resultTreeHandler.flushPending();
-
this.m_resultTreeHandler.endDocument();
// Restore the previous result tree handler.
@@ -1744,7 +1747,7 @@
/**
* Output handler to bottleneck SAX events.
*/
- private ResultTreeHandler m_resultTreeHandler = new
ResultTreeHandler(this);
+ private ResultTreeHandler m_resultTreeHandler;
/**
* Get the ResultTreeHandler object.
@@ -1910,6 +1913,31 @@
parent.setContentHandler(getInputContentHandler());
}
+ /**
+ * Allow an application to register a content event handler.
+ *
+ * <p>If the application does not register a content handler, all
+ * content events reported by the SAX parser will be silently
+ * ignored.</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The content handler.
+ * @exception java.lang.NullPointerException If the handler
+ * argument is null.
+ * @see #getContentHandler
+ */
+ public void setContentHandler (ContentHandler handler)
+ {
+ super.setContentHandler(handler);
+ if(null == m_resultTreeHandler)
+ m_resultTreeHandler = new ResultTreeHandler(this, handler);
+ else
+ m_resultTreeHandler.setContentHandler(handler);
+ }
+
/**
* Look up the value of a feature.
*
@@ -1977,6 +2005,29 @@
}
/**
+ * From a secondary thread, post the exception, so that
+ * it can be picked up from the main thread.
+ */
+ private void postExceptionFromThread(Exception e)
+ {
+ m_isTransformDone = true;
+ m_exceptionThrown = e;
+ ; // should have already been reported via the error handler?
+ synchronized (this)
+ {
+ String msg = e.getMessage();
+ // System.out.println(e.getMessage());
+ notifyAll();
+ if(null == msg)
+ {
+ // m_throwNewError = false;
+ e.printStackTrace();
+ }
+ // throw new org.apache.xalan.utils.WrappedRuntimeException(e);
+ }
+ }
+
+ /**
* Run the transform thread.
*/
public void run()
@@ -1992,6 +2043,11 @@
m_isTransformDone = false;
transformNode(m_doc);
}
+ catch(Exception e)
+ {
+ // Strange that the other catch won't catch this...
+ postExceptionFromThread(e);
+ }
finally
{
m_isTransformDone = true;
@@ -2008,21 +2064,7 @@
}
catch(Exception e)
{
- m_isTransformDone = true;
- m_exceptionThrown = e;
- ; // should have already been reported via the error handler?
- synchronized (this)
- {
- String msg = e.getMessage();
- // System.out.println(e.getMessage());
- notifyAll();
- if(null == msg)
- {
- // m_throwNewError = false;
- e.printStackTrace();
- }
- // throw new org.apache.xalan.utils.WrappedRuntimeException(e);
- }
+ postExceptionFromThread(e);
}
}
1.1
xml-xalan/java/src/org/apache/xalan/transformer/ClonerToResultTree.java
Index: ClonerToResultTree.java
===================================================================
package org.apache.xalan.transformer;
import org.apache.xalan.templates.Stylesheet;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.CDATASection;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.EntityReference;
import org.xml.sax.SAXException;
import org.xml.sax.Attributes;
import org.apache.xpath.XPathContext;
import org.apache.xpath.DOMHelper;
import org.apache.xalan.res.XSLTErrorResources;
public class ClonerToResultTree
{
private ResultTreeHandler m_rth;
private TransformerImpl m_transformer;
public ClonerToResultTree(TransformerImpl transformer, ResultTreeHandler
rth)
{
m_rth = rth;
m_transformer = transformer;
}
/**
* Clone an element with or without children.
* TODO: Fix or figure out node clone failure!
* the error condition is severe enough to halt processing.
*/
public void cloneToResultTree(Stylesheet stylesheetTree, Node node,
boolean shouldCloneWithChildren,
boolean overrideStrip,
boolean shouldCloneAttributes)
throws SAXException
{
boolean stripWhiteSpace = false;
XPathContext xctxt = m_transformer.getXPathContext();
DOMHelper dhelper = xctxt.getDOMHelper();
switch(node.getNodeType())
{
case Node.TEXT_NODE:
{
// If stripWhiteSpace is false, then take this as an override and
// just preserve the space, otherwise use the XSL whitespace rules.
if(!overrideStrip)
{
// stripWhiteSpace = isLiteral ? true : shouldStripSourceNode(node);
stripWhiteSpace = false;
}
Text tx = (Text)node;
String data = null;
// System.out.println("stripWhiteSpace = "+stripWhiteSpace+",
"+tx.getData());
if(stripWhiteSpace)
{
if(!dhelper.isIgnorableWhitespace(tx))
{
data = tx.getData();
if((null != data) && (0 == data.trim().length()))
{
data = null;
}
}
}
else
{
Node parent = node.getParentNode();
if(null != parent)
{
if( Node.DOCUMENT_NODE != parent.getNodeType())
{
data = tx.getData();
if((null != data) && (0 == data.length()))
{
data = null;
}
}
}
else
{
data = tx.getData();
if((null != data) && (0 == data.length()))
{
data = null;
}
}
}
if(null != data)
{
// TODO: Hack around the issue of comments next to literals.
// This would be, when a comment is present, the whitespace
// after the comment must be added to the literal. The
// parser should do this, but XML4J doesn't seem to.
// <foo>some lit text
// <!-- comment -->
// </foo>
// Loop through next siblings while they are comments, then,
// if the node after that is a ignorable text node, append
// it to the text node just added.
if(dhelper.isIgnorableWhitespace(tx))
{
m_rth.ignorableWhitespace(data.toCharArray(), 0, data.length());
}
else
{
m_rth.characters(data.toCharArray(), 0, data.length());
}
}
}
break;
case Node.DOCUMENT_NODE:
// Can't clone a document, but refrain from throwing an error
// so that copy-of will work
break;
case Node.ELEMENT_NODE:
{
Attributes atts;
if(shouldCloneAttributes)
{
m_rth.addAttributes( node );
m_rth.processNSDecls(node);
}
String ns = dhelper.getNamespaceOfNode(node);
String localName = dhelper.getLocalNameOfNode(node);
m_rth.startElement (ns, localName, node.getNodeName());
}
break;
case Node.CDATA_SECTION_NODE:
{
m_rth.startCDATA();
String data = ((CDATASection)node).getData();
m_rth.characters(data.toCharArray(), 0, data.length());
m_rth.endCDATA();
}
break;
case Node.ATTRIBUTE_NODE:
{
String ns = dhelper.getNamespaceOfNode(node);
String localName = dhelper.getLocalNameOfNode(node);
m_rth.addAttribute(ns, localName, node.getNodeName(), "CDATA",
((Attr)node).getValue());
}
break;
case Node.COMMENT_NODE:
{
m_rth.comment(((Comment)node).getData());
}
break;
case Node.DOCUMENT_FRAGMENT_NODE:
{
m_transformer.getMsgMgr().error(null, node,
XSLTErrorResources.ER_NO_CLONE_OF_DOCUMENT_FRAG); //"No clone of a document
fragment!");
}
break;
case Node.ENTITY_REFERENCE_NODE:
{
EntityReference er = (EntityReference)node;
m_rth.entityReference(er.getNodeName());
}
break;
case Node.PROCESSING_INSTRUCTION_NODE:
{
ProcessingInstruction pi = (ProcessingInstruction)node;
m_rth.processingInstruction(pi.getTarget(), pi.getData());
}
break;
default:
m_transformer.getMsgMgr().error(XSLTErrorResources.ER_CANT_CREATE_ITEM,
new Object[] {node.getNodeName()}); //"Can not create item in result tree:
"+node.getNodeName());
}
} // end cloneToResultTree function
}
1.1
xml-xalan/java/src/org/apache/xalan/transformer/QueuedEvents.java
Index: QueuedEvents.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xalan.transformer;
import java.util.Stack;
import org.apache.xalan.utils.ObjectPool;
import org.xml.sax.Attributes;
/**
* This class acts as a base for ResultTreeHandler, and keeps
* queud stack events. In truth, we don't need a stack,
* so I may change this down the line a bit.
*/
abstract class QueuedEvents
{
/**
* Get the queued document event.
*/
QueuedSAXEvent getQueuedSAXEvent()
{
return (QueuedSAXEvent)m_eventQueue.peek();
}
/**
* Get the queued document event.
*/
QueuedStartDocument getQueuedDoc()
{
QueuedSAXEvent event = (QueuedSAXEvent)m_eventQueue.peek();
return (event.getType() == QueuedSAXEvent.DOC)
? (QueuedStartDocument)event : null;
}
/**
* Get the queued document event.
*/
QueuedStartDocument getQueuedDocAtBottom()
{
return (QueuedStartDocument)m_eventQueue.elementAt(0);
}
/**
* Get the queued element.
*/
QueuedStartElement getQueuedElem()
{
QueuedSAXEvent event = (QueuedSAXEvent)m_eventQueue.peek();
return (event.getType() == QueuedSAXEvent.ELEM)
? (QueuedStartElement)event : null;
}
/**
* This is for the derived class to init new events.
*/
protected abstract void initQSE(QueuedSAXEvent qse);
protected void reInitEvents()
{
int n = m_eventQueue.size();
for(int i = 0; i < n; i++)
{
QueuedSAXEvent qse = (QueuedSAXEvent)m_eventQueue.elementAt(i);
initQSE(qse);
}
}
/**
* Push the document event. This never gets popped.
*/
void pushDocumentEvent()
{
QueuedStartDocument qsd
= new QueuedStartDocument();
qsd.setPending(true);
m_eventQueue.push(qsd);
initQSE(qsd);
}
void pushElementEvent(String ns, String localName, String name, Attributes
atts)
{
QueuedStartElement qse =
(QueuedStartElement)m_queuedStartElementPool.getInstance();
m_eventQueue.push(qse);
qse.setPending(ns, localName, name, atts);
initQSE(qse);
}
QueuedSAXEvent popEvent()
{
QueuedSAXEvent event = (QueuedSAXEvent)m_eventQueue.pop();
m_queuedStartElementPool.freeInstance(event);
event.reset();
return event;
}
/**
* Stack of QueuedSAXEvents.
*/
private Stack m_eventQueue = new Stack();
/**
* Pool of QueuedStartElement objects.
*/
private ObjectPool m_queuedStartElementPool = new
ObjectPool(QueuedStartElement.class);
/**
* The pending document event.
*/
private QueuedStartDocument m_queuedDocument;
}
1.1
xml-xalan/java/src/org/apache/xalan/transformer/QueuedSAXEvent.java
Index: QueuedSAXEvent.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xalan.transformer;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.Attributes;
import org.apache.xalan.trace.TraceManager;
import org.apache.xalan.trace.GenerateEvent;
/**
* Acts as a base class for queued SAX events.
*/
public abstract class QueuedSAXEvent
{
public QueuedSAXEvent(int type)
{
m_type = type;
}
static final int DOC = 1;
static final int ELEM = 2;
protected TraceManager m_traceManager;
protected TransformerImpl m_transformer;
protected boolean m_isPending = false;
protected boolean m_isEnded = false;
protected ContentHandler m_contentHandler;
private int m_type;
int getType()
{
return m_type;
}
void setTraceManager(TraceManager traceManager)
{
m_traceManager = traceManager;
}
void setTransformer(TransformerImpl transformer)
{
m_transformer = transformer;
}
protected void fireGenerateEvent(int type, String name, Attributes attrs)
{
GenerateEvent ge
= new GenerateEvent(m_transformer, type, name, attrs);
if(null != m_traceManager)
m_traceManager.fireGenerateEvent(ge);
}
ContentHandler getContentHandler()
{
return m_contentHandler;
}
void setContentHandler(ContentHandler ch)
{
m_contentHandler = ch;
}
/**
* Clear the pending event.
*/
void clearPending()
{
m_isPending = false;
}
boolean isPending()
{
return m_isPending;
}
void setPending(boolean b)
{
m_isPending = b;
m_isEnded = !m_isPending;
}
boolean isEnded()
{
return m_isEnded;
}
/**
* Flush the event.
*/
void flush()
throws SAXException
{
clearPending();
}
/**
* Flush the end event.
*/
void flushEnd()
throws SAXException
{
reset();
m_isEnded = true;
}
void reset()
{
m_isPending = false;
}
}
1.1
xml-xalan/java/src/org/apache/xalan/transformer/QueuedStartDocument.java
Index: QueuedStartDocument.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xalan.transformer;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.apache.xalan.trace.GenerateEvent;
/**
* Tracks the state of a queued document event.
*/
public class QueuedStartDocument extends QueuedSAXEvent
{
public QueuedStartDocument()
{
super(DOC);
}
/**
* Clear the pending event.
*/
void clearPending()
{
super.clearPending();
}
void setPending(boolean b)
{
super.setPending(b);
}
/**
* Flush the event.
*/
void flush()
throws SAXException
{
if(isPending())
{
m_contentHandler.startDocument();
fireGenerateEvent(GenerateEvent.EVENTTYPE_STARTDOCUMENT, null, null);
ContentHandler chandler = getContentHandler();
if((null != chandler)
&& (chandler instanceof TransformerClient))
{
((TransformerClient)chandler).setTransformState(m_transformer);
}
super.flush();
}
}
/**
* Flush the end event.
*/
void flushEnd()
throws SAXException
{
if(!isEnded())
{
m_contentHandler.endDocument();
fireGenerateEvent(GenerateEvent.EVENTTYPE_ENDDOCUMENT, null, null);
super.flushEnd();
}
}
/**
* Flag to indicate that we have some document content since the last
* call to startDocument()
*/
private boolean m_isTextEntity = false;
void setIsTextEntity(boolean b)
{
m_isTextEntity = b;
}
boolean getIsTextEntity()
{
return m_isTextEntity;
}
void reset()
{
super.reset();
m_isTextEntity = false;
}
}
1.1
xml-xalan/java/src/org/apache/xalan/transformer/QueuedStartElement.java
Index: QueuedStartElement.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xalan.transformer;
import java.util.Vector;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.Attributes;
import org.apache.xalan.utils.MutableAttrListImpl;
import org.apache.xalan.trace.GenerateEvent;
import org.apache.xalan.utils.NameSpace;
/**
* Tracks the state of a queued element event.
*/
public class QueuedStartElement extends QueuedSAXEvent
{
public QueuedStartElement()
{
super(ELEM);
}
/**
* The pending attributes. We have to delay the call to
* m_flistener.startElement(name, atts) because of the
* xsl:attribute and xsl:copy calls. In other words,
* the attributes have to be fully collected before you
* can call startElement.
*/
private MutableAttrListImpl m_attributes = new MutableAttrListImpl();
/**
* Flag to try and get the xmlns decls to the attribute list
* before other attributes are added.
*/
private boolean m_nsDeclsHaveBeenAdded = false;
/**
* The pending element, namespace, and local name.
*/
private String m_name;
private String m_url;
private String m_localName;
/**
* Set the pending element names.
*/
void setPending(String ns, String localName, String name, Attributes atts)
{
m_name = name;
m_url = ns;
m_localName = localName;
if(null != atts)
m_attributes.addAttributes(atts);
setPending(true);
}
/**
* Get the list of pending attributes.
*/
MutableAttrListImpl getAttrs()
{
return m_attributes;
}
/**
* Set an attribute in the pending attributes list.
*/
void addAttribute(String uri, String localName, String qName,
String type, String value)
{
m_attributes.addAttribute(uri, localName, qName, type, value);
}
boolean isElement(String ns, String localName)
{
if((null != m_localName) && m_localName.equals(localName))
{
if((null == ns) && (null == m_url))
return true;
if((null != ns) && (null != m_url))
return ns.equals(m_url);
}
return false;
}
/**
* Get the pending element name.
*/
String getName()
{
return m_name;
}
/**
* Get the pending element name.
*/
String getURL()
{
return m_url;
}
/**
* Get the the local name.
*/
String getLocalName()
{
return m_localName;
}
boolean nsDeclsHaveBeenAdded()
{
return m_nsDeclsHaveBeenAdded;
}
void setNSDeclsHaveBeenAdded(boolean b)
{
m_nsDeclsHaveBeenAdded = b;
}
void reset()
{
super.reset();
m_attributes.clear();
m_nsDeclsHaveBeenAdded = false;
m_name = null;
m_url = null;
m_localName = null;
m_namespaces = null;
}
Vector m_namespaces = null;
void startPrefixMapping(String prefix, String uri)
{
if(null == m_namespaces)
m_namespaces = new Vector();
NameSpace ns = new NameSpace(prefix, uri);
m_namespaces.addElement(ns);
}
/**
* Flush the event.
*/
void flush()
throws SAXException
{
if(isPending())
{
if(null != m_name)
{
m_contentHandler.startElement(m_url, m_localName,
m_name, m_attributes);
fireGenerateEvent(GenerateEvent.EVENTTYPE_STARTELEMENT, m_name,
m_attributes);
}
super.flush();
}
}
/**
* Flush the end event.
*/
void flushEnd()
throws SAXException
{
if(!isEnded())
{
if(null != m_name)
{
getContentHandler().endElement(m_url, m_localName, m_name);
fireGenerateEvent(GenerateEvent.EVENTTYPE_ENDELEMENT, m_name, null);
}
super.flushEnd();
}
}
}
1.1
xml-xalan/java/src/org/apache/xalan/transformer/SerializerSwitcher.java
Index: SerializerSwitcher.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xalan.transformer;
import java.io.Writer;
import java.io.OutputStream;
import org.apache.xalan.templates.StylesheetRoot;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import serialize.Serializer;
import serialize.SerializerFactory;
import serialize.Method;
import serialize.OutputFormat;
import org.apache.xalan.templates.OutputFormatExtended;
/**
* This is a helper class that decides if Xalan needs to switch
* serializers, based on the first output element.
*/
public class SerializerSwitcher
{
public static void switchSerializerIfHTML(TransformerImpl transformer,
String ns, String localName)
throws SAXException
{
if(null == transformer)
return;
StylesheetRoot stylesheet = transformer.getStylesheet();
if(null != stylesheet && !stylesheet.isOutputMethodSet())
{
if(((null == ns) || (ns.length() == 0)) &&
localName.equalsIgnoreCase("html"))
{
OutputFormat oformat = stylesheet.getOutputFormat();
if(oformat instanceof OutputFormatExtended)
{
boolean methodHasBeeenSet
= ((OutputFormatExtended)oformat).methodHasBeenSet();
if(methodHasBeeenSet)
return;
}
oformat.setMethod(Method.HTML);
try
{
Serializer oldSerializer = transformer.getSerializer();
if(null != oldSerializer)
{
Serializer serializer = SerializerFactory.getSerializer(oformat);
Writer writer = oldSerializer.getWriter();
if(null != writer)
serializer.setWriter(writer);
else
{
OutputStream os = serializer.getOutputStream();
if(null != os)
serializer.setOutputStream(os);
}
transformer.setSerializer(serializer);
ContentHandler ch = serializer.asContentHandler();
transformer.setContentHandler(ch);
}
}
catch(java.io.IOException e)
{
throw new SAXException(e);
}
}
}
}
}
1.1
xml-xalan/java/src/org/apache/xalan/utils/XMLCharacterRecognizer.java
Index: XMLCharacterRecognizer.java
===================================================================
package org.apache.xalan.utils;
public class XMLCharacterRecognizer
{
/**
* Returns whether the specified <var>ch</var> conforms to the XML 1.0
definition
* of whitespace. Refer to <A
href="http://www.w3.org/TR/1998/REC-xml-19980210#NT-S">
* the definition of <CODE>S</CODE></A> for details.
* @param ch Character to check as XML whitespace.
* @return =true if <var>ch</var> is XML whitespace; otherwise
=false.
*/
public static boolean isWhiteSpace(char ch)
{
return (ch == 0x20) || (ch == 0x09) || (ch == 0xD) || (ch == 0xA);
}
/**
* Tell if the string is whitespace.
* @param string String to be trimmed.
* @return The trimmed string.
*/
public static boolean isWhiteSpace(char ch[], int start, int length)
{
int end = start+length;
for(int s = start; s < end; s++)
{
if (!isWhiteSpace(ch[s]))
return false;
}
return true;
}
/**
* Tell if the string is whitespace.
* @param string String to be trimmed.
* @return The trimmed string.
*/
public static boolean isWhiteSpace(StringBuffer buf)
{
int n = buf.length();
for(int i = 0; i < n; i++)
{
if (!isWhiteSpace(buf.charAt(i)))
return false;
}
return true;
}
}
1.3 +12 -3
xml-xalan/java/src/org/apache/xml/serialize/transition/BaseMarkupSerializer.java
Index: BaseMarkupSerializer.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/serialize/transition/BaseMarkupSerializer.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- BaseMarkupSerializer.java 2000/10/02 23:41:44 1.2
+++ BaseMarkupSerializer.java 2000/10/13 00:34:48 1.3
@@ -138,7 +138,7 @@
* another element.
*
*
- * @version $Revision: 1.2 $ $Date: 2000/10/02 23:41:44 $
+ * @version $Revision: 1.3 $ $Date: 2000/10/13 00:34:48 $
* @author <a href="mailto:[EMAIL PROTECTED]">Assaf Arkin</a>
* @see Serializer
* @see DOMSerializer
@@ -409,10 +409,19 @@
// the writer. It is possible that the serializer has been
// reused with the same output stream and different encoding.
if ( _output != null ) {
+ try
+ {
if ( _format.getEncoding() == null )
- _writer = new OutputStreamWriter( _output );
+ _writer = new OutputStreamWriter( _output );
else
- _writer = Encodings.getWriter( _output,
_format.getEncoding() );
+ _writer = Encodings.getWriter( _output, _format.getEncoding()
);
+ }
+ catch(UnsupportedEncodingException uee)
+ {
+ System.out.println("Warning - Unsupported Encoding:
\""+_format.getEncoding()+"\"");
+ _format.setEncoding("UTF-8");
+ _writer = new OutputStreamWriter( _output );
+ }
}
// Determine the last printable character.
if ( _format.getEncoding() == null )
1.2 +2 -1
xml-xalan/java/src/org/apache/xpath/functions/FuncNormalizeSpace.java
Index: FuncNormalizeSpace.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xpath/functions/FuncNormalizeSpace.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FuncNormalizeSpace.java 2000/07/05 14:46:40 1.1
+++ FuncNormalizeSpace.java 2000/10/13 00:34:49 1.2
@@ -64,6 +64,7 @@
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XString;
import org.apache.xpath.objects.XNodeSet;
+import org.apache.xalan.utils.XMLCharacterRecognizer;
public class FuncNormalizeSpace extends FunctionDef1Arg
{
@@ -89,7 +90,7 @@
*/
private static boolean isSpace(char ch)
{
- return Character.isWhitespace(ch); // Take the easy way out for now.
+ return XMLCharacterRecognizer.isWhiteSpace(ch); // Take the easy way out
for now.
}
/**