1 7 package org.jboss.xb.binding.metadata.marshalling; 8 9 import org.jboss.xb.binding.JBossXBRuntimeException; 10 11 import java.util.Map ; 12 import java.util.HashMap ; 13 import java.util.List ; 14 import java.util.ArrayList ; 15 import java.util.Collection ; 16 import java.util.LinkedHashSet ; 17 import java.lang.reflect.Field ; 18 import java.lang.reflect.Method ; 19 20 21 25 public abstract class ObjectModelBindingFactory 26 { 27 public static ObjectModelBindingFactory newInstance() 28 { 29 return new ObjectModelBindingFactoryImpl(); 30 } 31 32 public abstract ObjectModelBinding newObjectModelBinding(); 33 34 public abstract FinalClassBinding bindFinalClass(ObjectModelBinding om, 35 Class cls, 36 String namespaceUri, 37 String elementName); 38 39 public abstract FieldBinding bindFieldToAttribute(FinalClassBinding cls, 40 String fieldName, 41 String namespaceUri, 42 String attributeName); 43 44 public abstract FieldBinding bindField(FinalClassBinding cls, String fieldName); 45 46 public abstract FieldBinding bindField(NonFinalClassBinding cls, String fieldName); 47 48 public abstract FieldGroupSequenceBinding bindFieldGroupSequence(FinalClassBinding cls); 49 50 public abstract FieldGroupSequenceBinding bindFieldGroupSequence(NonFinalClassBinding cls); 51 52 public abstract FieldGroupChoiceBinding bindFieldGroupChoice(FinalClassBinding cls); 53 54 public abstract FieldGroupChoiceBinding bindFieldGroupChoice(NonFinalClassBinding cls); 55 56 public abstract FieldGroupSequenceBinding bindFieldGroupSequence(FieldGroupBinding group); 57 58 public abstract FieldGroupChoiceBinding bindFieldGroupChoice(FieldGroupBinding group); 59 60 public abstract FieldBinding bindField(FieldGroupBinding group, String fieldName); 61 62 public abstract SimpleValueBinding bindSimpleValue(FieldBinding field, String namespaceUri, String elementName); 63 64 public abstract FinalClassBinding bindFinalClassValue(FieldBinding field, String namespaceUri, String elementName); 65 66 public abstract NonFinalClassBinding bindNonFinalClassValue(FieldBinding field); 67 68 public abstract NonFinalClassBinding bindNonFinalClass(NonFinalClassBinding parentClass, Class subclass); 69 70 public abstract FinalClassBinding bindFinalClass(NonFinalClassBinding parentClass, 71 Class subclass, 72 String namespaceUri, 73 String elementName); 74 75 public abstract CollectionBinding bindCollectionValue(FieldBinding field, String namespaceUri, String elementName); 76 77 public abstract NonFinalClassBinding bindNonFinalItem(CollectionBinding col, Class itemClass); 78 79 public abstract FinalClassBinding bindFinalItem(CollectionBinding col, 80 Class itemClass, 81 String namespaceUri, 82 String elementName); 83 84 public abstract SimpleValueBinding bindSimpleItem(CollectionBinding col, 85 Class itemClass, 86 String namespaceUri, 87 String elementName); 88 89 public abstract NonFinalClassBinding bindNonFinalClass(ObjectModelBinding om, Class cls); 90 91 93 static final class ObjectModelBindingFactoryImpl 94 extends ObjectModelBindingFactory 95 { 96 public ObjectModelBinding newObjectModelBinding() 97 { 98 return new ObjectModelBindingImpl(); 99 } 100 101 public FinalClassBinding bindFinalClass(ObjectModelBinding om, 102 Class cls, 103 String namespaceUri, 104 String elementName) 105 { 106 FinalClassBindingImpl clsBinding = new FinalClassBindingImpl(null, cls, namespaceUri, elementName); 107 ((ObjectModelBindingImpl)om).bindTop(clsBinding); 108 return clsBinding; 109 } 110 111 public FieldBinding bindFieldToAttribute(FinalClassBinding cls, 112 String fieldName, 113 String namespaceUri, 114 String attributeName) 115 { 116 FieldBinding field = new FieldBindingImpl(cls, fieldName); 117 this.bindSimpleValue(field, namespaceUri, attributeName); 118 ((FinalClassBindingImpl)cls).bindFieldToAttribute(field); 119 return field; 120 } 121 122 public FieldBinding bindField(FinalClassBinding cls, String fieldName) 123 { 124 FieldBinding field = new FieldBindingImpl(cls, fieldName); 125 ((FinalClassBindingImpl)cls).bindFieldGroup(field); 126 return field; 127 } 128 129 public FieldBinding bindField(NonFinalClassBinding cls, String fieldName) 130 { 131 FieldBinding field = new FieldBindingImpl(cls, fieldName); 132 ((NonFinalClassBindingImpl)cls).bindFieldGroup(field); 133 return field; 134 } 135 136 public FieldGroupSequenceBinding bindFieldGroupSequence(FinalClassBinding cls) 137 { 138 FieldGroupSequenceBindingImpl seq = new FieldGroupSequenceBindingImpl(cls); 139 ((FinalClassBindingImpl)cls).bindFieldGroup(seq); 140 return seq; 141 } 142 143 public FieldGroupSequenceBinding bindFieldGroupSequence(NonFinalClassBinding cls) 144 { 145 FieldGroupSequenceBindingImpl seq = new FieldGroupSequenceBindingImpl(cls); 146 ((NonFinalClassBindingImpl)cls).bindFieldGroup(seq); 147 return seq; 148 } 149 150 public FieldGroupChoiceBinding bindFieldGroupChoice(FinalClassBinding cls) 151 { 152 FieldGroupChoiceBindingImpl choice = new FieldGroupChoiceBindingImpl(cls); 153 ((FinalClassBindingImpl)cls).bindFieldGroup(choice); 154 return choice; 155 } 156 157 public FieldGroupChoiceBinding bindFieldGroupChoice(NonFinalClassBinding cls) 158 { 159 FieldGroupChoiceBindingImpl choice = new FieldGroupChoiceBindingImpl(cls); 160 ((NonFinalClassBindingImpl)cls).bindFieldGroup(choice); 161 return choice; 162 } 163 164 public FieldGroupSequenceBinding bindFieldGroupSequence(FieldGroupBinding group) 165 { 166 FieldGroupSequenceBindingImpl seq = new FieldGroupSequenceBindingImpl(group.getDeclaringClassBinding()); 167 bindFieldGroup(group, seq); 168 return seq; 169 } 170 171 public FieldGroupChoiceBinding bindFieldGroupChoice(FieldGroupBinding group) 172 { 173 FieldGroupChoiceBindingImpl choice = new FieldGroupChoiceBindingImpl(group.getDeclaringClassBinding()); 174 bindFieldGroup(group, choice); 175 return choice; 176 } 177 178 public FieldBinding bindField(FieldGroupBinding group, String fieldName) 179 { 180 FieldBinding field = new FieldBindingImpl(group.getDeclaringClassBinding(), fieldName); 181 bindFieldGroup(group, field); 182 return field; 183 } 184 185 public SimpleValueBinding bindSimpleValue(FieldBinding field, String namespaceUri, String elementName) 186 { 187 SimpleValueBinding value = new SimpleValueBindingImpl(field, field.getFieldType(), namespaceUri, elementName); 188 ((FieldBindingImpl)field).bindValue(value); 189 return value; 190 } 191 192 public FinalClassBinding bindFinalClassValue(FieldBinding field, String namespaceUri, String elementName) 193 { 194 FinalClassBinding value = new FinalClassBindingImpl(field, field.getFieldType(), namespaceUri, elementName); 195 ((FieldBindingImpl)field).bindValue(value); 196 return value; 197 } 198 199 public NonFinalClassBinding bindNonFinalClassValue(FieldBinding field) 200 { 201 NonFinalClassBinding value = new NonFinalClassBindingImpl(field, field.getFieldType()); 202 ((FieldBindingImpl)field).bindValue(value); 203 return value; 204 } 205 206 public NonFinalClassBinding bindNonFinalClass(NonFinalClassBinding parentClass, Class subclass) 207 { 208 NonFinalClassBindingImpl parent = ((NonFinalClassBindingImpl)parentClass); 209 NonFinalClassBinding subclassBinding = new NonFinalClassBindingImpl(parentClass.getFieldBinding(), 210 subclass, 211 parent.fieldGroups, 212 parent.fieldToAttribute 213 ); 214 parent.bindSubclass(subclassBinding); 215 return subclassBinding; 216 } 217 218 public FinalClassBinding bindFinalClass(NonFinalClassBinding parentClass, 219 Class subclass, 220 String namespaceUri, 221 String elementName) 222 { 223 NonFinalClassBindingImpl parent = ((NonFinalClassBindingImpl)parentClass); 224 FinalClassBinding subclassBinding = new FinalClassBindingImpl(parentClass.getFieldBinding(), 225 subclass, 226 namespaceUri, 227 elementName, 228 parent.fieldGroups, 229 parent.fieldToAttribute 230 ); 231 parent.bindSubclass(subclassBinding); 232 return subclassBinding; 233 } 234 235 public CollectionBinding bindCollectionValue(FieldBinding field, String namespaceUri, String elementName) 236 { 237 CollectionBinding value = new CollectionBindingImpl(field, field.getFieldType(), namespaceUri, elementName); 238 ((FieldBindingImpl)field).bindValue(value); 239 return value; 240 } 241 242 public NonFinalClassBinding bindNonFinalItem(CollectionBinding col, Class itemClass) 243 { 244 NonFinalClassBinding item = new NonFinalClassBindingImpl(null, itemClass); 245 ((CollectionBindingImpl)col).bindItem(item); 246 return item; 247 } 248 249 public FinalClassBinding bindFinalItem(CollectionBinding col, 250 Class itemClass, 251 String namespaceUri, 252 String elementName) 253 { 254 FinalClassBinding item = new FinalClassBindingImpl(null, itemClass, namespaceUri, elementName); 255 ((CollectionBindingImpl)col).bindItem(item); 256 return item; 257 } 258 259 public SimpleValueBinding bindSimpleItem(CollectionBinding col, 260 Class itemClass, 261 String namespaceUri, 262 String elementName) 263 { 264 SimpleValueBinding item = new SimpleValueBindingImpl(null, itemClass, namespaceUri, elementName); 265 ((CollectionBindingImpl)col).bindItem(item); 266 return item; 267 } 268 269 public NonFinalClassBinding bindNonFinalClass(ObjectModelBinding om, Class cls) 270 { 271 NonFinalClassBinding clsBinding = new NonFinalClassBindingImpl(null, cls); 272 ((ObjectModelBindingImpl)om).bindTop(clsBinding); 273 return clsBinding; 274 } 275 276 278 private void bindFieldGroup(FieldGroupBinding group, FieldGroupBinding subgroup) 279 { 280 switch(group.getCategory()) 281 { 282 case FieldGroupBinding.SEQUENCE: 283 ((FieldGroupSequenceBindingImpl)group).bindGroup(subgroup); 284 break; 285 case FieldGroupBinding.CHOICE: 286 ((FieldGroupChoiceBindingImpl)group).bindGroup(subgroup); 287 break; 288 case FieldGroupBinding.FIELD: 289 throw new JBossXBRuntimeException("Field binding can't contain nested field groups!"); 290 default: 291 throw new JBossXBRuntimeException("Unexpected field group category: " + group.getCategory()); 292 } 293 } 294 } 295 296 static final class ObjectModelBindingImpl 297 implements ObjectModelBinding 298 { 299 private final Map tops = new HashMap (); 300 301 void bindTop(FieldValueBinding fieldValue) 302 { 303 tops.put(fieldValue.getJavaClass(), fieldValue); 304 } 305 306 public FieldValueBinding getTopClass(Class cls) 307 { 308 return (FieldValueBinding)tops.get(cls); 309 } 310 } 311 312 static abstract class AbstractFieldValueBinding 313 implements FieldValueBinding 314 { 315 private final FieldBinding field; 316 private final Class javaClass; 317 318 protected AbstractFieldValueBinding(FieldBinding field, Class javaClass) 319 { 320 this.javaClass = javaClass; 321 this.field = field; 322 } 323 324 public FieldBinding getFieldBinding() 325 { 326 return field; 327 } 328 329 public Class getJavaClass() 330 { 331 return javaClass; 332 } 333 } 334 335 static abstract class AbstractBaseClassBinding 336 extends AbstractFieldValueBinding 337 implements BaseClassBinding 338 { 339 final LinkedHashSet fieldGroups; 341 final LinkedHashSet fieldToAttribute; 342 343 public AbstractBaseClassBinding(FieldBinding field, 344 Class javaClass, 345 Collection inheritedFieldGroups, 346 Collection inheritedFieldToAttribute) 347 { 348 super(field, javaClass); 349 this.fieldGroups = inheritedFieldGroups == null ? 350 new LinkedHashSet () : 351 new LinkedHashSet (inheritedFieldGroups); 352 this.fieldToAttribute = inheritedFieldToAttribute == null ? 353 new LinkedHashSet () : 354 new LinkedHashSet (inheritedFieldToAttribute); 355 } 356 357 void bindFieldGroup(FieldGroupBinding group) 358 { 359 fieldGroups.add(group); 360 } 361 362 void bindFieldToAttribute(FieldBinding field) 363 { 364 fieldToAttribute.add(field); 365 } 366 367 public FieldBinding[] getFieldToAttributeBindings() 368 { 369 return (FieldBinding[])fieldToAttribute.toArray(new FieldBinding[fieldToAttribute.size()]); 370 } 371 372 public FieldGroupBinding[] getFieldGroups() 373 { 374 return (FieldGroupBinding[])fieldGroups.toArray(new FieldGroupBinding[fieldGroups.size()]); 375 } 376 } 377 378 static final class SimpleValueBindingImpl 379 extends AbstractFieldValueBinding 380 implements SimpleValueBinding 381 { 382 private final String namespaceUri; 383 private final String elementName; 384 385 public SimpleValueBindingImpl(FieldBinding field, Class javaClass, String namespaceUri, String elementName) 386 { 387 super(field, javaClass); 388 this.namespaceUri = namespaceUri; 389 this.elementName = elementName; 390 } 391 392 public int getCategory() 393 { 394 return FieldValueBinding.SIMPLE_VALUE; 395 } 396 397 public String getNamespaceUri() 398 { 399 return namespaceUri; 400 } 401 402 public String getElementName() 403 { 404 return elementName; 405 } 406 } 407 408 static final class FinalClassBindingImpl 409 extends AbstractBaseClassBinding 410 implements FinalClassBinding 411 { 412 private final String namespaceUri; 413 private final String elementName; 414 415 public FinalClassBindingImpl(FieldBinding field, Class javaClass, String namespaceUri, String elementName) 416 { 417 this(field, javaClass, namespaceUri, elementName, null, null); 418 } 419 420 public FinalClassBindingImpl(FieldBinding field, 421 Class javaClass, 422 String namespaceUri, 423 String elementName, 424 Collection inheritedFieldGroups, 425 Collection inheritedFieldToAttribute) 426 { 427 super(field, javaClass, inheritedFieldGroups, inheritedFieldToAttribute); 428 this.namespaceUri = namespaceUri; 429 this.elementName = elementName; 430 } 431 432 public int getCategory() 433 { 434 return FieldValueBinding.FINAL_CLASS; 435 } 436 437 public String getNamespaceUri() 438 { 439 return namespaceUri; 440 } 441 442 public String getElementName() 443 { 444 return elementName; 445 } 446 } 447 448 static final class NonFinalClassBindingImpl 449 extends AbstractBaseClassBinding 450 implements NonFinalClassBinding 451 { 452 private final Map subclasses = new HashMap (); 453 454 public NonFinalClassBindingImpl(FieldBinding field, Class javaClass) 455 { 456 this(field, javaClass, null, null); 457 } 458 459 public NonFinalClassBindingImpl(FieldBinding field, 460 Class javaClass, 461 Collection inheritedFieldGroups, 462 Collection inheritedFieldToAttribute) 463 { 464 super(field, javaClass, inheritedFieldGroups, inheritedFieldToAttribute); 465 } 466 467 void bindSubclass(FieldValueBinding subclass) 468 { 469 subclasses.put(subclass.getJavaClass(), subclass); 470 } 471 472 public int getCategory() 473 { 474 return FieldValueBinding.NON_FINAL_CLASS; 475 } 476 477 public FieldValueBinding getSubclassBinding(Class type) 478 { 479 return (FieldValueBinding)subclasses.get(type); 480 } 481 } 482 483 static final class CollectionBindingImpl 484 extends AbstractFieldValueBinding 485 implements CollectionBinding 486 { 487 private final String namespaceUri; 488 private final String elementName; 489 private final Map items = new HashMap (); 490 491 public CollectionBindingImpl(FieldBinding field, Class javaClass, String namespaceUri, String elementName) 492 { 493 super(field, javaClass); 494 this.namespaceUri = namespaceUri; 495 this.elementName = elementName; 496 } 497 498 void bindItem(FieldValueBinding item) 499 { 500 items.put(item.getJavaClass(), item); 501 } 502 503 public int getCategory() 504 { 505 return FieldValueBinding.COLLECTION; 506 } 507 508 public String getNamespaceUri() 509 { 510 return namespaceUri; 511 } 512 513 public String getElementName() 514 { 515 return elementName; 516 } 517 518 public FieldValueBinding getItemBinding(Class type) 519 { 520 return (FieldValueBinding)items.get(type); 521 } 522 } 523 524 static abstract class AbstractFieldGroupBindingImpl 525 implements FieldGroupBinding 526 { 527 private final BaseClassBinding owner; 528 529 protected AbstractFieldGroupBindingImpl(BaseClassBinding owner) 530 { 531 this.owner = owner; 532 } 533 534 public BaseClassBinding getDeclaringClassBinding() 535 { 536 return owner; 537 } 538 } 539 540 static final class FieldGroupSequenceBindingImpl 541 extends AbstractFieldGroupBindingImpl 542 implements FieldGroupSequenceBinding 543 { 544 private final List groups = new ArrayList (); 545 546 public FieldGroupSequenceBindingImpl(BaseClassBinding owner) 547 { 548 super(owner); 549 } 550 551 void bindGroup(FieldGroupBinding group) 552 { 553 groups.add(group); 554 } 555 556 public FieldGroupBinding[] getFieldGroups() 557 { 558 return (FieldGroupBinding[])groups.toArray(new FieldGroupBinding[groups.size()]); 559 } 560 561 public int getCategory() 562 { 563 return FieldGroupBinding.SEQUENCE; 564 } 565 566 public boolean equals(Object o) 567 { 568 if(this == o) 569 { 570 return true; 571 } 572 if(!(o instanceof FieldGroupSequenceBindingImpl)) 573 { 574 return false; 575 } 576 577 final FieldGroupSequenceBindingImpl fieldGroupSequenceBinding = (FieldGroupSequenceBindingImpl)o; 578 579 if(!groups.equals(fieldGroupSequenceBinding.groups)) 580 { 581 return false; 582 } 583 584 return true; 585 } 586 587 public int hashCode() 588 { 589 return groups.hashCode(); 590 } 591 } 592 593 static final class FieldGroupChoiceBindingImpl 594 extends AbstractFieldGroupBindingImpl 595 implements FieldGroupChoiceBinding 596 { 597 private final List groups = new ArrayList (); 598 599 public FieldGroupChoiceBindingImpl(BaseClassBinding owner) 600 { 601 super(owner); 602 } 603 604 void bindGroup(FieldGroupBinding group) 605 { 606 groups.add(group); 607 } 608 609 public FieldGroupBinding[] getFieldGroups() 610 { 611 return (FieldGroupBinding[])groups.toArray(new FieldGroupBinding[groups.size()]); 612 } 613 614 public int getCategory() 615 { 616 return FieldGroupBinding.CHOICE; 617 } 618 619 public boolean equals(Object o) 620 { 621 if(this == o) 622 { 623 return true; 624 } 625 if(!(o instanceof FieldGroupChoiceBindingImpl)) 626 { 627 return false; 628 } 629 630 final FieldGroupChoiceBindingImpl fieldGroupChoiceBinding = (FieldGroupChoiceBindingImpl)o; 631 632 if(!groups.equals(fieldGroupChoiceBinding.groups)) 633 { 634 return false; 635 } 636 637 return true; 638 } 639 640 public int hashCode() 641 { 642 return groups.hashCode(); 643 } 644 } 645 646 static final class FieldBindingImpl 647 extends AbstractFieldGroupBindingImpl 648 implements FieldBinding 649 { 650 private final String fieldName; 651 private final Field field; 652 private final Method getter; 653 private final Class fieldType; 654 private FieldValueBinding value; 655 656 public FieldBindingImpl(BaseClassBinding owner, String fieldName) 657 { 658 super(owner); 659 660 Class ownerClass = owner.getJavaClass(); 661 662 this.fieldName = fieldName; 663 664 Field field = null; 665 Method getter = null; 666 Class fieldType; 667 668 String getterName = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); 669 try 670 { 671 getter = ownerClass.getMethod(getterName, null); 672 fieldType = getter.getReturnType(); 673 } 674 catch(NoSuchMethodException e1) 675 { 676 try 677 { 678 field = ownerClass.getField(fieldName); 679 fieldType = field.getType(); 680 } 681 catch(NoSuchFieldException e) 682 { 683 throw new JBossXBRuntimeException( 684 "Failed to bind field " + fieldName + " in " + owner + ": neither field nor getter were found." 685 ); 686 } 687 } 688 689 this.field = field; 690 this.getter = getter; 691 this.fieldType = fieldType; 692 } 693 694 void bindValue(FieldValueBinding value) 695 { 696 this.value = value; 697 } 698 699 public String getFieldName() 700 { 701 return fieldName; 702 } 703 704 public Field getField() 705 { 706 return field; 707 } 708 709 public Method getGetter() 710 { 711 return getter; 712 } 713 714 public Class getFieldType() 715 { 716 return fieldType; 717 } 718 719 public FieldValueBinding getValueBinding() 720 { 721 return value; 722 } 723 724 public int getCategory() 725 { 726 return FieldGroupBinding.FIELD; 727 } 728 729 public boolean equals(Object o) 730 { 731 if(this == o) 732 { 733 return true; 734 } 735 if(!(o instanceof FieldBindingImpl)) 736 { 737 return false; 738 } 739 740 final FieldBindingImpl fieldBinding = (FieldBindingImpl)o; 741 742 if(!fieldName.equals(fieldBinding.fieldName)) 743 { 744 return false; 745 } 746 747 return true; 748 } 749 750 public int hashCode() 751 { 752 return fieldName.hashCode(); 753 } 754 } 755 } 756 | Popular Tags |