1 29 30 package com.caucho.jsp.java; 31 32 import com.caucho.jsp.JspParseException; 33 import com.caucho.jsp.TagInstance; 34 import com.caucho.vfs.WriteStream; 35 import com.caucho.xml.QName; 36 37 import java.io.IOException ; 38 import java.util.ArrayList ; 39 40 43 public class JstlCoreForEach extends JstlNode { 44 private static final QName VAR = new QName("var"); 45 private static final QName VAR_STATUS = new QName("varStatus"); 46 47 private static final QName ITEMS = new QName("items"); 48 private static final QName BEGIN = new QName("begin"); 49 private static final QName END = new QName("end"); 50 private static final QName STEP = new QName("step"); 51 52 private String _var; 53 private String _varStatus; 54 55 private String _items; 56 private JspAttribute _itemsAttr; 57 58 private String _begin; 59 private JspAttribute _beginAttr; 60 61 private String _end; 62 private JspAttribute _endAttr; 63 64 private String _step; 65 private JspAttribute _stepAttr; 66 67 private boolean _isInteger; 68 private int _depth; 69 private String _tagVar; 70 71 private TagInstance _tag; 72 73 76 public void addAttribute(QName name, String value) 77 throws JspParseException 78 { 79 if (VAR.equals(name)) 80 _var = value; 81 else if (VAR_STATUS.equals(name)) 82 _varStatus = value; 83 else if (ITEMS.equals(name)) { 84 _items = value; 85 _attributeNames.add(name); 86 _attributeValues.add(value); 87 } 88 else if (BEGIN.equals(name)) 89 _begin = value; 90 else if (END.equals(name)) 91 _end = value; 92 else if (STEP.equals(name)) 93 _step = value; 94 else 95 throw error(L.l("`{0}' is an unknown attribute for <{1}>.", 96 name.getName(), getTagName())); 97 } 98 99 102 public void addAttribute(QName name, JspAttribute value) 103 throws JspParseException 104 { 105 if (ITEMS.equals(name)) 106 _itemsAttr = value; 107 else if (BEGIN.equals(name)) 108 _beginAttr = value; 109 else if (END.equals(name)) 110 _endAttr = value; 111 else if (STEP.equals(name)) 112 _stepAttr = value; 113 else 114 throw error(L.l("`{0}' is an unknown jsp:attribute for <{1}>.", 115 name.getName(), getTagName())); 116 } 117 118 121 public boolean hasScripting() 122 { 123 return (super.hasScripting() || 124 hasScripting(_items) || hasScripting(_itemsAttr) || 125 hasScripting(_begin) || hasScripting(_beginAttr) || 126 hasScripting(_end) || hasScripting(_endAttr) || 127 hasScripting(_step) || hasScripting(_stepAttr)); 128 } 129 130 133 public boolean isInteger() 134 { 135 return _items == null && _itemsAttr == null; 136 } 137 138 public TagInstance getTag() 139 { 140 return _tag; 141 } 142 143 146 public String getCustomTagName() 147 { 148 if (_tag == null) 149 return null; 150 else 151 return _tag.getId(); 152 } 153 154 157 public boolean isSimpleTag() 158 { 159 return false; 160 } 161 162 167 public void printXml(WriteStream os) 168 throws IOException 169 { 170 os.print("<c:forEach"); 171 172 if (_itemsAttr != null) { 173 os.print(" items=\""); 174 _itemsAttr.printXml(os); 175 os.print("\""); 176 } 177 else if (_items != null) { 178 os.print(" items=\""); 179 printXmlText(os, _items); 180 os.print("\""); 181 } 182 183 if (_beginAttr != null) { 184 os.print(" begin=\""); 185 _beginAttr.printXml(os); 186 os.print("\""); 187 } 188 else if (_begin != null) { 189 os.print(" begin=\""); 190 printXmlText(os, _begin); 191 os.print("\""); 192 } 193 194 if (_endAttr != null) { 195 os.print(" end=\""); 196 _endAttr.printXml(os); 197 os.print("\""); 198 } 199 else if (_end != null) { 200 os.print(" end=\""); 201 printXmlText(os, _end); 202 os.print("\""); 203 } 204 205 if (_stepAttr != null) { 206 os.print(" step=\""); 207 _stepAttr.printXml(os); 208 os.print("\""); 209 } 210 else if (_step != null) { 211 os.print(" step=\""); 212 printXmlText(os, _step); 213 os.print("\""); 214 } 215 216 os.print(">"); 217 218 printXmlChildren(os); 219 220 os.print("</c:forEach>"); 221 } 222 223 226 public void generatePrologue(JspJavaWriter out) 227 throws Exception 228 { 229 TagInstance parent = getParent().getTag(); 230 231 _tag = parent.findTag(getQName(), _attributeNames, false); 232 233 if (_tag != null) { 234 _tagVar = _tag.getId(); 235 } 236 else { 237 String id = "_jsp_loop_" + _gen.uniqueId(); 238 239 _tag = parent.addTag(getQName(), null, null, 240 _attributeNames, _attributeValues, false); 241 242 _tag.setId(id); 243 244 _tagVar = _tag.getId(); 245 246 if (isInteger()) 247 out.println("com.caucho.jsp.IntegerLoopSupportTag " + _tagVar + " = null;"); 248 else 249 out.println("com.caucho.jsp.IteratorLoopSupportTag " + _tagVar + " = null;"); 250 } 251 252 generatePrologueChildren(out); 253 } 254 255 private boolean hasDeclaration() 256 { 257 return (_varStatus != null || hasTag()); 258 } 259 260 263 private int getDepth() 264 { 265 JspNode node = this; 266 int depth = 0; 267 268 for (; ! (node instanceof JspSegmentNode); node = node.getParent()) { 269 if (node instanceof JstlCoreForEach) { 270 JstlCoreForEach forEach = (JstlCoreForEach) node; 271 272 if (forEach.isInteger() == isInteger()) 273 depth++; 274 } 275 } 276 277 return depth; 278 } 279 280 283 private boolean isFirst() 284 { 285 JspNode node = this; 286 287 for (; ! (node instanceof JspSegmentNode); node = node.getParent()) { 288 } 289 290 return isFirst(node, getDepth()) == 1; 291 } 292 293 296 private int isFirst(JspNode node, int depth) 297 { 298 if (node == this) 299 return 1; 300 else if (node instanceof JstlCoreForEach) { 301 JstlCoreForEach forEach = (JstlCoreForEach) node; 302 303 if (forEach.isInteger() == isInteger() && 304 forEach.getDepth() == depth && 305 forEach.hasDeclaration()) 306 return 0; 307 } 308 309 if (node instanceof JspContainerNode) { 310 ArrayList <JspNode> children = ((JspContainerNode) node).getChildren(); 311 312 if (children == null) 313 return -1; 314 315 for (int i = 0; i < children.size(); i++) { 316 JspNode child = children.get(i); 317 318 int result = isFirst(child, depth); 319 320 if (result >= 0) 321 return result; 322 } 323 } 324 325 return -1; 326 } 327 328 331 public void generate(JspJavaWriter out) 332 throws Exception 333 { 334 if (_items == null && _itemsAttr == null) 335 generateIntegerForEach(out); 336 else 337 generateCollectionForEach(out); 338 } 339 340 343 public void generateIntegerForEach(JspJavaWriter out) 344 throws Exception 345 { 346 if (_begin == null && _beginAttr == null) 347 throw error(L.l("required attribute `begin' missing from <{0}>", 348 getTagName())); 349 350 if (_end == null && _endAttr == null) 351 throw error(L.l("required attribute `end' missing from <{0}>", 352 getTagName())); 353 354 int uniqueId = _gen.uniqueId(); 355 356 String oldVar = "_jsp_oldVar_" + uniqueId; 357 String oldStatusVar = "_jsp_status_" + uniqueId; 358 359 if (_tagVar != null) { 360 out.println("if (" + _tagVar + " == null)"); 361 out.println(" " + _tagVar + " = new com.caucho.jsp.IntegerLoopSupportTag();"); 362 363 if (hasTag()) { 364 JspNode parentTagNode = getParent().getParentTagNode(); 365 366 if (parentTagNode == null) { 367 out.println(_tagVar + ".setParent((javax.servlet.jsp.tagext.Tag) null);"); 368 } 369 else { 370 out.println(_tagVar + ".setParent(" + parentTagNode.getCustomTagName() + ");"); 371 } 372 } 373 } 374 375 String beginVar = "_jsp_begin_" + uniqueId; 376 String endVar = "_jsp_end_" + uniqueId; 377 String iVar = "_jsp_i_" + uniqueId; 378 379 out.print("int " + beginVar + " = "); 380 if (_beginAttr != null) 381 out.print(_beginAttr.generateValue(int.class)); 382 else 383 out.print(generateValue(int.class, _begin)); 384 out.println(";"); 385 386 out.print("int " + endVar + " = "); 387 if (_endAttr != null) 388 out.print(_endAttr.generateValue(int.class)); 389 else 390 out.print(generateValue(int.class, _end)); 391 out.println(";"); 392 393 String stepVar = null; 394 if (_step != null || _stepAttr != null) { 395 stepVar = "_jsp_step_" + uniqueId; 396 out.print("int " + stepVar + " = "); 397 398 if (_stepAttr != null) 399 out.print(_stepAttr.generateValue(int.class)); 400 else 401 out.print(generateValue(int.class, _step)); 402 403 out.println(";"); 404 } 405 else 406 stepVar = "1"; 407 408 if (_tagVar != null) 409 out.println(_tagVar + ".init(" + beginVar + ", " + endVar + ", " + stepVar + ");"); 410 411 if (_varStatus != null) { 412 out.print("Object " + oldStatusVar + " = pageContext.putAttribute(\""); 413 out.print(escapeJavaString(_varStatus)); 414 out.println("\", " + _tagVar + ");"); 415 } 416 417 if (_var != null) { 418 out.print("Object " + oldVar + " = pageContext.getAttribute(\""); 419 out.print(escapeJavaString(_var)); 420 out.println("\");"); 421 } 422 423 out.print("for (int " + iVar + " = " + beginVar + "; "); 424 out.print(iVar + " <= " + endVar + "; "); 425 out.println(iVar + " += " + stepVar + ") {"); 426 out.pushDepth(); 427 428 if (_var != null) { 429 out.print("pageContext.setAttribute(\"" + escapeJavaString(_var) + "\""); 430 out.println(", new Integer(" + iVar + "));"); 431 } 432 433 if (_tagVar != null) { 434 out.println(_tagVar + ".setCurrent(" + iVar + ");"); 435 } 436 437 generateChildren(out); 438 439 out.popDepth(); 440 out.println("}"); 441 442 if (_var != null) { 443 out.print("pageContext.pageSetOrRemove(\""); 444 out.print(escapeJavaString(_var)); 445 out.println("\", " + oldVar + ");"); 446 } 447 448 if (_varStatus != null) { 449 out.print("pageContext.pageSetOrRemove(\""); 450 out.print(escapeJavaString(_varStatus)); 451 out.println("\", " + oldStatusVar + ");"); 452 } 453 } 454 455 458 public void generateCollectionForEach(JspJavaWriter out) 459 throws Exception 460 { 461 int uniqueId = _gen.uniqueId(); 462 463 String oldVar = "_jsp_oldVar_" + uniqueId; 464 String oldStatusVar = "_jsp_status_" + uniqueId; 465 466 if (_tagVar != null) { 467 out.println("if (" + _tagVar + " == null)"); 468 out.println(" " + _tagVar + " = new com.caucho.jsp.IteratorLoopSupportTag();"); 469 470 if (hasTag()) { 471 JspNode parentTagNode = getParent().getParentTagNode(); 472 473 if (parentTagNode == null) { 474 out.println(_tagVar + ".setParent((javax.servlet.jsp.tagext.Tag) null);"); 475 } 476 else { 477 out.println(_tagVar + ".setParent(" + parentTagNode.getCustomTagName() + ");"); 478 } 479 } 480 } 481 482 String iterVar = "_jsp_iter_" + uniqueId; 483 String iVar = "_jsp_i_" + uniqueId; 484 out.print("java.util.Iterator " + iterVar + " = com.caucho.jstl.el.ForEachTag.getIterator("); 485 if (_itemsAttr != null) 486 out.print(_itemsAttr.generateValue(Object .class)); 487 else 488 out.print(generateValue(Object .class, _items)); 489 out.println(");"); 490 491 String beginVar = null; 492 if (_beginAttr != null || _begin != null) { 493 beginVar = "_jsp_begin_" + uniqueId; 494 out.print("int " + beginVar + " = "); 495 if (_beginAttr != null) 496 out.print(_beginAttr.generateValue(int.class)); 497 else 498 out.print(generateValue(int.class, _begin)); 499 out.println(";"); 500 } 501 502 String intVar = "_jsp_int_" + uniqueId; 503 if (beginVar != null) { 504 out.print("for (int " + intVar + " = " + beginVar + ";"); 505 out.println(intVar + " > 0; " + intVar + "--)"); 506 out.println(" if (" + iterVar + ".hasNext()) " + iterVar + ".next();"); 507 } 508 509 String endVar = null; 510 if (_endAttr != null || _end != null) { 511 endVar = "_jsp_end_" + uniqueId; 512 513 out.print("int " + endVar + " = "); 514 if (_endAttr != null) 515 out.print(_endAttr.generateValue(int.class)); 516 else 517 out.print(generateValue(int.class, _end)); 518 out.println(";"); 519 } 520 521 String stepVar = null; 522 if (_step != null || _stepAttr != null) { 523 stepVar = "_jsp_step_" + uniqueId; 524 out.print("int " + stepVar + " = "); 525 526 if (_stepAttr != null) 527 out.print(_stepAttr.generateValue(int.class)); 528 else 529 out.print(generateValue(int.class, _step)); 530 531 out.println(";"); 532 } 533 else 534 stepVar = "1"; 535 536 if (_tagVar != null) { 537 out.print(_tagVar + ".init("); 538 if (beginVar != null) 539 out.print(beginVar + ", "); 540 else 541 out.print("0, "); 542 543 if (endVar != null) 544 out.print(endVar + ", "); 545 else 546 out.print("Integer.MAX_VALUE, "); 547 548 out.println(stepVar + ");"); 549 } 550 551 if (_varStatus != null) { 552 out.print("Object " + oldStatusVar + " = pageContext.putAttribute(\""); 553 out.print(escapeJavaString(_varStatus)); 554 out.println("\", " + _tagVar + ");"); 555 } 556 557 if (_var != null) { 558 out.print("Object " + oldVar + " = pageContext.getAttribute(\""); 559 out.print(escapeJavaString(_var)); 560 out.println("\");"); 561 } 562 563 if (endVar != null) { 564 String begin = beginVar == null ? "0" : beginVar; 565 566 out.print("for (int " + intVar + " = " + begin + "; "); 567 out.print(intVar + " <= " + endVar); 568 569 out.print(" && " + iterVar + ".hasNext(); "); 570 571 out.println(intVar + " += " + stepVar + ") {"); 572 } 573 else 574 out.println("while (" + iterVar + ".hasNext()) {"); 575 576 out.pushDepth(); 577 578 out.println("Object " + iVar + " = " + iterVar + ".next();"); 579 580 if (_var != null) { 581 out.print("pageContext.setAttribute(\"" + escapeJavaString(_var) + "\""); 582 out.println(", " + iVar + ");"); 583 } 584 585 if (_tagVar != null) { 586 out.println(_tagVar + ".setCurrent(" + iVar + ", " + iterVar + ".hasNext());"); 587 } 588 589 generateChildren(out); 590 591 if (! stepVar.equals("1")) { 592 String stepI = "_jsp_si_" + uniqueId; 593 594 out.print("for (int " + stepI + " = " + stepVar + "; "); 595 out.println(stepI + " > 1; " + stepI + "--)"); 596 out.println(" if (" + iterVar + ".hasNext()) " + iterVar + ".next();"); 597 out.println("if (! " + iterVar + ".hasNext())"); 598 out.println(" break;"); 599 } 600 601 out.popDepth(); 602 out.println("}"); 603 604 if (_var != null) { 605 out.print("pageContext.pageSetOrRemove(\""); 606 out.print(escapeJavaString(_var)); 607 out.println("\", " + oldVar + ");"); 608 } 609 610 if (_varStatus != null) { 611 out.print("pageContext.pageSetOrRemove(\""); 612 out.print(escapeJavaString(_varStatus)); 613 out.println("\", " + oldStatusVar + ");"); 614 } 615 } 616 } 617 | Popular Tags |