1 16 19 package org.apache.xalan.templates; 20 21 import java.util.Vector ; 22 23 import javax.xml.transform.TransformerException ; 24 25 import org.apache.xalan.transformer.NodeSorter; 26 import org.apache.xalan.transformer.TransformerImpl; 27 import org.apache.xml.dtm.DTM; 28 import org.apache.xml.dtm.DTMIterator; 29 import org.apache.xml.dtm.DTMManager; 30 import org.apache.xml.utils.IntStack; 31 import org.apache.xpath.Expression; 32 import org.apache.xpath.ExpressionOwner; 33 import org.apache.xpath.XPath; 34 import org.apache.xpath.XPathContext; 35 36 54 public class ElemForEach extends ElemTemplateElement implements ExpressionOwner 55 { 56 57 static final boolean DEBUG = false; 58 59 69 public boolean m_doc_cache_off=false; 70 71 74 public ElemForEach(){} 75 76 80 protected Expression m_selectExpression = null; 81 82 83 87 protected XPath m_xpath = null; 88 89 94 public void setSelect(XPath xpath) 95 { 96 m_selectExpression = xpath.getExpression(); 97 98 m_xpath = xpath; 101 } 102 103 108 public Expression getSelect() 109 { 110 return m_selectExpression; 111 } 112 113 123 public void compose(StylesheetRoot sroot) throws TransformerException 124 { 125 126 super.compose(sroot); 127 128 int length = getSortElemCount(); 129 130 for (int i = 0; i < length; i++) 131 { 132 getSortElem(i).compose(sroot); 133 } 134 135 java.util.Vector vnames = sroot.getComposeState().getVariableNames(); 136 137 if (null != m_selectExpression) 138 m_selectExpression.fixupVariables( 139 vnames, sroot.getComposeState().getGlobalsSize()); 140 else 141 { 142 m_selectExpression = 143 getStylesheetRoot().m_selectDefault.getExpression(); 144 } 145 } 146 147 150 public void endCompose(StylesheetRoot sroot) throws TransformerException 151 { 152 int length = getSortElemCount(); 153 154 for (int i = 0; i < length; i++) 155 { 156 getSortElem(i).endCompose(sroot); 157 } 158 159 super.endCompose(sroot); 160 } 161 162 163 181 185 protected Vector m_sortElems = null; 186 187 191 public int getSortElemCount() 192 { 193 return (m_sortElems == null) ? 0 : m_sortElems.size(); 194 } 195 196 203 public ElemSort getSortElem(int i) 204 { 205 return (ElemSort) m_sortElems.elementAt(i); 206 } 207 208 213 public void setSortElem(ElemSort sortElem) 214 { 215 216 if (null == m_sortElems) 217 m_sortElems = new Vector (); 218 219 m_sortElems.addElement(sortElem); 220 } 221 222 228 public int getXSLToken() 229 { 230 return Constants.ELEMNAME_FOREACH; 231 } 232 233 238 public String getNodeName() 239 { 240 return Constants.ELEMNAME_FOREACH_STRING; 241 } 242 243 250 public void execute(TransformerImpl transformer) throws TransformerException 251 { 252 253 transformer.pushCurrentTemplateRuleIsNull(true); 254 if (TransformerImpl.S_DEBUG) 255 transformer.getTraceManager().fireTraceEvent(this); 257 try 258 { 259 transformSelectedNodes(transformer); 260 } 261 finally 262 { 263 if (TransformerImpl.S_DEBUG) 264 transformer.getTraceManager().fireTraceEndEvent(this); 265 transformer.popCurrentTemplateRuleIsNull(); 266 } 267 } 268 269 275 protected ElemTemplateElement getTemplateMatch() 276 { 277 return this; 278 } 279 280 292 public DTMIterator sortNodes( 293 XPathContext xctxt, Vector keys, DTMIterator sourceNodes) 294 throws TransformerException 295 { 296 297 NodeSorter sorter = new NodeSorter(xctxt); 298 sourceNodes.setShouldCacheNodes(true); 299 sourceNodes.runTo(-1); 300 xctxt.pushContextNodeList(sourceNodes); 301 302 try 303 { 304 sorter.sort(sourceNodes, keys, xctxt); 305 sourceNodes.setCurrentPos(0); 306 } 307 finally 308 { 309 xctxt.popContextNodeList(); 310 } 311 312 return sourceNodes; 313 } 314 315 324 public void transformSelectedNodes(TransformerImpl transformer) 325 throws TransformerException 326 { 327 328 final XPathContext xctxt = transformer.getXPathContext(); 329 final int sourceNode = xctxt.getCurrentNode(); 330 DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt, 331 sourceNode); 332 333 try 334 { 335 336 final Vector keys = (m_sortElems == null) 337 ? null 338 : transformer.processSortKeys(this, sourceNode); 339 340 if (null != keys) 342 sourceNodes = sortNodes(xctxt, keys, sourceNodes); 343 344 if (TransformerImpl.S_DEBUG) 345 { 346 347 356 357 361 Expression expr = m_xpath.getExpression(); 362 org.apache.xpath.objects.XObject xObject = expr.execute(xctxt); 363 int current = xctxt.getCurrentNode(); 364 transformer.getTraceManager().fireSelectedEvent( 365 current, 366 this, 367 "select", 368 m_xpath, 369 xObject); 370 } 371 372 373 374 xctxt.pushCurrentNode(DTM.NULL); 375 376 IntStack currentNodes = xctxt.getCurrentNodeStack(); 377 378 xctxt.pushCurrentExpressionNode(DTM.NULL); 379 380 IntStack currentExpressionNodes = xctxt.getCurrentExpressionNodeStack(); 381 382 xctxt.pushSAXLocatorNull(); 383 xctxt.pushContextNodeList(sourceNodes); 384 transformer.pushElemTemplateElement(null); 385 386 DTM dtm = xctxt.getDTM(sourceNode); 389 int docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT; 390 int child; 391 392 while (DTM.NULL != (child = sourceNodes.nextNode())) 393 { 394 currentNodes.setTop(child); 395 currentExpressionNodes.setTop(child); 396 397 if ((child & DTMManager.IDENT_DTM_DEFAULT) != docID) 398 { 399 dtm = xctxt.getDTM(child); 400 docID = child & DTMManager.IDENT_DTM_DEFAULT; 401 } 402 403 final int nodeType = dtm.getNodeType(child); 405 406 if (TransformerImpl.S_DEBUG) 408 { 409 transformer.getTraceManager().fireTraceEvent(this); 410 } 411 412 for (ElemTemplateElement t = this.m_firstChild; t != null; 416 t = t.m_nextSibling) 417 { 418 xctxt.setSAXLocator(t); 419 transformer.setCurrentElement(t); 420 t.execute(transformer); 421 } 422 423 if (TransformerImpl.S_DEBUG) 424 { 425 transformer.setCurrentElement(null); 428 transformer.getTraceManager().fireTraceEndEvent(this); 429 } 430 431 432 if(m_doc_cache_off) 443 { 444 if(DEBUG) 445 System.out.println("JJK***** CACHE RELEASE *****\n"+ 446 "\tdtm="+dtm.getDocumentBaseURI()); 447 xctxt.getSourceTreeManager().removeDocumentFromCache(dtm.getDocument()); 451 xctxt.release(dtm,false); 452 } 453 } 454 } 455 finally 456 { 457 if (TransformerImpl.S_DEBUG) 458 transformer.getTraceManager().fireSelectedEndEvent(sourceNode, this, 459 "select", new XPath(m_selectExpression), 460 new org.apache.xpath.objects.XNodeSet(sourceNodes)); 461 462 xctxt.popSAXLocator(); 463 xctxt.popContextNodeList(); 464 transformer.popElemTemplateElement(); 465 xctxt.popCurrentExpressionNode(); 466 xctxt.popCurrentNode(); 467 sourceNodes.detach(); 468 } 469 } 470 471 483 public ElemTemplateElement appendChild(ElemTemplateElement newChild) 484 { 485 486 int type = ((ElemTemplateElement) newChild).getXSLToken(); 487 488 if (Constants.ELEMNAME_SORT == type) 489 { 490 setSortElem((ElemSort) newChild); 491 492 return newChild; 493 } 494 else 495 return super.appendChild(newChild); 496 } 497 498 502 public void callChildVisitors(XSLTVisitor visitor, boolean callAttributes) 503 { 504 if(callAttributes && (null != m_selectExpression)) 505 m_selectExpression.callVisitors(this, visitor); 506 507 int length = getSortElemCount(); 508 509 for (int i = 0; i < length; i++) 510 { 511 getSortElem(i).callVisitors(visitor); 512 } 513 514 super.callChildVisitors(visitor, callAttributes); 515 } 516 517 520 public Expression getExpression() 521 { 522 return m_selectExpression; 523 } 524 525 528 public void setExpression(Expression exp) 529 { 530 exp.exprSetParent(this); 531 m_selectExpression = exp; 532 } 533 534 } 535 | Popular Tags |