1 19 20 package org.apache.cayenne.map; 21 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.util.HashMap ; 25 import java.util.Map ; 26 import java.util.TreeMap ; 27 28 import org.apache.cayenne.CayenneRuntimeException; 29 import org.apache.cayenne.dba.TypesMapping; 30 import org.apache.cayenne.exp.Expression; 31 import org.apache.cayenne.project.DataMapFile; 32 import org.apache.cayenne.util.ResourceLocator; 33 import org.apache.cayenne.util.Util; 34 import org.xml.sax.Attributes ; 35 import org.xml.sax.InputSource ; 36 import org.xml.sax.SAXException ; 37 import org.xml.sax.XMLReader ; 38 import org.xml.sax.helpers.DefaultHandler ; 39 40 48 public class MapLoader extends DefaultHandler { 49 50 final static String _1_2_PACKAGE_PREFIX = "org.objectstyle.cayenne."; 54 final static String _2_0_PACKAGE_PREFIX = "org.apache.cayenne."; 55 56 public static final String DATA_MAP_TAG = "data-map"; 57 public static final String PROPERTY_TAG = "property"; 58 59 62 public static final String EMBEDDABLE_TAG = "embeddable"; 63 64 67 public static final String EMBEDDABLE_ATTRIBUTE_TAG = "embeddable-attribute"; 68 69 72 public static final String EMBEDDED_ATTRIBUTE_TAG = "embedded-attribute"; 73 74 77 public static final String EMBEDDABLE_ATTRIBUTE_OVERRIDE_TAG = "embeddable-attribute-override"; 78 79 public static final String DB_ENTITY_TAG = "db-entity"; 80 public static final String OBJ_ENTITY_TAG = "obj-entity"; 81 public static final String DB_ATTRIBUTE_TAG = "db-attribute"; 82 public static final String DB_ATTRIBUTE_DERIVED_TAG = "db-attribute-derived"; 83 public static final String DB_ATTRIBUTE_REF_TAG = "db-attribute-ref"; 84 public static final String OBJ_ATTRIBUTE_TAG = "obj-attribute"; 85 public static final String OBJ_RELATIONSHIP_TAG = "obj-relationship"; 86 public static final String DB_RELATIONSHIP_TAG = "db-relationship"; 87 public static final String DB_RELATIONSHIP_REF_TAG = "db-relationship-ref"; 88 public static final String DB_ATTRIBUTE_PAIR_TAG = "db-attribute-pair"; 89 public static final String PROCEDURE_TAG = "procedure"; 90 public static final String PROCEDURE_PARAMETER_TAG = "procedure-parameter"; 91 92 public static final String QUERY_TAG = "query"; 94 95 public static final String QUERY_SQL_TAG = "sql"; 96 public static final String QUERY_QUALIFIER_TAG = "qualifier"; 97 public static final String QUERY_ORDERING_TAG = "ordering"; 98 public static final String QUERY_PREFETCH_TAG = "prefetch"; 99 100 public static final String TRUE = "true"; 101 public static final String FALSE = "false"; 102 103 public static final String DB_KEY_GENERATOR_TAG = "db-key-generator"; 104 public static final String DB_GENERATOR_TYPE_TAG = "db-generator-type"; 105 public static final String DB_GENERATOR_NAME_TAG = "db-generator-name"; 106 public static final String DB_KEY_CACHE_SIZE_TAG = "db-key-cache-size"; 107 108 private DataMap dataMap; 110 private DbEntity dbEntity; 111 private ObjEntity objEntity; 112 private Embeddable embeddable; 113 private EmbeddedAttribute embeddedAttribute; 114 private DbRelationship dbRelationship; 115 private ObjRelationship objRelationship; 116 private DbAttribute attrib; 117 private Procedure procedure; 118 private QueryBuilder queryBuilder; 119 private String sqlKey; 120 private String descending; 121 private String ignoreCase; 122 123 private Map startTagOpMap; 124 private Map endTagOpMap; 125 private String currentTag; 126 private StringBuffer charactersBuffer; 127 private Map mapProperties; 128 129 public MapLoader() { 130 startTagOpMap = new HashMap (40); 132 endTagOpMap = new HashMap (40); 133 134 startTagOpMap.put(DB_ENTITY_TAG, new StartClosure() { 135 136 void execute(Attributes attributes) throws SAXException { 137 processStartDbEntity(attributes); 138 } 139 }); 140 141 startTagOpMap.put(DB_ATTRIBUTE_TAG, new StartClosure() { 142 143 void execute(Attributes attributes) throws SAXException { 144 processStartDbAttribute(attributes); 145 } 146 }); 147 148 startTagOpMap.put(DB_ATTRIBUTE_DERIVED_TAG, new StartClosure() { 149 150 void execute(Attributes attributes) throws SAXException { 151 processStartDerivedDbAttribute(attributes); 152 } 153 }); 154 155 startTagOpMap.put(DB_ATTRIBUTE_REF_TAG, new StartClosure() { 156 157 void execute(Attributes attributes) throws SAXException { 158 processStartDbAttributeRef(attributes); 159 } 160 }); 161 162 startTagOpMap.put(OBJ_ENTITY_TAG, new StartClosure() { 163 164 void execute(Attributes attributes) throws SAXException { 165 processStartObjEntity(attributes); 166 } 167 }); 168 169 startTagOpMap.put(OBJ_ATTRIBUTE_TAG, new StartClosure() { 170 171 void execute(Attributes attributes) throws SAXException { 172 processStartObjAttribute(attributes); 173 } 174 }); 175 176 startTagOpMap.put(EMBEDDABLE_TAG, new StartClosure() { 177 178 void execute(Attributes attributes) throws SAXException { 179 processStartEmbeddable(attributes); 180 } 181 }); 182 183 startTagOpMap.put(EMBEDDABLE_ATTRIBUTE_TAG, new StartClosure() { 184 185 void execute(Attributes attributes) throws SAXException { 186 processStartEmbeddableAttribute(attributes); 187 } 188 }); 189 190 startTagOpMap.put(EMBEDDABLE_ATTRIBUTE_OVERRIDE_TAG, new StartClosure() { 191 192 void execute(Attributes attributes) throws SAXException { 193 processStartEmbeddableAttributeOverride(attributes); 194 } 195 }); 196 197 startTagOpMap.put(EMBEDDED_ATTRIBUTE_TAG, new StartClosure() { 198 199 void execute(Attributes attributes) throws SAXException { 200 processStartEmbeddedAttribute(attributes); 201 } 202 }); 203 204 startTagOpMap.put(DB_RELATIONSHIP_TAG, new StartClosure() { 205 206 void execute(Attributes attributes) throws SAXException { 207 processStartDbRelationship(attributes); 208 } 209 }); 210 211 startTagOpMap.put(DB_ATTRIBUTE_PAIR_TAG, new StartClosure() { 212 213 void execute(Attributes attributes) throws SAXException { 214 processStartDbAttributePair(attributes); 215 } 216 }); 217 218 startTagOpMap.put(OBJ_RELATIONSHIP_TAG, new StartClosure() { 219 220 void execute(Attributes attributes) throws SAXException { 221 processStartObjRelationship(attributes); 222 } 223 }); 224 225 startTagOpMap.put(DB_RELATIONSHIP_REF_TAG, new StartClosure() { 226 227 void execute(Attributes attributes) throws SAXException { 228 processStartDbRelationshipRef(attributes); 229 } 230 }); 231 232 startTagOpMap.put(PROCEDURE_PARAMETER_TAG, new StartClosure() { 233 234 void execute(Attributes attributes) throws SAXException { 235 processStartProcedureParameter(attributes); 236 } 237 }); 238 239 startTagOpMap.put(PROCEDURE_TAG, new StartClosure() { 240 241 void execute(Attributes attributes) throws SAXException { 242 processStartProcedure(attributes); 243 } 244 }); 245 246 startTagOpMap.put(QUERY_TAG, new StartClosure() { 247 248 void execute(Attributes attributes) throws SAXException { 249 processStartQuery(attributes); 250 } 251 }); 252 253 startTagOpMap.put(QUERY_SQL_TAG, new StartClosure() { 254 255 void execute(Attributes attributes) throws SAXException { 256 charactersBuffer = new StringBuffer (); 257 processStartQuerySQL(attributes); 258 } 259 }); 260 261 startTagOpMap.put(QUERY_ORDERING_TAG, new StartClosure() { 262 263 void execute(Attributes attributes) throws SAXException { 264 charactersBuffer = new StringBuffer (); 265 processStartQueryOrdering(attributes); 266 } 267 }); 268 269 startTagOpMap.put(DB_KEY_GENERATOR_TAG, new StartClosure() { 270 271 void execute(Attributes attributes) throws SAXException { 272 processStartDbKeyGenerator(attributes); 273 } 274 }); 275 276 startTagOpMap.put(PROPERTY_TAG, new StartClosure() { 277 278 void execute(Attributes attributes) throws SAXException { 279 if (queryBuilder != null) { 281 processStartQueryProperty(attributes); 282 } 283 else { 284 processStartDataMapProperty(attributes); 285 } 286 } 287 }); 288 289 StartClosure resetBuffer = new StartClosure() { 290 291 void execute(Attributes attributes) throws SAXException { 292 charactersBuffer = new StringBuffer (); 293 } 294 }; 295 296 startTagOpMap.put(QUERY_PREFETCH_TAG, resetBuffer); 297 startTagOpMap.put(QUERY_QUALIFIER_TAG, resetBuffer); 298 startTagOpMap.put(DB_GENERATOR_TYPE_TAG, resetBuffer); 299 startTagOpMap.put(DB_GENERATOR_NAME_TAG, resetBuffer); 300 startTagOpMap.put(DB_KEY_CACHE_SIZE_TAG, resetBuffer); 301 302 endTagOpMap.put(DATA_MAP_TAG, new EndClosure() { 303 304 void execute() throws SAXException { 305 processEndDataMap(); 306 } 307 }); 308 endTagOpMap.put(DB_ENTITY_TAG, new EndClosure() { 309 310 void execute() throws SAXException { 311 processEndDbEntity(); 312 } 313 }); 314 endTagOpMap.put(OBJ_ENTITY_TAG, new EndClosure() { 315 316 void execute() throws SAXException { 317 processEndObjEntity(); 318 } 319 }); 320 endTagOpMap.put(EMBEDDABLE_TAG, new EndClosure() { 321 322 void execute() throws SAXException { 323 processEndEmbeddable(); 324 } 325 }); 326 endTagOpMap.put(EMBEDDABLE_ATTRIBUTE_TAG, new EndClosure() { 327 328 void execute() throws SAXException { 329 processEndEmbeddedAttribute(); 330 } 331 }); 332 333 endTagOpMap.put(DB_ATTRIBUTE_TAG, new EndClosure() { 334 335 void execute() throws SAXException { 336 processEndDbAttribute(); 337 } 338 }); 339 340 endTagOpMap.put(DB_ATTRIBUTE_DERIVED_TAG, new EndClosure() { 341 342 void execute() throws SAXException { 343 processEndDbAttribute(); 344 } 345 }); 346 endTagOpMap.put(DB_RELATIONSHIP_TAG, new EndClosure() { 347 348 void execute() throws SAXException { 349 processEndDbRelationship(); 350 } 351 }); 352 endTagOpMap.put(OBJ_RELATIONSHIP_TAG, new EndClosure() { 353 354 void execute() throws SAXException { 355 processEndObjRelationship(); 356 } 357 }); 358 endTagOpMap.put(DB_GENERATOR_TYPE_TAG, new EndClosure() { 359 360 void execute() throws SAXException { 361 processEndDbGeneratorType(); 362 } 363 }); 364 endTagOpMap.put(DB_GENERATOR_NAME_TAG, new EndClosure() { 365 366 void execute() throws SAXException { 367 processEndDbGeneratorName(); 368 } 369 }); 370 endTagOpMap.put(DB_KEY_CACHE_SIZE_TAG, new EndClosure() { 371 372 void execute() throws SAXException { 373 processEndDbKeyCacheSize(); 374 } 375 }); 376 endTagOpMap.put(PROCEDURE_PARAMETER_TAG, new EndClosure() { 377 378 void execute() throws SAXException { 379 processEndProcedureParameter(); 380 } 381 }); 382 endTagOpMap.put(PROCEDURE_TAG, new EndClosure() { 383 384 void execute() throws SAXException { 385 processEndProcedure(); 386 } 387 }); 388 endTagOpMap.put(QUERY_TAG, new EndClosure() { 389 390 void execute() throws SAXException { 391 processEndQuery(); 392 } 393 }); 394 endTagOpMap.put(QUERY_SQL_TAG, new EndClosure() { 395 396 void execute() throws SAXException { 397 processEndQuerySQL(); 398 } 399 }); 400 endTagOpMap.put(QUERY_QUALIFIER_TAG, new EndClosure() { 401 402 void execute() throws SAXException { 403 processEndQualifier(); 404 } 405 }); 406 endTagOpMap.put(QUERY_ORDERING_TAG, new EndClosure() { 407 408 void execute() throws SAXException { 409 processEndQueryOrdering(); 410 } 411 }); 412 endTagOpMap.put(QUERY_PREFETCH_TAG, new EndClosure() { 413 414 void execute() throws SAXException { 415 processEndQueryPrefetch(); 416 } 417 }); 418 } 419 420 423 public synchronized DataMap loadDataMap(InputSource src) 424 throws CayenneRuntimeException { 425 if (src == null) { 426 throw new NullPointerException ("Null InputSource."); 427 } 428 429 try { 430 String mapName = mapNameFromLocation(src.getSystemId()); 431 dataMap = new DataMap(mapName); 432 XMLReader parser = Util.createXmlReader(); 433 434 parser.setContentHandler(this); 435 parser.setErrorHandler(this); 436 parser.parse(src); 437 } 438 catch (SAXException e) { 439 dataMap = null; 440 throw new CayenneRuntimeException( 441 "Wrong DataMap format, last processed tag: <" + currentTag, 442 Util.unwindException(e)); 443 } 444 catch (Exception e) { 445 dataMap = null; 446 throw new CayenneRuntimeException( 447 "Error loading DataMap, last processed tag: <" + currentTag, 448 Util.unwindException(e)); 449 } 450 return dataMap; 451 } 452 453 458 public DataMap loadDataMap(String uri) throws CayenneRuntimeException { 459 ResourceLocator locator = configLocator(); 461 InputStream in = locator.findResourceStream(uri); 462 if (in == null) { 463 throw new CayenneRuntimeException("Can't find data map " + uri); 464 } 465 466 try { 467 InputSource inSrc = new InputSource (in); 468 inSrc.setSystemId(uri); 469 return loadDataMap(inSrc); 470 } 471 finally { 472 try { 473 in.close(); 474 } 475 catch (IOException ioex) { 476 } 477 } 478 } 479 480 483 protected String mapNameFromLocation(String location) { 484 if (location == null) { 485 return "Untitled"; 486 } 487 488 int lastSlash = location.lastIndexOf('/'); 489 if (lastSlash < 0) { 490 lastSlash = location.lastIndexOf('\\'); 491 } 492 493 if (lastSlash >= 0 && lastSlash + 1 < location.length()) { 494 location = location.substring(lastSlash + 1); 495 } 496 497 if (location.endsWith(DataMapFile.LOCATION_SUFFIX)) { 498 location = location.substring(0, location.length() 499 - DataMapFile.LOCATION_SUFFIX.length()); 500 } 501 502 return location; 503 } 504 505 509 protected ResourceLocator configLocator() { 510 ResourceLocator locator = new ResourceLocator(); 511 locator.setSkipAbsolutePath(true); 512 locator.setSkipClasspath(false); 513 locator.setSkipCurrentDirectory(false); 514 locator.setSkipHomeDirectory(false); 515 return locator; 516 } 517 518 public void startElement( 519 String namespaceUri, 520 String localName, 521 String qName, 522 Attributes attributes) throws SAXException { 523 524 rememberCurrentTag(localName); 525 526 StartClosure op = (StartClosure) startTagOpMap.get(localName); 527 if (op != null) { 528 op.execute(attributes); 529 } 530 } 531 532 public void endElement(String namespaceURI, String localName, String qName) 533 throws SAXException { 534 535 EndClosure op = (EndClosure) endTagOpMap.get(localName); 536 if (op != null) { 537 op.execute(); 538 } 539 540 resetCurrentTag(); 541 charactersBuffer = null; 542 } 543 544 private void processStartEmbeddable(Attributes atts) { 545 embeddable = new Embeddable(atts.getValue("", "className")); 546 dataMap.addEmbeddable(embeddable); 547 } 548 549 private void processStartEmbeddableAttribute(Attributes atts) { 550 String name = atts.getValue("", "name"); 551 String type = atts.getValue("", "type"); 552 String dbName = atts.getValue("", "db-attribute-name"); 553 554 EmbeddableAttribute ea = new EmbeddableAttribute(name); 555 ea.setType(type); 556 ea.setDbAttributeName(dbName); 557 embeddable.addAttribute(ea); 558 } 559 560 private void processStartEmbeddedAttribute(Attributes atts) { 561 562 String name = atts.getValue("", "name"); 563 String type = atts.getValue("", "type"); 564 565 embeddedAttribute = new EmbeddedAttribute(name); 566 embeddedAttribute.setType(type); 567 objEntity.addAttribute(embeddedAttribute); 568 } 569 570 private void processStartEmbeddableAttributeOverride(Attributes atts) { 571 String name = atts.getValue("", "name"); 572 String dbName = atts.getValue("", "db-attribute-path"); 573 embeddedAttribute.addAttributeOverride(name, dbName); 574 } 575 576 private void processStartDbEntity(Attributes atts) { 577 String name = atts.getValue("", "name"); 578 String parentName = atts.getValue("", "parentName"); 579 580 if (parentName != null) { 581 dbEntity = new DerivedDbEntity(name); 582 ((DerivedDbEntity) dbEntity).setParentEntityName(parentName); 583 } 584 else { 585 dbEntity = new DbEntity(name); 586 } 587 588 if (!(dbEntity instanceof DerivedDbEntity)) { 589 dbEntity.setSchema(atts.getValue("", "schema")); 590 dbEntity.setCatalog(atts.getValue("", "catalog")); 591 } 592 593 dataMap.addDbEntity(dbEntity); 594 } 595 596 private void processStartDbAttributeRef(Attributes atts) throws SAXException { 597 String name = atts.getValue("", "name"); 598 if ((attrib instanceof DerivedDbAttribute) 599 && (dbEntity instanceof DerivedDbEntity)) { 600 DbEntity parent = ((DerivedDbEntity) dbEntity).getParentEntity(); 601 DbAttribute ref = (DbAttribute) parent.getAttribute(name); 602 ((DerivedDbAttribute) attrib).addParam(ref); 603 } 604 else { 605 throw new SAXException ( 606 "Referenced attributes are not supported by regular DbAttributes. " 607 + " Offending attribute name '" 608 + attrib.getName() 609 + "'."); 610 } 611 } 612 613 private void processStartDbAttribute(Attributes atts) { 614 String name = atts.getValue("", "name"); 615 String type = atts.getValue("", "type"); 616 617 attrib = new DbAttribute(name); 618 attrib.setType(TypesMapping.getSqlTypeByName(type)); 619 dbEntity.addAttribute(attrib); 620 621 String length = atts.getValue("", "length"); 622 if (length != null) { 623 attrib.setMaxLength(Integer.parseInt(length)); 624 } 625 626 String pseudoPrecision = atts.getValue("", "precision"); 628 if (pseudoPrecision != null) { 629 attrib.setScale(Integer.parseInt(pseudoPrecision)); 630 } 631 632 String precision = atts.getValue("", "attributePrecision"); 633 if (precision != null) { 634 attrib.setAttributePrecision(Integer.parseInt(precision)); 635 } 636 637 String scale = atts.getValue("", "scale"); 638 if (scale != null) { 639 attrib.setScale(Integer.parseInt(scale)); 640 } 641 642 attrib.setPrimaryKey(TRUE.equalsIgnoreCase(atts.getValue("", "isPrimaryKey"))); 643 attrib.setMandatory(TRUE.equalsIgnoreCase(atts.getValue("", "isMandatory"))); 644 attrib.setGenerated(TRUE.equalsIgnoreCase(atts.getValue("", "isGenerated"))); 645 } 646 647 private void processStartDerivedDbAttribute(Attributes atts) { 648 String name = atts.getValue("", "name"); 649 String type = atts.getValue("", "type"); 650 String spec = atts.getValue("", "spec"); 651 652 attrib = new DerivedDbAttribute(name); 653 attrib.setType(TypesMapping.getSqlTypeByName(type)); 654 ((DerivedDbAttribute) attrib).setExpressionSpec(spec); 655 dbEntity.addAttribute(attrib); 656 657 String length = atts.getValue("", "length"); 658 if (length != null) { 659 attrib.setMaxLength(Integer.parseInt(length)); 660 } 661 662 String pseudoPrecision = atts.getValue("", "precision"); 664 if (pseudoPrecision != null) { 665 attrib.setScale(Integer.parseInt(pseudoPrecision)); 666 } 667 668 String precision = atts.getValue("", "attributePrecision"); 669 if (precision != null) { 670 attrib.setAttributePrecision(Integer.parseInt(precision)); 671 } 672 673 String scale = atts.getValue("", "scale"); 674 if (scale != null) { 675 attrib.setScale(Integer.parseInt(scale)); 676 } 677 678 String temp = atts.getValue("", "isPrimaryKey"); 679 if (temp != null && temp.equalsIgnoreCase(TRUE)) { 680 attrib.setPrimaryKey(true); 681 } 682 temp = atts.getValue("", "isMandatory"); 683 if (temp != null && temp.equalsIgnoreCase(TRUE)) { 684 attrib.setMandatory(true); 685 } 686 687 temp = atts.getValue("", "isGroupBy"); 688 if (temp != null && temp.equalsIgnoreCase(TRUE)) { 689 ((DerivedDbAttribute) attrib).setGroupBy(true); 690 } 691 } 692 693 private void processStartDbKeyGenerator(Attributes atts) { 694 DbKeyGenerator pkGenerator = new DbKeyGenerator(); 695 dbEntity.setPrimaryKeyGenerator(pkGenerator); 696 } 697 698 private void processStartQuerySQL(Attributes atts) { 699 this.sqlKey = convertClassNameFromV1_2(atts.getValue("", "adapter-class")); 700 } 701 702 private void processStartObjEntity(Attributes atts) { 703 objEntity = new ObjEntity(atts.getValue("", "name")); 704 objEntity.setClassName(atts.getValue("", "className")); 705 objEntity.setClientClassName(atts.getValue("", "clientClassName")); 706 707 String readOnly = atts.getValue("", "readOnly"); 708 objEntity.setReadOnly(TRUE.equalsIgnoreCase(readOnly)); 709 710 String serverOnly = atts.getValue("", "serverOnly"); 711 objEntity.setServerOnly(TRUE.equalsIgnoreCase(serverOnly)); 712 713 String lockType = atts.getValue("", "lock-type"); 714 if ("optimistic".equals(lockType)) { 715 objEntity.setDeclaredLockType(ObjEntity.LOCK_TYPE_OPTIMISTIC); 716 } 717 718 String superEntityName = atts.getValue("", "superEntityName"); 719 if (superEntityName != null) { 720 objEntity.setSuperEntityName(superEntityName); 721 } 722 else { 723 objEntity.setDbEntityName(atts.getValue("", "dbEntityName")); 724 objEntity.setSuperClassName(atts.getValue("", "superClassName")); 725 objEntity.setClientSuperClassName(atts.getValue("", "clientSuperClassName")); 726 } 727 728 dataMap.addObjEntity(objEntity); 729 } 730 731 private void processStartObjAttribute(Attributes atts) { 732 String name = atts.getValue("", "name"); 733 String type = atts.getValue("", "type"); 734 735 String lock = atts.getValue("", "lock"); 736 737 ObjAttribute oa = new ObjAttribute(name); 738 oa.setType(type); 739 oa.setUsedForLocking(TRUE.equalsIgnoreCase(lock)); 740 objEntity.addAttribute(oa); 741 String dbPath = atts.getValue("", "db-attribute-path"); 742 if (dbPath == null) { 743 dbPath = atts.getValue("", "db-attribute-name"); 744 } 745 oa.setDbAttributePath(dbPath); 746 } 747 748 private void processStartDbRelationship(Attributes atts) throws SAXException { 749 String name = atts.getValue("", "name"); 750 if (name == null) { 751 throw new SAXException ("MapLoader::processStartDbRelationship()," 752 + " Unable to parse name. Attributes:\n" 753 + printAttributes(atts).toString()); 754 } 755 756 String sourceName = atts.getValue("", "source"); 757 if (sourceName == null) { 758 throw new SAXException ( 759 "MapLoader::processStartDbRelationship() - null source entity"); 760 } 761 762 DbEntity source = dataMap.getDbEntity(sourceName); 763 if (source == null) { 764 return; 765 } 766 767 String toManyString = atts.getValue("", "toMany"); 768 boolean toMany = toManyString != null && toManyString.equalsIgnoreCase(TRUE); 769 770 String toDependPkString = atts.getValue("", "toDependentPK"); 771 boolean toDependentPK = toDependPkString != null 772 && toDependPkString.equalsIgnoreCase(TRUE); 773 774 dbRelationship = new DbRelationship(name); 775 dbRelationship.setSourceEntity(source); 776 dbRelationship.setTargetEntityName(atts.getValue("", "target")); 777 dbRelationship.setToMany(toMany); 778 dbRelationship.setToDependentPK(toDependentPK); 779 780 source.addRelationship(dbRelationship); 781 } 782 783 private void processStartDbRelationshipRef(Attributes atts) throws SAXException { 784 787 String name = atts.getValue("", "name"); 788 if (name == null) { 789 throw new SAXException ("MapLoader::processStartDbRelationshipRef()" 790 + ", Null DbRelationship name for " 791 + objRelationship.getName()); 792 } 793 794 String path = objRelationship.getDbRelationshipPath(); 795 path = (path != null) ? path + "." + name : name; 796 objRelationship.setDbRelationshipPath(path); 797 } 798 799 private void processStartDbAttributePair(Attributes atts) { 800 DbJoin join = new DbJoin(dbRelationship); 801 join.setSourceName(atts.getValue("", "source")); 802 join.setTargetName(atts.getValue("", "target")); 803 dbRelationship.addJoin(join); 804 } 805 806 private void processStartObjRelationship(Attributes atts) throws SAXException { 807 String name = atts.getValue("", "name"); 808 if (null == name) { 809 throw new SAXException ("MapLoader::processStartObjRelationship()," 810 + " Unable to parse target. Attributes:\n" 811 + printAttributes(atts).toString()); 812 } 813 814 String sourceName = atts.getValue("", "source"); 815 if (sourceName == null) { 816 throw new SAXException ("MapLoader::processStartObjRelationship()," 817 + " Unable to parse source. Attributes:\n" 818 + printAttributes(atts).toString()); 819 } 820 821 ObjEntity source = dataMap.getObjEntity(sourceName); 822 if (source == null) { 823 throw new SAXException ("MapLoader::processStartObjRelationship()," 824 + " Unable to find source " 825 + sourceName); 826 } 827 828 String deleteRuleName = atts.getValue("", "deleteRule"); 829 int deleteRule = (deleteRuleName != null) ? DeleteRule 830 .deleteRuleForName(deleteRuleName) : DeleteRule.NO_ACTION; 831 832 objRelationship = new ObjRelationship(name); 833 objRelationship.setSourceEntity(source); 834 objRelationship.setTargetEntityName(atts.getValue("", "target")); 835 objRelationship.setDeleteRule(deleteRule); 836 objRelationship.setUsedForLocking(TRUE 837 .equalsIgnoreCase(atts.getValue("", "lock"))); 838 objRelationship 839 .setDbRelationshipPath((atts.getValue("", "db-relationship-path"))); 840 source.addRelationship(objRelationship); 841 } 842 843 private void processStartProcedure(Attributes attributes) throws SAXException { 844 845 String name = attributes.getValue("", "name"); 846 if (null == name) { 847 throw new SAXException ("MapLoader::processStartProcedure()," 848 + " no procedure name."); 849 } 850 851 String schema = attributes.getValue("", "schema"); 852 String catalog = attributes.getValue("", "catalog"); 853 String returningValue = attributes.getValue("", "returningValue"); 854 855 procedure = new Procedure(name); 856 procedure.setReturningValue(returningValue != null 857 && returningValue.equalsIgnoreCase(TRUE)); 858 procedure.setSchema(schema); 859 procedure.setCatalog(catalog); 860 dataMap.addProcedure(procedure); 861 } 862 863 private void processStartProcedureParameter(Attributes attributes) 864 throws SAXException { 865 866 String name = attributes.getValue("", "name"); 867 if (name == null) { 868 throw new SAXException ("MapLoader::processStartProcedureParameter()," 869 + " no procedure parameter name."); 870 } 871 872 ProcedureParameter parameter = new ProcedureParameter(name); 873 874 String type = attributes.getValue("", "type"); 875 if (type != null) { 876 parameter.setType(TypesMapping.getSqlTypeByName(type)); 877 } 878 879 String length = attributes.getValue("", "length"); 880 if (length != null) { 881 parameter.setMaxLength(Integer.parseInt(length)); 882 } 883 884 String precision = attributes.getValue("", "precision"); 885 if (precision != null) { 886 parameter.setPrecision(Integer.parseInt(precision)); 887 } 888 889 String direction = attributes.getValue("", "direction"); 890 if ("in".equals(direction)) { 891 parameter.setDirection(ProcedureParameter.IN_PARAMETER); 892 } 893 else if ("out".equals(direction)) { 894 parameter.setDirection(ProcedureParameter.OUT_PARAMETER); 895 } 896 else if ("in_out".equals(direction)) { 897 parameter.setDirection(ProcedureParameter.IN_OUT_PARAMETER); 898 } 899 900 procedure.addCallParameter(parameter); 901 } 902 903 private void processStartQuery(Attributes attributes) throws SAXException { 904 String name = attributes.getValue("", "name"); 905 if (null == name) { 906 throw new SAXException ("MapLoader::processStartQuery(), no query name."); 907 } 908 909 String builder = attributes.getValue("", "factory"); 910 911 if (builder == null) { 912 builder = SelectQueryBuilder.class.getName(); 913 } 914 else { 915 if (builder.equals("org.objectstyle.cayenne.query.SelectQueryBuilder")) { 918 builder = SelectQueryBuilder.class.getName(); 919 } 920 else { 922 builder = convertClassNameFromV1_2(builder); 923 } 924 } 925 926 try { 927 queryBuilder = (QueryBuilder) Class.forName(builder).newInstance(); 928 } 929 catch (Exception ex) { 930 throw new SAXException ( 931 "MapLoader::processStartQuery(), invalid query builder: " + builder); 932 } 933 934 String rootType = attributes.getValue("", "root"); 935 String rootName = attributes.getValue("", "root-name"); 936 String resultEntity = attributes.getValue("", "result-entity"); 937 938 queryBuilder.setName(name); 939 queryBuilder.setRoot(dataMap, rootType, rootName); 940 941 if (!Util.isEmptyString(resultEntity)) { 944 queryBuilder.setResultEntity(resultEntity); 945 } 946 } 947 948 private void processStartQueryProperty(Attributes attributes) throws SAXException { 949 String name = attributes.getValue("", "name"); 950 if (null == name) { 951 throw new SAXException ( 952 "MapLoader::processStartQueryProperty(), no property name."); 953 } 954 955 String value = attributes.getValue("", "value"); 956 if (null == value) { 957 throw new SAXException ( 958 "MapLoader::processStartQueryProperty(), no property value."); 959 } 960 961 queryBuilder.addProperty(name, value); 962 } 963 964 private void processStartDataMapProperty(Attributes attributes) throws SAXException { 965 String name = attributes.getValue("", "name"); 966 if (null == name) { 967 throw new SAXException ( 968 "MapLoader::processStartDataMapProperty(), no property name."); 969 } 970 971 String value = attributes.getValue("", "value"); 972 if (null == value) { 973 throw new SAXException ( 974 "MapLoader::processStartDataMapProperty(), no property value."); 975 } 976 977 if (mapProperties == null) { 978 mapProperties = new TreeMap (); 979 } 980 981 mapProperties.put(name, value); 982 } 983 984 private void processEndQueryPrefetch() { 985 queryBuilder.addPrefetch(charactersBuffer.toString()); 986 } 987 988 private void processStartQueryOrdering(Attributes attributes) { 989 descending = attributes.getValue("", "descending"); 990 ignoreCase = attributes.getValue("", "ignore-case"); 991 } 992 993 private void processEndQuery() { 994 dataMap.addQuery(queryBuilder.getQuery()); 995 queryBuilder = null; 996 } 997 998 private void processEndQuerySQL() { 999 queryBuilder.addSql(charactersBuffer.toString(), sqlKey); 1000 sqlKey = null; 1001 } 1002 1003 private void processEndQualifier() { 1004 String qualifier = charactersBuffer.toString(); 1005 if (qualifier.trim().length() == 0) { 1006 return; 1007 } 1008 1009 if (objEntity != null) { 1011 objEntity.setDeclaredQualifier(Expression.fromString(qualifier)); 1012 } 1013 else { 1014 queryBuilder.setQualifier(qualifier); 1015 } 1016 } 1017 1018 private void processEndQueryOrdering() { 1019 String path = charactersBuffer.toString(); 1020 queryBuilder.addOrdering(path, descending, ignoreCase); 1021 } 1022 1023 private void processEndDbAttribute() { 1024 attrib = null; 1025 } 1026 1027 private void processEndDbEntity() { 1028 dbEntity = null; 1029 } 1030 1031 private void processEndProcedure() { 1032 procedure = null; 1033 } 1034 1035 private void processEndProcedureParameter() { 1036 } 1037 1038 private void processEndDbGeneratorType() { 1039 if (dbEntity == null) 1040 return; 1041 DbKeyGenerator pkGenerator = dbEntity.getPrimaryKeyGenerator(); 1042 if (pkGenerator == null) 1043 return; 1044 pkGenerator.setGeneratorType(charactersBuffer.toString()); 1045 if (pkGenerator.getGeneratorType() == null) { 1046 dbEntity.setPrimaryKeyGenerator(null); 1047 } 1048 } 1049 1050 private void processEndDbGeneratorName() { 1051 if (dbEntity == null) 1052 return; 1053 DbKeyGenerator pkGenerator = dbEntity.getPrimaryKeyGenerator(); 1054 if (pkGenerator == null) 1055 return; 1056 pkGenerator.setGeneratorName(charactersBuffer.toString()); 1057 } 1058 1059 private void processEndDbKeyCacheSize() { 1060 if (dbEntity == null) 1061 return; 1062 DbKeyGenerator pkGenerator = dbEntity.getPrimaryKeyGenerator(); 1063 if (pkGenerator == null) 1064 return; 1065 try { 1066 pkGenerator.setKeyCacheSize(new Integer (charactersBuffer.toString().trim())); 1067 } 1068 catch (Exception ex) { 1069 pkGenerator.setKeyCacheSize(null); 1070 } 1071 } 1072 1073 private void processEndDataMap() { 1074 if (mapProperties != null) { 1075 dataMap.initWithProperties(mapProperties); 1076 } 1077 1078 mapProperties = null; 1079 } 1080 1081 private void processEndObjEntity() { 1082 objEntity = null; 1083 } 1084 1085 private void processEndEmbeddable() { 1086 embeddable = null; 1087 } 1088 1089 private void processEndEmbeddedAttribute() { 1090 embeddedAttribute = null; 1091 } 1092 1093 private void processEndDbRelationship() { 1094 dbRelationship = null; 1095 } 1096 1097 private void processEndObjRelationship() { 1098 objRelationship = null; 1099 } 1100 1101 1102 private StringBuffer printAttributes(Attributes atts) { 1103 StringBuffer sb = new StringBuffer (); 1104 String name, value; 1105 for (int i = 0; i < atts.getLength(); i++) { 1106 value = atts.getQName(i); 1107 name = atts.getValue(i); 1108 sb.append("Name: " + name + "\tValue: " + value + "\n"); 1109 } 1110 return sb; 1111 } 1112 1113 public void characters(char[] text, int start, int length) 1114 throws org.xml.sax.SAXException { 1115 if (charactersBuffer != null) { 1116 charactersBuffer.append(text, start, length); 1117 } 1118 } 1119 1120 private void rememberCurrentTag(String tag) { 1121 currentTag = tag; 1122 } 1123 1124 private void resetCurrentTag() { 1125 currentTag = null; 1126 } 1127 1128 1131 String convertClassNameFromV1_2(String name) { 1132 if (name == null) { 1133 return null; 1134 } 1135 1136 if (name.startsWith(_1_2_PACKAGE_PREFIX)) { 1138 return _2_0_PACKAGE_PREFIX + name.substring(_1_2_PACKAGE_PREFIX.length()); 1139 } 1140 1141 return name; 1142 } 1143 1144 abstract class StartClosure { 1145 1146 abstract void execute(Attributes attributes) throws SAXException ; 1147 } 1148 1149 abstract class EndClosure { 1150 1151 abstract void execute() throws SAXException ; 1152 } 1153} 1154 | Popular Tags |