1 28 29 package org.jibx.binding.def; 30 31 import org.apache.bcel.generic.*; 32 33 import org.jibx.binding.classes.*; 34 import org.jibx.runtime.JiBXException; 35 36 43 44 public class NestedCollection extends NestedBase 45 { 46 47 private final String m_itemType; 48 49 50 private final CollectionLoad m_loadStrategy; 51 52 53 private final CollectionStore m_storeStrategy; 54 55 66 67 public NestedCollection(IContainer parent, IContextObj objc, boolean ord, 68 String type, CollectionLoad load, CollectionStore store) { 69 super(parent, objc, ord, false); 70 m_itemType = type; 71 m_loadStrategy = load; 72 m_storeStrategy = store; 73 } 74 75 78 public boolean hasAttribute() { 79 return false; 80 } 81 82 public void genAttrPresentTest(ContextMethodBuilder mb) { 83 throw new IllegalStateException 84 ("Internal error - no attributes present"); 85 } 86 87 public void genAttributeUnmarshal(ContextMethodBuilder mb) { 88 throw new IllegalStateException 89 ("Internal error - no attributes present"); 90 } 91 92 public void genAttributeMarshal(ContextMethodBuilder mb) { 93 throw new IllegalStateException 94 ("Internal error - no attributes present"); 95 } 96 97 public boolean hasContent() { 98 return m_contents.size() > 0; 99 } 100 101 public void genContentUnmarshal(ContextMethodBuilder mb) 102 throws JiBXException { 103 if (m_contents.size() > 0) { 104 105 m_storeStrategy.genStoreInit(mb); 107 BranchWrapper link = null; 108 int count = m_contents.size(); 109 if (m_isOrdered) { 110 111 for (int i = 0; i < count; i++) { 113 114 if (link != null) { 116 mb.initStackState(link); 117 } 118 BranchTarget start = mb.appendTargetNOP(); 119 if (link != null) { 120 link.setTarget(start, mb); 121 } 122 123 IComponent child = (IComponent)m_contents.get(i); 126 child.genContentPresentTest(mb); 127 link = mb.appendIFEQ(this); 128 129 child.genContentUnmarshal(mb); 133 m_storeStrategy.genStoreItem(mb); 134 mb.appendUnconditionalBranch(this).setTarget(start, mb); 135 } 136 137 } else { 138 139 BranchTarget first = mb.appendTargetNOP(); 143 for (int i = 0; i < count; i++) { 144 if (link != null) { 145 mb.targetNext(link); 146 } 147 IComponent child = (IComponent)m_contents.get(i); 148 child.genContentPresentTest(mb); 149 link = mb.appendIFEQ(this); 150 child.genContentUnmarshal(mb); 151 m_storeStrategy.genStoreItem(mb); 152 mb.appendUnconditionalBranch(this).setTarget(first, mb); 153 } 154 } 155 156 m_storeStrategy.genStoreDone(mb); 158 mb.targetNext(link); 159 160 } else { 161 throw new IllegalStateException 162 ("Internal error - no content present"); 163 } 164 } 165 166 public void genContentMarshal(ContextMethodBuilder mb) 167 throws JiBXException { 168 if (m_contents.size() > 0) { 169 170 BranchWrapper[] ifempties; 172 BranchWrapper link = null; 173 m_loadStrategy.genLoadInit(mb); 174 175 int count = m_contents.size(); 177 if (m_isOrdered) { 178 179 ifempties = new BranchWrapper[count]; 183 for (int i = 0; i < count; i++) { 184 185 if (link != null) { 188 mb.initStackState(link, 1); 189 } 190 BranchTarget start = mb.appendTargetNOP(); 191 ifempties[i] = m_loadStrategy.genLoadItem(mb); 192 mb.targetNext(link); 193 194 IComponent child = (IComponent)m_contents.get(i); 197 String type = child.getType(); 198 if (count > 1 || !"java.lang.Object".equals(type)) { 199 mb.appendDUP(); 200 mb.appendInstanceOf(type); 201 link = mb.appendIFEQ(this); 202 mb.appendCreateCast(type); 203 } 204 205 child.genContentMarshal(mb); 208 mb.appendUnconditionalBranch(this).setTarget(start, mb); 209 } 210 211 mb.targetNext(link); 213 214 } else { 215 216 BranchTarget start = mb.appendTargetNOP(); 221 ifempties = new BranchWrapper[1]; 222 ifempties[0] = m_loadStrategy.genLoadItem(mb); 223 for (int i = 0; i < count; i++) { 224 225 mb.targetNext(link); 227 228 IComponent child = (IComponent)m_contents.get(i); 231 String type = child.getType(); 232 if (count > 1 || !"java.lang.Object".equals(type)) { 233 mb.appendDUP(); 234 mb.appendInstanceOf(type); 235 link = mb.appendIFEQ(this); 236 mb.appendCreateCast(type); 237 } 238 239 child.genContentMarshal(mb); 242 mb.appendUnconditionalBranch(this).setTarget(start, mb); 243 } 244 245 } 246 247 if (link != null) { 249 250 mb.targetNext(link); 256 mb.appendCreateNew("java.lang.StringBuffer"); 257 mb.appendDUP(); 258 mb.appendLoadConstant("Collection item of type "); 259 mb.appendCallInit("java.lang.StringBuffer", 260 "(Ljava/lang/String;)V"); 261 mb.appendSWAP(); 262 mb.appendDUP(); 263 BranchWrapper ifnull = mb.appendIFNULL(this); 264 mb.appendCallVirtual("java.lang.Object.getClass", 265 "()Ljava/lang/Class;"); 266 mb.appendCallVirtual("java.lang.Class.getName", 267 "()Ljava/lang/String;"); 268 BranchWrapper toend = mb.appendUnconditionalBranch(this); 269 mb.targetNext(ifnull); 270 mb.appendPOP(); 271 mb.appendLoadConstant("NULL"); 272 mb.targetNext(toend); 273 mb.appendCallVirtual("java.lang.StringBuffer.append", 274 "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); 275 mb.appendLoadConstant(" has no binding defined"); 276 mb.appendCallVirtual("java.lang.StringBuffer.append", 277 "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); 278 mb.appendCallVirtual("java.lang.StringBuffer.toString", 279 "()Ljava/lang/String;"); 280 mb.appendCreateNew(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS); 281 mb.appendDUP_X1(); 282 mb.appendSWAP(); 283 mb.appendCallInit(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS, 284 MethodBuilder.EXCEPTION_CONSTRUCTOR_SIGNATURE1); 285 mb.appendThrow(); 286 } 287 288 m_loadStrategy.genLoadDone(mb); 290 for (int i = 0; i < ifempties.length; i++) { 291 mb.targetNext(ifempties[i]); 292 } 293 294 } else { 295 throw new IllegalStateException 296 ("Internal error - no content present"); 297 } 298 } 299 300 public boolean hasId() { 301 return false; 302 } 303 304 public void genLoadId(ContextMethodBuilder mb) throws JiBXException { 305 throw new IllegalStateException ("No ID child"); 306 } 307 308 public boolean checkContentSequence(boolean text) throws JiBXException { 309 310 for (int i = 0; i < m_contents.size(); i++) { 312 IComponent content = (IComponent)m_contents.get(i); 313 content.checkContentSequence(false); 314 } 315 return false; 316 } 317 318 public void setLinkages() throws JiBXException { 319 for (int i = 0; i < m_contents.size(); i++) { 320 ((IComponent)m_contents.get(i)).setLinkages(); 321 } 322 } 323 324 public void print(int depth) { 326 BindingDefinition.indent(depth); 327 System.out.print("collection " + 328 (m_isOrdered ? "ordered" : "unordered")); 329 System.out.println(); 330 for (int i = 0; i < m_contents.size(); i++) { 331 IComponent comp = (IComponent)m_contents.get(i); 332 comp.print(depth+1); 333 } 334 } 335 336 341 342 static abstract class CollectionLoad 343 { 344 353 354 protected void genLoadInit(ContextMethodBuilder mb) 355 throws JiBXException {} 356 357 369 370 protected abstract BranchWrapper genLoadItem(ContextMethodBuilder mb) 371 throws JiBXException; 372 373 382 383 protected void genLoadDone(ContextMethodBuilder mb) 384 throws JiBXException {} 385 } 386 387 392 393 static abstract class CollectionStore 394 { 395 405 406 protected void genStoreInit(ContextMethodBuilder mb) 407 throws JiBXException {} 408 409 420 421 protected abstract void genStoreItem(ContextMethodBuilder mb) 422 throws JiBXException; 423 424 433 434 protected void genStoreDone(ContextMethodBuilder mb) 435 throws JiBXException {} 436 } 437 438 442 443 static class IndexedLoad extends CollectionLoad 444 { 445 446 private final ClassItem m_sizeMethod; 447 448 449 private final ClassItem m_getMethod; 450 451 457 458 IndexedLoad(ClassItem size, ClassItem get) { 459 m_sizeMethod = size; 460 m_getMethod = get; 461 } 462 463 protected void genLoadInit(ContextMethodBuilder mb) 464 throws JiBXException { 465 466 mb.appendLoadConstant(-1); 468 mb.defineSlot(m_getMethod, Type.INT); 469 470 if (!m_sizeMethod.isStatic()) { 473 mb.loadObject(); 474 } 475 mb.appendCall(m_sizeMethod); 476 mb.defineSlot(m_sizeMethod, Type.INT); 477 } 478 479 protected BranchWrapper genLoadItem(ContextMethodBuilder mb) 480 throws JiBXException { 481 482 int islot = mb.getSlot(m_getMethod); 484 int sslot = mb.getSlot(m_sizeMethod); 485 486 mb.appendIncrementLocal(1, islot); 489 mb.appendLoadLocal(islot); 490 mb.appendLoadLocal(sslot); 491 mb.appendISUB(); 492 BranchWrapper ifempty = mb.appendIFGE(this); 493 494 if (!m_getMethod.isStatic()) { 497 mb.loadObject(); 498 } 499 mb.appendLoadLocal(islot); 500 mb.appendCall(m_getMethod); 501 return ifempty; 502 } 503 504 protected void genLoadDone(ContextMethodBuilder mb) 505 throws JiBXException { 506 mb.freeSlot(m_getMethod); 507 mb.freeSlot(m_sizeMethod); 508 } 509 } 510 511 515 516 static class IndexedStore extends CollectionStore 517 { 518 519 private final ClassItem m_setMethod; 520 521 522 private final boolean m_isReturned; 523 524 530 531 IndexedStore(ClassItem set, boolean ret) { 532 m_setMethod = set; 533 m_isReturned = ret; 534 } 535 536 protected void genStoreInit(ContextMethodBuilder mb) 537 throws JiBXException { 538 539 mb.appendLoadConstant(-1); 541 mb.defineSlot(m_setMethod, Type.INT); 542 } 543 544 protected void genStoreItem(ContextMethodBuilder mb) 545 throws JiBXException { 546 547 int islot = mb.getSlot(m_setMethod); 549 550 if (!m_setMethod.isStatic()) { 554 mb.loadObject(); 555 mb.appendSWAP(); 556 } 557 mb.appendIncrementLocal(1, islot); 558 mb.appendLoadLocal(islot); 559 mb.appendSWAP(); 560 mb.appendCall(m_setMethod); 561 if (m_isReturned) { 562 mb.appendPOP(); 563 } 564 } 565 566 protected void genStoreDone(ContextMethodBuilder mb) 567 throws JiBXException { 568 mb.freeSlot(m_setMethod); 569 } 570 } 571 572 576 577 static class IteratorLoad extends CollectionLoad 578 { 579 580 private final ClassItem m_iterMethod; 581 582 583 private final String m_moreName; 584 585 586 private final String m_nextName; 587 588 595 596 IteratorLoad(ClassItem iter, String more, String next) { 597 m_iterMethod = iter; 598 m_moreName = more; 599 m_nextName = next; 600 } 601 602 protected void genLoadInit(ContextMethodBuilder mb) 603 throws JiBXException { 604 605 if (!m_iterMethod.isStatic()) { 607 mb.loadObject(); 608 } 609 mb.appendCall(m_iterMethod); 610 mb.defineSlot(m_iterMethod, Type.getType("Ljava/util/Iterator;")); 611 } 612 613 protected BranchWrapper genLoadItem(ContextMethodBuilder mb) 614 throws JiBXException { 615 616 int islot = mb.getSlot(m_iterMethod); 618 mb.appendLoadLocal(islot); 619 mb.appendCallInterface(m_moreName, "()Z"); 620 BranchWrapper ifempty = mb.appendIFEQ(this); 621 622 mb.appendLoadLocal(islot); 624 mb.appendCallInterface(m_nextName, "()Ljava/lang/Object;"); 625 return ifempty; 626 } 627 628 protected void genLoadDone(ContextMethodBuilder mb) 629 throws JiBXException { 630 mb.freeSlot(m_iterMethod); 631 } 632 } 633 634 637 638 static class AddStore extends CollectionStore 639 { 640 641 private final ClassItem m_addMethod; 642 643 644 private final boolean m_isReturned; 645 646 652 653 AddStore(ClassItem add, boolean ret) { 654 m_addMethod = add; 655 m_isReturned = ret; 656 } 657 658 protected void genStoreItem(ContextMethodBuilder mb) 659 throws JiBXException { 660 661 if (!m_addMethod.isStatic()) { 663 mb.loadObject(); 664 mb.appendSWAP(); 665 } 666 mb.appendCall(m_addMethod); 667 if (m_isReturned) { 668 mb.appendPOP(); 669 } 670 } 671 } 672 } | Popular Tags |