This commit was manufactured by cvs2svn to create tag
'jaxp-ri-1_2_0-fcs-branch-01'.
git-svn-id: https://svn.apache.org/repos/asf/xalan/java/tags/jaxp-ri-1_2_0-fcs-branch-01@336222 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/build.xml b/build.xml
index 0e09c0f..5316f9c 100644
--- a/build.xml
+++ b/build.xml
@@ -361,7 +361,7 @@
</javac>
</target>
- <target name="xsltc.jar" depends="xsltc.compile"
+ <target name="xsltc.unbundledjar" depends="xsltc.compile"
description="Jar just the xsltc.jar file" >
<!-- Copy over the manifest, with filtering (for version number) -->
<filter token="impl.version" value="${impl.version}"/>
@@ -374,7 +374,7 @@
</target>
- <target name="xsltc.bundledjar" depends="xsltc.compile"
+ <target name="xsltc.jar" depends="xsltc.compile"
description="Jar xsltc, BCEL,JLex,java_cup,runtime and jakarta regexp">
<!-- make a tmp directory to work in -->
<delete dir="${build.dir}/xsltctmp" includeEmptyDirs="true" quiet="true"/>
@@ -449,11 +449,14 @@
includeEmptyDirs="true" quiet="true"/>
<!-- create new META-INF dir w/ transformer factory default -->
+ <!-- GTM: comment this out so that bundled xsltc.jar does not have
+ service provider default until further notice 2/20/2002
<mkdir dir="${build.dir}/xsltctmp/META-INF"/>
<mkdir dir="${build.dir}/xsltctmp/META-INF/services"/>
<copy todir="${build.dir}/xsltctmp/META-INF/services"
file="${src.dir}/${xsltc.reldir}/javax.xml.transform.TransformerFactory"
/>
+ -->
<!-- Copy over the manifest, with filtering (for version number) -->
<filter token="impl.version" value="${impl.version}"/>
diff --git a/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java b/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java
index b0143cb..985f683 100644
--- a/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java
+++ b/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java
@@ -139,6 +139,7 @@
* some template in the stylesheet uses parameters.
*/
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
+ boolean setStartNodeCalled = false;
final Stylesheet stylesheet = classGen.getStylesheet();
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
@@ -165,6 +166,7 @@
translateContents(classGen, methodGen);
}
+
il.append(classGen.loadTranslet());
// The 'select' expression is a result-tree
@@ -192,6 +194,7 @@
NODE_ITERATOR_SIG);
il.append(methodGen.loadCurrentNode());
il.append(new INVOKEINTERFACE(setStartNode,2));
+ setStartNodeCalled = true;
}
else {
if (_select == null)
@@ -201,7 +204,7 @@
}
}
- if (_select != null) {
+ if (_select != null && !setStartNodeCalled) {
_select.startResetIterator(classGen, methodGen);
}
diff --git a/src/org/apache/xalan/xsltc/compiler/Constants.java b/src/org/apache/xalan/xsltc/compiler/Constants.java
index 6772185..4e6acc7 100644
--- a/src/org/apache/xalan/xsltc/compiler/Constants.java
+++ b/src/org/apache/xalan/xsltc/compiler/Constants.java
@@ -486,6 +486,10 @@
public static final int POSITION_INDEX = 2;
public static final int LAST_INDEX = 3;
+ public static final String XMLNS_PREFIX = "xmlns";
+ public static final String XMLNS_STRING = "xmlns:";
+ public static final String XMLNS_URI
+ = "http://www.w3.org/2000/xmlns/";
public static final String XSLT_URI
= "http://www.w3.org/1999/XSL/Transform";
public static final String XHTML_URI
diff --git a/src/org/apache/xalan/xsltc/compiler/Expression.java b/src/org/apache/xalan/xsltc/compiler/Expression.java
index 3da80c6..727dc3b 100644
--- a/src/org/apache/xalan/xsltc/compiler/Expression.java
+++ b/src/org/apache/xalan/xsltc/compiler/Expression.java
@@ -103,7 +103,7 @@
public abstract String toString();
public boolean hasPositionCall() {
- return true;
+ return false; // default should be 'false' for StepPattern
}
public boolean hasLastCall() {
diff --git a/src/org/apache/xalan/xsltc/compiler/FormatNumberCall.java b/src/org/apache/xalan/xsltc/compiler/FormatNumberCall.java
index 9558f1a..124576d 100644
--- a/src/org/apache/xalan/xsltc/compiler/FormatNumberCall.java
+++ b/src/org/apache/xalan/xsltc/compiler/FormatNumberCall.java
@@ -97,7 +97,7 @@
_format = new CastExpr(_format, Type.String);
}
if (argumentCount() == 3) {
- final Type tname = _format.typeCheck(stable);
+ final Type tname = _name.typeCheck(stable);
if (tname instanceof StringType == false) {
_name = new CastExpr(_name, Type.String);
}
diff --git a/src/org/apache/xalan/xsltc/compiler/LiteralElement.java b/src/org/apache/xalan/xsltc/compiler/LiteralElement.java
index fffa79b..a041344 100644
--- a/src/org/apache/xalan/xsltc/compiler/LiteralElement.java
+++ b/src/org/apache/xalan/xsltc/compiler/LiteralElement.java
@@ -77,10 +77,11 @@
import org.apache.xalan.xsltc.compiler.util.*;
final class LiteralElement extends Instruction {
+
private String _name;
- private Hashtable _accessedPrefixes = null;
- private LiteralElement _parent;
+ private LiteralElement _literalElemParent;
private Vector _attributeElements = null;
+ private Hashtable _accessedPrefixes = null;
private final static String XMLNS_STRING = "xmlns";
@@ -119,10 +120,10 @@
SymbolTable stable, boolean declared) {
// Check if the parent has a declaration for this namespace
- if (_parent != null) {
- final String parentUri = _parent.accessedNamespace(prefix);
+ if (_literalElemParent != null) {
+ final String parentUri = _literalElemParent.accessedNamespace(prefix);
if (parentUri == null) {
- _parent.registerNamespace(prefix, uri, stable, declared);
+ _literalElemParent.registerNamespace(prefix, uri, stable, declared);
return;
}
if (parentUri.equals(uri)) return;
@@ -139,7 +140,7 @@
if (old != null) {
if (old.equals(uri))
return;
- else
+ else
prefix = stable.generateNamespacePrefix();
}
}
@@ -207,7 +208,6 @@
_attributeElements.insertElementAt(attribute,0);
}
-
/**
* Type-check the contents of this element. The element itself does not
* need any type checking as it leaves nothign on the JVM's stack.
@@ -255,23 +255,24 @@
* Registers all namespaces that are used by the element/attributes
*/
public void parseContents(Parser parser) {
-
final SymbolTable stable = parser.getSymbolTable();
stable.setCurrentNode(this);
// Find the closest literal element ancestor (if there is one)
- SyntaxTreeNode _parent = getParent();
- while ((_parent != null) && !(_parent instanceof LiteralElement))
- _parent = _parent.getParent();
- if (!(_parent instanceof LiteralElement))
- _parent = null;
+ SyntaxTreeNode _literalElemParent = getParent();
+ while (_literalElemParent != null && !(_literalElemParent instanceof LiteralElement)) {
+ _literalElemParent = _literalElemParent.getParent();
+ }
+
+ if (!(_literalElemParent instanceof LiteralElement)) {
+ _literalElemParent = null;
+ }
_name = translateQName(_qname, stable);
// Process all attributes and register all namespaces they use
final int count = _attributes.getLength();
for (int i = 0; i < count; i++) {
-
final QName qname = parser.getQName(_attributes.getQName(i));
final String uri = qname.getNamespace();
final String val = _attributes.getValue(i);
@@ -290,12 +291,15 @@
else if (qname == parser.getExcludeResultPrefixes()) {
stable.excludeNamespaces(val);
}
- // Ignore all other attributes in XSL namespace
- else if ((uri != null) && (uri.equals(XSLT_URI))) {
-
- }
- // Handle literal attributes (attributes not in XSL namespace)
else {
+ // Ignore special attributes
+ final String prefix = qname.getPrefix();
+ if (uri != null && uri.equals(XSLT_URI) ||
+ prefix != null && prefix.equals(XMLNS_STRING)) {
+ continue;
+ }
+
+ // Handle all other literal attributes
final String name = translateQName(qname, stable);
LiteralAttribute attr = new LiteralAttribute(name, val, parser);
addAttribute(attr);
@@ -311,9 +315,8 @@
final String prefix = (String)include.nextElement();
if (!prefix.equals("xml")) {
final String uri = lookupNamespace(prefix);
- if ((uri != null) && (!uri.equals(XSLT_URI))) {
- if (!stable.isExcludedNamespace(uri))
- registerNamespace(prefix,uri,stable,true);
+ if (uri != null && !stable.isExcludedNamespace(uri)) {
+ registerNamespace(prefix, uri, stable, true);
}
}
}
@@ -322,7 +325,6 @@
// Process all attributes and register all namespaces they use
for (int i = 0; i < count; i++) {
-
final QName qname = parser.getQName(_attributes.getQName(i));
final String val = _attributes.getValue(i);
@@ -344,7 +346,9 @@
/**
* Compiles code that emits the literal element to the output handler,
* first the start tag, then namespace declaration, then attributes,
- * then the element contents, and then the element end tag.
+ * then the element contents, and then the element end tag. Since the
+ * value of an attribute may depend on a variable, variables must be
+ * compiled first.
*/
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
@@ -354,23 +358,52 @@
// Compile code to emit element start tag
il.append(methodGen.loadHandler());
il.append(new PUSH(cpg, _name));
- il.append(DUP2); // duplicate these 2 args for endElement
+ il.append(DUP2); // duplicate these 2 args for endElement
il.append(methodGen.startElement());
+ // The value of an attribute may depend on a (sibling) variable
+ for (int i = 0; i < elementCount(); i++) {
+ final SyntaxTreeNode item = (SyntaxTreeNode) elementAt(i);
+ if (item instanceof Variable) {
+ item.translate(classGen, methodGen);
+ removeElement(item); // avoid translating it twice
+ }
+ }
+
// Compile code to emit namespace attributes
if (_accessedPrefixes != null) {
+ boolean declaresDefaultNS = false;
Enumeration e = _accessedPrefixes.keys();
+
while (e.hasMoreElements()) {
final String prefix = (String)e.nextElement();
final String uri = (String)_accessedPrefixes.get(prefix);
- if ((uri != Constants.EMPTYSTRING) ||
- (prefix != Constants.EMPTYSTRING)) {
+
+ if (uri != Constants.EMPTYSTRING ||
+ prefix != Constants.EMPTYSTRING)
+ {
+ if (prefix == Constants.EMPTYSTRING) {
+ declaresDefaultNS = true;
+ }
il.append(methodGen.loadHandler());
il.append(new PUSH(cpg,prefix));
il.append(new PUSH(cpg,uri));
il.append(methodGen.namespace());
}
}
+
+ /*
+ * If our XslElement parent redeclares the default NS, and this
+ * element doesn't, it must be redeclared one more time.
+ */
+ if (!declaresDefaultNS && (_parent instanceof XslElement)
+ && ((XslElement) _parent).declaresDefaultNS())
+ {
+ il.append(methodGen.loadHandler());
+ il.append(new PUSH(cpg, Constants.EMPTYSTRING));
+ il.append(new PUSH(cpg, Constants.EMPTYSTRING));
+ il.append(methodGen.namespace());
+ }
}
// Output all attributes
diff --git a/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java b/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java
index adca196..8ffd159 100644
--- a/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java
+++ b/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java
@@ -216,10 +216,12 @@
Expression stp = _step;
if (stp instanceof ParentLocationPath)
stp = ((ParentLocationPath)stp).getStep();
+
if ((_path instanceof Step) && (stp instanceof Step)) {
final int path = ((Step)_path).getAxis();
final int step = ((Step)stp).getAxis();
if ((path == Axis.DESCENDANTORSELF && step == Axis.CHILD) ||
+ (path == Axis.DESCENDANTORSELF && step == Axis.ATTRIBUTE) ||
(path == Axis.PRECEDING && step == Axis.PARENT)) {
final int incl = cpg.addMethodref(STEP_ITERATOR_CLASS,
"includeSelf",
diff --git a/src/org/apache/xalan/xsltc/compiler/Parser.java b/src/org/apache/xalan/xsltc/compiler/Parser.java
index c4b2fd6..486a35d 100644
--- a/src/org/apache/xalan/xsltc/compiler/Parser.java
+++ b/src/org/apache/xalan/xsltc/compiler/Parser.java
@@ -265,6 +265,10 @@
}
public QName getQName(final String stringRep) {
+ return getQName(stringRep, true);
+ }
+
+ public QName getQName(final String stringRep, boolean reportError) {
// parse and retrieve namespace
final int colon = stringRep.lastIndexOf(':');
if (colon != -1) {
@@ -275,7 +279,7 @@
// Get the namespace uri from the symbol table
if (prefix.equals("xmlns") == false) {
namespace = _symbolTable.lookupNamespace(prefix);
- if (namespace == null) {
+ if (namespace == null && reportError) {
final int line = _locator.getLineNumber();
ErrorMsg err = new ErrorMsg(ErrorMsg.NAMESPACE_UNDEF_ERR,
line, prefix);
@@ -1072,7 +1076,9 @@
* This has to be passed on to the symbol table!
*/
public void startPrefixMapping(String prefix, String uri) {
- if (_prefixMapping == null) _prefixMapping = new Hashtable();
+ if (_prefixMapping == null) {
+ _prefixMapping = new Hashtable();
+ }
_prefixMapping.put(prefix, uri);
}
diff --git a/src/org/apache/xalan/xsltc/compiler/ProcessingInstruction.java b/src/org/apache/xalan/xsltc/compiler/ProcessingInstruction.java
index 91e40a4..fa2a188 100644
--- a/src/org/apache/xalan/xsltc/compiler/ProcessingInstruction.java
+++ b/src/org/apache/xalan/xsltc/compiler/ProcessingInstruction.java
@@ -109,13 +109,13 @@
// get String out of the handler
il.append(new INVOKEVIRTUAL(cpg.addMethodref(STRING_VALUE_HANDLER,
- "getValue",
- "()"+STRING_SIG)));
+ "getValueOfPI",
+ "()" + STRING_SIG)));
// call "processingInstruction"
final int processingInstruction =
cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
"processingInstruction",
- "("+STRING_SIG+STRING_SIG+")V");
+ "(" + STRING_SIG + STRING_SIG + ")V");
il.append(new INVOKEINTERFACE(processingInstruction, 3));
// Restore old handler base from stack
il.append(methodGen.storeHandler());
diff --git a/src/org/apache/xalan/xsltc/compiler/Step.java b/src/org/apache/xalan/xsltc/compiler/Step.java
index 4d54224..9146616 100644
--- a/src/org/apache/xalan/xsltc/compiler/Step.java
+++ b/src/org/apache/xalan/xsltc/compiler/Step.java
@@ -508,22 +508,6 @@
il.append(new CHECKCAST(cpg.addClass(className)));
}
il.append(new INVOKESPECIAL(idx));
-
- // Determine if the node set should be generated using the
- // natural order of the node set or document order.
- // See CurrentNodeListIterator's constructor(s) for details.
- SyntaxTreeNode parent = getParent();
- while (!(parent instanceof Template)) {
- if (parent == null) break;
- if (parent instanceof ApplyTemplates) {
- idx = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR,
- "forceNaturalOrder",
- "()"+NODE_ITERATOR_SIG);
- il.append(new INVOKEVIRTUAL(idx));
- break;
- }
- parent = parent.getParent();
- }
}
}
}
diff --git a/src/org/apache/xalan/xsltc/compiler/StepPattern.java b/src/org/apache/xalan/xsltc/compiler/StepPattern.java
index 78243a3..c14b743 100644
--- a/src/org/apache/xalan/xsltc/compiler/StepPattern.java
+++ b/src/org/apache/xalan/xsltc/compiler/StepPattern.java
@@ -162,10 +162,12 @@
private int analyzeCases() {
boolean noContext = true;
final int n = _predicates.size();
+
for (int i = 0; i < n && noContext; i++) {
final Predicate pred = (Predicate)_predicates.elementAt(i);
- final Expression exp = pred.getExpr();
- if (exp.hasPositionCall()) noContext = false;
+ if (pred.getExpr().hasPositionCall()) {
+ noContext = false;
+ }
}
if (noContext) {
diff --git a/src/org/apache/xalan/xsltc/compiler/Stylesheet.java b/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
index 15b0522..fa2d816 100644
--- a/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
+++ b/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
@@ -284,7 +284,6 @@
super.addPrefixMapping(prefix, uri);
}
-
/**
* Store extension URIs
*/
@@ -308,8 +307,10 @@
public void excludeExtensionPrefixes(Parser parser) {
final SymbolTable stable = parser.getSymbolTable();
final String excludePrefixes = getAttribute("exclude-result-prefixes");
- final String extensionPrefixes =
- getAttribute("extension-element-prefixes");
+ final String extensionPrefixes = getAttribute("extension-element-prefixes");
+
+ // Exclude XSLT uri
+ stable.excludeURI(Constants.XSLT_URI);
stable.excludeNamespaces(excludePrefixes);
stable.excludeNamespaces(extensionPrefixes);
extensionURI(extensionPrefixes, stable);
@@ -878,6 +879,18 @@
"("+OUTPUT_HANDLER_SIG+")V");
il.append(new INVOKEVIRTUAL(index));
+ // Compile buildKeys -- TODO: omit if not needed
+ final String keySig = compileBuildKeys(classGen);
+ final int keyIdx = cpg.addMethodref(getClassName(),
+ "buildKeys", keySig);
+ il.append(classGen.loadTranslet()); // The 'this' pointer
+ il.append(classGen.loadTranslet());
+ il.append(new GETFIELD(domField)); // The DOM reference
+ il.append(transf.loadIterator()); // Not really used, but...
+ il.append(transf.loadHandler()); // The output handler
+ il.append(new PUSH(cpg, DOM.ROOTNODE)); // Start with the root node
+ il.append(new INVOKEVIRTUAL(keyIdx));
+
// Look for top-level elements that need handling
final Enumeration toplevel = elements();
if ((_globals.size() > 0) || (toplevel.hasMoreElements())) {
@@ -896,17 +909,6 @@
il.append(new INVOKEVIRTUAL(topLevelIdx));
}
- final String keySig = compileBuildKeys(classGen);
- final int keyIdx = cpg.addMethodref(getClassName(),
- "buildKeys", keySig);
- il.append(classGen.loadTranslet()); // The 'this' pointer
- il.append(classGen.loadTranslet());
- il.append(new GETFIELD(domField)); // The DOM reference
- il.append(transf.loadIterator()); // Not really used, but...
- il.append(transf.loadHandler()); // The output handler
- il.append(new PUSH(cpg, DOM.ROOTNODE)); // Start with the root node
- il.append(new INVOKEVIRTUAL(keyIdx));
-
// start document
il.append(transf.loadHandler());
il.append(transf.startDocument());
diff --git a/src/org/apache/xalan/xsltc/compiler/SymbolTable.java b/src/org/apache/xalan/xsltc/compiler/SymbolTable.java
index cf5c576..4b190d1 100644
--- a/src/org/apache/xalan/xsltc/compiler/SymbolTable.java
+++ b/src/org/apache/xalan/xsltc/compiler/SymbolTable.java
@@ -262,11 +262,10 @@
* Check if a namespace should not be declared in the output (unless used)
*/
public boolean isExcludedNamespace(String uri) {
- if (uri == null) return false;
- if (_excludedURI == null) return false;
- final Integer refcnt = (Integer)_excludedURI.get(uri);
- if (refcnt == null) return false;
- if (refcnt.intValue() > 0) return true;
+ if (uri != null && _excludedURI != null) {
+ final Integer refcnt = (Integer)_excludedURI.get(uri);
+ return (refcnt != null && refcnt.intValue() > 0);
+ }
return false;
}
diff --git a/src/org/apache/xalan/xsltc/compiler/SyntaxTreeNode.java b/src/org/apache/xalan/xsltc/compiler/SyntaxTreeNode.java
index 26f6c13..cd6f4d1 100644
--- a/src/org/apache/xalan/xsltc/compiler/SyntaxTreeNode.java
+++ b/src/org/apache/xalan/xsltc/compiler/SyntaxTreeNode.java
@@ -193,18 +193,16 @@
* @return The value of the attribute of name 'qname'.
*/
protected String getAttribute(String qname) {
- if (_attributes == null)
- return(Constants.EMPTYSTRING);
+ if (_attributes == null) {
+ return EMPTYSTRING;
+ }
final String value = _attributes.getValue(qname);
- if (value == null)
- return(Constants.EMPTYSTRING);
- else
- return(value);
+ return (value == null || value.equals(EMPTYSTRING)) ?
+ EMPTYSTRING : value;
}
protected boolean hasAttribute(String qname) {
- if (_attributes == null) return false;
- return (_attributes.getValue(qname) != null);
+ return (_attributes != null && _attributes.getValue(qname) != null);
}
/**
diff --git a/src/org/apache/xalan/xsltc/compiler/XslAttribute.java b/src/org/apache/xalan/xsltc/compiler/XslAttribute.java
index f6e8b6e..445eab0 100644
--- a/src/org/apache/xalan/xsltc/compiler/XslAttribute.java
+++ b/src/org/apache/xalan/xsltc/compiler/XslAttribute.java
@@ -73,10 +73,9 @@
final class XslAttribute extends Instruction {
- // Attribute contents
- private AttributeValue _name; // name treated as AVT (7.1.3)
- private AttributeValueTemplate _namespace = null;
private String _prefix;
+ private AttributeValue _name; // name treated as AVT (7.1.3)
+ private AttributeValueTemplate _namespace = null;
private boolean _ignore = false;
/**
@@ -99,15 +98,15 @@
* Parses the attribute's contents. Special care taken for namespaces.
*/
public void parseContents(Parser parser) {
-
- final SymbolTable stable = parser.getSymbolTable();
- String namespace = getAttribute("namespace");
- String name = getAttribute("name");
- QName qname = parser.getQName(name);
- final String prefix = qname.getPrefix();
boolean generated = false;
+ final SymbolTable stable = parser.getSymbolTable();
- if ((prefix != null) && (prefix.equals("xmlns"))) {
+ String name = getAttribute("name");
+ String namespace = getAttribute("namespace");
+ QName qname = parser.getQName(name, false);
+ final String prefix = qname.getPrefix();
+
+ if ((prefix != null) && (prefix.equals(XMLNS_PREFIX))) {
reportError(this, parser, ErrorMsg.ILLEGAL_ATTR_NAME_ERR, name);
return;
}
@@ -118,11 +117,13 @@
for (int i = 0; i < parent.elementCount(); i++) {
SyntaxTreeNode item = (SyntaxTreeNode)siblings.elementAt(i);
if (item == this) break;
+
// These three objects result in one or more attribute output
if (item instanceof XslAttribute) continue;
if (item instanceof UseAttributeSets) continue;
if (item instanceof LiteralAttribute) continue;
if (item instanceof Text) continue;
+
// These objects _can_ result in one or more attribute
// The output handler will generate an error if not (at runtime)
if (item instanceof If) continue;
@@ -134,24 +135,23 @@
}
// Get namespace from namespace attribute?
- if ((namespace != null) && (namespace != Constants.EMPTYSTRING)) {
- // Prefix could be in symbol table
+ if (namespace != null && namespace != Constants.EMPTYSTRING) {
_prefix = lookupPrefix(namespace);
_namespace = new AttributeValueTemplate(namespace, parser);
}
// Get namespace from prefix in name attribute?
- else if ((prefix != null) && (prefix != Constants.EMPTYSTRING)) {
+ else if (prefix != null && prefix != Constants.EMPTYSTRING) {
_prefix = prefix;
namespace = lookupNamespace(prefix);
- if (namespace != null)
+ if (namespace != null) {
_namespace = new AttributeValueTemplate(namespace, parser);
+ }
}
// Common handling for namespaces:
if (_namespace != null) {
-
// Generate prefix if we have none
- if (_prefix == null) {
+ if (_prefix == null || _prefix == Constants.EMPTYSTRING) {
if (prefix != null) {
_prefix = prefix;
}
@@ -160,25 +160,25 @@
generated = true;
}
}
-
- if (_prefix == Constants.EMPTYSTRING) {
- name = qname.getLocalPart();
+ else if (prefix != null && !prefix.equals(_prefix)) {
+ _prefix = prefix;
}
- else {
- name = _prefix+":"+qname.getLocalPart();
- // PROBLEM:
- // The namespace URI must be passed to the parent element,
- // but we don't yet know what the actual URI is (as we only
- // know it as an attribute value template). New design needed.
- if ((parent instanceof LiteralElement) && (!generated)) {
- ((LiteralElement)parent).registerNamespace(_prefix,
- namespace,
- stable,false);
- }
+
+ name = _prefix + ":" + qname.getLocalPart();
+
+ /*
+ * TODO: The namespace URI must be passed to the parent
+ * element but we don't yet know what the actual URI is
+ * (as we only know it as an attribute value template).
+ */
+ if ((parent instanceof LiteralElement) && (!generated)) {
+ ((LiteralElement)parent).registerNamespace(_prefix,
+ namespace,
+ stable, false);
}
}
- if (name.equals("xmlns")) {
+ if (name.equals(XMLNS_PREFIX)) {
reportError(this, parser, ErrorMsg.ILLEGAL_ATTR_NAME_ERR, name);
return;
}
@@ -191,15 +191,14 @@
parseChildren(parser);
}
- /**
- *
- */
public Type typeCheck(SymbolTable stable) throws TypeCheckError {
- if (_ignore) return(Type.Void);
- _name.typeCheck(stable);
- if (_namespace != null)
- _namespace.typeCheck(stable);
- typeCheckContents(stable);
+ if (!_ignore) {
+ _name.typeCheck(stable);
+ if (_namespace != null) {
+ _namespace.typeCheck(stable);
+ }
+ typeCheckContents(stable);
+ }
return Type.Void;
}
diff --git a/src/org/apache/xalan/xsltc/compiler/XslElement.java b/src/org/apache/xalan/xsltc/compiler/XslElement.java
index 84d7d38..8f79435 100644
--- a/src/org/apache/xalan/xsltc/compiler/XslElement.java
+++ b/src/org/apache/xalan/xsltc/compiler/XslElement.java
@@ -88,6 +88,10 @@
displayContents(indent + IndentIncrement);
}
+ public boolean declaresDefaultNS() {
+ return (_namespace != null && _prefix == EMPTYSTRING);
+ }
+
/**
* Parses the element's contents. Special care taken for namespaces.
* TODO: The namespace attribute that specifies the namespace to use
diff --git a/src/org/apache/xalan/xsltc/compiler/util/Util.java b/src/org/apache/xalan/xsltc/compiler/util/Util.java
index 2082fe1..0fc872b 100644
--- a/src/org/apache/xalan/xsltc/compiler/util/Util.java
+++ b/src/org/apache/xalan/xsltc/compiler/util/Util.java
@@ -108,17 +108,20 @@
* Replace all illegal Java chars by '_'.
*/
public static String toJavaName(String name) {
- final StringBuffer result = new StringBuffer();
+ if (name.length() > 0) {
+ final StringBuffer result = new StringBuffer();
- char ch = name.charAt(0);
- result.append(Character.isJavaIdentifierStart(ch) ? ch : '_');
+ char ch = name.charAt(0);
+ result.append(Character.isJavaIdentifierStart(ch) ? ch : '_');
- final int n = name.length();
- for (int i = 1; i < n; i++) {
- ch = name.charAt(i);
- result.append(Character.isJavaIdentifierPart(ch) ? ch : '_');
+ final int n = name.length();
+ for (int i = 1; i < n; i++) {
+ ch = name.charAt(i);
+ result.append(Character.isJavaIdentifierPart(ch) ? ch : '_');
+ }
+ return result.toString();
}
- return result.toString();
+ return name;
}
public static Type getJCRefType(String signature) {
@@ -130,15 +133,11 @@
}
public static void println(String s) {
- if (false) {
- System.out.println(s);
- }
+ System.out.println(s);
}
public static void println(char ch) {
- if (false) {
- System.out.println(ch);
- }
+ System.out.println(ch);
}
public static void TRACE1() {
diff --git a/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java b/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java
index dfb9f3d..79df194 100644
--- a/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java
+++ b/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java
@@ -99,11 +99,6 @@
_currentNode = currentNode;
}
- public NodeIterator forceNaturalOrder() {
- _docOrder = true;
- return this;
- }
-
public void setRestartable(boolean isRestartable) {
_isRestartable = isRestartable;
_source.setRestartable(isRestartable);
@@ -139,9 +134,8 @@
final int currentNode = _currentNode;
for (int index = _current; index < last; ) {
- final int node = _nodes.at(index++); // note increment
- final int position = docOrder ? index : last - index + 1;
- if (_filter.test(node, position, last, currentNode, _translet, this)) {
+ final int node = _nodes.at(index++); // note increment
+ if (_filter.test(node, index, last, currentNode, _translet, this)) {
_current = index;
return returnNode(node);
}
@@ -156,9 +150,8 @@
final int currNode = _currentNode;
for (int index = _current; index < last; ) {
- int nodeIndex = _nodes.at(index++); // note increment
- final int pos = docOrder ? index : last - index + 1;
- if (_filter.test(nodeIndex, pos, last, currNode, _translet, this)) {
+ int nodeIndex = _nodes.at(index++); // note increment
+ if (_filter.test(nodeIndex, index, last, currNode, _translet, this)) {
lastPosition++;
}
}
@@ -185,7 +178,7 @@
}
public int getLast() {
- return ( _last == -1 ) ? computePositionOfLast() : _last;
+ return (_last == -1) ? computePositionOfLast() : _last;
}
public void setMark() {
diff --git a/src/org/apache/xalan/xsltc/dom/DOMBuilder.java b/src/org/apache/xalan/xsltc/dom/DOMBuilder.java
index cc67a53..dabd49e 100644
--- a/src/org/apache/xalan/xsltc/dom/DOMBuilder.java
+++ b/src/org/apache/xalan/xsltc/dom/DOMBuilder.java
@@ -64,4 +64,4 @@
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
-public interface DOMBuilder extends ContentHandler, LexicalHandler { }
+public interface DOMBuilder extends ExtendedSAX { }
diff --git a/src/org/apache/xalan/xsltc/dom/DOMImpl.java b/src/org/apache/xalan/xsltc/dom/DOMImpl.java
index df1a7ea..a4ceb85 100644
--- a/src/org/apache/xalan/xsltc/dom/DOMImpl.java
+++ b/src/org/apache/xalan/xsltc/dom/DOMImpl.java
@@ -81,6 +81,7 @@
import org.xml.sax.*;
import org.xml.sax.ext.*;
+import org.xml.sax.helpers.AttributesImpl;
import org.apache.xalan.xsltc.*;
import org.apache.xalan.xsltc.util.IntegerArray;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
@@ -136,6 +137,9 @@
// Tracks which textnodes are whitespaces and which are not
private BitArray _whitespace; // takes xml:space into acc.
+ // Tracks which textnodes are not escaped
+ private BitArray _dontEscape = null;
+
// The URI to this document
private String _documentURI;
@@ -1053,6 +1057,7 @@
while ((_ns == DOM.NULL) && (_node != DOM.NULL)) {
_node = _parent[_node];
_ns = _lengthOrAttr[_node];
+
while ((_ns != DOM.NULL) && (_type[_ns] != NAMESPACE)) {
_ns = _nextSibling[_ns];
}
@@ -1980,6 +1985,7 @@
case ROOT:
return getNodeValue(_offsetOrChild[node]);
case TEXT:
+ // GTM - add escapign code here too.
case COMMENT:
return makeStringValue(node);
case PROCESSING_INSTRUCTION:
@@ -2162,6 +2168,13 @@
out.writeObject(_whitespace);
+ if (_dontEscape != null) {
+ out.writeObject(_dontEscape);
+ }
+ else {
+ out.writeObject(new BitArray(0));
+ }
+
out.flush();
}
@@ -2190,6 +2203,11 @@
_whitespace = (BitArray)in.readObject();
+ _dontEscape = (BitArray)in.readObject();
+ if (_dontEscape.size() == 0) {
+ _dontEscape = null;
+ }
+
_types = setupMapping(_namesArray);
}
@@ -2614,9 +2632,23 @@
_lengthOrAttr[node]));
break;
case TEXT:
+ boolean last = false;
+ boolean escapeBit = false;
+
+ if (_dontEscape != null) {
+ escapeBit = _dontEscape.getBit(node);
+ if (escapeBit) {
+ last = handler.setEscaping(false);
+ }
+ }
+
handler.characters(_text,
_offsetOrChild[node],
_lengthOrAttr[node]);
+
+ if (_dontEscape != null && escapeBit) {
+ handler.setEscaping(last);
+ }
break;
case ATTRIBUTE:
shallowCopy(node, handler);
@@ -2628,6 +2660,7 @@
if (isElement(node)) {
// Start element definition
final String name = copyElement(node, type, handler);
+
// Copy element attribute
for (int a=_lengthOrAttr[node]; a!=NULL; a=_nextSibling[a]) {
if (_type[a] != NAMESPACE) {
@@ -2694,9 +2727,11 @@
case ROOT: // do nothing
return EMPTYSTRING;
case TEXT:
+
handler.characters(_text,
_offsetOrChild[node],
_lengthOrAttr[node]);
+
return null;
case PROCESSING_INSTRUCTION:
copyPI(node, handler);
@@ -2899,8 +2934,7 @@
* DOM builder's interface is pure SAX2 (must investigate)
*/
public TransletOutputHandler getOutputDomBuilder() {
- DOMBuilder builder = getBuilder();
- return new SAXAdapter(builder, builder);
+ return new SAXAdapter(new DOMBuilderImpl());
}
/**
@@ -2959,6 +2993,11 @@
private static final String XML_STRING = "xml:";
private static final String XMLSPACE_STRING = "xml:space";
private static final String PRESERVE_STRING = "preserve";
+ private static final String XML_PREFIX = "xml";
+ private static final String XMLNS_PREFIX = "xmlns";
+
+ private boolean _escaping = true;
+ private boolean _disableEscaping = false;
/**
* Default constructor for the DOMBuiler class
@@ -3076,7 +3115,6 @@
*/
private short makeElementNode(String uri, String localname)
throws SAXException {
-
final String name;
if (uri != EMPTYSTRING)
name = uri + ':' + localname;
@@ -3170,6 +3208,7 @@
*/
private int makeTextNode(boolean isWhitespace) {
if (_currentOffset > _baseOffset) {
+
final int node = nextNode();
final int limit = _currentOffset;
// Tag as whitespace node if the parser tells us that it is...
@@ -3188,6 +3227,14 @@
_type[node] = TEXT;
linkChildren(node);
storeTextRef(node);
+
+ if (_disableEscaping) {
+ if (_dontEscape == null) {
+ _dontEscape = new BitArray(_whitespace.size());
+ }
+ _dontEscape.setBit(node);
+ _disableEscaping = false;
+ }
return node;
}
return -1;
@@ -3217,33 +3264,29 @@
* Creates an attribute node
*/
private int makeAttributeNode(int parent, Attributes attList, int i)
- throws SAXException {
-
+ throws SAXException
+ {
final int node = nextAttributeNode();
-
final String qname = attList.getQName(i);
- final String localname = attList.getLocalName(i);
+ String localname = attList.getLocalName(i);
final String value = attList.getValue(i);
StringBuffer namebuf = new StringBuffer(EMPTYSTRING);
- // Create the internal attribute node name (uri+@+localname)
- if (qname.startsWith(XML_STRING)) {
- if (qname.startsWith(XMLSPACE_STRING))
- xmlSpaceDefine(attList.getValue(i), parent);
+ if (qname.startsWith(XMLSPACE_STRING)) {
+ xmlSpaceDefine(attList.getValue(i), parent);
}
+
+ // Create the internal attribute node name (uri+@+localname)
final String uri = attList.getURI(i);
- if ((uri != null) && (!uri.equals(EMPTYSTRING))) {
+ if (uri != null && !uri.equals(EMPTYSTRING)) {
namebuf.append(uri);
namebuf.append(':');
}
namebuf.append('@');
- if (localname != null )
- namebuf.append(localname);
- else
- namebuf.append(qname);
+ namebuf.append(localname.length() > 0 ? localname : qname);
String name = namebuf.toString();
-
+
// Get the index of the attribute node name (create new if non-ex).
Integer obj = (Integer)_names.get(name);
if (obj == null) {
@@ -3280,6 +3323,9 @@
}
System.arraycopy(ch, start, _text, _currentOffset, length);
_currentOffset += length;
+
+ _disableEscaping = !_escaping;
+
}
/**
@@ -3295,7 +3341,7 @@
_type2[0] = NAMESPACE;
startPrefixMapping(EMPTYSTRING, EMPTYSTRING);
- startPrefixMapping("xml", "http://www.w3.org/XML/1998/namespace");
+ startPrefixMapping(XML_PREFIX, "http://www.w3.org/XML/1998/namespace");
_lengthOrAttr[ROOTNODE] = _nextNamespace;
_parent2[_nextNamespace] = ROOTNODE;
_nextNamespace = DOM.NULL;
@@ -3374,41 +3420,56 @@
_lengthOrAttr[node] = DOM.NULL;
+ int last = -1;
final int count = attributes.getLength();
// Append any namespace nodes
if (_nextNamespace != DOM.NULL) {
_lengthOrAttr[node] = _nextNamespace;
+
while (_nextNamespace != DOM.NULL) {
_parent2[_nextNamespace] = node;
- int tail = _nextNamespace;
- _nextNamespace = _nextSibling2[_nextNamespace];
+ _nextNamespace = _nextSibling2[last = _nextNamespace];
// Chain last namespace node to following attribute node(s)
- if ((_nextNamespace == DOM.NULL) && (count > 0))
- _nextSibling2[tail] = _currentAttributeNode;
+ if (_nextNamespace == DOM.NULL && count > 0) {
+ _nextSibling2[last] = _currentAttributeNode;
+ }
}
}
// Append any attribute nodes
+ boolean attrsAdded = false;
if (count > 0) {
int attr = _currentAttributeNode;
- if (_lengthOrAttr[node] == DOM.NULL)
+ if (_lengthOrAttr[node] == DOM.NULL) {
_lengthOrAttr[node] = attr;
- for (int i = 0; i<count; i++) {
- attr = makeAttributeNode(node, attributes, i);
- _parent2[attr] = node;
- _nextSibling2[attr] = attr + 1;
}
- _nextSibling2[attr] = DOM.NULL;
+ for (int i = 0; i < count; i++) {
+ if (!attributes.getQName(i).startsWith(XMLNS_PREFIX)) {
+ attr = makeAttributeNode(node, attributes, i);
+ _parent2[attr] = node;
+ _nextSibling2[attr] = attr + 1;
+ attrsAdded = true;
+ }
+ }
+ // Did we append namespace nodes only?
+ if (!attrsAdded && last != -1) {
+ _nextSibling2[last] = DOM.NULL;
+ }
+ else {
+ _nextSibling2[attr] = DOM.NULL;
+ }
}
final int col = qname.lastIndexOf(':');
// Assign an internal type to this element (may exist)
- if ((uri != null) && (localName.length() > 0))
+ if (uri != null && localName.length() > 0) {
_type[node] = makeElementNode(uri, localName);
- else
+ }
+ else {
_type[node] = makeElementNode(qname, col);
+ }
// Assign an internal type to the element's prefix (may exist)
if (col > -1) {
@@ -3502,7 +3563,8 @@
else
_nextSibling2[attr-1] = attr;
_nextSibling2[attr] = DOM.NULL;
- _prefix2[attr] = idx.shortValue();
+ // _prefix2[attr] = idx.shortValue();
+ _prefix2[attr] = ((Integer) stack.elementAt(0)).shortValue();
}
}
@@ -3587,6 +3649,11 @@
// Resize the '_whitespace' array (a BitArray instance)
_whitespace.resize(newSize);
+ // Resize the '_dontEscape' array (a BitArray instance)
+ if (_dontEscape != null) {
+ _dontEscape.resize(newSize);
+ }
+
// Resize the '_prefix' array
final short[] newPrefix = new short[newSize];
System.arraycopy(_prefix, 0, newPrefix, 0, length);
@@ -3656,5 +3723,11 @@
}
}
+ public boolean setEscaping(boolean value) {
+ final boolean temp = _escaping;
+ _escaping = value;
+ return temp;
+ }
+
} // end of DOMBuilder
}
diff --git a/src/org/apache/xalan/xsltc/dom/ExtendedSAX.java b/src/org/apache/xalan/xsltc/dom/ExtendedSAX.java
new file mode 100644
index 0000000..8e87428
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/dom/ExtendedSAX.java
@@ -0,0 +1,69 @@
+/*
+ * @(#)$Id$
+ *
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001 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 apache@apache.org.
+ *
+ * 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) 2001, Sun
+ * Microsystems., http://www.sun.com. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * @author Morten Jorgensen
+ *
+ */
+package org.apache.xalan.xsltc.dom;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ext.LexicalHandler;
+
+public interface ExtendedSAX extends ContentHandler, LexicalHandler {
+ public boolean setEscaping(boolean escape);
+}
diff --git a/src/org/apache/xalan/xsltc/dom/SortingIterator.java b/src/org/apache/xalan/xsltc/dom/SortingIterator.java
index 9d16c2b..e2ffd9e 100644
--- a/src/org/apache/xalan/xsltc/dom/SortingIterator.java
+++ b/src/org/apache/xalan/xsltc/dom/SortingIterator.java
@@ -66,11 +66,12 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.TransletException;
+import org.apache.xalan.xsltc.runtime.BasisLibrary;
public final class SortingIterator extends NodeIteratorBase {
private final static int INIT_DATA_SIZE = 16;
- private final NodeIterator _source;
- private final NodeSortRecordFactory _factory;
+ private NodeIterator _source;
+ private NodeSortRecordFactory _factory;
private NodeSortRecord[] _data;
private int _free = 0;
private int _current; // index in _nodes of the next node to try
@@ -124,6 +125,29 @@
_current = _markedNode;
}
+ /**
+ * Clone a <code>SortingIterator</code> by cloning its source
+ * iterator and then sharing the factory and the array of
+ * <code>NodeSortRecords</code>.
+ */
+ public NodeIterator cloneIterator() {
+ try {
+ final SortingIterator clone = (SortingIterator) super.clone();
+ clone._source = _source.cloneIterator();
+ clone._factory = _factory; // shared between clones
+ clone._data = _data; // shared between clones
+ clone._free = _free;
+ clone._current = _current;
+ clone.setRestartable(false);
+ return clone.reset();
+ }
+ catch (CloneNotSupportedException e) {
+ BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
+ e.toString());
+ return null;
+ }
+ }
+
private void addRecord(NodeSortRecord record) {
if (_free == _data.length) {
NodeSortRecord[] newArray = new NodeSortRecord[_data.length * 2];
diff --git a/src/org/apache/xalan/xsltc/dom/UnionIterator.java b/src/org/apache/xalan/xsltc/dom/UnionIterator.java
index bfd1452..be22cd1 100644
--- a/src/org/apache/xalan/xsltc/dom/UnionIterator.java
+++ b/src/org/apache/xalan/xsltc/dom/UnionIterator.java
@@ -152,8 +152,10 @@
final int smallest = _heap[0].node;
if (smallest == END) { // iterator _heap[0] is done
if (_heapSize > 1) {
- // replace it with last
+ // Swap first and last (iterator must be restartable)
+ final LookAheadIterator temp = _heap[0];
_heap[0] = _heap[--_heapSize];
+ _heap[_heapSize] = temp;
}
else {
return END;
diff --git a/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java b/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java
index e363410..9b4c431 100644
--- a/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java
+++ b/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java
@@ -143,44 +143,15 @@
*/
public final void popParamFrame() {
if (pbase > 0) {
- int bot = pbase - 1;
- int top = pframe - 1;
- pframe = pbase - 1;
- pbase = ((Integer) paramsStack.elementAt(pframe)).intValue();
- // bug fix #3424, John Howard.
- // remove objects that are in the stack since objects are
- // added with insertElementAt(int) and will cause memory retention
- for (int i=top; i>=bot; i--) {
- paramsStack.removeElementAt(i);
+ final int oldpbase = ((Integer)paramsStack.elementAt(--pbase)).intValue();
+ for (int i = pbase; i < pframe; i++) {
+ paramsStack.setElementAt(null, i); // for the GC
}
+ pframe = pbase; pbase = oldpbase;
}
}
/**
- * Replace a certain character in a string with a new substring.
- */
- private static String replace(String base, char c, String str) {
- final int len = base.length() - 1;
- int pos;
- while ((pos = base.indexOf(c)) > -1) {
- if (pos == 0) {
- final String after = base.substring(1);
- base = str + after;
- }
- else if (pos == len) {
- final String before = base.substring(0, pos);
- base = before + str;
- }
- else {
- final String before = base.substring(0, pos);
- final String after = base.substring(pos+1);
- base = before + str + after;
- }
- }
- return base;
- }
-
- /**
* Add a new global parameter if not already in the current frame.
*/
public final Object addParameter(String name, Object value) {
@@ -224,6 +195,7 @@
* Clears the parameter stack.
*/
public void clearParameters() {
+ pbase = pframe = 0;
paramsStack.clear();
}
@@ -246,6 +218,7 @@
varsStack.insertElementAt(new Integer(vbase), vframe);
vbase = ++vframe;
vframe += frameSize;
+ varsStack.setSize(vframe + 1); // clear stack frame
}
/**
@@ -253,16 +226,11 @@
*/
public final void popVarFrame() {
if (vbase > 0) {
- int bot = vbase - 1;
- int top = vframe - 1;
- vframe = vbase - 1;
- vbase = ((Integer)varsStack.elementAt(vframe)).intValue();
- // bug fix 3424, John Howard
- // remove objects that are in the stack since objects are
- // added with insertElementAt(int) and will cause memory retention
- for (int i=top; i>=bot; i--) {
- varsStack.removeElementAt(i);
+ final int oldvbase = ((Integer)varsStack.elementAt(--vbase)).intValue();
+ for (int i = vbase; i < vframe; i++) {
+ varsStack.setElementAt(null, i); // for the GC
}
+ vframe = vbase; vbase = oldvbase;
}
}
@@ -270,18 +238,38 @@
* Get the value of a variable given its index.
*/
public final Object getVariable(int vindex) {
- // bug fix 3424, John Howard
return varsStack.elementAt(vbase + vindex);
}
-
/**
* Set the value of a variable in the current frame.
*/
public final void addVariable(int vindex, Object value) {
- final int index = vbase + vindex;
- if (index > varsStack.size()) varsStack.setSize(index);
- varsStack.insertElementAt(value, index);
+ varsStack.setElementAt(value, vbase + vindex);
+ }
+
+ /**
+ * Replace a certain character in a string with a new substring.
+ */
+ private static String replace(String base, char c, String str) {
+ final int len = base.length() - 1;
+ int pos;
+ while ((pos = base.indexOf(c)) > -1) {
+ if (pos == 0) {
+ final String after = base.substring(1);
+ base = str + after;
+ }
+ else if (pos == len) {
+ final String before = base.substring(0, pos);
+ base = before + str;
+ }
+ else {
+ final String before = base.substring(0, pos);
+ final String after = base.substring(pos+1);
+ base = before + str + after;
+ }
+ }
+ return base;
}
/************************************************************************
@@ -582,10 +570,10 @@
// Transfer all settings relevant to XML output
if (_method.equals("xml")) {
if (_standalone != null) handler.setStandalone(_standalone);
+ if (_omitHeader) handler.omitHeader(true);
handler.setType(TextOutput.XML);
handler.setCdataElements(_cdata);
if (_version != null) handler.setVersion(_version);
- if (_omitHeader) handler.omitHeader(true);
handler.setIndent(_indent);
if (_doctypeSystem != null)
handler.setDoctype(_doctypeSystem, _doctypePublic);
diff --git a/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java b/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
index 18f223b..b800d89 100644
--- a/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
+++ b/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
@@ -427,7 +427,7 @@
if (name.equals("xsl:version"))
return("1.0");
if (name.equals("xsl:vendor"))
- return("Apache Xalan XSLTC");
+ return("Apache Software Foundation");
if (name.equals("xsl:vendor-url"))
return("http://xml.apache.org/xalan-j");
diff --git a/src/org/apache/xalan/xsltc/runtime/Constants.java b/src/org/apache/xalan/xsltc/runtime/Constants.java
index 4f72e23..da2bdb3 100644
--- a/src/org/apache/xalan/xsltc/runtime/Constants.java
+++ b/src/org/apache/xalan/xsltc/runtime/Constants.java
@@ -83,4 +83,9 @@
public static final String NAMESPACE_FEATURE =
"http://xml.org/sax/features/namespaces";
+ public static final String EMPTYSTRING = "";
+ public static final String XML_PREFIX = "xml";
+ public static final String XMLNS_PREFIX = "xmlns";
+ public static final String XMLNS_STRING = "xmlns:";
+ public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
}
diff --git a/src/org/apache/xalan/xsltc/runtime/DefaultSAXOutputHandler.java b/src/org/apache/xalan/xsltc/runtime/DefaultSAXOutputHandler.java
index 37e3c3e..b3d356f 100644
--- a/src/org/apache/xalan/xsltc/runtime/DefaultSAXOutputHandler.java
+++ b/src/org/apache/xalan/xsltc/runtime/DefaultSAXOutputHandler.java
@@ -63,6 +63,8 @@
package org.apache.xalan.xsltc.runtime;
+import java.util.Vector;
+
import java.io.IOException;
import java.io.Writer;
import java.io.FileOutputStream;
@@ -122,7 +124,7 @@
private int _indentLevel = 0;
// This is used for aggregating namespace declarations
- private AttributeList _namespaceDeclarations = new AttributeList();
+ private Vector _namespaceDecls = null;
/**
* Constructor - set Writer to send output to and output encoding
@@ -239,7 +241,8 @@
/**
* SAX2: Receive notification of the beginning of a document.
*/
- public void startDocument() throws SAXException { }
+ public void startDocument() throws SAXException {
+ }
/**
* SAX2: Receive notification of the end of an element.
@@ -266,7 +269,7 @@
if (_startTagOpen) closeStartTag(true); // Close any open element.
_element = elementName; // Save element name
- // Handle indentation (not a requirement)
+ // Handle inden3dcb50483dcb504tation (not a requirement)
if (_indent) {
if (!_emptyElements.containsKey(elementName.toLowerCase())) {
indent(_lineFeedNextStartTag);
@@ -283,24 +286,26 @@
_indentNextEndTag = false;
// Output namespace declarations first...
- int declCount = _namespaceDeclarations.getLength();
- for (int i=0; i<declCount; i++) {
- final String prefix = _namespaceDeclarations.getQName(i);
- _writer.write(XMLNS);
- if ((prefix != null) && (prefix != EMPTYSTRING)) {
- _writer.write(':');
- _writer.write(prefix);
+ if (_namespaceDecls != null) {
+ int nDecls = _namespaceDecls.size();
+ for (int i = 0; i < nDecls; i++) {
+ final String prefix = (String) _namespaceDecls.elementAt(i++);
+ _writer.write(XMLNS);
+ if ((prefix != null) && (prefix != EMPTYSTRING)) {
+ _writer.write(':');
+ _writer.write(prefix);
+ }
+ _writer.write('=');
+ _writer.write('\"');
+ _writer.write((String) _namespaceDecls.elementAt(i));
+ _writer.write('\"');
}
- _writer.write('=');
- _writer.write('\"');
- _writer.write(_namespaceDeclarations.getValue(i));
- _writer.write('\"');
- }
- _namespaceDeclarations.clear();
+ _namespaceDecls.clear();
+ }
// ...then output all attributes
int attrCount = attrs.getLength();
- for (int i=0; i<attrCount; i++) {
+ for (int i = 0; i < attrCount; i++) {
_writer.write(' ');
_writer.write(attrs.getQName(i));
_writer.write('=');
@@ -440,7 +445,11 @@
* Namespace declarations are output in startElement()
*/
public void startPrefixMapping(String prefix, String uri) {
- _namespaceDeclarations.add(prefix,uri);
+ if (_namespaceDecls == null) {
+ _namespaceDecls = new Vector(2);
+ }
+ _namespaceDecls.addElement(prefix);
+ _namespaceDecls.addElement(uri);
}
/**
diff --git a/src/org/apache/xalan/xsltc/runtime/SAXAdapter.java b/src/org/apache/xalan/xsltc/runtime/SAXAdapter.java
index ae0e891..8642def 100644
--- a/src/org/apache/xalan/xsltc/runtime/SAXAdapter.java
+++ b/src/org/apache/xalan/xsltc/runtime/SAXAdapter.java
@@ -65,37 +65,32 @@
package org.apache.xalan.xsltc.runtime;
import org.xml.sax.*;
-import org.xml.sax.ext.LexicalHandler;
-import org.apache.xalan.xsltc.*;
+import org.xml.sax.ext.*;
+import org.apache.xalan.xsltc.TransletException;
+import org.apache.xalan.xsltc.TransletOutputHandler;
+import org.apache.xalan.xsltc.dom.DOMBuilder;
public final class SAXAdapter implements TransletOutputHandler {
- private final ContentHandler _saxHandler;
- private final LexicalHandler _lexHandler;
+ private final DOMBuilder _domBuilder;
private final AttributeList _attributes = new AttributeList();
private String _openElementName;
- public SAXAdapter(ContentHandler saxHandler) {
- _saxHandler = saxHandler;
- _lexHandler = null;
- }
-
- public SAXAdapter(ContentHandler saxHandler, LexicalHandler lexHandler) {
- _saxHandler = saxHandler;
- _lexHandler = lexHandler;
+ public SAXAdapter(DOMBuilder domBuilder) {
+ _domBuilder = domBuilder;
}
private void maybeEmitStartElement() throws SAXException {
if (_openElementName != null) {
- _saxHandler.startElement(null, null, _openElementName, _attributes);
+ _domBuilder.startElement(null, null, _openElementName, _attributes);
_openElementName = null;
}
}
public void startDocument() throws TransletException {
try {
- _saxHandler.startDocument();
+ _domBuilder.startDocument();
}
catch (SAXException e) {
throw new TransletException(e);
@@ -104,7 +99,7 @@
public void endDocument() throws TransletException {
try {
- _saxHandler.endDocument();
+ _domBuilder.endDocument();
}
catch (SAXException e) {
throw new TransletException(e);
@@ -115,7 +110,7 @@
throws TransletException {
try {
maybeEmitStartElement();
- _saxHandler.characters(characters, offset, length);
+ _domBuilder.characters(characters, offset, length);
}
catch (SAXException e) {
throw new TransletException(e);
@@ -136,7 +131,7 @@
public void endElement(String elementName) throws TransletException {
try {
maybeEmitStartElement();
- _saxHandler.endElement(null, null, elementName);
+ _domBuilder.endElement(null, null, elementName);
}
catch (SAXException e) {
throw new TransletException(e);
@@ -161,9 +156,9 @@
public void comment(String comment) throws TransletException {
try {
maybeEmitStartElement();
- if (_lexHandler != null) {
+ if (_domBuilder != null) {
char[] chars = comment.toCharArray();
- _lexHandler.comment(chars, 0, chars.length);
+ _domBuilder.comment(chars, 0, chars.length);
}
}
catch (SAXException e) {
@@ -175,13 +170,17 @@
throws TransletException {
try {
maybeEmitStartElement();
- _saxHandler.processingInstruction(target, data);
+ _domBuilder.processingInstruction(target, data);
}
catch (SAXException e) {
throw new TransletException(e);
}
}
+ public boolean setEscaping(boolean escape) throws TransletException {
+ return _domBuilder.setEscaping(escape);
+ }
+
// The SAX handler does not handle these:
public void setType(int type) {}
public void setHeader(String header) {}
@@ -189,8 +188,5 @@
public void omitHeader(boolean value) {}
public void setCdataElements(Hashtable elements) { }
public void close() {}
- public boolean setEscaping(boolean escape) throws TransletException {
- return(true);
- }
public String getPrefix(String uri) { return(""); }
}
diff --git a/src/org/apache/xalan/xsltc/runtime/StringValueHandler.java b/src/org/apache/xalan/xsltc/runtime/StringValueHandler.java
index 2e47eb4..cd0f76e 100644
--- a/src/org/apache/xalan/xsltc/runtime/StringValueHandler.java
+++ b/src/org/apache/xalan/xsltc/runtime/StringValueHandler.java
@@ -86,4 +86,29 @@
_free = 0; // getValue resets
return new String(_buffer, 0, length);
}
+
+ /**
+ * The value of a PI must not contain the substring "?>". Should
+ * that substring be present, replace it by "? >".
+ */
+ public String getValueOfPI() {
+ final String value = getValue();
+
+ if (value.indexOf("?>") > 0) {
+ final int n = value.length();
+ final StringBuffer valueOfPI = new StringBuffer();
+
+ for (int i = 0; i < n;) {
+ final char ch = value.charAt(i++);
+ if (ch == '?' && value.charAt(i) == '>') {
+ valueOfPI.append("? >"); i++;
+ }
+ else {
+ valueOfPI.append(ch);
+ }
+ }
+ return valueOfPI.toString();
+ }
+ return value;
+ }
}
diff --git a/src/org/apache/xalan/xsltc/runtime/TextOutput.java b/src/org/apache/xalan/xsltc/runtime/TextOutput.java
index fd29db7..4e7a27e 100644
--- a/src/org/apache/xalan/xsltc/runtime/TextOutput.java
+++ b/src/org/apache/xalan/xsltc/runtime/TextOutput.java
@@ -72,10 +72,11 @@
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.AttributesImpl;
import org.apache.xalan.xsltc.*;
-public final class TextOutput implements TransletOutputHandler {
+public final class TextOutput implements TransletOutputHandler, Constants {
// These are the various output types we handle
public static final int UNKNOWN = 0; // determine type from output contents
@@ -100,8 +101,6 @@
// Contains all elements that should be output as CDATA sections
private Hashtable _cdata = null;
- private static final String XML_PREFIX = "xml";
-
private static final char[] AMP = "&".toCharArray();
private static final char[] LT = "<".toCharArray();
private static final char[] GT = ">".toCharArray();
@@ -124,15 +123,15 @@
private static final int BEGCOMM_length = BEGCOMM.length;
private static final int ENDCOMM_length = ENDCOMM.length;
- private static final String EMPTYSTRING = "";
private static final String HREF_STR = "href";
- private static final String SRC_STR = "str";
+ private static final String CITE_STR = "cite";
+ private static final String SRC_STR = "src";
private static final String CHAR_ESC_START = "&#";
private static final String CDATA_ESC_START = "]]>&#";
private static final String CDATA_ESC_END = ";<![CDATA[";
- private AttributeList _attributes = new AttributeList();
- private String _elementName = null;
+ private AttributesImpl _attributes = new AttributesImpl();
+ private String _elementName = null;
// Each entry (prefix) in this hashtable points to a Stack of URIs
private Hashtable _namespaces;
@@ -252,8 +251,8 @@
AttributeList attrs = new AttributeList();
attrs.add("http-equiv", "Content-Type");
attrs.add("content", _mediaType+"; charset="+_encoding);
- _saxHandler.startElement(null, null, "meta", attrs);
- _saxHandler.endElement(null, null, "meta");
+ _saxHandler.startElement(EMPTYSTRING, EMPTYSTRING, "meta", attrs);
+ _saxHandler.endElement(EMPTYSTRING, EMPTYSTRING, "meta");
}
}
@@ -264,27 +263,10 @@
public void closeStartTag() throws TransletException {
try {
_startTagOpen = false;
-
- // Final check to assure that the element is within a namespace
- // that has been declared (all declarations for this element
- // should have been processed at this point).
- int col = _elementName.lastIndexOf(':');
- if (col > 0) {
- final String prefix = _elementName.substring(0,col);
- final String localname = _elementName.substring(col+1);
- final String uri = lookupNamespace(prefix);
- if (uri == null)
- BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR,
- prefix);
- if (uri.equals(EMPTYSTRING)) _elementName = localname;
- _saxHandler.startElement(uri, localname,
- _elementName, _attributes);
- }
- else {
- final String uri = lookupNamespace(EMPTYSTRING);
- _saxHandler.startElement(uri, _elementName,
- _elementName, _attributes);
- }
+
+ // Now is time to send the startElement event
+ _saxHandler.startElement(getNamespaceURI(_elementName, true),
+ getLocalName(_elementName), _elementName, _attributes);
// Insert <META> tag directly after <HEAD> element in HTML output
if (_headTagOpen) {
@@ -467,9 +449,7 @@
* Start an element in the output document. This might be an XML
* element (<elem>data</elem> type) or a CDATA section.
*/
- public void startElement(String elementName)
- throws TransletException {
-
+ public void startElement(String elementName) throws TransletException {
try {
switch(_outputType) {
@@ -670,6 +650,14 @@
return(buf.toString());
}
+ private String makeHHString(int i) {
+ String s = Integer.toHexString(i).toUpperCase();
+ if (s.length() == 1) {
+ s = "0"+s;
+ }
+ return s;
+ }
+
/**
* This method escapes special characters used in HTML attribute values
*/
@@ -681,9 +669,17 @@
char[] ch = base.toCharArray();
StringBuffer buf = new StringBuffer();
for(int i=0; i<base.length(); i++){
- if (ch[i] > '\u007F') {
- buf.append('%');
- buf.append(Integer.toHexString((int)ch[i]));
+ if (ch[i] <= 0x20) {
+ buf.append('%');
+ buf.append(makeHHString(ch[i]));
+ }
+ else if (ch[i] > '\u007F') {
+ int high = (ch[i] >> 6) | 0xC0;
+ int low = (ch[i] & 0x3F) | 0x80; // First 6 bits + high bit
+ buf.append('%');
+ buf.append(makeHHString(high));
+ buf.append('%');
+ buf.append(makeHHString(low));
}
else {
// These chars are reserved or unsafe in URLs
@@ -705,7 +701,8 @@
buf.append(Integer.toHexString((int)ch[i]));
break;
case '\u0026' :
- buf.append("&");
+ //bug fix for customer/murphy3: buf.append("&");
+ buf.append("&");
break;
default:
buf.append(ch[i]); break;
@@ -758,27 +755,51 @@
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)
+ /**
+ * Returns the URI of an element or attribute. Note that default namespaces
+ * do not apply directly to attributes.
+ */
+ private String getNamespaceURI(String qname, boolean isElement)
+ throws TransletException
+ {
+ String uri = EMPTYSTRING;
+ int col = qname.lastIndexOf(':');
+ final String prefix = (col > 0) ? qname.substring(0, col) : EMPTYSTRING;
+
+ if (prefix != EMPTYSTRING || isElement) {
+ uri = lookupNamespace(prefix);
+ if (uri == null && !prefix.equals(XMLNS_PREFIX)) {
BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR,
- prefix);
- // 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);
+ qname.substring(0, col));
+ }
+ }
+ return uri;
+ }
+
+ /**
+ * Returns the local name of a qualified name. If the name has no prefix
+ * then return null.
+ */
+ private static String getLocalName(String qname) throws TransletException {
+ final int col = qname.lastIndexOf(':');
+ return (col > 0) ? qname.substring(col + 1) : null;
+ }
+
+ /**
+ * TODO: This method is a HACK! Since XSLTC does not have access to the
+ * XML file, it sometimes generates a NS prefix of the form "ns?" for
+ * an attribute. If at runtime, when the qname of the attribute is
+ * known, another prefix is specified for the attribute, then we can get
+ * a qname of the form "ns?:otherprefix:name". This function patches the
+ * qname by simply ignoring "otherprefix".
+ */
+ private static String patchQName(String qname) throws TransletException {
+ final int lastColon = qname.lastIndexOf(':');
+ if (lastColon > 0) {
+ final int firstColon = qname.indexOf(':');
+ if (firstColon != lastColon) {
+ return qname.substring(0, firstColon) + qname.substring(lastColon);
+ }
}
return qname;
}
@@ -790,59 +811,110 @@
public void attribute(String name, final String value)
throws TransletException {
- switch(_outputType) {
- case TEXT:
- // Do not output attributes if output mode is 'text'
- return;
- case XML:
- if (!_startTagOpen)
- BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,name);
- // 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);
- return;
- }
- // Output as xml:<blah> attribute
- _attributes.add(name, value);
- }
- else {
- // Output as regular attribute
- _attributes.add(expandAttribute(name), escapeString(value));
- }
- return;
- case HTML:
- if (!_startTagOpen)
- BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,name);
- // 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.
+ if (_outputType == TEXT) return;
- // URL-encode href attributes in HTML output
- final String tmp = name.toLowerCase();
- if (tmp.equals(HREF_STR) || tmp.equals(SRC_STR)) {
- _attributes.add(name,quickAndDirtyUrlEncode(escapeAttr(value)));
+ final String patchedName = patchQName(name);
+ final String localName = getLocalName(patchedName);
+ final String uri = getNamespaceURI(patchedName, false);
+ final int index = (localName == null) ?
+ _attributes.getIndex(name) : /* don't use patchedName */
+ _attributes.getIndex(uri, localName);
+
+ switch(_outputType) {
+ case XML:
+ if (!_startTagOpen) {
+ BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR, patchedName);
+ }
+
+/*
+System.err.println("TextOutput.attribute() uri = " + uri
+ + " localname = " + localName
+ + " qname = " + name
+ + "\n value = " + value
+ + " escapeString(value) = " + escapeString(value));
+*/
+
+ // Output as namespace declaration
+ if (name.startsWith(XMLNS_PREFIX)) {
+ namespace(name.length() > 6 ? name.substring(6) : EMPTYSTRING, value);
}
else {
- _attributes.add(expandAttribute(name), escapeAttr(value));
+ if (index >= 0) { // Duplicate attribute?
+ _attributes.setAttribute(index, uri, localName, patchedName, "CDATA",
+ escapeString(value));
+ }
+ else {
+ _attributes.addAttribute(uri, localName, patchedName, "CDATA",
+ escapeString(value));
+ }
}
- return;
+ break;
+ case HTML:
+ if (!_startTagOpen) {
+ BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,name);
+ }
+
+ /*
+ * 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.
+ */
+ final String tmp = name.toLowerCase();
+ if (tmp.equals(HREF_STR) || tmp.equals(SRC_STR) || tmp.equals(CITE_STR)) {
+ if (index >= 0) {
+ _attributes.setAttribute(index, EMPTYSTRING, EMPTYSTRING, name,
+ "CDATA", quickAndDirtyUrlEncode(escapeAttr(value)));
+ }
+ else {
+ _attributes.addAttribute(EMPTYSTRING, EMPTYSTRING, name, "CDATA",
+ quickAndDirtyUrlEncode(escapeAttr(value)));
+ }
+ }
+ else {
+ if (index >= 0) {
+ _attributes.setAttribute(index, EMPTYSTRING, EMPTYSTRING,
+ name, "CDATA", escapeNonURLAttr(value));
+ }
+ else {
+ _attributes.addAttribute(EMPTYSTRING, EMPTYSTRING,
+ name, "CDATA", escapeNonURLAttr(value));
+ }
+ }
+ break;
}
}
/**
+ * Escape non ASCII characters (> u007F) as &#XXX; entities.
+ */
+ private String escapeNonURLAttr(String base) {
+ final int len = base.length() - 1;
+
+ char[] ch = base.toCharArray();
+ StringBuffer buf = new StringBuffer();
+ for(int i=0; i<base.length(); i++){
+ if (ch[i] > '\u007F') {
+ buf.append(CHAR_ESC_START);
+ buf.append(Integer.toString((int)ch[i]));
+ buf.append(';');
+ }
+ else {
+ buf.append(ch[i]);
+ }
+ }
+ base = buf.toString();
+ return base;
+ }
+
+
+ /**
* End an element or CDATA section in the output document
*/
public void endElement(String elementName) throws TransletException {
-
try {
switch(_outputType) {
case TEXT:
@@ -853,7 +925,10 @@
if (_startTagOpen) closeStartTag();
if (_cdataTagOpen) closeCDATA();
- _saxHandler.endElement(null, null, (String)(_qnameStack.pop()));
+ final String qname = (String) _qnameStack.pop();
+ _saxHandler.endElement(getNamespaceURI(qname, true),
+ getLocalName(qname), qname);
+
popNamespaces();
if (((Integer)_cdataStack.peek()).intValue() == _depth)
_cdataStack.pop();
@@ -862,7 +937,8 @@
case HTML:
// Close any open element
if (_startTagOpen) closeStartTag();
- _saxHandler.endElement(null, null, (String)(_qnameStack.pop()));
+ _saxHandler.endElement(EMPTYSTRING, EMPTYSTRING,
+ (String)(_qnameStack.pop()));
popNamespaces();
_depth--;
return;
@@ -929,10 +1005,15 @@
_prefixStack = new Stack();
// Define the default namespace (initially maps to "" uri)
- Stack stack = new Stack();
- _namespaces.put(EMPTYSTRING, stack);
+ Stack stack;
+ _namespaces.put(EMPTYSTRING, stack = new Stack());
stack.push(EMPTYSTRING);
_prefixStack.push(EMPTYSTRING);
+
+ _namespaces.put(XML_PREFIX, stack = new Stack());
+ stack.push("http://www.w3.org/XML/1998/namespace");
+ _prefixStack.push(XML_PREFIX);
+
_nodeStack.push(new Integer(-1));
_depth = 0;
}
@@ -941,9 +1022,9 @@
* Declare a prefix to point to a namespace URI
*/
private void pushNamespace(String prefix, String uri) throws SAXException {
-
+ // Prefixes "xml" and "xmlns" cannot be redefined
if (prefix.equals(XML_PREFIX)) return;
-
+
Stack stack;
// Get the stack that contains URIs for the specified prefix
if ((stack = (Stack)_namespaces.get(prefix)) == null) {
@@ -958,15 +1039,15 @@
_prefixStack.push(prefix);
_nodeStack.push(new Integer(_depth));
- if ((!prefix.equals(EMPTYSTRING)) && (uri.equals(EMPTYSTRING))) return;
- _saxHandler.startPrefixMapping(prefix, uri);
+ // Inform the SAX handler
+ _saxHandler.startPrefixMapping(prefix, escapeString(uri));
}
/**
* Undeclare the namespace that is currently pointed to by a given prefix
*/
private void popNamespace(String prefix) throws SAXException {
-
+ // Prefixes "xml" and "xmlns" cannot be redefined
if (prefix.equals(XML_PREFIX)) return;
Stack stack;
diff --git a/src/org/apache/xalan/xsltc/runtime/TransletLoader.java b/src/org/apache/xalan/xsltc/runtime/TransletLoader.java
index 1974afa..faa8861 100644
--- a/src/org/apache/xalan/xsltc/runtime/TransletLoader.java
+++ b/src/org/apache/xalan/xsltc/runtime/TransletLoader.java
@@ -57,6 +57,7 @@
* <http://www.apache.org/>.
*
* @author Morten Jorgensen
+ * @author Santiago Pericas-Geertsen
*
*/
@@ -64,6 +65,9 @@
import java.lang.Class;
import java.lang.ClassLoader;
+import java.lang.Thread;
+
+import java.net.*; // temporary
/**
* This class is intended used when the default Class.forName() method fails.
@@ -91,14 +95,14 @@
* Get a handle to the system class loader
*/
public TransletLoader() {
- // Get the default class loader
- ClassLoader loader = this.getClass().getClassLoader();
- // If this is the extensions class loader we need to get the
- // default system class loader instead. This is permitted if
- // this class was loaded by the extensions class loader.
- String loaderName = loader.getClass().getName();
- if (loaderName.equals("sun.misc.Launcher$ExtClassLoader"))
+ // Get the loader for the current thread (not the current class)
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+ // Avoid using the extensions class loader (see comment above)
+ final String loaderName = loader.getClass().getName();
+ if (loaderName.equals("sun.misc.Launcher$ExtClassLoader")) {
loader = ClassLoader.getSystemClassLoader();
+ }
_loader = loader;
}
@@ -108,6 +112,7 @@
public Class loadClass(String name) throws ClassNotFoundException {
return(Class.forName(name, false, _loader));
}
+
/**
* Loads a Class definition and runs static initializers.
*/
diff --git a/src/org/apache/xalan/xsltc/trax/DOM2SAX.java b/src/org/apache/xalan/xsltc/trax/DOM2SAX.java
index af2ddb7..b0101c7 100644
--- a/src/org/apache/xalan/xsltc/trax/DOM2SAX.java
+++ b/src/org/apache/xalan/xsltc/trax/DOM2SAX.java
@@ -63,6 +63,10 @@
package org.apache.xalan.xsltc.trax;
+import java.util.Stack;
+import java.util.Vector;
+import java.util.Hashtable;
+
import org.xml.sax.XMLReader;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
@@ -74,6 +78,9 @@
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.AttributeList;
+import org.xml.sax.helpers.AttributeListImpl;
+
import org.w3c.dom.Node;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
@@ -81,49 +88,110 @@
import org.w3c.dom.Entity;
import org.w3c.dom.Notation;
-import org.apache.xalan.xsltc.runtime.AttributeList;
+// import org.apache.xalan.xsltc.runtime.AttributeList;
-class DOM2SAX implements XMLReader , Locator {
+class DOM2SAX implements XMLReader, Locator {
- private Document _dom = null;
+ private final static String EMPTYSTRING = "";
+ private static final String XMLNS_PREFIX = "xmlns";
+
+ private Node _dom = null;
private ContentHandler _sax = null;
-
+ private Hashtable _nsPrefixes = new Hashtable();
+
public DOM2SAX(Node root) {
- _dom = (Document)root;
+ _dom = root;
}
public ContentHandler getContentHandler() {
return _sax;
}
- public DTDHandler getDTDHandler() {
- return null;
- }
-
- public ErrorHandler getErrorHandler() {
- return null;
- }
-
- public boolean getFeature(String name) throws SAXNotRecognizedException,
- SAXNotSupportedException
+ public void setContentHandler(ContentHandler handler) throws
+ NullPointerException
{
- return false;
+ if (handler == null) throw new NullPointerException();
+ _sax = handler;
}
- public void setFeature(String name, boolean value) throws
- SAXNotRecognizedException, SAXNotSupportedException
+ /**
+ * Begin the scope of namespace prefix. Forward the event to the
+ * SAX handler only if the prefix is unknown or it is mapped to a
+ * different URI.
+ */
+ private boolean startPrefixMapping(String prefix, String uri)
+ throws SAXException
{
-
+ boolean pushed = true;
+ Stack uriStack = (Stack) _nsPrefixes.get(prefix);
+
+ if (uriStack != null) {
+ if (uriStack.isEmpty()) {
+ _sax.startPrefixMapping(prefix, uri);
+ uriStack.push(uri);
+ }
+ else {
+ final String lastUri = (String) uriStack.peek();
+ if (!lastUri.equals(uri)) {
+ _sax.startPrefixMapping(prefix, uri);
+ uriStack.push(uri);
+ }
+ else {
+ pushed = false;
+ }
+ }
+ }
+ else {
+ _sax.startPrefixMapping(prefix, uri);
+ _nsPrefixes.put(prefix, uriStack = new Stack());
+ uriStack.push(uri);
+ }
+ return pushed;
+ }
+
+ /*
+ * End the scope of a name prefix by popping it from the stack and
+ * passing the event to the SAX Handler.
+ */
+ private void endPrefixMapping(String prefix)
+ throws SAXException
+ {
+ final Stack uriStack = (Stack) _nsPrefixes.get(prefix);
+
+ if (uriStack != null) {
+ _sax.endPrefixMapping(prefix);
+ uriStack.pop();
+ }
+ }
+
+ /**
+ * If the DOM was created using a DOM 1.0 API, the local name may be
+ * null. If so, get the local name from the qualified name before
+ * generating the SAX event.
+ */
+ private static String getLocalName(Node node) {
+ final String localName = node.getLocalName();
+
+ if (localName == null) {
+ final String qname = node.getNodeName();
+ final int col = qname.lastIndexOf(':');
+ return (col > 0) ? qname.substring(col + 1) : qname;
+ }
+ return localName;
}
public void parse(InputSource unused) throws IOException, SAXException {
- Node currNode = _dom;
- parse(currNode);
+ parse(_dom);
}
+ /**
+ * Traverse the DOM and generate SAX events for a handler. A
+ * startElement() event passes all attributes, including namespace
+ * declarations.
+ */
private void parse(Node node) throws IOException, SAXException {
Node first = null;
- if (node == null ) return;
+ if (node == null) return;
switch (node.getNodeType()) {
case Node.ATTRIBUTE_NODE: // handled by ELEMENT_NODE
@@ -139,6 +207,7 @@
case Node.DOCUMENT_NODE:
_sax.setDocumentLocator(this);
+
_sax.startDocument();
Node next = node.getFirstChild();
while (next != null) {
@@ -149,29 +218,85 @@
break;
case Node.ELEMENT_NODE:
- // Gather all attribute node of the element
- AttributeList attrs = new AttributeList();
- NamedNodeMap map = node.getAttributes();
- int length = map.getLength();
- for (int i=0; i<length; i++ ) {
- Node attr = map.item(i);
- attrs.add(attr.getNodeName(), attr.getNodeValue());
+ String prefix;
+ Vector pushedPrefixes = new Vector();
+ final AttributesImpl attrs = new AttributesImpl();
+ final NamedNodeMap map = node.getAttributes();
+ final int length = map.getLength();
+
+ // Process all namespace declarations
+ for (int i = 0; i < length; i++) {
+ final Node attr = map.item(i);
+ final String qnameAttr = attr.getNodeName();
+
+ // Ignore everything but NS declarations here
+ if (qnameAttr.startsWith(XMLNS_PREFIX)) {
+ final String uriAttr = attr.getNodeValue();
+ final int colon = qnameAttr.lastIndexOf(':');
+ prefix = (colon > 0) ? qnameAttr.substring(colon + 1) : EMPTYSTRING;
+ if (startPrefixMapping(prefix, uriAttr)) {
+ pushedPrefixes.addElement(prefix);
+ }
+ }
+ }
+
+ // Process all other attributes
+ for (int i = 0; i < length; i++) {
+ final Node attr = map.item(i);
+ final String qnameAttr = attr.getNodeName();
+
+ // Ignore NS declarations here
+ if (!qnameAttr.startsWith(XMLNS_PREFIX)) {
+ final String uriAttr = node.getNamespaceURI();
+ final String localNameAttr = getLocalName(attr);
+
+ // Uri may be implicitly declared
+ if (uriAttr != null) {
+ final int colon = qnameAttr.lastIndexOf(':');
+ prefix = (colon > 0) ? qnameAttr.substring(0, colon) : EMPTYSTRING;
+ if (startPrefixMapping(prefix, uriAttr)) {
+ pushedPrefixes.addElement(prefix);
+ }
+ }
+
+ // Add attribute to list
+ attrs.addAttribute(attr.getNamespaceURI(), getLocalName(attr),
+ qnameAttr, "CDATA", attr.getNodeValue());
+ }
+ }
+
+ // Now process the element itself
+ final String qname = node.getNodeName();
+ final String uri = node.getNamespaceURI();
+ final String localName = getLocalName(node);
+
+ // Uri may be implicitly declared
+ if (uri != null) {
+ final int colon = qname.lastIndexOf(':');
+ prefix = (colon > 0) ? qname.substring(0, colon) : EMPTYSTRING;
+ if (startPrefixMapping(prefix, uri)) {
+ pushedPrefixes.addElement(prefix);
+ }
}
// Generate SAX event to start element
- _sax.startElement(node.getNamespaceURI(), node.getLocalName(),
- node.getNodeName(), attrs);
+ _sax.startElement(uri, localName, qname, attrs);
// Traverse all child nodes of the element (if any)
next = node.getFirstChild();
- while ( next != null ) {
+ while (next != null) {
parse(next);
next = next.getNextSibling();
}
// Generate SAX event to close element
- _sax.endElement(node.getNamespaceURI(),
- node.getLocalName(), node.getNodeName());
+ _sax.endElement(uri, localName, qname);
+
+ // Generate endPrefixMapping() for all pushed prefixes
+ final int nPushedPrefixes = pushedPrefixes.size();
+ for (int i = 0; i < nPushedPrefixes; i++) {
+ endPrefixMapping((String) pushedPrefixes.elementAt(i));
+ }
break;
case Node.PROCESSING_INSTRUCTION_NODE:
@@ -186,48 +311,133 @@
}
}
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public DTDHandler getDTDHandler() {
+ return null;
+ }
+
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public ErrorHandler getErrorHandler() {
+ return null;
+ }
+
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public boolean getFeature(String name) throws SAXNotRecognizedException,
+ SAXNotSupportedException
+ {
+ return false;
+ }
+
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public void setFeature(String name, boolean value) throws
+ SAXNotRecognizedException, SAXNotSupportedException
+ {
+ }
+
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
public void parse(String sysId) throws IOException, SAXException {
throw new IOException("This method is not yet implemented.");
}
- public void setContentHandler(ContentHandler handler) throws
- NullPointerException
- {
- if (handler == null ) throw new NullPointerException();
- _sax = handler;
- }
+
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
public void setDTDHandler(DTDHandler handler) throws NullPointerException {
- if (handler == null ) throw new NullPointerException();
}
+
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
public void setEntityResolver(EntityResolver resolver) throws
NullPointerException
{
- if (resolver == null ) throw new NullPointerException();
}
+
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
public EntityResolver getEntityResolver() {
return null;
}
+
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
public void setErrorHandler(ErrorHandler handler) throws
NullPointerException
{
- if (handler == null ) throw new NullPointerException();
}
+
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
public void setProperty(String name, Object value) throws
SAXNotRecognizedException, SAXNotSupportedException {
}
+
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
public Object getProperty(String name) throws SAXNotRecognizedException,
SAXNotSupportedException
{
return null;
}
- // Locator methods
- public int getColumnNumber() { return 0; }
- public int getLineNumber() { return 0; }
- public String getPublicId() { return null; }
- public String getSystemId() { return null; }
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public int getColumnNumber() {
+ return 0;
+ }
+
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public int getLineNumber() {
+ return 0;
+ }
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public String getPublicId() {
+ return null;
+ }
- // private
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public String getSystemId() {
+ return null;
+ }
+
+ // Debugging
private String getNodeTypeFromCode(short code) {
String retval = null;
switch (code) {
diff --git a/src/org/apache/xalan/xsltc/trax/SAX2DOM.java b/src/org/apache/xalan/xsltc/trax/SAX2DOM.java
index 82177b7..8fd398c 100644
--- a/src/org/apache/xalan/xsltc/trax/SAX2DOM.java
+++ b/src/org/apache/xalan/xsltc/trax/SAX2DOM.java
@@ -57,12 +57,14 @@
* <http://www.apache.org/>.
*
* @author G. Todd Miller
- *
*/
package org.apache.xalan.xsltc.trax;
+import java.util.Stack;
+import java.util.Vector;
+
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.Attributes;
@@ -75,15 +77,17 @@
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.w3c.dom.Attr;
-import java.util.Stack;
+import org.apache.xalan.xsltc.runtime.Constants;
-class SAX2DOM implements ContentHandler {
+class SAX2DOM implements ContentHandler, Constants {
+ private Stack _nodeStk = null;
private Document _document = null;
private DocumentBuilder _builder = null;
- private Stack _nodeStk = null;
+ private Vector _namespaceDecls = null;
+
public SAX2DOM() throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
_builder = factory.newDocumentBuilder();
@@ -95,144 +99,107 @@
}
public void characters(char[] ch, int start, int length) {
- Text text = _document.createTextNode(new String(ch, start, length));
- Node last = (Node)_nodeStk.peek();
- last.appendChild(text);
+ final Node last = (Node)_nodeStk.peek();
+ final String text = new String(ch, start, length);
+
+ // No text nodes can be children of root (DOM006 exception)
+ if (last != _document) {
+ last.appendChild(_document.createTextNode(text));
+ }
}
public void startDocument() {
_document = _builder.newDocument();
- Element root = (Element)_document.createElement("root");
- _document.appendChild(root);
- _nodeStk.push(root);
+ _nodeStk.push(_document);
}
public void endDocument() {
- //printDOM();
}
public void startElement(String namespace, String localName, String qName,
- Attributes attrs )
+ Attributes attrs)
{
- // create new element
- Element tmp = (Element)_document.createElementNS(namespace, qName);
- int nattrs = attrs.getLength();
- for (int i=0; i<nattrs; i++ ) {
- String namespaceuri = attrs.getURI(i);
- String value = attrs.getValue(i);
- String qname = attrs.getQName(i);
- if ((namespaceuri == null) || (namespaceuri.equals("")))
- tmp.setAttribute(qname, value);
- else
- tmp.setAttributeNS(namespaceuri, qname, value);
+ final Element tmp = (Element)_document.createElementNS(namespace, qName);
+
+ // Add namespace declarations first
+ if (_namespaceDecls != null) {
+ final int nDecls = _namespaceDecls.size();
+ for (int i = 0; i < nDecls; i++) {
+ final String prefix = (String) _namespaceDecls.elementAt(i++);
+
+ if (prefix == null || prefix.equals(EMPTYSTRING)) {
+ tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX,
+ (String) _namespaceDecls.elementAt(i));
+ }
+ else {
+ tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix,
+ (String) _namespaceDecls.elementAt(i));
+ }
+ }
+ _namespaceDecls.clear();
}
- // append this new node onto current stack node
+
+ // Add attributes to element
+ final int nattrs = attrs.getLength();
+ for (int i = 0; i < nattrs; i++) {
+ if (attrs.getLocalName(i) == null) {
+ tmp.setAttribute(attrs.getQName(i), attrs.getValue(i));
+ }
+ else {
+ tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i),
+ attrs.getValue(i));
+ }
+ }
+
+ // Append this new node onto current stack node
Node last = (Node)_nodeStk.peek();
last.appendChild(tmp);
- // push this node onto stack
+
+ // Push this node onto stack
_nodeStk.push(tmp);
}
public void endElement(String namespace, String localName, String qName) {
- Node lastActive = (Node)_nodeStk.pop();
- }
-
-
- public void ignorableWhitespace(char[] ch, int start, int length) {
- }
-
- public void processingInstruction(String target, String data) {
- }
-
- public void setDocumentLocator(Locator locator) {
- }
-
- public void skippedEntity(String name) {
+ _nodeStk.pop();
}
public void startPrefixMapping(String prefix, String uri) {
+ if (_namespaceDecls == null) {
+ _namespaceDecls = new Vector(2);
+ }
+ _namespaceDecls.addElement(prefix);
+ _namespaceDecls.addElement(uri);
}
public void endPrefixMapping(String prefix) {
+ // do nothing
}
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public void ignorableWhitespace(char[] ch, int start, int length) {
+ }
- // for debugging - will be removed
- private void printDOM() {
- System.out.println("SAX2DOM.java:Printing DOM...");
- Node currNode = _document;
- while (currNode != null) {
- // start of node processing
- switch (currNode.getNodeType()) {
- case Node.ATTRIBUTE_NODE :
- break;
- case Node.CDATA_SECTION_NODE :
- break;
- case Node.COMMENT_NODE :
- break;
- case Node.DOCUMENT_FRAGMENT_NODE :
- break;
- case Node.DOCUMENT_NODE :
- break;
- case Node.DOCUMENT_TYPE_NODE :
- break;
- case Node.ELEMENT_NODE :
- System.out.println("ELEMT NODE " + currNode.getLocalName() +":");
- org.w3c.dom.NamedNodeMap map = currNode.getAttributes();
- int length = map.getLength();
- for (int i=0; i<length; i++ ){
- Node attrNode = map.item(i);
- short code = attrNode.getNodeType();
- System.out.println("\tattr:"+attrNode.getNamespaceURI()+
- "," + attrNode.getLocalName() +
- "," + attrNode.getNodeName() +
- "=" + attrNode.getNodeValue());
- }
- break;
- case Node.ENTITY_NODE :
- org.w3c.dom.Entity edecl = (org.w3c.dom.Entity)currNode;
- String name = edecl.getNotationName();
- if ( name != null ) {
- System.out.println("ENT NODE: "+currNode.getNodeName()+
- ", "+ edecl.getSystemId()+ "," + name);
- }
- break;
- case Node.ENTITY_REFERENCE_NODE :
- break;
- case Node.NOTATION_NODE :
- break;
- case Node.PROCESSING_INSTRUCTION_NODE :
- break;
- case Node.TEXT_NODE :
- String data = currNode.getNodeValue();
- System.out.println("TEXT NODE:" + data);
- break;
- }
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public void processingInstruction(String target, String data) {
+ }
- // move to first child
- Node next = currNode.getFirstChild();
- if (next != null) {
- currNode = next;
- continue;
- }
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public void setDocumentLocator(Locator locator) {
+ }
- // no child nodes, walk the tree
- while (currNode != null) {
- switch (currNode.getNodeType()) {
- case Node.DOCUMENT_NODE:
- break;
- case Node.ELEMENT_NODE:
- break;
- }
- next = currNode.getNextSibling();
- if (next != null ) {
- currNode = next;
- break;
- }
- // move up a level
- currNode = currNode.getParentNode();
- }
- }
- }
-
+ /**
+ * This class is only used internally so this method should never
+ * be called.
+ */
+ public void skippedEntity(String name) {
+ }
}
diff --git a/src/org/apache/xalan/xsltc/trax/TemplatesHandlerImpl.java b/src/org/apache/xalan/xsltc/trax/TemplatesHandlerImpl.java
index 3c8f8f0..0252cc3 100644
--- a/src/org/apache/xalan/xsltc/trax/TemplatesHandlerImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TemplatesHandlerImpl.java
@@ -91,8 +91,9 @@
// Create and initialize a stylesheet compiler
final XSLTC xsltc = new XSLTC();
super.setXSLTC(xsltc);
- xsltc.setParser(this);
xsltc.init();
+ super.init();
+ xsltc.setParser(this);
xsltc.setOutputType(XSLTC.BYTEARRAY_OUTPUT);
}
@@ -126,10 +127,7 @@
* process, or null if no Templates object has been created.
*/
public Templates getTemplates() {
-
try {
- // Create a placeholder for the translet bytecodes
- byte[][] bytecodes = null;
final XSLTC xsltc = getXSLTC();
@@ -161,6 +159,7 @@
xsltc.printWarnings();
// Check that the transformation went well before returning
+ final byte[][] bytecodes = xsltc.getBytecodes();
if (bytecodes == null) {
xsltc.printErrors();
return null;
diff --git a/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java b/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
index e1c099c..26cde36 100644
--- a/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
@@ -59,6 +59,7 @@
* @author Morten Jorgensen
* @author G. Todd Millerj
* @author Jochen Cordes <Jochen.Cordes@t-online.de>
+ * @author Santiago Pericas-Geertsen
*
*/
@@ -176,8 +177,13 @@
(TransletClassLoader) AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
- ClassLoader current = getClass().getClassLoader();
- return new TransletClassLoader(current);
+ /*
+ * Get the loader from the current thread instead of
+ * the class. This is important for translets that load
+ * external Java classes and run in multi-threaded envs.
+ */
+ return new TransletClassLoader(
+ Thread.currentThread().getContextClassLoader());
}
}
);
diff --git a/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java b/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
index 2f2cc9b..a652020 100644
--- a/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
@@ -527,7 +527,9 @@
*/
public TemplatesHandler newTemplatesHandler()
throws TransformerConfigurationException {
- return(new TemplatesHandlerImpl());
+ final TemplatesHandlerImpl handler = new TemplatesHandlerImpl();
+ handler.init();
+ return handler;
}
/**
diff --git a/src/org/apache/xalan/xsltc/trax/TransformerImpl.java b/src/org/apache/xalan/xsltc/trax/TransformerImpl.java
index 24e66cf..d178273 100644
--- a/src/org/apache/xalan/xsltc/trax/TransformerImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TransformerImpl.java
@@ -409,8 +409,14 @@
// Handle DOMSource input
else if (source instanceof DOMSource) {
final DOMSource domsrc = (DOMSource)source;
- final Document tree = (Document)domsrc.getNode();
- final DOM2SAX dom2sax = new DOM2SAX(tree);
+ final org.w3c.dom.Node node = domsrc.getNode();
+
+ boolean isComplete = true;
+ if (node.getNodeType() != org.w3c.dom.Node.DOCUMENT_NODE) {
+ isComplete = false;
+ }
+
+ final DOM2SAX dom2sax = new DOM2SAX(node);
final InputSource input = null;
final String systemId = domsrc.getSystemId();
@@ -425,7 +431,13 @@
dom2sax.setContentHandler(builder);
// Parse the input and build the internal DOM
+ if (!isComplete) {
+ builder.startDocument();
+ }
dom2sax.parse(input); // need this parameter?
+ if (!isComplete) {
+ builder.endDocument();
+ }
dom.setDocumentURI(systemId);
}
// Handle StreamSource input
@@ -708,7 +720,8 @@
while (names.hasMoreElements()) {
// Get the next property name and value
String name = (String)names.nextElement();
- String value = (String)properties.get(name);
+ // bug fix # 6636- contributed by Tim Elcott
+ String value = (String)properties.getProperty(name);
// Pass property value to translet - override previous setting
if (name.equals(OutputKeys.ENCODING))
@@ -756,13 +769,14 @@
private Properties createOutputProperties() {
// Level3: Return the default property value
+ // bug # 6751 fixed by removing setProperty lines for
+ // OutputKeys.(DOCTYPE_PUBLIC|DOCTYPE_SYSTEM|CDATA_SECTION_ELEMENTS)
+ // instead of setting them to "" (EMPTY_STRING). Fix contributed
+ // by Derek Sayeau.
Properties third = new Properties();
third.setProperty(OutputKeys.ENCODING, "UTF-8");
third.setProperty(OutputKeys.METHOD, XML_STRING);
third.setProperty(OutputKeys.INDENT, NO_STRING);
- third.setProperty(OutputKeys.DOCTYPE_PUBLIC, EMPTY_STRING);
- third.setProperty(OutputKeys.DOCTYPE_SYSTEM, EMPTY_STRING);
- third.setProperty(OutputKeys.CDATA_SECTION_ELEMENTS, EMPTY_STRING);
third.setProperty(OutputKeys.MEDIA_TYPE, "text/xml");
third.setProperty(OutputKeys.OMIT_XML_DECLARATION, NO_STRING);
third.setProperty(OutputKeys.STANDALONE, NO_STRING);
diff --git a/src/trax/trax.properties b/src/trax/trax.properties
deleted file mode 100644
index e593c39..0000000
--- a/src/trax/trax.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-# $Revision$ $Date$
-#
-# Note: This properties file is provided for illustrative purposes
-# only and is not part of the interface definition.
-# This properties file is located in the implementation JAR
-# and different implementations will specify different
-# implementation classes and output methods.
-#
-
-# The TRaX Stylesheet processor
-trax.processor.xslt=org.apache.xalan.processor.StylesheetProcessor