You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sa...@apache.org on 2002/05/03 16:17:32 UTC
cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/compiler Mode.java
santiagopg 02/05/03 07:17:32
Modified: java/src/org/apache/xalan/xsltc/compiler Mode.java
Log:
Fixed for Bugzilla 2886 (node15).
Revision Changes Path
1.20 +162 -82 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Mode.java
Index: Mode.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Mode.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- Mode.java 1 Feb 2002 20:07:08 -0000 1.19
+++ Mode.java 3 May 2002 14:17:32 -0000 1.20
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: Mode.java,v 1.19 2002/02/01 20:07:08 tmiller Exp $
+ * @(#)$Id: Mode.java,v 1.20 2002/05/03 14:17:32 santiagopg Exp $
*
* The Apache Software License, Version 1.1
*
@@ -82,21 +82,54 @@
*/
final class Mode implements Constants {
- private final QName _name; // The QName of this mode
- private final Stylesheet _stylesheet; // The owning stylesheet
- private final String _methodName; // The method name for this mode
- private Vector _templates; // All templates in this mode
-
- // Pattern/test sequence for pattern with node()-type kernel
- private Vector _nodeGroup = null;
- private TestSeq _nodeTestSeq = null;
-
- // Pattern/test sequence for pattern with id() or key()-type kernel
- private Vector _idxGroup = null;
- private TestSeq _idxTestSeq = null;
+ /**
+ * The name of this mode as defined in the stylesheet.
+ */
+ private final QName _name;
+
+ /**
+ * A reference to the stylesheet object that owns this mode.
+ */
+ private final Stylesheet _stylesheet;
+
+ /**
+ * The name of the method in which this mode is compiled.
+ */
+ private final String _methodName;
+
+ /**
+ * A vector of all the templates in this mode.
+ */
+ private Vector _templates;
+
+ /**
+ * Group for patterns with node()-type kernel.
+ */
+ private Vector _nodeGroup = null;
+
+ /**
+ * Test sequence for patterns with node()-type kernel.
+ */
+ private TestSeq _nodeTestSeq = null;
+
+ /**
+ * Group for patterns with id() or key()-type kernel.
+ */
+ private Vector _idxGroup = null;
- // Pattern/test sequence for patterns with any other kernel type
+ /**
+ * Test sequence for patterns with id() or key()-type kernel.
+ */
+ private TestSeq _idxTestSeq = null;
+
+ /**
+ * Group for patterns with any other kernel type.
+ */
private Vector[] _patternGroups;
+
+ /**
+ * Test sequence for patterns with any other kernel type.
+ */
private TestSeq[] _testSeq;
private Hashtable _neededTemplates = new Hashtable();
@@ -114,7 +147,8 @@
/**
- * Creates a new Mode
+ * Creates a new Mode.
+ *
* @param name A textual representation of the mode's QName
* @param stylesheet The Stylesheet in which the mode occured
* @param suffix A suffix to append to the method name for this mode
@@ -200,15 +234,20 @@
// Get the next template
final Template template = (Template)templates.nextElement();
- // Add this template to a table of named templates if it has a name.
- // If there are multiple templates with the same name, all but one
- // (the one with highest priority) will be disabled.
- if (template.isNamed() && !template.disabled())
+ /*
+ * Add this template to a table of named templates if it has a name.
+ * If there are multiple templates with the same name, all but one
+ * (the one with highest priority) will be disabled.
+ */
+ if (template.isNamed() && !template.disabled()) {
_namedTemplates.put(template, this);
+ }
// Add this template to a test sequence if it has a pattern
final Pattern pattern = template.getPattern();
- if (pattern != null) flattenAlternative(pattern, template, keys);
+ if (pattern != null) {
+ flattenAlternative(pattern, template, keys);
+ }
}
prepareTestSequences();
}
@@ -261,10 +300,7 @@
Vector patterns;
// Use the vector for id()/key()/node() patterns if no kernel type
- if (kernelType == -1)
- patterns = _nodeGroup;
- else
- patterns = _patternGroups[kernelType];
+ patterns = (kernelType == -1) ? _nodeGroup : _patternGroups[kernelType];
// Create a new vector if needed and insert the very first pattern
if (patterns == null) {
@@ -389,7 +425,8 @@
private void compileTemplates(ClassGenerator classGen,
MethodGenerator methodGen,
- InstructionHandle next) {
+ InstructionHandle next)
+ {
Enumeration templates = _namedTemplates.keys();
while (templates.hasMoreElements()) {
final Template template = (Template)templates.nextElement();
@@ -563,22 +600,16 @@
}
/**
- * Auxillary method to determine if a qname describes an attribute/element
+ * Auxiliary method to determine if a qname describes an attribute/element
*/
private static boolean isAttributeName(String qname) {
final int col = qname.lastIndexOf(':') + 1;
- if (qname.charAt(col) == '@')
- return(true);
- else
- return(false);
+ return (qname.charAt(col) == '@');
}
private static boolean isNamespaceName(String qname) {
final int col = qname.lastIndexOf(':');
- if ((col > -1) && (qname.charAt(qname.length()-1) == '*'))
- return(true);
- else
- return(false);
+ return (col > -1 && qname.charAt(qname.length()-1) == '*');
}
/**
@@ -588,9 +619,9 @@
public void compileApplyTemplates(ClassGenerator classGen) {
final XSLTC xsltc = classGen.getParser().getXSLTC();
final ConstantPoolGen cpg = classGen.getConstantPool();
- final Vector names = xsltc.getNamesIndex();
+ final Vector names = xsltc.getNamesIndex();
- // (*) Create the applyTemplates() method
+ // Create the applyTemplates() method
final org.apache.bcel.generic.Type[] argTypes =
new org.apache.bcel.generic.Type[3];
argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
@@ -611,20 +642,20 @@
classGen.getConstantPool());
methodGen.addException("org.apache.xalan.xsltc.TransletException");
- // (*) Create the local variablea
+ // Create a local variable to hold the current node
final LocalVariableGen current;
current = methodGen.addLocalVariable2("current",
org.apache.bcel.generic.Type.INT,
mainIL.getEnd());
_currentIndex = current.getIndex();
- // (*) Create the "body" instruction list that will eventually hold the
- // code for the entire method (other ILs will be appended).
+ // Create the "body" instruction list that will eventually hold the
+ // code for the entire method (other ILs will be appended).
final InstructionList body = new InstructionList();
body.append(NOP);
- // (*) Create an instruction list that contains the default next-node
- // iteration
+ // Create an instruction list that contains the default next-node
+ // iteration
final InstructionList ilLoop = new InstructionList();
ilLoop.append(methodGen.loadIterator());
ilLoop.append(methodGen.nextNode());
@@ -635,41 +666,44 @@
// by a single IFNE(body.getStart()) instruction - need workaround:
final BranchHandle ifeq = ilLoop.append(new IFEQ(null));
final BranchHandle loop = ilLoop.append(new GOTO_W(null));
- ifeq.setTarget(ilLoop.append(RETURN)); // applyTemplates() ends here!
+ ifeq.setTarget(ilLoop.append(RETURN)); // applyTemplates() ends here!
final InstructionHandle ihLoop = ilLoop.getStart();
- // (*) Compile default handling of elements (traverse children)
+ // Compile default handling of elements (traverse children)
InstructionList ilRecurse =
compileDefaultRecursion(classGen, methodGen, ihLoop);
InstructionHandle ihRecurse = ilRecurse.getStart();
- // (*) Compile default handling of text/attribute nodes (output text)
+ // Compile default handling of text/attribute nodes (output text)
InstructionList ilText =
compileDefaultText(classGen, methodGen, ihLoop);
InstructionHandle ihText = ilText.getStart();
// Distinguish attribute/element/namespace tests for further processing
final int[] types = new int[DOM.NTYPES + names.size()];
- for (int i = 0; i < types.length; i++) types[i] = i;
+ for (int i = 0; i < types.length; i++) {
+ types[i] = i;
+ }
+ // Initialize isAttribute[] and isNamespace[] arrays
final boolean[] isAttribute = new boolean[types.length];
final boolean[] isNamespace = new boolean[types.length];
for (int i = 0; i < names.size(); i++) {
final String name = (String)names.elementAt(i);
- isAttribute[i+DOM.NTYPES] = isAttributeName(name);
- isNamespace[i+DOM.NTYPES] = isNamespaceName(name);
+ isAttribute[i + DOM.NTYPES] = isAttributeName(name);
+ isNamespace[i + DOM.NTYPES] = isNamespaceName(name);
}
- // (*) Compile all templates - regardless of pattern type
+ // Compile all templates - regardless of pattern type
compileTemplates(classGen, methodGen, ihLoop);
- // (*) Handle template with explicit "*" pattern
+ // Handle template with explicit "*" pattern
final TestSeq elemTest = _testSeq[DOM.ELEMENT];
InstructionHandle ihElem = ihRecurse;
if (elemTest != null)
ihElem = elemTest.compile(classGen, methodGen, ihRecurse);
- // (*) Handle template with explicit "@*" pattern
+ // Handle template with explicit "@*" pattern
final TestSeq attrTest = _testSeq[DOM.ATTRIBUTE];
InstructionHandle ihAttr = ihText;
if (attrTest != null)
@@ -685,39 +719,58 @@
loop.setTarget(body.getStart());
}
- // (*) If there is a match on node() we need to replace ihElem
- // and ihText (default behaviour for elements & text).
+ // If there is a match on node() we need to replace ihElem
+ // and ihText if the priority of node() is higher
if (_nodeTestSeq != null) {
- double nodePrio = -0.5; //_nodeTestSeq.getPriority();
+
+ // Compare priorities of node() and "*"
+ double nodePrio = -0.5; //_nodeTestSeq.getPriority();
int nodePos = _nodeTestSeq.getPosition();
double elemPrio = (0 - Double.MAX_VALUE);
int elemPos = Integer.MIN_VALUE;
+
if (elemTest != null) {
elemPrio = elemTest.getPriority();
elemPos = elemTest.getPosition();
}
- if ((elemPrio == Double.NaN) || (elemPrio < nodePrio) ||
- ((elemPrio == nodePrio) && (elemPos < nodePos))) {
+ if (elemPrio == Double.NaN || elemPrio < nodePrio ||
+ (elemPrio == nodePrio && elemPos < nodePos))
+ {
ihElem = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
- ihText = ihElem;
+ }
+
+ // Compare priorities of node() and text()
+ final TestSeq textTest = _testSeq[DOM.TEXT];
+ double textPrio = (0 - Double.MAX_VALUE);
+ int textPos = Integer.MIN_VALUE;
+
+ if (textTest != null) {
+ textPrio = textTest.getPriority();
+ textPos = textTest.getPosition();
+ }
+ if (textPrio == Double.NaN || textPrio < nodePrio ||
+ (textPrio == nodePrio && textPos < nodePos))
+ {
+ ihText = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
+ _testSeq[DOM.TEXT] = _nodeTestSeq;
}
}
- // (*) Handle templates with "ns:*" pattern
+ // Handle templates with "ns:*" pattern
InstructionHandle elemNamespaceHandle = ihElem;
InstructionList nsElem = compileNamespaces(classGen, methodGen,
isNamespace, isAttribute,
false, ihElem);
if (nsElem != null) elemNamespaceHandle = nsElem.getStart();
- // (*) Handle templates with "ns:@*" pattern
+ // Handle templates with "ns:@*" pattern
InstructionHandle attrNamespaceHandle = ihAttr;
InstructionList nsAttr = compileNamespaces(classGen, methodGen,
isNamespace, isAttribute,
true, ihAttr);
if (nsAttr != null) attrNamespaceHandle = nsAttr.getStart();
- // (*) Handle templates with "ns:elem" or "ns:@attr" pattern
+ // Handle templates with "ns:elem" or "ns:@attr" pattern
final InstructionHandle[] targets = new InstructionHandle[types.length];
for (int i = DOM.NTYPES; i < targets.length; i++) {
final TestSeq testSeq = _testSeq[i];
@@ -902,7 +955,7 @@
// Process all patterns from those templates
processPatterns(_keys);
- // (*) Create the applyTemplates() method
+ // Create the applyTemplates() method
final org.apache.bcel.generic.Type[] argTypes =
new org.apache.bcel.generic.Type[3];
argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
@@ -936,20 +989,20 @@
return;
}
- // (*) Create the local variablea
+ // Create the local variablea
final LocalVariableGen current;
current = methodGen.addLocalVariable2("current",
org.apache.bcel.generic.Type.INT,
mainIL.getEnd());
_currentIndex = current.getIndex();
- // (*) Create the "body" instruction list that will eventually hold the
- // code for the entire method (other ILs will be appended).
+ // Create the "body" instruction list that will eventually hold the
+ // code for the entire method (other ILs will be appended).
final InstructionList body = new InstructionList();
body.append(NOP);
- // (*) Create an instruction list that contains the default next-node
- // iteration
+ // Create an instruction list that contains the default next-node
+ // iteration
final InstructionList ilLoop = new InstructionList();
ilLoop.append(methodGen.loadIterator());
ilLoop.append(methodGen.nextNode());
@@ -965,7 +1018,9 @@
// Distinguish attribute/element/namespace tests for further processing
final int[] types = new int[DOM.NTYPES + names.size()];
- for (int i = 0; i < types.length; i++) types[i] = i;
+ for (int i = 0; i < types.length; i++) {
+ types[i] = i;
+ }
final boolean[] isAttribute = new boolean[types.length];
final boolean[] isNamespace = new boolean[types.length];
@@ -975,20 +1030,22 @@
isNamespace[i+DOM.NTYPES] = isNamespaceName(name);
}
- // (*) Compile all templates - regardless of pattern type
+ // Compile all templates - regardless of pattern type
compileTemplateCalls(classGen, methodGen, ihLoop, min, max);
- // (*) Handle template with explicit "*" pattern
+ // Handle template with explicit "*" pattern
final TestSeq elemTest = _testSeq[DOM.ELEMENT];
InstructionHandle ihElem = ihLoop;
- if (elemTest != null)
+ if (elemTest != null) {
ihElem = elemTest.compile(classGen, methodGen, ihLoop);
+ }
- // (*) Handle template with explicit "@*" pattern
+ // Handle template with explicit "@*" pattern
final TestSeq attrTest = _testSeq[DOM.ATTRIBUTE];
InstructionHandle ihAttr = ihLoop;
- if (attrTest != null)
+ if (attrTest != null) {
ihAttr = attrTest.compile(classGen, methodGen, ihAttr);
+ }
// Do tests for id() and key() patterns first
InstructionList ilKey = null;
@@ -1000,40 +1057,61 @@
loop.setTarget(body.getStart());
}
- // (*) If there is a match on node() we need to replace ihElem
- // and ihText (default behaviour for elements & text).
+ // If there is a match on node() we need to replace ihElem
+ // and ihText if the priority of node() is higher
InstructionHandle ihText = ihLoop;
if (_nodeTestSeq != null) {
- double nodePrio = -0.5; //_nodeTestSeq.getPriority();
+
+ // Compare priorities of node() and "*"
+ double nodePrio = -0.5; //_nodeTestSeq.getPriority();
int nodePos = _nodeTestSeq.getPosition();
double elemPrio = (0 - Double.MAX_VALUE);
int elemPos = Integer.MIN_VALUE;
+
if (elemTest != null) {
elemPrio = elemTest.getPriority();
elemPos = elemTest.getPosition();
}
- if ((elemPrio == Double.NaN) || (elemPrio < nodePrio) ||
- ((elemPrio == nodePrio) && (elemPos < nodePos))) {
+
+ if (elemPrio == Double.NaN || elemPrio < nodePrio ||
+ (elemPrio == nodePrio && elemPos < nodePos))
+ {
ihElem = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
- ihText = ihElem;
+ }
+
+ // Compare priorities of node() and text()
+ final TestSeq textTest = _testSeq[DOM.TEXT];
+ double textPrio = (0 - Double.MAX_VALUE);
+ int textPos = Integer.MIN_VALUE;
+
+ if (textTest != null) {
+ textPrio = textTest.getPriority();
+ textPos = textTest.getPosition();
+ }
+
+ if (textPrio == Double.NaN || textPrio < nodePrio ||
+ (textPrio == nodePrio && textPos < nodePos))
+ {
+ ihText = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
+ _testSeq[DOM.TEXT] = _nodeTestSeq;
}
}
- // (*) Handle templates with "ns:*" pattern
+ // Handle templates with "ns:*" pattern
InstructionHandle elemNamespaceHandle = ihElem;
InstructionList nsElem = compileNamespaces(classGen, methodGen,
isNamespace, isAttribute,
false, ihElem);
if (nsElem != null) elemNamespaceHandle = nsElem.getStart();
- // (*) Handle templates with "ns:@*" pattern
+ // Handle templates with "ns:@*" pattern
InstructionList nsAttr = compileNamespaces(classGen, methodGen,
isNamespace, isAttribute,
true, ihAttr);
InstructionHandle attrNamespaceHandle = ihAttr;
if (nsAttr != null) attrNamespaceHandle = nsAttr.getStart();
- // (*) Handle templates with "ns:elem" or "ns:@attr" pattern
+ // Handle templates with "ns:elem" or "ns:@attr" pattern
final InstructionHandle[] targets = new InstructionHandle[types.length];
for (int i = DOM.NTYPES; i < targets.length; i++) {
final TestSeq testSeq = _testSeq[i];
@@ -1080,12 +1158,14 @@
// Match on processing instruction - default: loop
InstructionHandle ihPI = ihLoop;
if (_nodeTestSeq != null) ihPI = ihElem;
- if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null)
+ if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null) {
targets[DOM.PROCESSING_INSTRUCTION] =
_testSeq[DOM.PROCESSING_INSTRUCTION].
compile(classGen, methodGen, ihPI);
- else
+ }
+ else {
targets[DOM.PROCESSING_INSTRUCTION] = ihPI;
+ }
// Match on comments - default: process next node
InstructionHandle ihComment = ihLoop;
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org