santiagopg 2002/10/15 10:55:07
Modified: java/src/org/apache/xalan/xsltc/compiler XslElement.java
java/src/org/apache/xalan/xsltc/runtime BasisLibrary.java
Log:
New implementation of xsl:element that properly handles the case where
the namespace URI computed at runtime is "". Some of the code implementing
the xsl:element instruction has been factored out from the translet into
the basis library.
Revision Changes Path
1.19 +18 -50
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslElement.java
Index: XslElement.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslElement.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- XslElement.java 23 Aug 2002 21:31:32 -0000 1.18
+++ XslElement.java 15 Oct 2002 17:55:07 -0000 1.19
@@ -279,62 +279,30 @@
}
if (!_ignore) {
+ // Push handler for call to endElement()
il.append(methodGen.loadHandler());
- _name.translate(classGen, methodGen);
-
- // Call BasisLibrary.getPrefix() and store result in local variable
- il.append(DUP);
- final int getPrefix = cpg.addMethodref(BASIS_LIBRARY_CLASS,
"getPrefix",
- "(" + STRING_SIG + ")" +
STRING_SIG);
- il.append(new INVOKESTATIC(getPrefix));
- il.append(DUP);
- local = methodGen.addLocalVariable("prefix",
-
org.apache.bcel.generic.Type.STRING,
- il.getEnd(), null);
- il.append(new ASTORE(local.getIndex()));
-
- // If prefix is null then generate a prefix at runtime
- final BranchHandle ifNotNull = il.append(new IFNONNULL(null));
- if (_namespace != null) {
- final int generatePrefix =
cpg.addMethodref(BASIS_LIBRARY_CLASS,
- "generatePrefix",
- "()" + STRING_SIG);
- il.append(new INVOKESTATIC(generatePrefix));
- il.append(DUP);
- il.append(new ASTORE(local.getIndex()));
-
- // Prepend newly generated prefix to the name
- final int makeQName = cpg.addMethodref(BASIS_LIBRARY_CLASS,
"makeQName",
- "(" + STRING_SIG + STRING_SIG + ")" +
STRING_SIG);
- il.append(new INVOKESTATIC(makeQName));
- }
- ifNotNull.setTarget(il.append(DUP2));
- il.append(methodGen.startElement());
+ // Push name and namespace URI
+ _name.translate(classGen, methodGen);
if (_namespace != null) {
- il.append(methodGen.loadHandler());
- il.append(new ALOAD(local.getIndex()));
_namespace.translate(classGen, methodGen);
- il.append(methodGen.namespace());
}
else {
- // If prefix not known at compile time, call
DOM.lookupNamespace()
- il.append(new ALOAD(local.getIndex()));
- final BranchHandle ifNull = il.append(new IFNULL(null));
- il.append(methodGen.loadHandler());
- il.append(new ALOAD(local.getIndex()));
+ il.append(ACONST_NULL);
+ }
- il.append(methodGen.loadDOM());
- il.append(methodGen.loadCurrentNode());
- il.append(new ALOAD(local.getIndex()));
+ // Push additional arguments
+ il.append(methodGen.loadHandler());
+ il.append(methodGen.loadDOM());
+ il.append(methodGen.loadCurrentNode());
- final int lookupNamespace = cpg.addInterfaceMethodref(DOM_INTF,
- "lookupNamespace",
- "(I" + STRING_SIG + ")" + STRING_SIG);
- il.append(new INVOKEINTERFACE(lookupNamespace, 3));
- il.append(methodGen.namespace());
- ifNull.setTarget(il.append(NOP));
- }
+ // Invoke BasisLibrary.startXslElement()
+ il.append(new INVOKESTATIC(
+ cpg.addMethodref(BASIS_LIBRARY_CLASS, "startXslElement",
+ "(" + STRING_SIG
+ + STRING_SIG
+ + TRANSLET_OUTPUT_SIG
+ + DOM_INTF_SIG + "I)" + STRING_SIG)));
}
translateContents(classGen, methodGen);
1.53 +42 -9
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
Index: BasisLibrary.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- BasisLibrary.java 27 Sep 2002 22:11:12 -0000 1.52
+++ BasisLibrary.java 15 Oct 2002 17:55:07 -0000 1.53
@@ -1176,6 +1176,46 @@
}
}
+
+ /**
+ * Utility function for the implementation of xsl:element.
+ */
+ public static String startXslElement(String qname, String namespace,
+ TransletOutputHandler handler, DOM dom, int node)
+ {
+ try {
+ // Get prefix from qname
+ String prefix;
+ final int index = qname.indexOf(':');
+
+ if (index > 0) {
+ prefix = qname.substring(0, index);
+
+ // Handle case when prefix is not known at compile time
+ if (namespace == null || namespace.length() == 0) {
+ namespace = dom.lookupNamespace(node, prefix);
+ }
+ handler.namespace(prefix, namespace);
+ }
+ else {
+ // Need to generate a prefix?
+ if (namespace != null && namespace.length() > 0) {
+ prefix = generatePrefix();
+ handler.namespace(prefix, namespace);
+ qname = prefix + ':' + qname;
+ }
+ }
+
+ // Call start element before returning
+ handler.startElement(qname);
+ }
+ catch (TransletException e) {
+ throw new RuntimeException(e);
+ }
+
+ return qname;
+ }
+
/**
* This function is used in the execution of xsl:element
*/
@@ -1187,16 +1227,9 @@
/**
* This function is used in the execution of xsl:element
*/
- private static int prefixIndex = 0;
+ private static int prefixIndex = 0; // not thread safe!!
public static String generatePrefix() {
return ("ns" + prefixIndex++);
- }
-
- /**
- * This function is used in the execution of xsl:element
- */
- public static String makeQName(String localName, String prefix) {
- return (new
StringBuffer(prefix).append(':').append(localName).toString());
}
public static final int RUN_TIME_INTERNAL_ERR = 0;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]