Package org.apache.xalan.templates
Class RedundentExprEliminator
java.lang.Object
org.apache.xpath.XPathVisitor
org.apache.xalan.templates.XSLTVisitor
org.apache.xalan.templates.RedundentExprEliminator
public class RedundentExprEliminator extends XSLTVisitor
This class eleminates redundent XPaths from a given subtree,
and also collects all absolute paths within the subtree. First
it must be called as a visitor to the subtree, and then
eleminateRedundent must be called.
-
Field Summary
Fields Modifier and Type Field Description static booleanDEBUGstatic booleanDIAGNOSE_MULTISTEPLISTstatic booleanDIAGNOSE_NUM_PATHS_REDUCED -
Constructor Summary
Constructors Constructor Description RedundentExprEliminator()Construct a RedundentExprEliminator. -
Method Summary
Modifier and Type Method Description protected ElemVariableaddVarDeclToElem(ElemTemplateElement psuedoVarRecipient, LocPathIterator lpi, ElemVariable psuedoVar)Add the given variable to the psuedoVarRecipient.protected static voidassertion(boolean b, String msg)Simple assertion.protected LocPathIteratorchangePartToRef(QName uniquePseudoVarName, WalkingIterator wi, int numSteps, boolean isGlobal)Change a given number of steps to a single variable reference.protected voidchangeToVarRef(QName varName, ExpressionOwner owner, Vector paths, ElemTemplateElement psuedoVarRecipient)Change the expression owned by the owner argument to a variable reference of the given name.protected intcountAncestors(ElemTemplateElement elem)Count the number of ancestors that a ElemTemplateElement has.protected intcountSteps(LocPathIterator lpi)Count the steps in a given location path.protected ElemVariablecreateGlobalPseudoVarDecl(QName uniquePseudoVarName, StylesheetRoot stylesheetRoot, LocPathIterator lpi)Create a psuedo variable reference that will represent the shared redundent XPath, for a local reduction.protected WalkingIteratorcreateIteratorFromSteps(WalkingIterator wi, int numSteps)Create a new WalkingIterator from the steps in another WalkingIterator.protected ElemVariablecreateLocalPseudoVarDecl(QName uniquePseudoVarName, ElemTemplateElement psuedoVarRecipient, LocPathIterator lpi)Create a psuedo variable reference that will represent the shared redundent XPath, for a local reduction.protected org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHoldercreateMultistepExprList(Vector paths)For the reduction of location path parts, create a list of all the multistep paths with more than one step, sorted by the number of steps, with the most steps occuring earlier in the list.protected ElemVariablecreatePseudoVarDecl(ElemTemplateElement psuedoVarRecipient, LocPathIterator lpi, boolean isGlobal)Create a psuedo variable reference that will represent the shared redundent XPath, and add it to the stylesheet.protected voiddiagnoseLineNumber(Expression expr)Tell what line number belongs to a given expression.protected voiddiagnoseMultistepList(int matchCount, int lengthToTest, boolean isGlobal)Print out diagnostics about partial multistep evaluation.protected voiddiagnoseNumPaths(Vector paths, int numPathsEliminated, int numUniquePathsEliminated)Print out to std err the number of paths reduced.protected voideleminateRedundent(ElemTemplateElement psuedoVarRecipient, Vector paths)Method to be called after the all expressions within an node context have been visited.voideleminateRedundentGlobals(StylesheetRoot stylesheet)Method to be called after the all global expressions within a stylesheet have been collected.voideleminateRedundentLocals(ElemTemplateElement psuedoVarRecipient)Method to be called after the all expressions within an node context have been visited.protected voideleminateSharedPartialPaths(ElemTemplateElement psuedoVarRecipient, Vector paths)Eliminate the shared partial paths in the expression list.protected intfindAndEliminateRedundant(int start, int firstOccuranceIndex, ExpressionOwner firstOccuranceOwner, ElemTemplateElement psuedoVarRecipient, Vector paths)Look through the vector from start point, looking for redundant occurances.protected ElemTemplateElementfindCommonAncestor(org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHolder head)Given a linked list of expressions, find the common ancestor that is suitable for holding a psuedo variable for shared access.protected ElemTemplateElementgetElemFromExpression(Expression expr)From an XPath expression component, get the ElemTemplateElement owner.protected ElemTemplateElementgetPrevElementWithinContext(ElemTemplateElement elem)Get the previous sibling or parent of the given template, stopping at xsl:for-each, xsl:template, or xsl:stylesheet.protected ElemVariablegetPrevVariableElem(ElemTemplateElement elem)Find the previous occurance of a xsl:variable.booleanisAbsolute(LocPathIterator path)Tell if the given LocPathIterator is relative to an absolute path, i.e.protected booleanisNotSameAsOwner(org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHolder head, ElemTemplateElement ete)Find out if the given ElemTemplateElement is not the same as one of the ElemTemplateElement owners of the expressions.protected booleanisParam(ExpressionNode expr)Tell if the expr param is contained within an xsl:param.protected org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHoldermatchAndEliminatePartialPaths(org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHolder testee, org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHolder head, boolean isGlobal, int lengthToTest, ElemTemplateElement varScope)For a given path, see if there are any partitial matches in the list, and, if there are, replace those partial paths with psuedo variable refs, and create the psuedo variable decl.protected intoldFindAndEliminateRedundant(int start, int firstOccuranceIndex, ExpressionOwner firstOccuranceOwner, ElemTemplateElement psuedoVarRecipient, Vector paths)To be removed.protected booleanstepsEqual(WalkingIterator iter1, WalkingIterator iter2, int numSteps)Compare a given number of steps between two iterators, to see if they are equal.booleanvisitInstruction(ElemTemplateElement elem)Visit an XSLT instruction.booleanvisitLocationPath(ExpressionOwner owner, LocPathIterator path)Visit a LocationPath.booleanvisitPredicate(ExpressionOwner owner, Expression pred)Visit a predicate within a location path.booleanvisitTopLevelInstruction(ElemTemplateElement elem)Visit an XSLT top-level instruction.Methods inherited from class org.apache.xalan.templates.XSLTVisitor
visitAVT, visitExtensionElement, visitLiteralResultElement, visitStylesheet, visitTopLevelVariableOrParamDecl, visitVariableOrParamDeclMethods inherited from class org.apache.xpath.XPathVisitor
visitBinaryOperation, visitFunction, visitMatchPattern, visitNumberLiteral, visitStep, visitStringLiteral, visitUnaryOperation, visitUnionPath, visitUnionPattern, visitVariableRef
-
Field Details
-
DEBUG
public static final boolean DEBUG- See Also:
- Constant Field Values
-
DIAGNOSE_NUM_PATHS_REDUCED
public static final boolean DIAGNOSE_NUM_PATHS_REDUCED- See Also:
- Constant Field Values
-
DIAGNOSE_MULTISTEPLIST
public static final boolean DIAGNOSE_MULTISTEPLIST- See Also:
- Constant Field Values
-
-
Constructor Details
-
RedundentExprEliminator
public RedundentExprEliminator()Construct a RedundentExprEliminator.
-
-
Method Details
-
eleminateRedundentLocals
Method to be called after the all expressions within an node context have been visited. It eliminates redundent expressions by creating a variable in the psuedoVarRecipient for each redundent expression, and then rewriting the redundent expression to be a variable reference.- Parameters:
psuedoVarRecipient- The recipient of the psuedo vars. The variables will be inserted as first children of the element, before any existing variables.
-
eleminateRedundentGlobals
Method to be called after the all global expressions within a stylesheet have been collected. It eliminates redundent expressions by creating a variable in the psuedoVarRecipient for each redundent expression, and then rewriting the redundent expression to be a variable reference. -
eleminateRedundent
Method to be called after the all expressions within an node context have been visited. It eliminates redundent expressions by creating a variable in the psuedoVarRecipient for each redundent expression, and then rewriting the redundent expression to be a variable reference.- Parameters:
psuedoVarRecipient- The owner of the subtree from where the paths were collected.paths- A vector of paths that hold ExpressionOwner objects, which must yield LocationPathIterators.
-
matchAndEliminatePartialPaths
protected org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHolder matchAndEliminatePartialPaths(org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHolder testee, org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHolder head, boolean isGlobal, int lengthToTest, ElemTemplateElement varScope)For a given path, see if there are any partitial matches in the list, and, if there are, replace those partial paths with psuedo variable refs, and create the psuedo variable decl.- Returns:
- The head of the list, which may have changed.
-
diagnoseLineNumber
Tell what line number belongs to a given expression. -
findCommonAncestor
protected ElemTemplateElement findCommonAncestor(org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHolder head)Given a linked list of expressions, find the common ancestor that is suitable for holding a psuedo variable for shared access. -
isNotSameAsOwner
protected boolean isNotSameAsOwner(org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHolder head, ElemTemplateElement ete)Find out if the given ElemTemplateElement is not the same as one of the ElemTemplateElement owners of the expressions.- Parameters:
head- Head of linked list of expression owners.ete- The ElemTemplateElement that is a candidate for a psuedo variable parent.- Returns:
- true if the given ElemTemplateElement is not the same as one of the ElemTemplateElement owners of the expressions. This is to make sure we find an ElemTemplateElement that is in a viable position to hold psuedo variables that are visible to the references.
-
countAncestors
Count the number of ancestors that a ElemTemplateElement has.- Parameters:
elem- An representation of an element in an XSLT stylesheet.- Returns:
- The number of ancestors of elem (including the element itself).
-
diagnoseMultistepList
protected void diagnoseMultistepList(int matchCount, int lengthToTest, boolean isGlobal)Print out diagnostics about partial multistep evaluation. -
changePartToRef
protected LocPathIterator changePartToRef(QName uniquePseudoVarName, WalkingIterator wi, int numSteps, boolean isGlobal)Change a given number of steps to a single variable reference.- Parameters:
uniquePseudoVarName- The name of the variable reference.wi- The walking iterator that is to be changed.numSteps- The number of steps to be changed.isGlobal- true if this will be a global reference.
-
createIteratorFromSteps
Create a new WalkingIterator from the steps in another WalkingIterator.- Parameters:
wi- The iterator from where the steps will be taken.numSteps- The number of steps from the first to copy into the new iterator.- Returns:
- The new iterator.
-
stepsEqual
Compare a given number of steps between two iterators, to see if they are equal.- Parameters:
iter1- The first iterator to compare.iter2- The second iterator to compare.numSteps- The number of steps to compare.- Returns:
- true If the given number of steps are equal.
-
createMultistepExprList
protected org.apache.xalan.templates.RedundentExprEliminator.MultistepExprHolder createMultistepExprList(Vector paths)For the reduction of location path parts, create a list of all the multistep paths with more than one step, sorted by the number of steps, with the most steps occuring earlier in the list. If the list is only one member, don't bother returning it.- Parameters:
paths- Vector of ExpressionOwner objects, which may contain null entries. The ExpressionOwner objects must own LocPathIterator objects.- Returns:
- null if no multipart paths are found or the list is only of length 1, otherwise the first MultistepExprHolder in a linked list of these objects.
-
findAndEliminateRedundant
protected int findAndEliminateRedundant(int start, int firstOccuranceIndex, ExpressionOwner firstOccuranceOwner, ElemTemplateElement psuedoVarRecipient, Vector paths) throws DOMExceptionLook through the vector from start point, looking for redundant occurances. When one or more are found, create a psuedo variable declaration, insert it into the stylesheet, and replace the occurance with a reference to the psuedo variable. When a redundent variable is found, it's slot in the vector will be replaced by null.- Parameters:
start- The position to start looking in the vector.firstOccuranceIndex- The position of firstOccuranceOwner.firstOccuranceOwner- The owner of the expression we are looking for.psuedoVarRecipient- Where to put the psuedo variables.- Returns:
- The number of expression occurances that were modified.
- Throws:
DOMException
-
oldFindAndEliminateRedundant
protected int oldFindAndEliminateRedundant(int start, int firstOccuranceIndex, ExpressionOwner firstOccuranceOwner, ElemTemplateElement psuedoVarRecipient, Vector paths) throws DOMExceptionTo be removed.- Throws:
DOMException
-
countSteps
Count the steps in a given location path.- Parameters:
lpi- The location path iterator that owns the steps.- Returns:
- The number of steps in the given location path.
-
changeToVarRef
protected void changeToVarRef(QName varName, ExpressionOwner owner, Vector paths, ElemTemplateElement psuedoVarRecipient)Change the expression owned by the owner argument to a variable reference of the given name. Warning: For global vars, this function relies on the variable declaration to which it refers having been added just prior to this function being called, so that the reference index can be determined from the size of the global variables list minus one.- Parameters:
varName- The name of the variable which will be referenced.owner- The owner of the expression which will be replaced by a variable ref.paths- The paths list that the iterator came from, mainly to determine if this is a local or global reduction.psuedoVarRecipient- The element within whose scope the variable is being inserted, possibly a StylesheetRoot.
-
createPseudoVarDecl
protected ElemVariable createPseudoVarDecl(ElemTemplateElement psuedoVarRecipient, LocPathIterator lpi, boolean isGlobal) throws DOMExceptionCreate a psuedo variable reference that will represent the shared redundent XPath, and add it to the stylesheet.- Parameters:
psuedoVarRecipient- The broadest scope of where the variable should be inserted, usually an xsl:template or xsl:for-each.lpi- The LocationPathIterator that the variable should represent.isGlobal- true if the paths are global.- Returns:
- The new psuedo var element.
- Throws:
DOMException
-
createGlobalPseudoVarDecl
protected ElemVariable createGlobalPseudoVarDecl(QName uniquePseudoVarName, StylesheetRoot stylesheetRoot, LocPathIterator lpi) throws DOMExceptionCreate a psuedo variable reference that will represent the shared redundent XPath, for a local reduction.- Parameters:
uniquePseudoVarName- The name of the new variable.stylesheetRoot- The broadest scope of where the variable should be inserted, which must be a StylesheetRoot element in this case.lpi- The LocationPathIterator that the variable should represent.- Returns:
- null if the decl was not created, otherwise the new Pseudo var element.
- Throws:
DOMException
-
createLocalPseudoVarDecl
protected ElemVariable createLocalPseudoVarDecl(QName uniquePseudoVarName, ElemTemplateElement psuedoVarRecipient, LocPathIterator lpi) throws DOMExceptionCreate a psuedo variable reference that will represent the shared redundent XPath, for a local reduction.- Parameters:
uniquePseudoVarName- The name of the new variable.psuedoVarRecipient- The broadest scope of where the variable should be inserted, usually an xsl:template or xsl:for-each.lpi- The LocationPathIterator that the variable should represent.- Returns:
- null if the decl was not created, otherwise the new Pseudo var element.
- Throws:
DOMException
-
addVarDeclToElem
protected ElemVariable addVarDeclToElem(ElemTemplateElement psuedoVarRecipient, LocPathIterator lpi, ElemVariable psuedoVar) throws DOMExceptionAdd the given variable to the psuedoVarRecipient.- Throws:
DOMException
-
isParam
Tell if the expr param is contained within an xsl:param. -
getPrevVariableElem
Find the previous occurance of a xsl:variable. Stop the search when a xsl:for-each, xsl:template, or xsl:stylesheet is encountered.- Parameters:
elem- Should be non-null template element.- Returns:
- The first previous occurance of an xsl:variable or xsl:param, or null if none is found.
-
getPrevElementWithinContext
Get the previous sibling or parent of the given template, stopping at xsl:for-each, xsl:template, or xsl:stylesheet.- Parameters:
elem- Should be non-null template element.- Returns:
- previous sibling or parent, or null if previous is xsl:for-each, xsl:template, or xsl:stylesheet.
-
getElemFromExpression
From an XPath expression component, get the ElemTemplateElement owner.- Parameters:
expr- Should be static expression with proper parentage.- Returns:
- Valid ElemTemplateElement, or throw a runtime exception if it is not found.
-
isAbsolute
Tell if the given LocPathIterator is relative to an absolute path, i.e. in not dependent on the context.- Returns:
- true if the LocPathIterator is not dependent on the context node.
-
visitLocationPath
Visit a LocationPath.- Overrides:
visitLocationPathin classXPathVisitor- Parameters:
owner- The owner of the expression, to which the expression can be reset if rewriting takes place.path- The LocationPath object.- Returns:
- true if the sub expressions should be traversed.
-
visitPredicate
Visit a predicate within a location path. Note that there isn't a proper unique component for predicates, and that the expression will be called also for whatever type Expression is.- Overrides:
visitPredicatein classXPathVisitor- Parameters:
owner- The owner of the expression, to which the expression can be reset if rewriting takes place.pred- The predicate object.- Returns:
- true if the sub expressions should be traversed.
-
visitTopLevelInstruction
Visit an XSLT top-level instruction.- Overrides:
visitTopLevelInstructionin classXSLTVisitor- Parameters:
elem- The xsl instruction element object.- Returns:
- true if the sub expressions should be traversed.
-
visitInstruction
Visit an XSLT instruction. Any element that isn't called by one of the other visit methods, will be called by this method.- Overrides:
visitInstructionin classXSLTVisitor- Parameters:
elem- The xsl instruction element object.- Returns:
- true if the sub expressions should be traversed.
-
diagnoseNumPaths
protected void diagnoseNumPaths(Vector paths, int numPathsEliminated, int numUniquePathsEliminated)Print out to std err the number of paths reduced. -
assertion
Simple assertion.
-