1 16 17 package org.apache.cocoon.taglib.core; 18 19 import org.apache.cocoon.environment.ObjectModelHelper; 20 import org.apache.cocoon.environment.Request; 21 import org.apache.cocoon.taglib.IterationTag; 22 import org.apache.cocoon.taglib.VarTagSupport; 23 import org.xml.sax.Attributes ; 24 import org.xml.sax.SAXException ; 25 26 68 public abstract class LoopTagSupport extends VarTagSupport implements LoopTag, IterationTag { 70 73 82 83 84 protected int begin; 85 86 91 protected int end; 92 93 94 protected int step; 95 96 97 protected boolean beginSpecified; 98 99 100 protected boolean endSpecified; 101 102 103 protected boolean stepSpecified; 104 105 106 protected String statusId; 107 108 111 129 private LoopTagStatus status; private Object item; protected int index; protected int count; protected boolean last; 135 138 143 public LoopTagSupport() { 144 super(); 145 init(); 146 } 147 148 151 168 protected abstract Object next() throws SAXException ; 169 170 184 protected abstract boolean hasNext() throws SAXException ; 185 186 194 protected abstract void prepare() throws SAXException ; 195 196 199 public void recycle() { 201 unExposeVariables(); init(); 203 super.recycle(); 204 } 205 206 public int doStartTag(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 208 209 if (end != -1 && begin > end) 211 throw new SAXException ("begin (" + begin + ") > end (" + end + ")"); 212 213 index = 0; 215 count = 1; 216 last = false; 217 218 prepare(); 220 221 discardIgnoreSubset(begin); 223 224 if (hasNext()) 226 item = next(); 228 else 229 return SKIP_BODY; 230 231 235 discard(step - 1); 236 237 exposeVariables(); 239 calibrateLast(); 240 return EVAL_BODY; 241 } 242 243 247 public int doAfterBody() throws SAXException { 248 249 index += step - 1; 251 252 count++; 254 255 if (hasNext() && !atEnd()) { 257 index++; 258 item = next(); 259 } else 260 return SKIP_BODY; 261 262 266 discard(step - 1); 267 268 exposeVariables(); 270 calibrateLast(); 271 return EVAL_BODY_AGAIN; 272 } 273 274 279 public void doFinally() { 280 284 unExposeVariables(); 285 } 286 287 290 public void doCatch(Throwable t) throws Throwable { 291 throw t; 292 } 293 294 297 304 305 310 public Object getCurrent() { 311 return item; 312 } 313 314 321 public LoopTagStatus getIteratorStatus() { 322 323 class Status implements LoopTagStatus { 325 326 331 332 public Object getCurrent() { 333 339 return (LoopTagSupport.this.getCurrent()); 340 } 341 public int getIndex() { 342 return index + begin; } 344 public int getCount() { 345 return count; 346 } 347 public boolean isFirst() { 348 return (index == 0); } 350 public boolean isLast() { 351 return (last); } 353 public Integer getBegin() { 354 if (beginSpecified) { 355 return (new Integer (begin)); 356 } 357 return null; 358 } 359 public Integer getEnd() { 360 if (endSpecified) { 361 return (new Integer (end)); 362 } 363 return null; 364 } 365 public Integer getStep() { 366 if (stepSpecified) { 367 return (new Integer (step)); 368 } 369 return null; 370 } 371 } 372 373 378 if (status == null) { 379 status = new Status(); 380 } 381 382 return status; 383 } 384 385 395 396 397 public void setVarStatus(String statusId) { 399 this.statusId = statusId; 400 } 401 402 405 410 411 415 protected void validateBegin() throws SAXException { 416 if (begin < 0) 417 throw new SAXException ("'begin' < 0"); 418 } 419 420 424 protected void validateEnd() throws SAXException { 425 if (end < 0) 426 throw new SAXException ("'end' < 0"); 427 } 428 429 433 protected void validateStep() throws SAXException { 434 if (step < 1) 435 throw new SAXException ("'step' <= 0"); 436 } 437 438 441 442 private void init() { 443 index = 0; count = 1; status = null; item = null; last = false; beginSpecified = false; endSpecified = false; stepSpecified = false; 453 begin = 0; end = -1; step = 1; statusId = null; } 459 460 461 private void calibrateLast() throws SAXException { 462 466 last = !hasNext() || atEnd() || (end != -1 && (begin + index + step > end)); 467 } 468 469 474 private void exposeVariables() throws SAXException { 475 476 492 493 if (var != null) { 494 if (getCurrent() == null) 495 removeVariable(var); 496 else 497 setVariable(var, getCurrent()); 498 } 499 if (statusId != null) { 500 if (getIteratorStatus() == null) 501 removeVariable(statusId); 502 else 503 setVariable(statusId, getIteratorStatus()); 504 } 505 506 } 507 508 512 private void unExposeVariables() { 513 Request request = ObjectModelHelper.getRequest(objectModel); 515 if (var != null) 516 request.removeAttribute(var); 517 if (statusId != null) 518 request.removeAttribute(statusId); 519 } 520 521 534 private void discard(int n) throws SAXException { 535 539 int oldIndex = index; 540 while (n-- > 0 && !atEnd() && hasNext()) { 541 index++; 542 next(); 543 } 544 index = oldIndex; 545 } 546 547 552 private void discardIgnoreSubset(int n) throws SAXException { 553 while (n-- > 0 && hasNext()) 554 next(); 555 } 556 557 563 private boolean atEnd() { 564 return ((end != -1) && (begin + index >= end)); 565 } 566 } 567 | Popular Tags |