1 28 29 package org.jibx.binding; 30 31 import java.io.FileNotFoundException; 32 import java.io.FileOutputStream; 33 import java.io.PrintStream; 34 import java.util.ArrayList; 35 import java.util.Arrays; 36 import java.util.HashMap; 37 import java.util.HashSet; 38 import java.util.Iterator; 39 40 import org.apache.bcel.classfile.Field; 41 import org.apache.bcel.classfile.JavaClass; 42 import org.jibx.binding.classes.ClassCache; 43 import org.jibx.binding.classes.ClassFile; 44 import org.jibx.binding.classes.ClassItem; 45 import org.jibx.binding.model.BindingElement; 46 import org.jibx.binding.model.CollectionElement; 47 import org.jibx.binding.model.ContainerElementBase; 48 import org.jibx.binding.model.MappingElement; 49 import org.jibx.binding.model.NamespaceElement; 50 import org.jibx.binding.model.StructureElement; 51 import org.jibx.binding.model.StructureElementBase; 52 import org.jibx.binding.model.ValueElement; 53 import org.jibx.binding.util.ObjectStack; 54 import org.jibx.runtime.BindingDirectory; 55 import org.jibx.runtime.IBindingFactory; 56 import org.jibx.runtime.IMarshallingContext; 57 import org.jibx.runtime.JiBXException; 58 59 66 67 public class BindingGenerator 68 { 69 70 private static String CURRENT_VERSION = "0.2"; 71 72 73 private static HashSet s_objectPrimitiveSet = new HashSet(); 74 75 static { 76 s_objectPrimitiveSet.add("java.lang.Boolean"); 77 s_objectPrimitiveSet.add("java.lang.Byte"); 78 s_objectPrimitiveSet.add("java.lang.Char"); 79 s_objectPrimitiveSet.add("java.lang.Double"); 80 s_objectPrimitiveSet.add("java.lang.Float"); 81 s_objectPrimitiveSet.add("java.lang.Integer"); 82 s_objectPrimitiveSet.add("java.lang.Long"); 83 s_objectPrimitiveSet.add("java.lang.Short"); 84 s_objectPrimitiveSet.add("java.math.BigDecimal"); 85 s_objectPrimitiveSet.add("java.math.BigInteger"); 86 s_objectPrimitiveSet.add("java.sql.Date"); 87 s_objectPrimitiveSet.add("java.sql.Time"); 88 s_objectPrimitiveSet.add("java.sql.Timestamp"); 89 s_objectPrimitiveSet.add("java.util.Date"); 90 } 91 92 93 private boolean m_verbose; 94 95 96 private boolean m_mixedCase; 97 98 99 private String m_namespaceUri; 100 101 102 private HashMap m_mappedNames; 103 104 105 private HashMap m_beanNames; 106 107 108 private HashMap m_enumerationNames; 109 110 111 private ObjectStack m_structureStack; 112 113 114 private HashSet m_structureNames; 115 116 117 private HashSet m_ignoreNames; 118 119 122 public BindingGenerator() { 123 m_mappedNames = new HashMap(); 124 m_structureStack = new ObjectStack(); 125 m_structureNames = new HashSet(); 126 m_ignoreNames = new HashSet(); 127 } 128 129 136 public BindingGenerator(boolean verbose, boolean mixed, String uri) { 137 this(); 138 m_verbose = verbose; 139 m_mixedCase = mixed; 140 m_namespaceUri = uri; 141 } 142 143 148 public void setVerbose(boolean verbose) { 149 m_verbose = verbose; 150 } 151 152 157 public void setCamelCase(boolean camel) { 158 m_mixedCase = camel; 159 } 160 161 166 private void nestingIndent(PrintStream pw) { 167 for (int i = 0; i < m_structureStack.size(); i++) { 168 pw.print(' '); 169 } 170 } 171 172 178 private String convertName(String base) { 179 StringBuffer name = new StringBuffer(); 180 name.append(Character.toLowerCase(base.charAt(0))); 181 if (m_mixedCase) { 182 name.append(base.substring(1)); 183 } else { 184 boolean ignore = true; 185 for (int i = 1; i < base.length(); i++) { 186 char chr = base.charAt(i); 187 if (Character.isUpperCase(chr)) { 188 chr = Character.toLowerCase(chr); 189 if (ignore) { 190 int next = i + 1; 191 ignore = next >= base.length() || 192 Character.isUpperCase(base.charAt(next)); 193 } 194 if (ignore) { 195 name.append(chr); 196 } else { 197 name.append('-'); 198 name.append(chr); 199 ignore = true; 200 } 201 } else { 202 name.append(chr); 203 ignore = false; 204 } 205 } 206 } 207 return name.toString(); 208 } 209 210 216 public String elementName(String cname) { 217 int split = cname.lastIndexOf('.'); 218 if (split >= 0) { 219 cname = cname.substring(split+1); 220 } 221 while ((split = cname.indexOf('$')) >= 0) { 222 cname = cname.substring(0, split) + cname.substring(split+1); 223 } 224 return convertName(cname); 225 } 226 227 233 private String valueName(String fname) { 234 String base = fname; 235 if (base.startsWith("m_")) { 236 base = base.substring(2); 237 } else if (base.startsWith("_")) { 238 base = base.substring(1); 239 } else if (base.startsWith("f") && base.length() > 1) { 240 if (Character.isUpperCase(base.charAt(1))) { 241 base = base.substring(1); 242 } 243 } 244 return convertName(base); 245 } 246 247 258 private void defineFields(ClassFile cf, ContainerElementBase contain) 259 throws JiBXException { 260 261 JavaClass clas = cf.getRawClass(); 263 Field[] fields = clas.getFields(); 264 for (int i = 0; i < fields.length; i++) { 265 Field field = fields[i]; 266 if (!field.isFinal() && !field.isStatic() && !field.isTransient()) { 267 268 boolean simple = false; 270 boolean object = true; 271 boolean attribute = true; 272 String fname = field.getName(); 273 String tname = field.getType().toString(); 274 if (ClassItem.isPrimitive(tname)) { 275 simple = true; 276 object = false; 277 } else if (s_objectPrimitiveSet.contains(tname)) { 278 simple = true; 279 } else if (tname.equals("byte[]")) { 280 simple = true; 281 attribute = false; 282 } else if (tname.startsWith("java.")) { 283 284 ClassFile pcf = ClassCache.getClassFile(tname); 286 ClassItem init = pcf.getInitializerMethod 287 ("(Ljava/lang/String;)"); 288 if (init != null) { 289 simple = pcf.getMethod("toString", 290 "()Ljava/lang/String;") != null; 291 attribute = false; 292 } 293 294 } 295 296 if (m_enumerationNames.get(tname) != null) { 298 299 String mname = (String)m_enumerationNames.get(tname); 301 int split = mname.lastIndexOf('.'); 302 ClassFile dcf = 303 ClassCache.getClassFile(mname.substring(0, split)); 304 ClassItem dser = 305 dcf.getStaticMethod(mname.substring(split+1), 306 "(Ljava/lang/String;)"); 307 if (dser == null || !tname.equals(dser.getTypeName())) { 308 throw new JiBXException("Deserializer method not " + 309 "found for enumeration class " + tname); 310 } 311 ValueElement value = new ValueElement(); 312 value.setFieldName(fname); 313 value.setName(valueName(fname)); 314 value.setUsageName("optional"); 315 value.setStyleName("element"); 316 value.setDeserializerName(mname); 317 contain.addChild(value); 318 319 } else if (m_mappedNames.get(tname) != null) { 320 321 StructureElement structure = new StructureElement(); 323 structure.setUsageName("optional"); 324 structure.setFieldName(fname); 325 if (((String)m_mappedNames.get(tname)).length() == 0) { 326 327 structure.setName(elementName(tname)); 329 } 330 contain.addChild(structure); 331 if (m_verbose) { 332 nestingIndent(System.out); 333 System.out.println("referenced existing binding for " + 334 tname); 335 } 336 337 } else if (simple) { 338 339 ValueElement value = new ValueElement(); 341 value.setFieldName(fname); 342 value.setName(valueName(fname)); 343 if (object) { 344 value.setUsageName("optional"); 345 } 346 if (!attribute) { 347 value.setStyleName("element"); 348 } 349 contain.addChild(value); 350 351 } else if (tname.endsWith("[]")) { 352 353 String bname = tname.substring(0, tname.length()-2); 355 if (m_mappedNames.get(bname) == null) { 356 throw new JiBXException("Base element type " + bname + 357 " must be mapped"); 358 } else { 359 StructureElement structure = new StructureElement(); 360 structure.setUsageName("optional"); 361 structure.setFieldName(fname); 362 structure.setMarshallerName 363 ("org.jibx.extras.TypedArrayMapper"); 364 structure.setUnmarshallerName 365 ("org.jibx.extras.TypedArrayMapper"); 366 contain.addChild(structure); 367 } 368 369 } else { 370 371 ClassFile pcf = ClassCache.getClassFile(tname); 373 StructureElementBase element; 374 if (pcf.isImplements("Ljava/util/List;")) { 375 376 System.err.println("Warning: field " + fname + 378 " requires mapped implementation of item classes"); 379 element = new CollectionElement(); 380 element.setComment(" add details of collection items " + 381 "to complete binding definition "); 382 element.setFieldName(fname); 383 384 if ("java.util.List".equals(tname)) { 386 element.setFactoryName 387 ("org.jibx.runtime.Utility.arrayListFactory"); 388 } 389 390 } else if (pcf.isInterface() || 391 m_ignoreNames.contains(tname)) { 392 393 nestingIndent(System.err); 395 System.err.println("Warning: reference to interface " + 396 "or abstract class " + tname + 397 " requires mapped implementation"); 398 element = new StructureElement(); 399 element.setFieldName(fname); 400 401 } else { 402 403 element = createStructure(pcf, fname); 405 } 406 407 element.setUsageName("optional"); 409 contain.addChild(element); 410 411 } 412 } 413 } 414 } 415 416 429 private void defineProperties(ClassFile cf, ArrayList props, 430 boolean internal, ContainerElementBase contain) throws JiBXException { 431 432 for (int i = 0; i < props.size(); i++) { 434 String pname = (String)props.get(i); 435 String base = Character.toUpperCase(pname.charAt(0)) + 436 pname.substring(1); 437 String gname = "get" + base; 438 ClassItem gmeth = cf.getMethod(gname, "()"); 439 if (gmeth == null) { 440 throw new JiBXException("No method " + gname + 441 "() found for property " + base + " in class " + 442 cf.getName()); 443 } else { 444 String tname = gmeth.getTypeName(); 445 String sname = "set" + base; 446 String sig = "(" + gmeth.getSignature().substring(2) + ")V"; 447 ClassItem smeth = cf.getMethod(sname, sig); 448 if (smeth == null) { 449 throw new JiBXException("No method " + sname + "(" + tname + 450 ") found for property " + base + " in class " + 451 cf.getName()); 452 } else { 453 454 boolean simple = false; 456 boolean object = true; 457 boolean attribute = true; 458 if (ClassItem.isPrimitive(tname)) { 459 simple = true; 460 object = false; 461 } else if (s_objectPrimitiveSet.contains(tname)) { 462 simple = true; 463 } else if (tname.equals("byte[]")) { 464 simple = true; 465 attribute = false; 466 } else if (tname.startsWith("java.")) { 467 468 ClassFile pcf = ClassCache.getClassFile(tname); 470 if (pcf.getInitializerMethod("()") != null) { 471 simple = pcf.getMethod("toString", 472 "()Ljava/lang/String;") != null; 473 attribute = false; 474 } 475 476 } 477 if (simple) { 478 479 ValueElement value = new ValueElement(); 481 value.setGetName(gname); 482 value.setSetName(sname); 483 value.setName(valueName(pname)); 484 if (object) { 485 value.setUsageName("optional"); 486 } 487 if (!attribute) { 488 value.setStyleName("element"); 489 } 490 contain.addChild(value); 491 492 } else if (m_enumerationNames.get(tname) != null) { 493 494 String mname = (String)m_enumerationNames.get(tname); 496 int split = mname.lastIndexOf('.'); 497 ClassFile dcf = 498 ClassCache.getClassFile(mname.substring(0, split)); 499 ClassItem dser = 500 dcf.getStaticMethod(mname.substring(split+1), 501 "(Ljava/lang/String;)"); 502 if (dser == null || !tname.equals(dser.getTypeName())) { 503 throw new JiBXException("Deserializer method not " + 504 "found for enumeration class " + tname); 505 } 506 ValueElement value = new ValueElement(); 507 value.setGetName(gname); 508 value.setSetName(sname); 509 value.setName(valueName(pname)); 510 value.setUsageName("optional"); 511 value.setStyleName("element"); 512 value.setDeserializerName(mname); 513 contain.addChild(value); 514 515 } else if (m_mappedNames.get(tname) != null) { 516 517 StructureElement structure = new StructureElement(); 519 structure.setUsageName("optional"); 520 structure.setGetName(gname); 521 structure.setSetName(sname); 522 if (((String)m_mappedNames.get(tname)).length() == 0) { 523 524 structure.setName(elementName(tname)); 526 } 527 contain.addChild(structure); 528 if (m_verbose) { 529 nestingIndent(System.out); 530 System.out.println 531 ("referenced existing binding for " + tname); 532 } 533 534 } else if (tname.endsWith("[]")) { 535 536 String bname = tname.substring(0, tname.length()-2); 538 if (m_mappedNames.get(bname) == null) { 539 throw new JiBXException("Base element type " + 540 bname + " must be mapped"); 541 } else { 542 StructureElement structure = new StructureElement(); 543 structure.setUsageName("optional"); 544 structure.setGetName(gname); 545 structure.setSetName(sname); 546 structure.setMarshallerName 547 ("org.jibx.extras.TypedArrayMapper"); 548 structure.setUnmarshallerName 549 ("org.jibx.extras.TypedArrayMapper"); 550 contain.addChild(structure); 551 } 552 553 } else { 554 555 ClassFile pcf = ClassCache.getClassFile(tname); 557 StructureElementBase element; 558 if (pcf.isImplements("Ljava/util/List;")) { 559 560 System.err.println("Warning: property " + pname + 562 " requires mapped implementation of item " + 563 "classes"); 564 element = new CollectionElement(); 565 element.setComment(" add details of collection " + 566 "items to complete binding definition "); 567 element.setGetName(gname); 568 element.setSetName(sname); 569 570 if ("java.util.List".equals(tname)) { 572 element.setFactoryName("org.jibx.runtime." + 573 "Utility.arrayListFactory"); 574 } 575 576 } else if (pcf.isInterface() || 577 m_ignoreNames.contains(tname)) { 578 579 nestingIndent(System.err); 581 System.err.println("Warning: reference to " + 582 "interface or abstract class " + tname + 583 " requires mapped implementation"); 584 element = new StructureElement(); 585 element.setGetName(gname); 586 element.setSetName(sname); 587 588 } else { 589 590 element = createStructure(pcf, pname); 592 } 593 594 element.setUsageName("optional"); 596 contain.addChild(element); 597 598 } 599 } 600 } 601 } 602 } 603 604 615 private void defineStructure(ClassFile cf, ContainerElementBase contain) 616 throws JiBXException { 617 618 Object props = m_beanNames.get(cf.getName()); 620 if (props == null) { 621 defineFields(cf, contain); 622 } else { 623 defineProperties(cf, (ArrayList)props, true, contain); 624 } 625 626 ClassFile sf = cf.getSuperFile(); 628 String sname = sf.getName(); 629 if (!"java.lang.Object".equals(sname) && 630 !m_ignoreNames.contains(sname)) { 631 if (m_mappedNames.get(sname) != null) { 632 StructureElement structure = new StructureElement(); 633 structure.setMapAsName(sname); 634 structure.setName(elementName(sname)); 635 contain.addChild(structure); 636 } else if (m_beanNames.get(sname) != null) { 637 defineProperties(sf, (ArrayList)m_beanNames.get(sname), 638 false, contain); 639 } else if (sf.getRawClass().getFields().length > 0) { 640 nestingIndent(System.err); 641 System.err.println("Warning: fields from base class " + sname + 642 " of class " + cf.getName() + " not handled by generated " + 643 "binding; use mapping or specify property list"); 644 contain.setComment(" missing information for base class " + 645 sname + " "); 646 } 647 } 648 } 649 650 659 private StructureElement createStructure(ClassFile cf, String fname) 660 throws JiBXException { 661 JavaClass clas = cf.getRawClass(); 662 if (m_verbose) { 663 nestingIndent(System.out); 664 System.out.println("creating nested structure definition for " + 665 clas.getClassName()); 666 } 667 String cname = clas.getClassName(); 668 for (int i = 0; i < m_structureStack.size(); i++) { 669 if (cname.equals(m_structureStack.peek(i))) { 670 StringBuffer buff = 671 new StringBuffer("Error: recursive use of "); 672 buff.append(cname); 673 buff.append(" requires <mapping>:\n "); 674 while (i >= 0) { 675 buff.append(m_structureStack.peek(i--)); 676 buff.append(" -> "); 677 } 678 buff.append(cname); 679 throw new JiBXException(buff.toString()); 680 } 681 } 682 if (cname.startsWith("java.")) { 683 nestingIndent(System.err); 684 System.err.println("Warning: trying to create structure for " + 685 cname); 686 } else if (m_structureNames.contains(cname)) { 687 nestingIndent(System.err); 688 System.err.println("Warning: repeated usage of class " + 689 cname + "; consider adding to mapping list"); 690 } else { 691 m_structureNames.add(cname); 692 } 693 m_structureStack.push(cname); 694 StructureElement element = new StructureElement(); 695 element.setFieldName(fname); 696 element.setName(valueName(fname)); 697 defineStructure(cf, element); 698 if (element.children().isEmpty()) { 699 throw new JiBXException("No content found for class " + cname); 700 } 701 m_structureStack.pop(); 702 if (m_verbose) { 703 nestingIndent(System.out); 704 System.out.println("completed nested structure definition for " + 705 clas.getClassName()); 706 } 707 return element; 708 } 709 710 719 private MappingElement createMapping(ClassFile cf, boolean abstr) 720 throws JiBXException { 721 JavaClass clas = cf.getRawClass(); 722 if (m_verbose) { 723 System.out.println("\nBuilding mapping definition for " + 724 clas.getClassName()); 725 } 726 MappingElement element = new MappingElement(); 727 element.setAbstract(abstr || clas.isAbstract() || clas.isInterface()); 728 String name = clas.getClassName(); 729 element.setClassName(name); 730 if (abstr) { 731 element.setAbstract(true); 732 } else { 733 element.setName((String)m_mappedNames.get(name)); 734 } 735 m_structureStack.push(name); 736 defineStructure(cf, element); 737 m_structureStack.pop(); 738 return element; 739 } 740 741 private static boolean isMappable(String cname) { 742 if ("java.lang.String".equals(cname)) { 743 return false; 744 } else if ("java.lang.Object".equals(cname)) { 745 return false; 746 } else if (ClassItem.isPrimitive(cname)) { 747 return false; 748 } else { 749 return !s_objectPrimitiveSet.contains(cname); 750 } 751 } 752 753 767 public static void findClassesUsed(String cname, ArrayList mnames, 768 HashSet dataset, HashSet exceptset) throws JiBXException { 769 ClassFile cf = ClassCache.getClassFile(cname); 770 if (cf != null) { 771 for (int i = 0; i < mnames.size(); i++) { 772 String mname = (String)mnames.get(i); 773 ClassItem mitem = cf.getMethod(mname, ""); 774 if (mitem == null) { 775 System.err.println("Method " + mname + 776 " not found in class " + cname); 777 } else { 778 if (dataset != null) { 779 String type = mitem.getTypeName(); 780 if (type != null && isMappable(type)) { 781 dataset.add(type); 782 } 783 String[] args = mitem.getArgumentTypes(); 784 for (int j = 0; j < args.length; j++) { 785 type = args[j]; 786 if (isMappable(type)) { 787 dataset.add(args[j]); 788 } 789 } 790 } 791 if (exceptset != null) { 792 String[] excepts = mitem.getExceptions(); 793 for (int j = 0; j < excepts.length; j++) { 794 exceptset.add(excepts[j]); 795 } 796 } 797 } 798 } 799 } 800 } 801 802 816 public BindingElement generate(ArrayList names, HashSet abstracts, 817 HashMap customs, HashMap beans, HashMap enums, ArrayList ignores) 818 throws JiBXException { 819 820 System.out.println("Running binding generator version " + 822 CURRENT_VERSION); 823 824 m_mappedNames.clear(); 826 for (int i = 0; i < names.size(); i++) { 827 828 boolean drop = false; 830 String name = (String)names.get(i); 831 ClassFile cf = ClassCache.getClassFile(name); 832 if (cf.isImplements("Ljava/util/List;") || 833 cf.isImplements("Ljava/util/Map;")) { 834 System.err.println("Warning: referenced class " + name + 835 " is a collection class that cannot be mapped " + 836 "automatically; dropped from mapped list in binding"); 837 drop = true; 838 } else if (cf.isInterface()) { 839 System.err.println("Warning: interface " + name + 840 " is being handled as abstract mapping"); 841 abstracts.add(name); 842 drop = true; 843 } else if (cf.isAbstract()) { 844 System.err.println("Warning: mapping abstract class " + name + 845 "; make sure actual subclasses are mapped as extending " + 846 "this abstract mapping"); 847 abstracts.add(name); 848 drop = true; 849 } 850 if (drop) { 851 names.remove(i--); 852 } else { 853 m_mappedNames.put(name, elementName(name)); 854 } 855 } 856 for (Iterator iter = abstracts.iterator(); iter.hasNext();) { 857 m_mappedNames.put((String)iter.next(), ""); 858 } 859 for (Iterator iter = customs.keySet().iterator(); iter.hasNext();) { 860 String name = (String)iter.next(); 861 m_mappedNames.put(name, elementName(name)); 862 } 863 864 m_ignoreNames.clear(); 866 m_ignoreNames.addAll(ignores); 867 868 BindingElement binding = new BindingElement(); 870 binding.setStyleName("attribute"); 871 if (m_namespaceUri != null) { 872 NamespaceElement namespace = new NamespaceElement(); 873 namespace.setComment(" namespace for all elements of binding "); 874 namespace.setDefaultName("elements"); 875 namespace.setUri(m_namespaceUri); 876 binding.addTopChild(namespace); 877 } 878 879 m_structureStack.clear(); 881 m_structureNames.clear(); 882 m_beanNames = beans; 883 m_enumerationNames = enums; 884 for (int i = 0; i < names.size(); i++) { 885 String cname = (String)names.get(i); 886 if (!abstracts.contains(cname)) { 887 ClassFile cf = ClassCache.getClassFile(cname); 888 MappingElement mapping = createMapping(cf, false); 889 mapping.setComment(" generated mapping for class " + cname); 890 binding.addTopChild(mapping); 891 } 892 } 893 for (Iterator iter = abstracts.iterator(); iter.hasNext();) { 894 String cname = (String)iter.next(); 895 ClassFile cf = ClassCache.getClassFile(cname); 896 MappingElement mapping = createMapping(cf, true); 897 mapping.setComment(" generate abstract mapping for class " + cname); 898 binding.addTopChild(mapping); 899 } 900 901 for (Iterator iter = customs.keySet().iterator(); iter.hasNext();) { 903 String cname = (String)iter.next(); 904 String mname = (String)customs.get(cname); 905 MappingElement mapping = new MappingElement(); 906 mapping.setComment(" specified mapping for class " + cname); 907 mapping.setClassName(cname); 908 mapping.setName((String)m_mappedNames.get(cname)); 909 mapping.setMarshallerName(mname); 910 mapping.setUnmarshallerName(mname); 911 binding.addTopChild(mapping); 912 } 913 914 if (m_verbose) { 916 for (int i = 0; i < names.size(); i++) { 917 m_structureNames.add(names.get(i)); 918 } 919 m_structureNames.addAll(customs.keySet()); 920 String[] classes = (String[])m_structureNames. 921 toArray(new String[m_structureNames.size()]); 922 Arrays.sort(classes); 923 System.out.println("\nClasses included in binding:"); 924 for (int i = 0; i < classes.length; i++) { 925 System.out.println(" " + classes[i]); 926 } 927 } 928 return binding; 929 } 930 931 936 public static void main(String[] args) { 937 if (args.length > 0) { 938 try { 939 940 boolean mixed = false; 942 boolean verbose = false; 943 String uri = null; 944 String fname = "binding.xml"; 945 ArrayList paths = new ArrayList(); 946 HashMap enums = new HashMap(); 947 HashSet abstracts = new HashSet(); 948 ArrayList ignores = new ArrayList(); 949 HashMap customs = new HashMap(); 950 HashMap beans = new HashMap(); 951 int offset = 0; 952 for (; offset < args.length; offset++) { 953 String arg = args[offset]; 954 if ("-v".equalsIgnoreCase(arg)) { 955 verbose = true; 956 } else if ("-b".equalsIgnoreCase(arg)) { 957 String plist = args[++offset]; 958 int split = plist.indexOf("="); 959 String bname = plist.substring(0, split); 960 ArrayList props = new ArrayList(); 961 int base = ++split; 962 while ((split = plist.indexOf(',', split)) >= 0) { 963 props.add(plist.substring(base, split)); 964 base = ++split; 965 } 966 props.add(plist.substring(base)); 967 beans.put(bname, props); 968 } else if ("-c".equalsIgnoreCase(arg)) { 969 String custom = args[++offset]; 970 int split = custom.indexOf('='); 971 if (split > 0) { 972 customs.put(custom.substring(0, split), 973 custom.substring(split+1)); 974 } else { 975 System.err.println 976 ("Unable to interpret customization " + custom); 977 } 978 } else if ("-e".equalsIgnoreCase(arg)) { 979 String cname; 980 String mname; 981 String enum = args[++offset]; 982 int split = enum.indexOf('='); 983 if (split > 0) { 984 cname = enum.substring(0, split); 985 mname = enum.substring(split+1); 986 if (mname.indexOf('.') < 0) { 987 mname = cname + '.' + mname; 988 } 989 } else { 990 cname = enum; 991 split = cname.lastIndexOf('.'); 992 if (split >= 0) { 993 mname = cname + '.' + "get" + 994 cname.substring(split+1); 995 } else { 996 mname = cname + '.' + "get" + cname; 997 } 998 } 999 enums.put(cname, mname); 1000 } else if ("-i".equalsIgnoreCase(arg)) { 1001 ignores.add(args[++offset]); 1002 } else if ("-m".equalsIgnoreCase(arg)) { 1003 mixed = true; 1004 } else if ("-f".equalsIgnoreCase(arg)) { 1005 fname = args[++offset]; 1006 } else if ("-n".equalsIgnoreCase(arg)) { 1007 uri = args[++offset]; 1008 } else if ("-p".equalsIgnoreCase(arg)) { 1009 paths.add(args[++offset]); 1010 } else if ("-a".equalsIgnoreCase(arg)) { 1011 abstracts.add(args[++offset]); 1012 } else { 1013 break; 1014 } 1015 } 1016 1017 String[] vmpaths = Utility.getClassPaths(); 1019 for (int i = 0; i < vmpaths.length; i++) { 1020 paths.add(vmpaths[i]); 1021 } 1022 ArrayList names = new ArrayList(); 1023 for (int i = offset; i < args.length; i++) { 1024 if (!abstracts.contains(args[i])) { 1025 names.add(args[i]); 1026 } 1027 } 1028 1029 if (verbose) { 1031 System.out.println("Using paths:"); 1032 for (int i = 0; i < paths.size(); i++) { 1033 System.out.println(" " + paths.get(i)); 1034 } 1035 System.out.println("Using class names:"); 1036 for (int i = 0; i < names.size(); i++) { 1037 System.out.println(" " + names.get(i)); 1038 } 1039 if (abstracts.size() > 0) { 1040 System.out.println("Using abstract class names:"); 1041 for (Iterator iter = abstracts.iterator(); 1042 iter.hasNext();) { 1043 System.out.println(" " + iter.next()); 1044 } 1045 } 1046 if (customs.size() > 0) { 1047 System.out.println 1048 ("Using custom marshaller/unmarshallers:"); 1049 Iterator iter = customs.keySet().iterator(); 1050 while (iter.hasNext()) { 1051 String key = (String)iter.next(); 1052 System.out.println(" " + customs.get(key) + 1053 " for " + key); 1054 } 1055 } 1056 if (beans.size() > 0) { 1057 System.out.println("Using bean property lists:"); 1058 Iterator iter = beans.keySet().iterator(); 1059 while (iter.hasNext()) { 1060 String key = (String)iter.next(); 1061 System.out.print(" " + key + " with properties:"); 1062 ArrayList props = (ArrayList)beans.get(key); 1063 for (int i = 0; i < props.size(); i++) { 1064 System.out.print(i > 0 ? ", " : " "); 1065 System.out.print(props.get(i)); 1066 } 1067 } 1068 } 1069 if (enums.size() > 0) { 1070 System.out.println("Using enumeration classes:"); 1071 Iterator iter = enums.keySet().iterator(); 1072 while (iter.hasNext()) { 1073 String key = (String)iter.next(); 1074 System.out.println(" " + key + 1075 " with deserializer " + enums.get(key)); 1076 } 1077 } 1078 } 1079 1080 String[] parray = 1082 (String[])paths.toArray(new String[paths.size()]); 1083 ClassCache.setPaths(parray); 1084 ClassFile.setPaths(parray); 1085 1086 BindingGenerator generate = 1088 new BindingGenerator(verbose, mixed, uri); 1089 BindingElement binding = generate.generate(names, abstracts, 1090 customs, beans, enums, ignores); 1091 1092 IBindingFactory bfact = 1094 BindingDirectory.getFactory(BindingElement.class); 1095 IMarshallingContext mctx = bfact.createMarshallingContext(); 1096 mctx.setIndent(2); 1097 mctx.marshalDocument(binding, "UTF-8", null, 1098 new FileOutputStream(fname)); 1099 1100 } catch (JiBXException ex) { 1101 ex.printStackTrace(System.out); 1102 System.exit(1); 1103 } catch (FileNotFoundException e) { 1104 e.printStackTrace(System.out); 1105 System.exit(2); 1106 } 1107 1108 } else { 1109 System.out.println 1110 ("\nUsage: java org.jibx.binding.BindingGenerator [options] " + 1111 "class1 class2 ...\nwhere options are:\n -a abstract class\n" + 1112 " -b bean property class,\n -c custom mapped class,\n" + 1113 " -e enumeration class,\n -f binding file name,\n" + 1114 " -i ignore class,\n -m use mixed case XML names (instead " + 1115 "of hyphenated),\n -n namespace URI,\n -p class " + 1116 "loading path component,\n -v turns on verbose output\n" + 1117 "The class# files are different classes to be included in " + 1118 "binding (references from\nthese classes will also be " + 1119 "included).\n"); 1120 System.exit(1); 1121 } 1122 } 1123} | Popular Tags |