1 19 20 21 package org.apache.cayenne.wocompat; 22 23 import java.io.FileNotFoundException ; 24 import java.io.InputStream ; 25 import java.net.URL ; 26 import java.util.ArrayList ; 27 import java.util.Collection ; 28 import java.util.Collections ; 29 import java.util.Comparator ; 30 import java.util.Iterator ; 31 import java.util.List ; 32 import java.util.Map ; 33 import java.util.StringTokenizer ; 34 35 import org.apache.cayenne.dba.TypesMapping; 36 import org.apache.cayenne.map.DataMap; 37 import org.apache.cayenne.map.DbEntity; 38 import org.apache.cayenne.map.DbJoin; 39 import org.apache.cayenne.map.DbRelationship; 40 import org.apache.cayenne.map.ObjEntity; 41 import org.apache.cayenne.map.ObjRelationship; 42 import org.apache.cayenne.project.NamedObjectFactory; 43 import org.apache.cayenne.query.AbstractQuery; 44 import org.apache.cayenne.query.Query; 45 import org.apache.cayenne.util.ResourceLocator; 46 import org.apache.cayenne.wocompat.parser.Parser; 47 import org.apache.commons.collections.CollectionUtils; 48 import org.apache.commons.collections.Predicate; 49 import org.apache.commons.collections.PredicateUtils; 50 51 54 public class EOModelProcessor { 55 56 protected Predicate prototypeChecker; 57 58 public EOModelProcessor() { 59 prototypeChecker = new Predicate() { 60 61 public boolean evaluate(Object object) { 62 if (object == null) { 63 return false; 64 } 65 66 String entityName = object.toString(); 67 return entityName.startsWith("EO") && entityName.endsWith("Prototypes"); 68 } 69 }; 70 } 71 72 77 public Map loadModeIndex(String path) throws Exception { 80 81 ResourceLocator locator = new ResourceLocator(); 82 locator.setSkipClasspath(false); 83 locator.setSkipCurrentDirectory(false); 84 locator.setSkipHomeDirectory(true); 85 locator.setSkipAbsolutePath(false); 86 87 if (!path.endsWith(".eomodeld")) { 88 path += ".eomodeld"; 89 } 90 91 URL base = locator.findDirectoryResource(path); 92 if (base == null) { 93 throw new FileNotFoundException ("Can't find EOModel: " + path); 94 } 95 96 Parser plistParser = new Parser(); 97 InputStream in = new URL (base, "index.eomodeld").openStream(); 98 99 try { 100 plistParser.ReInit(in); 101 return (Map ) plistParser.propertyList(); 102 } 103 finally { 104 in.close(); 105 } 106 } 107 108 114 public DataMap loadEOModel(String path) throws Exception { 115 return loadEOModel(path, false); 116 } 117 118 127 public DataMap loadEOModel(String path, boolean generateClientClass) throws Exception { 128 EOModelHelper helper = makeHelper(path, generateClientClass); 129 130 DataMap dataMap = helper.getDataMap(); 132 133 List modelNames = new ArrayList (helper.modelNamesAsList()); 135 CollectionUtils.filter(modelNames, PredicateUtils.notPredicate(prototypeChecker)); 136 137 Iterator it = modelNames.iterator(); 138 while (it.hasNext()) { 139 String name = (String ) it.next(); 140 141 makeEntity(helper, name, generateClientClass); 143 } 144 145 Collections.sort(modelNames, new InheritanceComparator(dataMap)); 147 148 it = modelNames.iterator(); 150 while (it.hasNext()) { 151 String name = (String ) it.next(); 152 153 EOObjEntity e = (EOObjEntity) dataMap.getObjEntity(name); 154 makeAttributes(helper, e); 156 } 157 158 it = modelNames.iterator(); 160 while (it.hasNext()) { 161 String name = (String ) it.next(); 162 makeRelationships(helper, dataMap.getObjEntity(name)); 163 } 164 165 it = modelNames.iterator(); 167 while (it.hasNext()) { 168 String name = (String ) it.next(); 169 makeFlatRelationships(helper, dataMap.getObjEntity(name)); 170 } 171 172 it = modelNames.iterator(); 175 while (it.hasNext()) { 176 String name = (String ) it.next(); 177 DbEntity dbEntity = dataMap.getObjEntity(name).getDbEntity(); 178 179 if (dbEntity != null) { 180 makeReverseDbRelationships(dbEntity); 181 } 182 } 183 184 it = modelNames.iterator(); 186 while (it.hasNext()) { 187 String name = (String ) it.next(); 188 Iterator queries = helper.queryNames(name); 189 while (queries.hasNext()) { 190 String queryName = (String ) queries.next(); 191 EOObjEntity entity = (EOObjEntity) dataMap.getObjEntity(name); 192 makeQuery(helper, entity, queryName); 193 } 194 } 195 196 return dataMap; 197 } 198 199 206 protected boolean isPrototypesEntity(String entityName) { 207 return prototypeChecker.evaluate(entityName); 208 } 209 210 214 protected EOModelHelper makeHelper(String path, boolean genereateClientClass) 215 throws Exception { 216 return new EOModelHelper(path); 217 } 218 219 224 protected Query makeQuery(EOModelHelper helper, EOObjEntity entity, String queryName) { 225 226 DataMap dataMap = helper.getDataMap(); 227 Map queryPlist = helper.queryPListMap(entity.getName(), queryName); 228 if (queryPlist == null) { 229 return null; 230 } 231 232 AbstractQuery query; 233 if (queryPlist.containsKey("hints")) { query = new EOSQLQuery(entity, queryPlist); 235 } else { 236 query = new EOQuery(entity, queryPlist); 237 } 238 query.setName(entity.qualifiedQueryName(queryName)); 239 dataMap.addQuery(query); 240 241 return query; 242 } 243 244 247 protected EOObjEntity makeEntity( 248 EOModelHelper helper, 249 String name, 250 boolean generateClientClass) { 251 252 DataMap dataMap = helper.getDataMap(); 253 Map entityPlist = helper.entityPListMap(name); 254 255 EOObjEntity objEntity = new EOObjEntity(name); 257 objEntity.setEoMap(entityPlist); 258 objEntity.setServerOnly(!generateClientClass); 259 String parent = (String ) entityPlist.get("parent"); 260 objEntity.setClassName(helper.entityClass(name, generateClientClass)); 261 262 if (parent != null) { 263 objEntity.setSubclass(true); 264 objEntity.setSuperClassName(helper.entityClass(parent, generateClientClass)); 265 } 266 267 objEntity.setAbstractEntity("Y".equals(entityPlist.get("isAbstractEntity"))); 269 270 String dbEntityName = (String ) entityPlist.get("externalName"); 273 if (dbEntityName != null) { 274 275 boolean createDbEntity = true; 278 if (parent != null) { 279 String parentName = parent; 280 while (parentName != null) { 281 Map parentData = helper.entityPListMap(parentName); 282 if (parentData == null) { 283 break; 284 } 285 286 String parentExternalName = (String ) parentData.get("externalName"); 287 if (parentExternalName == null) { 288 parentName = (String ) parentData.get("parent"); 289 continue; 290 } 291 292 if (dbEntityName.equals(parentExternalName)) { 293 createDbEntity = false; 294 } 295 296 break; 297 } 298 } 299 300 if (createDbEntity) { 301 int i = 0; 302 String dbEntityBaseName = dbEntityName; 303 while (dataMap.getDbEntity(dbEntityName) != null) { 304 dbEntityName = dbEntityBaseName + i++; 305 } 306 307 objEntity.setDbEntityName(dbEntityName); 308 DbEntity de = new DbEntity(dbEntityName); 309 dataMap.addDbEntity(de); 310 } 311 } 312 313 objEntity.setReadOnly("Y".equals(entityPlist.get("isReadOnly"))); 315 objEntity.setSuperEntityName((String ) entityPlist.get("parent")); 316 317 dataMap.addObjEntity(objEntity); 318 319 return objEntity; 320 } 321 322 326 protected void makeAttributes(EOModelHelper helper, EOObjEntity objEntity) { 327 Map entityPlistMap = helper.entityPListMap(objEntity.getName()); 328 List primaryKeys = (List ) entityPlistMap.get("primaryKeyAttributes"); 329 330 List classProperties; 331 if (objEntity.isServerOnly()) { 332 classProperties = (List ) entityPlistMap.get("classProperties"); 333 } 334 else { 335 classProperties = (List ) entityPlistMap.get("clientClassProperties"); 336 } 337 338 List attributes = (List ) entityPlistMap.get("attributes"); 339 DbEntity dbEntity = objEntity.getDbEntity(); 340 341 if (primaryKeys == null) { 342 primaryKeys = Collections.EMPTY_LIST; 343 } 344 345 if (classProperties == null) { 346 classProperties = Collections.EMPTY_LIST; 347 } 348 349 if (attributes == null) { 350 attributes = Collections.EMPTY_LIST; 351 } 352 353 boolean singleTableInheritance = false; 355 String parentName = (String ) entityPlistMap.get("parent"); 356 while (parentName != null) { 357 Map parentData = helper.entityPListMap(parentName); 358 if (parentData == null) { 359 break; 360 } 361 362 String parentExternalName = (String ) parentData.get("externalName"); 363 if (parentExternalName == null) { 364 parentName = (String ) parentData.get("parent"); 365 continue; 366 } 367 368 if (dbEntity.getName() != null 369 && dbEntity.getName().equals(parentExternalName)) { 370 singleTableInheritance = true; 371 } 372 373 break; 374 } 375 376 Iterator it = attributes.iterator(); 377 while (it.hasNext()) { 378 Map attrMap = (Map ) it.next(); 379 380 String prototypeName = (String ) attrMap.get("prototypeName"); 381 Map prototypeAttrMap = helper.getPrototypeAttributeMapFor(prototypeName); 382 383 String dbAttrName = (String ) attrMap.get("columnName"); 384 if (null == dbAttrName) { 385 dbAttrName = (String ) prototypeAttrMap.get("columnName"); 386 } 387 388 String attrName = (String ) attrMap.get("name"); 389 if (null == attrName) { 390 attrName = (String ) prototypeAttrMap.get("name"); 391 } 392 393 String attrType = (String ) attrMap.get("valueClassName"); 394 if (null == attrType) { 395 attrType = (String ) prototypeAttrMap.get("valueClassName"); 396 } 397 398 String valueType = (String ) attrMap.get("valueType"); 399 if (valueType == null) { 400 valueType = (String ) prototypeAttrMap.get("valueType"); 401 } 402 403 String javaType = helper.javaTypeForEOModelerType(attrType, valueType); 404 EODbAttribute dbAttr = null; 405 406 if (dbAttrName != null && dbEntity != null) { 407 408 if (!singleTableInheritance || dbEntity.getAttribute(dbAttrName) == null) { 410 411 int i = 0; 414 String dbAttributeBaseName = dbAttrName; 415 while (dbEntity.getAttribute(dbAttrName) != null) { 416 dbAttrName = dbAttributeBaseName + i++; 417 } 418 419 dbAttr = new EODbAttribute(dbAttrName, TypesMapping 420 .getSqlTypeByJava(javaType), dbEntity); 421 dbAttr.setEoAttributeName(attrName); 422 dbEntity.addAttribute(dbAttr); 423 424 int width = getInt("width", attrMap, prototypeAttrMap, -1); 425 if (width >= 0) { 426 dbAttr.setMaxLength(width); 427 } 428 429 int scale = getInt("scale", attrMap, prototypeAttrMap, -1); 430 if (scale >= 0) { 431 dbAttr.setScale(scale); 432 } 433 434 if (primaryKeys.contains(attrName)) 435 dbAttr.setPrimaryKey(true); 436 437 Object allowsNull = attrMap.get("allowsNull"); 438 442 dbAttr.setMandatory(!"Y".equals(allowsNull)); 443 } 444 } 445 446 if (classProperties.contains(attrName)) { 447 EOObjAttribute attr = new EOObjAttribute(attrName, javaType, objEntity); 448 449 String entityReadOnlyString = (String ) entityPlistMap.get("isReadOnly"); 452 String attributeReadOnlyString = (String ) attrMap.get("isReadOnly"); 453 if ("Y".equals(entityReadOnlyString) 454 || "Y".equals(attributeReadOnlyString)) { 455 attr.setReadOnly(true); 456 } 457 458 attr.setDbAttributeName(dbAttrName); 460 objEntity.addAttribute(attr); 461 } 462 } 463 } 464 465 int getInt(String key, Map map, Map prototypes, int defaultValue) { 466 467 Object value = map.get(key); 468 if (value == null) { 469 value = prototypes.get(key); 470 } 471 472 if (value == null) { 473 return defaultValue; 474 } 475 476 if (value instanceof Number ) { 478 return ((Number ) value).intValue(); 479 } 480 else { 481 try { 482 return Integer.parseInt(value.toString()); 483 } 484 catch(NumberFormatException nfex) { 485 return defaultValue; 486 } 487 } 488 } 489 490 494 protected void makeRelationships(EOModelHelper helper, ObjEntity objEntity) { 495 Map entityPlistMap = helper.entityPListMap(objEntity.getName()); 496 List classProps = (List ) entityPlistMap.get("classProperties"); 497 List rinfo = (List ) entityPlistMap.get("relationships"); 498 499 Collection attributes = (Collection ) entityPlistMap.get("attributes"); 500 501 if (rinfo == null) { 502 return; 503 } 504 505 if (classProps == null) { 506 classProps = Collections.EMPTY_LIST; 507 } 508 509 if (attributes == null) { 510 attributes = Collections.EMPTY_LIST; 511 } 512 513 DbEntity dbSrc = objEntity.getDbEntity(); 514 Iterator it = rinfo.iterator(); 515 while (it.hasNext()) { 516 Map relMap = (Map ) it.next(); 517 String targetName = (String ) relMap.get("destination"); 518 519 if (targetName == null) { 521 continue; 522 } 523 524 String relName = (String ) relMap.get("name"); 525 boolean toMany = "Y".equals(relMap.get("isToMany")); 526 boolean toDependentPK = "Y".equals(relMap.get("propagatesPrimaryKey")); 527 ObjEntity target = helper.getDataMap().getObjEntity(targetName); 528 529 if (target == null) { 532 continue; 533 } 534 535 DbEntity dbTarget = target.getDbEntity(); 536 Map targetPlistMap = helper.entityPListMap(targetName); 537 Collection targetAttributes = (Collection ) targetPlistMap.get("attributes"); 538 DbRelationship dbRel = null; 539 540 if (dbSrc != null && dbTarget != null) { 544 545 549 dbRel = (DbRelationship) dbSrc.getRelationship(relName); 550 if (dbRel == null) { 551 552 dbRel = new DbRelationship(); 553 dbRel.setSourceEntity(dbSrc); 554 dbRel.setTargetEntity(dbTarget); 555 dbRel.setToMany(toMany); 556 dbRel.setName(relName); 557 dbRel.setToDependentPK(toDependentPK); 558 dbSrc.addRelationship(dbRel); 559 560 List joins = (List ) relMap.get("joins"); 561 Iterator jIt = joins.iterator(); 562 while (jIt.hasNext()) { 563 Map joinMap = (Map ) jIt.next(); 564 565 DbJoin join = new DbJoin(dbRel); 566 567 String sourceAttributeName = (String ) joinMap 569 .get("sourceAttribute"); 570 join.setSourceName(columnName(attributes, sourceAttributeName)); 571 572 String targetAttributeName = (String ) joinMap 573 .get("destinationAttribute"); 574 575 join.setTargetName(columnName( 576 targetAttributes, 577 targetAttributeName)); 578 dbRel.addJoin(join); 579 } 580 } 581 } 582 583 if (classProps.contains(relName)) { 585 ObjRelationship rel = new ObjRelationship(); 586 rel.setName(relName); 587 rel.setSourceEntity(objEntity); 588 rel.setTargetEntity(target); 589 objEntity.addRelationship(rel); 590 591 if (dbRel != null) { 592 rel.addDbRelationship(dbRel); 593 } 594 } 595 } 596 } 597 598 604 protected void makeReverseDbRelationships(DbEntity dbEntity) { 605 if (dbEntity == null) { 606 throw new NullPointerException ( 607 "Attempt to create reverse relationships for the null DbEntity."); 608 } 609 610 Collection clone = new ArrayList (dbEntity.getRelationships()); 613 Iterator it = clone.iterator(); 614 while (it.hasNext()) { 615 DbRelationship relationship = (DbRelationship) it.next(); 616 617 if (relationship.getReverseRelationship() == null) { 618 DbRelationship reverse = relationship.createReverseRelationship(); 619 620 String name = NamedObjectFactory.createName(DbRelationship.class, reverse 621 .getSourceEntity(), relationship.getName() + "Reverse"); 622 reverse.setName(name); 623 relationship.getTargetEntity().addRelationship(reverse); 624 } 625 } 626 } 627 628 631 protected void makeFlatRelationships(EOModelHelper helper, ObjEntity e) { 632 Map info = helper.entityPListMap(e.getName()); 633 List rinfo = (List ) info.get("relationships"); 634 if (rinfo == null) { 635 return; 636 } 637 638 Iterator it = rinfo.iterator(); 639 while (it.hasNext()) { 640 Map relMap = (Map ) it.next(); 641 String targetPath = (String ) relMap.get("definition"); 642 643 if (targetPath == null) { 645 continue; 646 } 647 648 ObjRelationship flatRel = new ObjRelationship(); 649 flatRel.setName((String ) relMap.get("name")); 650 flatRel.setSourceEntity(e); 651 flatRel.setDbRelationshipPath(targetPath); 652 653 Map entityInfo = info; 655 StringTokenizer toks = new StringTokenizer (targetPath, "."); 656 while (toks.hasMoreTokens() && entityInfo != null) { 657 String pathComponent = toks.nextToken(); 658 659 Collection relationshipInfo = (Collection ) entityInfo 663 .get("relationships"); 664 entityInfo = null; 665 666 if (relationshipInfo == null) { 667 break; 668 } 669 670 Iterator rit = relationshipInfo.iterator(); 671 while (rit.hasNext()) { 672 Map pathRelationship = (Map ) rit.next(); 673 if (pathComponent.equals(pathRelationship.get("name"))) { 674 String targetName = (String ) pathRelationship.get("destination"); 675 entityInfo = helper.entityPListMap(targetName); 676 break; 677 } 678 } 679 } 680 681 if(entityInfo != null) { 682 flatRel.setTargetEntityName((String ) entityInfo.get("name")); 683 } 684 685 686 e.addRelationship(flatRel); 687 } 688 } 689 690 696 String columnName(Collection entityAttributes, String attributeName) { 697 if (attributeName == null) { 698 return null; 699 } 700 701 Iterator it = entityAttributes.iterator(); 702 while (it.hasNext()) { 703 Map map = (Map ) it.next(); 704 if (attributeName.equals(map.get("name"))) { 705 return (String ) map.get("columnName"); 706 } 707 } 708 709 return null; 710 } 711 712 final class InheritanceComparator implements Comparator { 714 715 DataMap dataMap; 716 717 InheritanceComparator(DataMap dataMap) { 718 this.dataMap = dataMap; 719 } 720 721 public int compare(Object o1, Object o2) { 722 if (o1 == null) { 723 return o2 != null ? -1 : 0; 724 } 725 else if (o2 == null) { 726 return 1; 727 } 728 729 String name1 = o1.toString(); 730 String name2 = o2.toString(); 731 732 ObjEntity e1 = dataMap.getObjEntity(name1); 733 ObjEntity e2 = dataMap.getObjEntity(name2); 734 735 return compareEntities(e1, e2); 736 } 737 738 int compareEntities(ObjEntity e1, ObjEntity e2) { 739 if (e1 == null) { 740 return e2 != null ? -1 : 0; 741 } 742 else if (e2 == null) { 743 return 1; 744 } 745 746 if (e1.isSubentityOf(e2)) { 749 return 1; 750 } 751 752 if (e2.isSubentityOf(e1)) { 753 return -1; 754 } 755 756 return e1.getName().compareTo(e2.getName()); 758 } 759 } 760 } 761 | Popular Tags |