morten 01/10/02 04:17:32 Modified: java/src/org/apache/xalan/xsltc/compiler CopyOf.java Text.java java/src/org/apache/xalan/xsltc/dom DOMAdapter.java java/src/org/apache/xalan/xsltc/runtime BasisLibrary.java TextOutput.java Log: A few fixes to speed up output processing. PR: n/a Obtained from: n/a Submitted by: [EMAIL PROTECTED] Reviewed by: [EMAIL PROTECTED] Revision Changes Path 1.8 +2 -2 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/CopyOf.java Index: CopyOf.java =================================================================== RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/CopyOf.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- CopyOf.java 2001/08/27 09:07:19 1.7 +++ CopyOf.java 2001/10/02 11:17:32 1.8 @@ -1,5 +1,5 @@ /* - * @(#)$Id: CopyOf.java,v 1.7 2001/08/27 09:07:19 morten Exp $ + * @(#)$Id: CopyOf.java,v 1.8 2001/10/02 11:17:32 morten Exp $ * * The Apache Software License, Version 1.1 * @@ -156,7 +156,7 @@ } else { il.append(classGen.loadTranslet()); - _select.translate(classGen, methodGen); + _select.translate(classGen, methodGen); il.append(methodGen.loadHandler()); il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS, CHARACTERSW, 1.6 +11 -6 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Text.java Index: Text.java =================================================================== RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Text.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- Text.java 2001/08/27 09:07:20 1.5 +++ Text.java 2001/10/02 11:17:32 1.6 @@ -1,5 +1,5 @@ /* - * @(#)$Id: Text.java,v 1.5 2001/08/27 09:07:20 morten Exp $ + * @(#)$Id: Text.java,v 1.6 2001/10/02 11:17:32 morten Exp $ * * The Apache Software License, Version 1.1 * @@ -129,12 +129,17 @@ il.append(new INVOKEINTERFACE(esc, 2)); } - il.append(classGen.loadTranslet()); - il.append(new PUSH(cpg, _text)); + final int toCharArr = cpg.addMethodref("java/lang/String", + "toCharArray", "()[C"); + final int characters = cpg.addInterfaceMethodref(OUTPUT_HANDLER, + "characters", + "([CII)V"); il.append(methodGen.loadHandler()); - il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS, - CHARACTERSW, - CHARACTERSW_SIG))); + il.append(new PUSH(cpg, _text)); + il.append(new INVOKEVIRTUAL(toCharArr)); + il.append(new ICONST(0)); + il.append(new PUSH(cpg, _text.length())); + il.append(new INVOKEINTERFACE(characters, 4)); // Restore character escaping setting to whatever it was. // Note: setEscaping(bool) returns the original (old) value 1.7 +2 -2 xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java Index: DOMAdapter.java =================================================================== RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- DOMAdapter.java 2001/09/25 15:57:22 1.6 +++ DOMAdapter.java 2001/10/02 11:17:32 1.7 @@ -1,5 +1,5 @@ /* - * @(#)$Id: DOMAdapter.java,v 1.6 2001/09/25 15:57:22 morten Exp $ + * @(#)$Id: DOMAdapter.java,v 1.7 2001/10/02 11:17:32 morten Exp $ * * The Apache Software License, Version 1.1 * @@ -218,7 +218,7 @@ public void characters(final int textNode, TransletOutputHandler handler) throws TransletException { - _domImpl.characters(textNode, handler); + _domImpl.characters(textNode, handler); } public Node makeNode(int index) { 1.21 +8 -10 xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java Index: BasisLibrary.java =================================================================== RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- BasisLibrary.java 2001/09/25 20:47:20 1.20 +++ BasisLibrary.java 2001/10/02 11:17:32 1.21 @@ -1,5 +1,5 @@ /* - * @(#)$Id: BasisLibrary.java,v 1.20 2001/09/25 20:47:20 morten Exp $ + * @(#)$Id: BasisLibrary.java,v 1.21 2001/10/02 11:17:32 morten Exp $ * * The Apache Software License, Version 1.1 * @@ -470,13 +470,13 @@ public static boolean compare(NodeIterator left, NodeIterator right, int op, int node, DOM dom) { int lnode; - left.reset(); + //left.reset(); while ((lnode = left.next()) != NodeIterator.END) { final String lvalue = dom.getNodeValue(lnode); int rnode; - right.reset(); + //right.reset(); while ((rnode = right.next()) != NodeIterator.END) { if (compareStrings(lvalue, dom.getNodeValue(rnode), op, dom)) { return true; @@ -493,7 +493,7 @@ int op, DOM dom) { final String lvalue = dom.getNodeValue(node); int rnode; - nodeSet.reset(); + //nodeSet.reset(); while ((rnode = nodeSet.next()) != NodeIterator.END) { if (compareStrings(lvalue, dom.getNodeValue(rnode), op, dom)) { return true; @@ -504,7 +504,7 @@ public static boolean compare(int node, NodeIterator iterator, int op, int dummy, DOM dom) { - iterator.reset(); + //iterator.reset(); int rnode; String value; @@ -552,7 +552,7 @@ public static boolean compare(NodeIterator left, final double rnumber, final int op, DOM dom) { int node; - left.reset(); + //left.reset(); switch (op) { case EQ: @@ -610,7 +610,7 @@ public static boolean compare(NodeIterator left, final String rstring, int op, DOM dom) { int node; - left.reset(); + //left.reset(); while ((node = left.next()) != NodeIterator.END) { if (compareStrings(dom.getNodeValue(node), rstring, op, dom)) { return true; @@ -907,9 +907,7 @@ try { if (obj instanceof NodeIterator) { NodeIterator iter = (NodeIterator) obj; - //dom.copy(iter.reset(), handler); - //!! - System.err.println("not implemented copy iter"); + dom.copy(iter.reset(), handler); } else if (obj instanceof Node) { dom.copy(((Node) obj).node, handler); 1.35 +186 -134 xml-xalan/java/src/org/apache/xalan/xsltc/runtime/TextOutput.java Index: TextOutput.java =================================================================== RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/TextOutput.java,v retrieving revision 1.34 retrieving revision 1.35 diff -u -r1.34 -r1.35 --- TextOutput.java 2001/09/25 16:07:48 1.34 +++ TextOutput.java 2001/10/02 11:17:32 1.35 @@ -1,5 +1,5 @@ /* - * @(#)$Id: TextOutput.java,v 1.34 2001/09/25 16:07:48 morten Exp $ + * @(#)$Id: TextOutput.java,v 1.35 2001/10/02 11:17:32 morten Exp $ * * The Apache Software License, Version 1.1 * @@ -78,11 +78,11 @@ public final class TextOutput implements TransletOutputHandler { // These are the various output types we handle - public static final int UNKNOWN = -1; // determine type from output contents - public static final int TEXT = 0; + public static final int UNKNOWN = 0; // determine type from output contents public static final int XML = 1; public static final int HTML = 2; - public static final int QNAME = 3; // no special handling + public static final int TEXT = 3; + public static final int QNAME = 4; // no special handling // These parameters are set by the <xsl:output> element, or by the // get/setOutputProperty() methods in TrAX @@ -447,36 +447,54 @@ public void characters(char[] ch, int off, int len) throws TransletException { try { - // Close any open start tag - if (_startTagOpen) closeStartTag(); - - // Set output type to XML (the default) if still unknown. - if (_outputType == UNKNOWN) setTypeInternal(XML); + switch(_outputType) { + case UNKNOWN: // Set type to XML and fall through + setTypeInternal(XML); + case XML: + // Close any open start tag + if (_startTagOpen) closeStartTag(); + + // Take special precautions if within a CDATA section. If we + // encounter the sequence ']]>' within the CDATA, we need to + // break the section in two and leave the ']]' at the end of + // the first CDATA and '>' at the beginning of the next. Other + // special characters/sequences are _NOT_ escaped within CDATA. + Integer I = (Integer)_cdataStack.peek(); + if ((I.intValue() == _depth) && (!_cdataTagOpen)) + startCDATA(ch, off, len); + // Output characters escaped if required. + else if (_escapeChars) + escapeCharacters(ch, off, len); + // Output the chracters as the are if not. + else + _saxHandler.characters(ch, off, len); + return; - // Take special precautions if within a CDATA section. If we - // encounter the sequence ']]>' within the CDATA, we need to - // break the section in two and leave the ']]' at the end of - // the first CDATA and '>' at the beginning of the next. Other - // special characters/sequences are _NOT_ escaped within CDATA. - Integer I = (Integer)_cdataStack.peek(); - if ((I.intValue() == _depth) && (!_cdataTagOpen)) { - startCDATA(ch, off, len); - } - // Output escaped characters if required. Non-ASCII characters - // within HTML attributes should _NOT_ be escaped. - else if (_escapeChars) { - if ((_outputType == HTML) && (!_qnameStack.isEmpty())) { - final String qname = (String)_qnameStack.peek(); - if ((qname.equals("style")) || (qname.equals("script"))) { - _saxHandler.characters(ch, off, len); - return; + case HTML: + // Close any open start tag + if (_startTagOpen) closeStartTag(); + + // Output escaped characters if required. Non-ASCII characters + // within HTML attributes should _NOT_ be escaped. + if (_escapeChars) { + if (!_qnameStack.isEmpty()) { + final String qname = (String)_qnameStack.peek(); + if ((qname.equals("style"))||(qname.equals("script"))) { + _saxHandler.characters(ch, off, len); + return; + } } + escapeCharacters(ch, off, len); } - escapeCharacters(ch, off, len); - } - // Output the chracters as the are - else { + // Output the chracters as the are + else { + _saxHandler.characters(ch, off, len); + } + return; + + case TEXT: _saxHandler.characters(ch, off, len); + return; } } catch (SAXException e) { @@ -492,48 +510,70 @@ throws TransletException { try { - // Do not output element tags if output mode is 'text' - if (_outputType == TEXT) return; - - // Close any open start tag - if (_startTagOpen) closeStartTag(); - if (_cdataTagOpen) closeCDATA(); + switch(_outputType) { - // If we don't know the output type yet we need to examine - // the very first element to see if it is "html". - if (_outputType == UNKNOWN) { + case UNKNOWN: + // If we don't know the output type yet we need to examine + // the very first element to see if it is "html". if (elementName.toLowerCase().equals("html")) setTypeInternal(HTML); else setTypeInternal(XML); - } - - // Handle document type declaration (for first element only) - if (_lexHandler != null) { - if (((_outputType == XML) && (_doctypeSystem != null)) || - ((_doctypeSystem != null) || (_doctypePublic != null))) - _lexHandler.startDTD(elementName, - _doctypePublic,_doctypeSystem); - _lexHandler = null; - } - - _depth++; - _elementName = elementName; - _attributes.clear(); - _startTagOpen = true; + startElement(elementName); + return; - _qnameStack.push(elementName); + case XML: + // Close any open start tag + if (_startTagOpen) closeStartTag(); + if (_cdataTagOpen) closeCDATA(); + + // Handle document type declaration (for first element only) + if (_lexHandler != null) { + if (_doctypeSystem != null) + _lexHandler.startDTD(elementName, + _doctypePublic,_doctypeSystem); + _lexHandler = null; + } - if (_cdata != null) { - if (_cdata.get(elementName) != null) { + _depth++; + _elementName = elementName; + _attributes.clear(); + _startTagOpen = true; + _qnameStack.push(elementName); + + if ((_cdata != null) && (_cdata.get(elementName) != null)) _cdataStack.push(new Integer(_depth)); + + return; + + case HTML: + // Close any open start tag + if (_startTagOpen) closeStartTag(); + + // Handle document type declaration (for first element only) + if (_lexHandler != null) { + if ((_doctypeSystem != null) || (_doctypePublic != null)) + _lexHandler.startDTD(elementName, + _doctypePublic,_doctypeSystem); + _lexHandler = null; } - } + + _depth++; + _elementName = elementName; + _attributes.clear(); + _startTagOpen = true; + _qnameStack.push(elementName); - // Insert <META> tag directly after <HEAD> element in HTML doc - if (_outputType == HTML) + // Insert <META> tag directly after <HEAD> element in HTML doc if (elementName.toLowerCase().equals("head")) _headTagOpen = true; + return; + + case TEXT: + // Do not output element tags if output mode is 'text' + return; + + } } catch (SAXException e) { throw new TransletException(e); @@ -612,79 +652,84 @@ return base; } + private String expandAttribute(String qname) throws TransletException { + // If this attribute was created using an <xsl:attribute> + // element with a 'namespace' attribute and a 'name' attribute + // containing an AVT, then we might get an attribute name on + // a strange format like 'prefix1:prefix2:localpart', where + // prefix1 is from the AVT and prefix2 from the namespace. + final int endcol = qname.lastIndexOf(':'); + if (endcol > 0) { + final int startcol = qname.indexOf(':'); + final String localname = qname.substring(endcol+1); + final String prefix = qname.substring(0,startcol); + final String uri = lookupNamespace(prefix); + if (uri == null) { + throw new TransletException("Namespace for prefix "+ + prefix+" has not been "+ + "declared."); + } + // Omit prefix (use default) if the namespace URI is null + if (uri.equals(EMPTYSTRING)) + return(localname); + // Construct new QName if we've got two alt. prefixes + else if (endcol != startcol) + return(prefix+':'+localname); + } + return qname; + } + /** * Put an attribute and its value in the start tag of an element. * Signal an exception if this is attempted done outside a start tag. */ public void attribute(String name, final String value) throws TransletException { - - // Do not output attributes if output mode is 'text' - if (_outputType == TEXT) return; - if (_startTagOpen) { - - // The following is an attempt to escape an URL stored in a href - // attribute of HTML output. Normally URLs should be encoded at - // the time they are created, since escaping or unescaping a - // completed URI might change its semantics. We limit or escaping - // to include space characters only - and nothing else. This is for - // two reasons: (1) performance and (2) we want to make sure that - // we do not change the meaning of the URL. - - // URL-encode href attributes in HTML output - if (_outputType == HTML) { - if (name.toLowerCase().equals("href")) { - _attributes.add(name, quickAndDirtyUrlEncode(value)); - return; - } - } - - // Intercept namespace declarations and handle them separately + switch(_outputType) { + case TEXT: + // Do not output attributes if output mode is 'text' + return; + case XML: + if (!_startTagOpen) + throw new TransletException("attribute '"+name+ + "' outside of element"); + // Attributes whose names start with XML need special handling if (name.startsWith("xml")) { + // Output as namespace declaration if (name.startsWith("xmlns")) { if (name.length() == 5) namespace(EMPTYSTRING, value); else namespace(name.substring(6),value); - } - else { - namespace(name, value); } + // Output as xml:<blah> attribute + _attributes.add(name, value); } else { - // If this attribute was created using an <xsl:attribute> - // element with a 'namespace' attribute and a 'name' attribute - // containing an AVT, then we might get an attribute name on - // a strange format like 'prefix1:prefix2:localpart', where - // prefix1 is from the AVT and prefix2 from the namespace. - final int endcol = name.lastIndexOf(':'); - final int startcol = name.indexOf(':'); - if (endcol > 0) { - final String localname = name.substring(endcol+1); - final String prefix = name.substring(0,startcol); - final String uri = lookupNamespace(prefix); - if (uri == null) { - throw new TransletException("Namespace for prefix "+ - prefix+" has not been "+ - "declared."); - } - // Omit prefix (use default) if the namespace URI is null - if (uri.equals(EMPTYSTRING)) - name = localname; - // Construct new QName if we've got two alt. prefixes - else if (endcol != startcol) - name = prefix+':'+localname; - } - if (_outputType == HTML) - _attributes.add(name, value); - else - _attributes.add(name, escapeChars(value)); + // Output as regular attribute + _attributes.add(expandAttribute(name), escapeChars(value)); } - } - else { - throw new TransletException("attribute '"+name+ - "' outside of element"); + return; + case HTML: + if (!_startTagOpen) + throw new TransletException("attribute '"+name+ + "' outside of element"); + + // The following is an attempt to escape an URL stored in a href + // attribute of HTML output. Normally URLs should be encoded at + // the time they are created, since escaping or unescaping a + // completed URI might change its semantics. We limit or escaping + // to include space characters only - and nothing else. This is for + // two reasons: (1) performance and (2) we want to make sure that + // we do not change the meaning of the URL. + + // URL-encode href attributes in HTML output + if (name.toLowerCase().equals("href")) + _attributes.add(name, quickAndDirtyUrlEncode(value)); + else + _attributes.add(expandAttribute(name), value); + return; } } @@ -693,25 +738,30 @@ */ public void endElement(String elementName) throws TransletException { - // Do not output element tags if output mode is 'text' - if (_outputType == TEXT) return; - try { - boolean closeElement = true; - - // Close any open element - if (_startTagOpen) closeStartTag(); - if (_cdataTagOpen) closeCDATA(); - - final String qname = (String)(_qnameStack.pop()); - if (closeElement) _saxHandler.endElement(null, null, qname); - - popNamespaces(); - - Integer I = (Integer)_cdataStack.peek(); - if (I.intValue() == _depth) _cdataStack.pop(); - - _depth--; + switch(_outputType) { + case TEXT: + // Do not output element tags if output mode is 'text' + return; + case XML: + // Close any open element + if (_startTagOpen) closeStartTag(); + if (_cdataTagOpen) closeCDATA(); + + _saxHandler.endElement(null, null, (String)(_qnameStack.pop())); + popNamespaces(); + if (((Integer)_cdataStack.peek()).intValue() == _depth) + _cdataStack.pop(); + _depth--; + return; + case HTML: + // Close any open element + if (_startTagOpen) closeStartTag(); + _saxHandler.endElement(null, null, (String)(_qnameStack.pop())); + popNamespaces(); + _depth--; + return; + } } catch (SAXException e) { throw new TransletException(e); @@ -864,6 +914,7 @@ * Takes a qname as a string on the format prefix:local-name and * returns a strig with the expanded QName on the format uri:local-name. */ + /* private String expandQName(String withPrefix) { int col = withPrefix.lastIndexOf(':'); if (col == -1) return(withPrefix); @@ -879,6 +930,7 @@ else return(uri+":"+local); } + */ /************************************************************************ * The following are all methods for configuring the output settings
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]