redundentexpreliminator.java

来自「java jdk 1.4的源码」· Java 代码 · 共 1,474 行 · 第 1/4 页

JAVA
1,474
字号
			Expression expr2 = owner2.getExpression();			boolean isEqual = expr2.deepEquals(lpi);			if(isEqual)			{  						LocPathIterator lpi2  = (LocPathIterator)expr2;								if(!foundFirst)				{					foundFirst = true;					// Insert variable decl into psuedoVarRecipient					// We want to insert this into the first legitimate 					// position for a variable.				    ElemVariable var = createPsuedoVarDecl(psuedoVarRecipient, lpi, isGlobal);				    if(null == var)				    	return 0;				    uniquePsuedoVarName = var.getName();						changeToVarRef(uniquePsuedoVarName, firstOccuranceOwner, 					               paths, psuedoVarRecipient);					               					// Replace the first occurance with the variable's XPath, so  					// that further reduction may take place if needed.					paths.setElementAt(var.getSelect(), firstOccuranceIndex);					numPathsFound++;				}					changeToVarRef(uniquePsuedoVarName, owner2, paths, psuedoVarRecipient);					// Null out the occurance, so we don't have to test it again.				paths.setElementAt(null, j);								// foundFirst = true;				numPathsFound++;			}		}	}		// Change all globals in xsl:templates, etc, to global vars no matter what.	if((0 == numPathsFound) && (paths == m_absPaths))	{      ElemVariable var = createPsuedoVarDecl(psuedoVarRecipient, lpi, true);      if(null == var)        return 0;	  uniquePsuedoVarName = var.getName();      changeToVarRef(uniquePsuedoVarName, firstOccuranceOwner, paths, psuedoVarRecipient);      paths.setElementAt(var.getSelect(), firstOccuranceIndex);      numPathsFound++;	}	return numPathsFound;  }    /**   * Count the steps in a given location path.   *    * @param lpi The location path iterator that owns the steps.   * @return The number of steps in the given location path.   */  protected int countSteps(LocPathIterator lpi)  {  	if(lpi instanceof WalkingIterator)  	{  		WalkingIterator wi = (WalkingIterator)lpi;  		AxesWalker aw = wi.getFirstWalker();  		int count = 0;  		while(null != aw)  		{  			count++;  			aw = aw.getNextWalker();  		}  		return count;  	}  	else  		return 1;  }    /**   * 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.   *    * @param varName The name of the variable which will be referenced.   * @param owner The owner of the expression which will be replaced by a variable ref.   * @param paths The paths list that the iterator came from, mainly to determine   *              if this is a local or global reduction.   * @param psuedoVarRecipient The element within whose scope the variable is    *                           being inserted, possibly a StylesheetRoot.   */  protected void changeToVarRef(QName varName, ExpressionOwner owner,                                 Vector paths, ElemTemplateElement psuedoVarRecipient)   {	Variable varRef = (paths == m_absPaths) ? new VariableSafeAbsRef() : new Variable();	varRef.setQName(varName);	if(paths == m_absPaths)	{		StylesheetRoot root = (StylesheetRoot)psuedoVarRecipient;		Vector globalVars = root.getVariablesAndParamsComposed();		// Assume this operation is occuring just after the decl has 		// been added.		varRef.setIndex(globalVars.size()-1);		varRef.setIsGlobal(true);	}	owner.setExpression(varRef);  }  /**   * Create a psuedo variable reference that will represent the    * shared redundent XPath, and add it to the stylesheet.   *    * @param psuedoVarRecipient The broadest scope of where the variable    * should be inserted, usually an xsl:template or xsl:for-each.   * @param lpi The LocationPathIterator that the variable should represent.   * @param isGlobal true if the paths are global.   * @return The new psuedo var element.   */  protected ElemVariable createPsuedoVarDecl(      ElemTemplateElement psuedoVarRecipient,      LocPathIterator lpi, boolean isGlobal)      throws org.w3c.dom.DOMException  {    QName uniquePsuedoVarName = new QName (PSUEDOVARNAMESPACE, "#"+m_uniquePsuedoVarID);    m_uniquePsuedoVarID++;  		  	if(isGlobal)  	{  	  return createGlobalPsuedoVarDecl(uniquePsuedoVarName,   	                                  (StylesheetRoot)psuedoVarRecipient, lpi);  	}  	else						      return createLocalPsuedoVarDecl(uniquePsuedoVarName, psuedoVarRecipient, lpi);  }    /**   * Create a psuedo variable reference that will represent the    * shared redundent XPath, for a local reduction.   *    * @param uniquePsuedoVarName The name of the new variable.   * @param stylesheetRoot The broadest scope of where the variable    *        should be inserted, which must be a StylesheetRoot element in this case.   * @param lpi The LocationPathIterator that the variable should represent.   * @return null if the decl was not created, otherwise the new Psuedo var     *              element.   */  protected ElemVariable createGlobalPsuedoVarDecl(QName uniquePsuedoVarName,                                           StylesheetRoot stylesheetRoot,                                            LocPathIterator lpi)         throws org.w3c.dom.DOMException   {  	ElemVariable psuedoVar = new ElemVariable();  	psuedoVar.setIsTopLevel(true);	XPath xpath = new XPath(lpi);	psuedoVar.setSelect(xpath);	psuedoVar.setName(uniquePsuedoVarName);		Vector globalVars = stylesheetRoot.getVariablesAndParamsComposed();	psuedoVar.setIndex(globalVars.size());	globalVars.addElement(psuedoVar);	return psuedoVar;  }      /**   * Create a psuedo variable reference that will represent the    * shared redundent XPath, for a local reduction.   *    * @param uniquePsuedoVarName The name of the new variable.   * @param psuedoVarRecipient The broadest scope of where the variable    * should be inserted, usually an xsl:template or xsl:for-each.   * @param lpi The LocationPathIterator that the variable should represent.   * @param addToContext true if the decl should be added to psuedoVarRecipient.   * @return null if the decl was not created, otherwise the new Psuedo var     *              element.   */  protected ElemVariable createLocalPsuedoVarDecl(QName uniquePsuedoVarName,                                           ElemTemplateElement psuedoVarRecipient,                                            LocPathIterator lpi)         throws org.w3c.dom.DOMException   {		ElemVariable psuedoVar = new ElemVariablePsuedo();				XPath xpath = new XPath(lpi);		psuedoVar.setSelect(xpath);		psuedoVar.setName(uniquePsuedoVarName);		ElemVariable var = addVarDeclToElem(psuedoVarRecipient, lpi, psuedoVar);				lpi.exprSetParent(var);				return var;  }  /**   * Add the given variable to the psuedoVarRecipient.   */  protected ElemVariable addVarDeclToElem(    ElemTemplateElement psuedoVarRecipient,    LocPathIterator lpi,    ElemVariable psuedoVar)    throws org.w3c.dom.DOMException  {    // Create psuedo variable element    ElemTemplateElement ete = psuedoVarRecipient.getFirstChildElem();    lpi.callVisitors(null, m_varNameCollector);    // If the location path contains variables, we have to insert the     // psuedo variable after the reference. (Otherwise, we want to     // insert it as close as possible to the top, so we'll be sure     // it is in scope for any other vars.    if (m_varNameCollector.getVarCount() > 0)    {      ElemTemplateElement baseElem = getElemFromExpression(lpi);      ElemVariable varElem = getPrevVariableElem(baseElem);      while (null != varElem)      {        if (m_varNameCollector.doesOccur(varElem.getName()))          {          psuedoVarRecipient = varElem.getParentElem();          ete = varElem.getNextSiblingElem();          break;        }        varElem = getPrevVariableElem(varElem);      }    }    if ((null != ete) && (Constants.ELEMNAME_PARAMVARIABLE == ete.getXSLToken()))    {      // Can't stick something in front of a param, so abandon! (see variable13.xsl)      if(isParam(lpi))        return null;      while (null != ete)      {        ete = ete.getNextSiblingElem();        if ((null != ete) && Constants.ELEMNAME_PARAMVARIABLE != ete.getXSLToken())            break;      }    }    psuedoVarRecipient.insertBefore(psuedoVar, ete);    m_varNameCollector.reset();    return psuedoVar;  }      /**   * Tell if the expr param is contained within an xsl:param.   */  protected boolean isParam(ExpressionNode expr)  {  	while(null != expr)  	{  		if(expr instanceof ElemTemplateElement)  			break;  		expr = expr.exprGetParent();  	}  	if(null != expr)  	{  		ElemTemplateElement ete = (ElemTemplateElement)expr;  		while(null != ete)  		{  			int type = ete.getXSLToken();  			switch(type)  			{  				case Constants.ELEMNAME_PARAMVARIABLE:  					return true;  				case Constants.ELEMNAME_TEMPLATE:  				case Constants.ELEMNAME_STYLESHEET:  					return false;  			}  			ete = ete.getParentElem();  		}  	}  	return false;  	  }    /**   * Find the previous occurance of a xsl:variable.  Stop    * the search when a xsl:for-each, xsl:template, or xsl:stylesheet is    * encountered.   *    * @param elem Should be non-null template element.   * @return The first previous occurance of an xsl:variable or xsl:param,    * or null if none is found.   */  protected ElemVariable getPrevVariableElem(ElemTemplateElement elem)  {  	// This could be somewhat optimized.  since getPreviousSiblingElem is a    	// fairly expensive operation.  	while(null != (elem = getPrevElementWithinContext(elem)))  	{  		int type = elem.getXSLToken();  			  		if((Constants.ELEMNAME_VARIABLE == type) ||  		   (Constants.ELEMNAME_PARAMVARIABLE == type))  		{  			return (ElemVariable)elem;  		}  	}  	return null;  }    /**   * Get the previous sibling or parent of the given template, stopping at    * xsl:for-each, xsl:template, or xsl:stylesheet.   *    * @param elem Should be non-null template element.   * @return previous sibling or parent, or null if previous is xsl:for-each,    * xsl:template, or xsl:stylesheet.   */  protected ElemTemplateElement getPrevElementWithinContext(ElemTemplateElement elem)  {  	ElemTemplateElement prev = elem.getPreviousSiblingElem();  	if(null == prev)  		prev = elem.getParentElem();  	if(null != prev)  	{  	  int type = prev.getXSLToken();  	  if((Constants.ELEMNAME_FOREACH == type) ||   	     (Constants.ELEMNAME_TEMPLATE == type) ||  	     (Constants.ELEMNAME_STYLESHEET == type))  	  {  	  	prev = null;  	  }  	}  	return prev;  }    /**   * From an XPath expression component, get the ElemTemplateElement    * owner.   *    * @param expr Should be static expression with proper parentage.   * @return Valid ElemTemplateElement, or throw a runtime exception    * if it is not found.   */  protected ElemTemplateElement getElemFromExpression(Expression expr)  {  	ExpressionNode parent = expr.exprGetParent();  	while(null != parent)  	{  		if(parent instanceof ElemTemplateElement)  			return (ElemTemplateElement)parent;  		parent = parent.exprGetParent();  	}  	throw new RuntimeException(XSLMessages.createMessage(XSLTErrorResources.ER_ASSERT_NO_TEMPLATE_PARENT, null));  	// "Programmer's error! expr has no ElemTemplateElement parent!");  }        /**   * Tell if the given LocPathIterator is relative to an absolute path, i.e.    * in not dependent on the context.   *    * @return true if the LocPathIterator is not dependent on the context node.   */  public boolean isAbsolute(LocPathIterator path)  {  	int analysis = path.getAnalysisBits();    boolean isAbs = (WalkerFactory.isSet(analysis, WalkerFactory.BIT_ROOT) ||            WalkerFactory.isSet(analysis, WalkerFactory.BIT_ANY_DESCENDANT_FROM_ROOT));    if(isAbs)    {    	isAbs = m_absPathChecker.checkAbsolute(path);    }    return isAbs;  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?