morten 01/10/26 01:07:01 Modified: java/src/org/apache/xalan/xsltc/compiler ApplyImports.java Mode.java Stylesheet.java Log: A fix for setting the scope of templates for an <xsl:apply-imports/> element. This fix allows for proper "multiple inheritance" in XSLTC. PR: bugzilla 1397 Obtained from: n/a Submitted by: [EMAIL PROTECTED] Reviewed by: [EMAIL PROTECTED] Revision Changes Path 1.8 +44 -8 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ApplyImports.java Index: ApplyImports.java =================================================================== RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ApplyImports.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- ApplyImports.java 2001/10/25 10:23:32 1.7 +++ ApplyImports.java 2001/10/26 08:07:01 1.8 @@ -1,5 +1,5 @@ /* - * @(#)$Id: ApplyImports.java,v 1.7 2001/10/25 10:23:32 morten Exp $ + * @(#)$Id: ApplyImports.java,v 1.8 2001/10/26 08:07:01 morten Exp $ * * The Apache Software License, Version 1.1 * @@ -56,8 +56,7 @@ * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * - * @author Jacek Ambroziak - * @author Santiago Pericas-Geertsen + * @author Morten Jorgensen * */ @@ -66,10 +65,6 @@ import java.util.Vector; import java.util.Enumeration; -import javax.xml.parsers.*; - -import org.xml.sax.*; - import org.apache.xalan.xsltc.compiler.util.Type; import org.apache.xalan.xsltc.compiler.util.ReferenceType; import de.fub.bytecode.generic.*; @@ -100,6 +95,41 @@ } /** + * Determine the lowest import precedence for any stylesheet imported + * or included by the stylesheet in which this <xsl:apply-imports/> + * element occured. The templates that are imported by the stylesheet in + * which this element occured will all have higher import precedence than + * the integer returned by this method. + */ + private int getMinPrecedence(int max) { + Stylesheet stylesheet = getStylesheet(); + Stylesheet root = getParser().getTopLevelStylesheet(); + + int min = max; + + Enumeration templates = root.getContents().elements(); + while (templates.hasMoreElements()) { + SyntaxTreeNode child = (SyntaxTreeNode)templates.nextElement(); + if (child instanceof Template) { + Stylesheet curr = child.getStylesheet(); + while ((curr != null) && (curr != stylesheet)) { + if (curr._importedFrom != null) + curr = curr._importedFrom; + else if (curr._includedFrom != null) + curr = curr._includedFrom; + else + curr = null; + } + if (curr == stylesheet) { + int prec = child.getStylesheet().getImportPrecedence(); + if (prec < min) min = prec; + } + } + } + return (min); + } + + /** * Parse the attributes and contents of an <xsl:apply-imports/> element. */ public void parseContents(Parser parser) { @@ -115,7 +145,13 @@ // Get the method name for <xsl:apply-imports/> in this mode stylesheet = parser.getTopLevelStylesheet(); - _functionName = stylesheet.getMode(_modeName).functionName(_precedence); + + // Get the [min,max> precedence of all templates imported under the + // current stylesheet + final int maxPrecedence = _precedence; + final int minPrecedence = getMinPrecedence(maxPrecedence); + final Mode mode = stylesheet.getMode(_modeName); + _functionName = mode.functionName(minPrecedence, maxPrecedence); parseChildren(parser); // with-params } 1.14 +40 -16 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.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- Mode.java 2001/10/23 19:28:07 1.13 +++ Mode.java 2001/10/26 08:07:01 1.14 @@ -1,5 +1,5 @@ /* - * @(#)$Id: Mode.java,v 1.13 2001/10/23 19:28:07 morten Exp $ + * @(#)$Id: Mode.java,v 1.14 2001/10/26 08:07:01 morten Exp $ * * The Apache Software License, Version 1.1 * @@ -104,7 +104,7 @@ private Hashtable _templateILs = new Hashtable(); private LocationPathPattern _rootPattern = null; - private HashSet _importLevels = null; + private Hashtable _importLevels = null; private Hashtable _keys = null; @@ -139,10 +139,10 @@ return _methodName; } - public String functionName(int precedence) { - if (_importLevels == null) _importLevels = new HashSet(); - _importLevels.add(new Integer(precedence)); - return _methodName+'_'+precedence; + public String functionName(int min, int max) { + if (_importLevels == null) _importLevels = new Hashtable(); + _importLevels.put(new Integer(max), new Integer(min)); + return _methodName+'_'+max; } /** @@ -813,21 +813,23 @@ // Compile method(s) for <xsl:apply-imports/> for this mode if (_importLevels != null) { - Iterator levels = _importLevels.iterator(); - while (levels.hasNext()) { - Integer level = (Integer)levels.next(); - compileApplyImports(classGen, level.intValue()); + Enumeration levels = _importLevels.keys(); + while (levels.hasMoreElements()) { + Integer max = (Integer)levels.nextElement(); + Integer min = (Integer)_importLevels.get(max); + compileApplyImports(classGen, min.intValue(), max.intValue()); } } } private void compileTemplateCalls(ClassGenerator classGen, MethodGenerator methodGen, - InstructionHandle next, int level) { + InstructionHandle next, int min, int max){ Enumeration templates = _neededTemplates.keys(); while (templates.hasMoreElements()) { final Template template = (Template)templates.nextElement(); - if (template.getImportPrecedence() < level) { + final int prec = template.getImportPrecedence(); + if ((prec >= min) && (prec < max)) { if (template.hasContents()) { InstructionList til = template.compile(classGen, methodGen); til.append(new GOTO_W(next)); @@ -843,7 +845,7 @@ } - public void compileApplyImports(ClassGenerator classGen, int level) { + public void compileApplyImports(ClassGenerator classGen, int min, int max) { final XSLTC xsltc = classGen.getParser().getXSLTC(); final ConstantPoolGen cpg = classGen.getConstantPool(); final Vector names = xsltc.getNamesIndex(); @@ -856,13 +858,19 @@ _patternGroups = new Vector[32]; _rootPattern = null; + // IMPORTANT: Save orignal & complete set of templates!!!! Vector oldTemplates = _templates; + + // Gather templates that are within the scope of this import _templates = new Vector(); final Enumeration templates = oldTemplates.elements(); while (templates.hasMoreElements()) { final Template template = (Template)templates.nextElement(); - if (template.getImportPrecedence() < level) addTemplate(template); + final int prec = template.getImportPrecedence(); + if ((prec >= min) && (prec < max)) addTemplate(template); } + + // Process all patterns from those templates processPatterns(_keys); // (*) Create the applyTemplates() method @@ -881,11 +889,24 @@ final MethodGenerator methodGen = new MethodGenerator(ACC_PUBLIC | ACC_FINAL, de.fub.bytecode.generic.Type.VOID, - argTypes, argNames, functionName()+'_'+level, + argTypes, argNames, functionName()+'_'+max, getClassName(), mainIL, classGen.getConstantPool()); methodGen.addException("org.apache.xalan.xsltc.TransletException"); + // No templates? Then just stuff in a single 'return' instruction + if (_neededTemplates.size() == 0) { + mainIL.append(new RETURN()); + methodGen.stripAttributes(true); + methodGen.setMaxLocals(); + methodGen.setMaxStack(); + methodGen.removeNOPs(); + classGen.addMethod(methodGen.getMethod()); + // Restore original/complete set of templates for the transformation + _templates = oldTemplates; + return; + } + // (*) Create the local variablea final LocalVariableGen current; current = methodGen.addLocalVariable2("current", @@ -936,7 +957,7 @@ } // (*) Compile all templates - regardless of pattern type - compileTemplateCalls(classGen, methodGen, ihLoop, level); + compileTemplateCalls(classGen, methodGen, ihLoop, min, max); // (*) Handle template with explicit "*" pattern final TestSeq elemTest = _testSeq[DOM.ELEMENT]; @@ -1114,6 +1135,9 @@ methodGen.setMaxStack(); methodGen.removeNOPs(); classGen.addMethod(methodGen.getMethod()); + + // Restore original (complete) set of templates for this transformation + _templates = oldTemplates; } /** 1.26 +2 -2 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java Index: Stylesheet.java =================================================================== RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- Stylesheet.java 2001/10/25 15:48:11 1.25 +++ Stylesheet.java 2001/10/26 08:07:01 1.26 @@ -1,5 +1,5 @@ /* - * @(#)$Id: Stylesheet.java,v 1.25 2001/10/25 15:48:11 morten Exp $ + * @(#)$Id: Stylesheet.java,v 1.26 2001/10/26 08:07:01 morten Exp $ * * The Apache Software License, Version 1.1 * @@ -103,7 +103,7 @@ // The name of the class being generated. private String _className; - // Contains all templates dedined in this stylesheet + // Contains all templates defined in this stylesheet private final Vector _templates = new Vector(); private int _nextModeSerial = 1;
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]