📄 mode.java
字号:
/* * Copyright 2001-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: Mode.java,v 1.2.4.1 2005/09/19 05:18:11 pvedula Exp $ */package com.sun.org.apache.xalan.internal.xsltc.compiler;import java.util.Enumeration;import java.util.Hashtable;import java.util.Iterator;import java.util.Vector;import com.sun.org.apache.bcel.internal.generic.Instruction;import com.sun.org.apache.bcel.internal.generic.BranchHandle;import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;import com.sun.org.apache.bcel.internal.generic.DUP;import com.sun.org.apache.bcel.internal.generic.GOTO_W;import com.sun.org.apache.bcel.internal.generic.IFLT;import com.sun.org.apache.bcel.internal.generic.ILOAD;import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;import com.sun.org.apache.bcel.internal.generic.ISTORE;import com.sun.org.apache.bcel.internal.generic.InstructionHandle;import com.sun.org.apache.bcel.internal.generic.InstructionList;import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;import com.sun.org.apache.bcel.internal.generic.SWITCH;import com.sun.org.apache.bcel.internal.generic.TargetLostException;import com.sun.org.apache.bcel.internal.util.InstructionFinder;import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NamedMethodGenerator;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;import com.sun.org.apache.xml.internal.dtm.Axis;import com.sun.org.apache.xml.internal.dtm.DTM;/** * Mode gathers all the templates belonging to a given mode; * it is responsible for generating an appropriate * applyTemplates + (mode name) method in the translet. * @author Jacek Ambroziak * @author Santiago Pericas-Geertsen * @author Morten Jorgensen * @author Erwin Bolwidt <ejb@klomp.org> * @author G. Todd Miller */final class Mode implements Constants { /** * 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 and child axis. */ private Vector _childNodeGroup = null; /** * Test sequence for patterns with node()-type kernel and child axis. */ private TestSeq _childNodeTestSeq = null; /** * Group for patterns with node()-type kernel and attribute axis. */ private Vector _attribNodeGroup = null; /** * Test sequence for patterns with node()-type kernel and attribute axis. */ private TestSeq _attribNodeTestSeq = null; /** * Group for patterns with id() or key()-type kernel. */ private Vector _idxGroup = null; /** * 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; /** * A mapping between templates and test sequences. */ private Hashtable _neededTemplates = new Hashtable(); /** * A mapping between named templates and Mode objects. */ private Hashtable _namedTemplates = new Hashtable(); /** * A mapping between templates and instruction handles. */ private Hashtable _templateIHs = new Hashtable(); /** * A mapping between templates and instruction lists. */ private Hashtable _templateILs = new Hashtable(); /** * A reference to the pattern matching the root node. */ private LocationPathPattern _rootPattern = null; /** * Stores ranges of template precendences for the compilation * of apply-imports (a Hashtable for historical reasons). */ private Hashtable _importLevels = null; /** * A mapping between key names and keys. */ private Hashtable _keys = null; /** * Variable index for the current node used in code generation. */ private int _currentIndex; /** * 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 * (normally a sequence number - still in a String). */ public Mode(QName name, Stylesheet stylesheet, String suffix) { _name = name; _stylesheet = stylesheet; _methodName = APPLY_TEMPLATES + suffix; _templates = new Vector(); _patternGroups = new Vector[32]; } /** * Returns the name of the method (_not_ function) that will be * compiled for this mode. Normally takes the form 'applyTemplates()' * or * 'applyTemplates2()'. * * @return Method name for this mode */ public String functionName() { return _methodName; } public String functionName(int min, int max) { if (_importLevels == null) { _importLevels = new Hashtable(); } _importLevels.put(new Integer(max), new Integer(min)); return _methodName + '_' + max; } /** * Shortcut to get the class compiled for this mode (will be inlined). */ private String getClassName() { return _stylesheet.getClassName(); } public Stylesheet getStylesheet() { return _stylesheet; } public void addTemplate(Template template) { _templates.addElement(template); } private Vector quicksort(Vector templates, int p, int r) { if (p < r) { final int q = partition(templates, p, r); quicksort(templates, p, q); quicksort(templates, q + 1, r); } return templates; } private int partition(Vector templates, int p, int r) { final Template x = (Template)templates.elementAt(p); int i = p - 1; int j = r + 1; while (true) { while (x.compareTo((Template)templates.elementAt(--j)) > 0); while (x.compareTo((Template)templates.elementAt(++i)) < 0); if (i < j) { templates.set(j, templates.set(i, templates.elementAt(j))); } else { return j; } } } /** * Process all the test patterns in this mode */ public void processPatterns(Hashtable keys) { _keys = keys;/*System.out.println("Before Sort " + _name);for (int i = 0; i < _templates.size(); i++) { System.out.println("name = " + ((Template)_templates.elementAt(i)).getName()); System.out.println("pattern = " + ((Template)_templates.elementAt(i)).getPattern()); System.out.println("priority = " + ((Template)_templates.elementAt(i)).getPriority()); System.out.println("position = " + ((Template)_templates.elementAt(i)).getPosition());}*/ _templates = quicksort(_templates, 0, _templates.size() - 1);/*System.out.println("\n After Sort " + _name);for (int i = 0; i < _templates.size(); i++) { System.out.println("name = " + ((Template)_templates.elementAt(i)).getName()); System.out.println("pattern = " + ((Template)_templates.elementAt(i)).getPattern()); System.out.println("priority = " + ((Template)_templates.elementAt(i)).getPriority()); System.out.println("position = " + ((Template)_templates.elementAt(i)).getPosition());}*/ // Traverse all templates final Enumeration templates = _templates.elements(); while (templates.hasMoreElements()) { // 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()) { _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); } } prepareTestSequences(); } /** * This method will break up alternative patterns (ie. unions of patterns, * such as match="A/B | C/B") and add the basic patterns to their * respective pattern groups. */ private void flattenAlternative(Pattern pattern, Template template, Hashtable keys) { // Patterns on type id() and key() are special since they do not have // any kernel node type (it can be anything as long as the node is in // the id's or key's index). if (pattern instanceof IdKeyPattern) { final IdKeyPattern idkey = (IdKeyPattern)pattern; idkey.setTemplate(template); if (_idxGroup == null) _idxGroup = new Vector(); _idxGroup.add(pattern); } // Alternative patterns are broken up and re-processed recursively else if (pattern instanceof AlternativePattern) { final AlternativePattern alt = (AlternativePattern)pattern; flattenAlternative(alt.getLeft(), template, keys); flattenAlternative(alt.getRight(), template, keys); } // Finally we have a pattern that can be added to a test sequence! else if (pattern instanceof LocationPathPattern) { final LocationPathPattern lpp = (LocationPathPattern)pattern; lpp.setTemplate(template); addPatternToGroup(lpp); } } /** * Group patterns by NodeTests of their last Step * Keep them sorted by priority within group */ private void addPatternToGroup(final LocationPathPattern lpp) { // id() and key()-type patterns do not have a kernel type if (lpp instanceof IdKeyPattern) { addPattern(-1, lpp); } // Otherwise get the kernel pattern from the LPP else { // kernel pattern is the last (maybe only) Step final StepPattern kernel = lpp.getKernelPattern(); if (kernel != null) { addPattern(kernel.getNodeType(), lpp); } else if (_rootPattern == null || lpp.noSmallerThan(_rootPattern)) { _rootPattern = lpp; } } } /** * Adds a pattern to a pattern group */ private void addPattern(int kernelType, LocationPathPattern pattern) { // Make sure the array of pattern groups is long enough final int oldLength = _patternGroups.length; if (kernelType >= oldLength) { Vector[] newGroups = new Vector[kernelType * 2]; System.arraycopy(_patternGroups, 0, newGroups, 0, oldLength); _patternGroups = newGroups; } // Find the vector to put this pattern into Vector patterns; if (kernelType == DOM.NO_TYPE) { if (pattern.getAxis() == Axis.ATTRIBUTE) { patterns = (_attribNodeGroup == null) ? (_attribNodeGroup = new Vector(2)) : _attribNodeGroup; } else { patterns = (_childNodeGroup == null) ? (_childNodeGroup = new Vector(2)) : _childNodeGroup; } } else { patterns = (_patternGroups[kernelType] == null) ? (_patternGroups[kernelType] = new Vector(2)) : _patternGroups[kernelType]; } if (patterns.size() == 0) { patterns.addElement(pattern); } else { boolean inserted = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -