1 56 57 package org.objectstyle.cayenne.wocompat; 58 59 import java.io.FileNotFoundException ; 60 import java.io.InputStream ; 61 import java.net.URL ; 62 import java.util.ArrayList ; 63 import java.util.Collection ; 64 import java.util.Collections ; 65 import java.util.Comparator ; 66 import java.util.Iterator ; 67 import java.util.List ; 68 import java.util.Map ; 69 70 import org.apache.commons.collections.CollectionUtils; 71 import org.apache.commons.collections.Predicate; 72 import org.apache.commons.collections.PredicateUtils; 73 import org.objectstyle.cayenne.CayenneRuntimeException; 74 import org.objectstyle.cayenne.dba.TypesMapping; 75 import org.objectstyle.cayenne.exp.Expression; 76 import org.objectstyle.cayenne.exp.parser.ASTDbPath; 77 import org.objectstyle.cayenne.map.DataMap; 78 import org.objectstyle.cayenne.map.DbEntity; 79 import org.objectstyle.cayenne.map.DbJoin; 80 import org.objectstyle.cayenne.map.DbRelationship; 81 import org.objectstyle.cayenne.map.ObjEntity; 82 import org.objectstyle.cayenne.map.ObjRelationship; 83 import org.objectstyle.cayenne.project.NamedObjectFactory; 84 import org.objectstyle.cayenne.query.Query; 85 import org.objectstyle.cayenne.util.ResourceLocator; 86 import org.objectstyle.cayenne.wocompat.parser.Parser; 87 88 91 public class EOModelProcessor { 92 93 protected Predicate prototypeChecker; 94 95 public EOModelProcessor() { 96 prototypeChecker = new Predicate() { 97 98 public boolean evaluate(Object object) { 99 if (object == null) { 100 return false; 101 } 102 103 String entityName = object.toString(); 104 105 return entityName.startsWith("EO") && entityName.endsWith("Prototypes"); 106 } 107 }; 108 } 109 110 115 public Map loadModeIndex(String path) throws Exception { 118 119 ResourceLocator locator = new ResourceLocator(); 120 locator.setSkipClasspath(false); 121 locator.setSkipCurrentDirectory(false); 122 locator.setSkipHomeDirectory(true); 123 locator.setSkipAbsolutePath(false); 124 125 if (!path.endsWith(".eomodeld")) { 126 path += ".eomodeld"; 127 } 128 129 URL base = locator.findDirectoryResource(path); 130 if (base == null) { 131 throw new FileNotFoundException ("Can't find EOModel: " + path); 132 } 133 134 Parser plistParser = new Parser(); 135 InputStream in = new URL (base, "index.eomodeld").openStream(); 136 137 try { 138 plistParser.ReInit(in); 139 return (Map ) plistParser.propertyList(); 140 } 141 finally { 142 in.close(); 143 } 144 } 145 146 152 public DataMap loadEOModel(String path) throws Exception { 153 return loadEOModel(path, false); 154 } 155 156 165 public DataMap loadEOModel(String path, boolean generateClientClass) throws Exception { 166 EOModelHelper helper = makeHelper(path, generateClientClass); 167 168 DataMap dataMap = helper.getDataMap(); 170 171 List modelNames = new ArrayList (helper.modelNamesAsList()); 173 CollectionUtils.filter(modelNames, PredicateUtils.notPredicate(prototypeChecker)); 174 175 Iterator it = modelNames.iterator(); 176 while (it.hasNext()) { 177 String name = (String ) it.next(); 178 179 makeEntity(helper, name, generateClientClass); 181 } 182 183 Collections.sort(modelNames, new InheritanceComparator(dataMap)); 185 186 it = modelNames.iterator(); 188 while (it.hasNext()) { 189 String name = (String ) it.next(); 190 191 EOObjEntity e = (EOObjEntity) dataMap.getObjEntity(name); 192 makeAttributes(helper, e); 194 } 195 196 it = modelNames.iterator(); 198 while (it.hasNext()) { 199 String name = (String ) it.next(); 200 makeRelationships(helper, dataMap.getObjEntity(name)); 201 } 202 203 it = modelNames.iterator(); 205 while (it.hasNext()) { 206 String name = (String ) it.next(); 207 makeFlatRelationships(helper, dataMap.getObjEntity(name)); 208 } 209 210 it = modelNames.iterator(); 213 while (it.hasNext()) { 214 String name = (String ) it.next(); 215 DbEntity dbEntity = dataMap.getObjEntity(name).getDbEntity(); 216 217 if (dbEntity != null) { 218 makeReverseDbRelationships(dbEntity); 219 } 220 } 221 222 it = modelNames.iterator(); 224 while (it.hasNext()) { 225 String name = (String ) it.next(); 226 Iterator queries = helper.queryNames(name); 227 while (queries.hasNext()) { 228 String queryName = (String ) queries.next(); 229 System.out.println("Processing FetchSpecification: " + queryName); 230 EOObjEntity entity = (EOObjEntity) dataMap.getObjEntity(name); 231 makeQuery(helper, entity, queryName); 232 } 233 } 234 235 return dataMap; 236 } 237 238 245 protected boolean isPrototypesEntity(String entityName) { 246 return prototypeChecker.evaluate(entityName); 247 } 248 249 253 protected EOModelHelper makeHelper(String path, boolean genereateClientClass) 254 throws Exception { 255 return new EOModelHelper(path); 256 } 257 258 263 protected Query makeQuery(EOModelHelper helper, EOObjEntity entity, String queryName) { 264 265 DataMap dataMap = helper.getDataMap(); 266 Map queryPlist = helper.queryPListMap(entity.getName(), queryName); 267 if (queryPlist == null) { 268 return null; 269 } 270 271 Query query; 272 if (queryPlist.containsKey("hints")) { query = new EOSQLQuery(entity, queryPlist); 274 } else { 275 query = new EOQuery(entity, queryPlist); 276 } 277 query.setName(entity.qualifiedQueryName(queryName)); 278 dataMap.addQuery(query); 279 280 return query; 281 } 282 283 286 protected EOObjEntity makeEntity( 287 EOModelHelper helper, 288 String name, 289 boolean generateClientClass) { 290 291 DataMap dataMap = helper.getDataMap(); 292 Map entityPlist = helper.entityPListMap(name); 293 294 EOObjEntity objEntity = new EOObjEntity(name); 296 objEntity.setIsClientEntity(generateClientClass); 297 String parent = (String ) entityPlist.get("parent"); 298 objEntity.setClassName(helper.entityClass(name, generateClientClass)); 299 300 if (parent != null) { 301 objEntity.setHasSuperClass(true); 302 objEntity.setSuperClassName(helper.entityClass(parent, generateClientClass)); 303 } 304 305 objEntity.setIsAbstractEntity("Y".equals(entityPlist.get("isAbstractEntity"))); 307 308 String dbEntityName = (String ) entityPlist.get("externalName"); 311 if (dbEntityName != null) { 312 313 boolean createDbEntity = true; 316 if (parent != null) { 317 String parentName = parent; 318 while (parentName != null) { 319 Map parentData = helper.entityPListMap(parentName); 320 if (parentData == null) { 321 break; 322 } 323 324 String parentExternalName = (String ) parentData.get("externalName"); 325 if (parentExternalName == null) { 326 parentName = (String ) parentData.get("parent"); 327 continue; 328 } 329 330 if (dbEntityName.equals(parentExternalName)) { 331 createDbEntity = false; 332 } 333 334 break; 335 } 336 } 337 338 if (createDbEntity) { 339 int i = 0; 340 String dbEntityBaseName = dbEntityName; 341 while (dataMap.getDbEntity(dbEntityName) != null) { 342 dbEntityName = dbEntityBaseName + i++; 343 } 344 345 objEntity.setDbEntityName(dbEntityName); 346 DbEntity de = new DbEntity(dbEntityName); 347 dataMap.addDbEntity(de); 348 } 349 } 350 351 objEntity.setReadOnly("Y".equals(entityPlist.get("isReadOnly"))); 353 objEntity.setSuperEntityName((String ) entityPlist.get("parent")); 354 355 dataMap.addObjEntity(objEntity); 356 357 return objEntity; 358 } 359 360 364 protected void makeAttributes(EOModelHelper helper, EOObjEntity objEntity) { 365 Map entityPlistMap = helper.entityPListMap(objEntity.getName()); 366 List primaryKeys = (List ) entityPlistMap.get("primaryKeyAttributes"); 367 368 List classProperties; 369 if (objEntity.getIsClientEntity()) { 370 classProperties = (List ) entityPlistMap.get("clientClassProperties"); 371 } 372 else { 373 classProperties = (List ) entityPlistMap.get("classProperties"); 374 } 375 376 List attributes = (List ) entityPlistMap.get("attributes"); 377 DbEntity dbEntity = objEntity.getDbEntity(); 378 379 if (primaryKeys == null) { 380 primaryKeys = Collections.EMPTY_LIST; 381 } 382 383 if (classProperties == null) { 384 classProperties = Collections.EMPTY_LIST; 385 } 386 387 if (attributes == null) { 388 attributes = Collections.EMPTY_LIST; 389 } 390 391 boolean singleTableInheritance = false; 393 String parentName = (String ) entityPlistMap.get("parent"); 394 while (parentName != null) { 395 Map parentData = helper.entityPListMap(parentName); 396 if (parentData == null) { 397 break; 398 } 399 400 String parentExternalName = (String ) parentData.get("externalName"); 401 if (parentExternalName == null) { 402 parentName = (String ) parentData.get("parent"); 403 continue; 404 } 405 406 if (dbEntity.getName() != null 407 && dbEntity.getName().equals(parentExternalName)) { 408 singleTableInheritance = true; 409 } 410 411 break; 412 } 413 414 Iterator it = attributes.iterator(); 415 while (it.hasNext()) { 416 Map attrMap = (Map ) it.next(); 417 418 String prototypeName = (String ) attrMap.get("prototypeName"); 419 Map prototypeAttrMap = helper.getPrototypeAttributeMapFor(prototypeName); 420 421 String dbAttrName = (String ) attrMap.get("columnName"); 422 if (null == dbAttrName) { 423 dbAttrName = (String ) prototypeAttrMap.get("columnName"); 424 } 425 426 String attrName = (String ) attrMap.get("name"); 427 if (null == attrName) { 428 attrName = (String ) prototypeAttrMap.get("name"); 429 } 430 431 String attrType = (String ) attrMap.get("valueClassName"); 432 if (null == attrType) { 433 attrType = (String ) prototypeAttrMap.get("valueClassName"); 434 } 435 436 String valueType = (String ) attrMap.get("valueType"); 437 if (valueType == null) { 438 valueType = (String ) prototypeAttrMap.get("valueType"); 439 } 440 441 String javaType = helper.javaTypeForEOModelerType(attrType, valueType); 442 EODbAttribute dbAttr = null; 443 444 if (dbAttrName != null && dbEntity != null) { 445 446 if (!singleTableInheritance || dbEntity.getAttribute(dbAttrName) == null) { 448 449 int i = 0; 452 String dbAttributeBaseName = dbAttrName; 453 while (dbEntity.getAttribute(dbAttrName) != null) { 454 dbAttrName = dbAttributeBaseName + i++; 455 } 456 457 dbAttr = new EODbAttribute(dbAttrName, TypesMapping 458 .getSqlTypeByJava(javaType), dbEntity); 459 dbAttr.setEoAttributeName(attrName); 460 dbEntity.addAttribute(dbAttr); 461 462 Integer width = (Integer ) attrMap.get("width"); 463 if (null == width) 464 width = (Integer ) prototypeAttrMap.get("width"); 465 466 if (width != null) 467 dbAttr.setMaxLength(width.intValue()); 468 469 Integer scale = (Integer ) attrMap.get("scale"); 470 if (null == scale) 471 scale = (Integer ) prototypeAttrMap.get("scale"); 472 473 if (scale != null) 474 dbAttr.setPrecision(scale.intValue()); 475 476 if (primaryKeys.contains(attrName)) 477 dbAttr.setPrimaryKey(true); 478 479 Object allowsNull = attrMap.get("allowsNull"); 480 484 dbAttr.setMandatory(!"Y".equals(allowsNull)); 485 } 486 } 487 488 if (classProperties.contains(attrName)) { 489 EOObjAttribute attr = new EOObjAttribute(attrName, javaType, objEntity); 490 491 String entityReadOnlyString = (String ) entityPlistMap.get("isReadOnly"); 494 String attributeReadOnlyString = (String ) attrMap.get("isReadOnly"); 495 if ("Y".equals(entityReadOnlyString) 496 || "Y".equals(attributeReadOnlyString)) { 497 attr.setReadOnly(true); 498 } 499 500 attr.setDbAttributeName(dbAttrName); 502 objEntity.addAttribute(attr); 503 } 504 } 505 } 506 507 511 protected void makeRelationships(EOModelHelper helper, ObjEntity objEntity) { 512 Map entityPlistMap = helper.entityPListMap(objEntity.getName()); 513 List classProps = (List ) entityPlistMap.get("classProperties"); 514 List rinfo = (List ) entityPlistMap.get("relationships"); 515 516 Collection attributes = (Collection ) entityPlistMap.get("attributes"); 517 518 if (rinfo == null) { 519 return; 520 } 521 522 if (classProps == null) { 523 classProps = Collections.EMPTY_LIST; 524 } 525 526 if (attributes == null) { 527 attributes = Collections.EMPTY_LIST; 528 } 529 530 DbEntity dbSrc = objEntity.getDbEntity(); 531 Iterator it = rinfo.iterator(); 532 while (it.hasNext()) { 533 Map relMap = (Map ) it.next(); 534 String targetName = (String ) relMap.get("destination"); 535 536 if (targetName == null) { 538 continue; 539 } 540 541 String relName = (String ) relMap.get("name"); 542 boolean toMany = "Y".equals(relMap.get("isToMany")); 543 boolean toDependentPK = "Y".equals(relMap.get("propagatesPrimaryKey")); 544 ObjEntity target = helper.getDataMap().getObjEntity(targetName); 545 546 if (target == null) { 549 continue; 550 } 551 552 DbEntity dbTarget = target.getDbEntity(); 553 Map targetPlistMap = helper.entityPListMap(targetName); 554 Collection targetAttributes = (Collection ) targetPlistMap.get("attributes"); 555 DbRelationship dbRel = null; 556 557 if (dbSrc != null && dbTarget != null) { 561 562 566 dbRel = (DbRelationship) dbSrc.getRelationship(relName); 567 if (dbRel == null) { 568 569 dbRel = new DbRelationship(); 570 dbRel.setSourceEntity(dbSrc); 571 dbRel.setTargetEntity(dbTarget); 572 dbRel.setToMany(toMany); 573 dbRel.setName(relName); 574 dbRel.setToDependentPK(toDependentPK); 575 dbSrc.addRelationship(dbRel); 576 577 List joins = (List ) relMap.get("joins"); 578 Iterator jIt = joins.iterator(); 579 while (jIt.hasNext()) { 580 Map joinMap = (Map ) jIt.next(); 581 582 DbJoin join = new DbJoin(dbRel); 583 584 String sourceAttributeName = (String ) joinMap 586 .get("sourceAttribute"); 587 join.setSourceName(columnName(attributes, sourceAttributeName)); 588 589 String targetAttributeName = (String ) joinMap 590 .get("destinationAttribute"); 591 592 join.setTargetName(columnName( 593 targetAttributes, 594 targetAttributeName)); 595 dbRel.addJoin(join); 596 } 597 } 598 } 599 600 if (classProps.contains(relName)) { 602 ObjRelationship rel = new ObjRelationship(); 603 rel.setName(relName); 604 rel.setSourceEntity(objEntity); 605 rel.setTargetEntity(target); 606 objEntity.addRelationship(rel); 607 608 if (dbRel != null) { 609 rel.addDbRelationship(dbRel); 610 } 611 } 612 } 613 } 614 615 621 protected void makeReverseDbRelationships(DbEntity dbEntity) { 622 if (dbEntity == null) { 623 throw new NullPointerException ( 624 "Attempt to create reverse relationships for the null DbEntity."); 625 } 626 627 Collection clone = new ArrayList (dbEntity.getRelationships()); 630 Iterator it = clone.iterator(); 631 while (it.hasNext()) { 632 DbRelationship relationship = (DbRelationship) it.next(); 633 634 if (relationship.getReverseRelationship() == null) { 635 DbRelationship reverse = relationship.createReverseRelationship(); 636 637 String name = NamedObjectFactory.createName(DbRelationship.class, reverse 638 .getSourceEntity(), relationship.getName() + "Reverse"); 639 reverse.setName(name); 640 relationship.getTargetEntity().addRelationship(reverse); 641 } 642 } 643 } 644 645 648 protected void makeFlatRelationships(EOModelHelper helper, ObjEntity e) { 649 Map info = helper.entityPListMap(e.getName()); 650 List rinfo = (List ) info.get("relationships"); 651 if (rinfo == null) { 652 return; 653 } 654 655 Iterator it = rinfo.iterator(); 656 while (it.hasNext()) { 657 Map relMap = (Map ) it.next(); 658 String targetPath = (String ) relMap.get("definition"); 659 660 if (targetPath == null) { 662 continue; 663 } 664 665 ObjRelationship flatRel = new ObjRelationship(); 666 flatRel.setName((String ) relMap.get("name")); 667 flatRel.setSourceEntity(e); 668 e.addRelationship(flatRel); 669 670 DbEntity dbEntity = e.getDbEntity(); 671 if (dbEntity == null) { 672 continue; 674 } 675 676 Expression exp = new ASTDbPath(targetPath); 678 Iterator path = dbEntity.resolvePathComponents(exp); 679 680 DbRelationship firstRel = null; 681 DbRelationship lastRel = null; 682 while (path.hasNext()) { 683 lastRel = (DbRelationship) path.next(); 684 flatRel.addDbRelationship(lastRel); 685 686 if (firstRel == null) { 687 firstRel = lastRel; 688 } 689 } 690 691 if ((firstRel != null) && (lastRel != null)) { 692 Collection potentialTargets = e.getDataMap().getMappedEntities( 693 (DbEntity) lastRel.getTargetEntity()); 694 695 if (potentialTargets.size() != 1) { 697 throw new CayenneRuntimeException( 698 "One and only one entity should be mapped" 699 + " to " 700 + lastRel.getTargetEntity().getName() 701 + ". Instead found : " 702 + potentialTargets.size()); 703 } 704 705 flatRel.setTargetEntity((ObjEntity) potentialTargets.iterator().next()); 706 } 707 else { 708 throw new CayenneRuntimeException("relationship in the path was null!"); 709 } 710 } 711 712 } 713 714 720 String columnName(Collection entityAttributes, String attributeName) { 721 if (attributeName == null) { 722 return null; 723 } 724 725 Iterator it = entityAttributes.iterator(); 726 while (it.hasNext()) { 727 Map map = (Map ) it.next(); 728 if (attributeName.equals(map.get("name"))) { 729 return (String ) map.get("columnName"); 730 } 731 } 732 733 return null; 734 } 735 736 final class InheritanceComparator implements Comparator { 738 739 DataMap dataMap; 740 741 InheritanceComparator(DataMap dataMap) { 742 this.dataMap = dataMap; 743 } 744 745 public int compare(Object o1, Object o2) { 746 if (o1 == null) { 747 return o2 != null ? -1 : 0; 748 } 749 else if (o2 == null) { 750 return 1; 751 } 752 753 String name1 = o1.toString(); 754 String name2 = o2.toString(); 755 756 ObjEntity e1 = dataMap.getObjEntity(name1); 757 ObjEntity e2 = dataMap.getObjEntity(name2); 758 759 return compareEntities(e1, e2); 760 } 761 762 int compareEntities(ObjEntity e1, ObjEntity e2) { 763 if (e1 == null) { 764 return e2 != null ? -1 : 0; 765 } 766 else if (e2 == null) { 767 return 1; 768 } 769 770 if (e1.isSubentityOf(e2)) { 773 return 1; 774 } 775 776 if (e2.isSubentityOf(e1)) { 777 return -1; 778 } 779 780 return e1.getName().compareTo(e2.getName()); 782 } 783 } 784 } | Popular Tags |