1 25 26 package org.objectweb.jorm.mapper.rdb.lib; 27 28 import java.util.ArrayList ; 29 import java.util.Collection ; 30 import java.util.Collections ; 31 import java.util.HashMap ; 32 import java.util.HashSet ; 33 import java.util.Iterator ; 34 import java.util.Map ; 35 36 import org.objectweb.jorm.api.PException; 37 import org.objectweb.jorm.mapper.rdb.metainfo.RdbClassMapping; 38 import org.objectweb.jorm.mapper.rdb.metainfo.RdbClassMultiMapping; 39 import org.objectweb.jorm.mapper.rdb.metainfo.RdbJoin; 40 import org.objectweb.jorm.mapper.rdb.metainfo.RdbPrimitiveElementMapping; 41 import org.objectweb.jorm.mapper.rdb.metainfo.RdbTable; 42 import org.objectweb.jorm.metainfo.api.Class; 43 import org.objectweb.jorm.metainfo.api.NameDef; 44 import org.objectweb.jorm.metainfo.api.ParentClassMapping; 45 import org.objectweb.jorm.metainfo.api.PrimitiveElement; 46 import org.objectweb.util.monolog.api.BasicLevel; 47 import org.objectweb.util.monolog.api.Logger; 48 49 public class RdbExtentGenInfos { 50 51 public Logger logger; 52 public boolean debug = false; 53 54 public RdbExtentGenInfos(Logger logger) { 55 this.logger = logger; 56 debug = logger != null && logger.isLoggable(BasicLevel.DEBUG); 57 } 58 59 119 public Collection getPolymorphicClassExtent(Class classA, String projectName, 122 String mapperName) throws PException { 123 if (debug) logger.log(BasicLevel.INFO, "Calculating extent for class" 126 + classA.getFQName() + " project: " + projectName + 127 ", mapperName: " + mapperName); 128 RdbClassMapping classMappingOfA = (RdbClassMapping) 129 classA.getClassMapping(projectName, mapperName); 130 131 132 135 ArrayList primElsOfA = new ArrayList (); 137 if (debug) logger.log(BasicLevel.DEBUG, "Primitive elements are: "); 138 for (Iterator itTE = classA.getAllFields().iterator(); itTE.hasNext();) { 139 Object te = itTE.next(); 140 if (te instanceof PrimitiveElement) { 141 primElsOfA.add(te); 142 if (debug) logger.log(BasicLevel.DEBUG, " " + 143 ((PrimitiveElement) te).getName()); 144 } 145 } 146 for (Iterator itTE = classA.getAllHiddenFields().iterator(); itTE.hasNext();) { 148 Object te = itTE.next(); 149 if (te instanceof PrimitiveElement) { 150 primElsOfA.add(te); 151 if (debug) logger.log(BasicLevel.DEBUG, " " + 152 ((PrimitiveElement) te).getName() + " (hidden)"); 153 } 154 } 155 156 HashMap extMappingInfosMap = new HashMap (); HashSet extMappingInfos = new HashSet (); 159 ArrayList remClasses = new ArrayList (); 163 remClasses.add(classA); 164 while (!remClasses.isEmpty()) { 165 Class classX = (Class ) remClasses.remove(0); 167 Collection xSubClasses = classX.getSubClasses(); 169 if (xSubClasses != null) { 170 remClasses.addAll(xSubClasses); 171 } 172 173 RdbClassMultiMapping classMappingOfX = (RdbClassMultiMapping) 175 classX.getClassMapping(projectName, mapperName); 176 if (classMappingOfX == null) { 177 throw new PException("Could not find a class mapping for class " 178 + classA.getName()); 179 } 180 181 182 RdbExtentMappingInfos emi; 185 186 187 if (classX != classA) { 189 if (debug) logger.log(BasicLevel.DEBUG, "Inspecting subclass: " 190 + classX.getName()); 191 Class [] parent = new Class [1]; 192 RdbExtentMappingInfos emiParent = getParentEMI(classX, extMappingInfosMap, parent); 193 ParentClassMapping pcmOfX = classMappingOfX. 196 getParentClassMapping(parent[0].getFQName()); 197 198 if (pcmOfX == null) { 200 throw new PException("Could not find a parent class mapping" + 201 " for class " + classX.getName() + " to super class" + 202 classA.getName()); 203 } 204 205 String ruleName = pcmOfX.getRuleName(); 207 if (debug) logger.log(BasicLevel.DEBUG, " inherits mapping from : " + 208 ((Class ) pcmOfX.getLinkedMO()).getFQName() + 209 " with rule=" + ruleName); 210 211 212 if ((RdbClassMapping.MAP_NEW_FIELDS_TO_EXTENDED_STRUCTURES 216 .equalsIgnoreCase(ruleName)) || 217 (RdbClassMapping.MAP_NEW_FIELDS_TO_ADDED_STRUCTURES 218 .equalsIgnoreCase(ruleName))) { 219 if (emiParent.hasUnmappedFields) { 224 if (debug) logger.log(BasicLevel.DEBUG, 225 "Parent class has unmapped fields, create new EMI"); 226 emi = new RdbExtentMappingInfos(classX, classX.getName(), primElsOfA.size()); 227 extMappingInfos.add(emi); 228 emi.addFilters = emiParent.addFilters; 229 emi.hasUnmappedFields = classMappingOfX. 230 hasUnmappedPrimitiveElements(primElsOfA); 231 } else { 232 if (debug) logger.log(BasicLevel.DEBUG, 233 "Parent class has all its fields mapped, complement its EMI"); 234 emi = emiParent; 235 } 236 237 if (emi.addFilters && (!classX.isAbstract())) { 240 emi.filters.add(classX.getFQName()); 241 } 242 } else if (RdbClassMapping.REMAP_FIELDS_TO_NEW_STRUCTURES 243 .equalsIgnoreCase(ruleName)) { 244 emi = new RdbExtentMappingInfos(classX, classX.getName(), primElsOfA.size()); 248 emi.addFilters = true; 251 extMappingInfos.add(emi); 252 emi.hasUnmappedFields = classMappingOfX.hasUnmappedPrimitiveElements(primElsOfA); 253 } else { 254 throw new InternalError ("Unexpected inheritance rule: " 255 + ruleName); 256 } 257 extMappingInfosMap.put(classX, emi); 259 260 if (classX.isAbstract()) { 264 if (debug) logger.log(BasicLevel.DEBUG, "Class is abstract, next one"); 265 continue; 266 } 267 268 } else { emi = new RdbExtentMappingInfos(classX, classX.getName(), primElsOfA.size()); 270 extMappingInfos.add(emi); 271 extMappingInfosMap.put(classX, emi); 272 273 emi.addFilters = true; 279 emi.hasUnmappedFields = classMappingOfX.hasUnmappedPrimitiveElements(primElsOfA); 280 if (debug) logger.log(BasicLevel.DEBUG, " should add filters ? " 281 + (emi.addFilters ? "yes" : "no")); 282 283 if (classX.isAbstract()) { 287 if (debug) logger.log(BasicLevel.DEBUG, "Class is abstract, next one"); 288 continue; 289 } 290 if (emi.addFilters) { 291 emi.filters.add(classX.getFQName()); 292 } 293 } 294 295 296 297 int pos = 0; 301 for (Iterator it = primElsOfA.iterator(); it.hasNext(); pos++) { 302 PrimitiveElement pe = (PrimitiveElement) it.next(); 303 if (debug) logger.log(BasicLevel.DEBUG, " find mapping for " 304 + "primitive element " + pe.getName()); 305 if (emi.mappingDone(pos)) { 306 if (debug) logger.log(BasicLevel.DEBUG, " already done"); 307 continue; 308 } 309 RdbPrimitiveElementMapping mappingOfpeInX = (RdbPrimitiveElementMapping) 311 classMappingOfX.getPrimitiveElementMapping(pe.getName(), true); 312 RdbJoin join = mappingOfpeInX.getJoinByPrimitiveElement(pe); 315 String tableName; 316 if (join != null) { 317 if (debug) logger.log(BasicLevel.DEBUG, " mapped to external table"); 318 tableName = join.getExternalTable().getName(); 319 emi.addJoin(join); 320 } else { 321 if (debug) logger.log(BasicLevel.DEBUG, " mapped to main table"); 322 emi.mainTable = (RdbTable) mappingOfpeInX.getParent(); 323 tableName = emi.mainTable.getName(); 324 } 325 326 emi.addProjection(tableName, mappingOfpeInX.getName(), 327 pe.getName(), classX.getFQName(), pos); 328 } 329 } 331 for (Iterator emiIt = extMappingInfos.iterator(); emiIt.hasNext();) { 333 RdbExtentMappingInfos emi = (RdbExtentMappingInfos) emiIt.next(); 334 if (emi.isEmpty()) { 335 emiIt.remove(); 336 } 337 } 338 339 return extMappingInfos; 340 } 341 342 349 public Collection getPolymorphicClassExtent(Class classA, String projectName, String mapperName, boolean prefetch) throws PException { 350 if (debug) 351 logger.log(BasicLevel.INFO, "Calculating extent for class" 352 + classA.getFQName() + " project: " + projectName 353 + ", mapperName: " + mapperName); 354 RdbClassMapping classMappingOfA = (RdbClassMapping) classA 355 .getClassMapping(projectName, mapperName); 356 357 361 ArrayList primElsOfA = new ArrayList (); 363 364 ArrayList primEls = getPrimitiveElements(prefetch, classA, projectName, primElsOfA); 366 367 HashMap extMappingInfosMap = new HashMap (); HashSet extMappingInfos = new HashSet (); 370 ArrayList remClasses = new ArrayList (); 374 remClasses.add(classA); 375 while (!remClasses.isEmpty()) { 376 Class classX = (Class ) remClasses.remove(0); 378 Collection xSubClasses = classX.getSubClasses(); 380 if (xSubClasses != null) { 381 remClasses.addAll(xSubClasses); 382 } 383 384 RdbClassMultiMapping classMappingOfX = (RdbClassMultiMapping) classX 386 .getClassMapping(projectName, mapperName); 387 if (classMappingOfX == null) { 388 throw new PException( 389 "Could not find a class mapping for class " 390 + classA.getName()); 391 } 392 393 RdbExtentMappingInfos emi; 397 398 if (classX != classA) { 400 if (debug) 401 logger.log(BasicLevel.DEBUG, "Inspecting subclass: " 402 + classX.getName()); 403 Class [] parent = new Class [1]; 404 RdbExtentMappingInfos emiParent = getParentEMI(classX, 405 extMappingInfosMap, parent); 406 ParentClassMapping pcmOfX = classMappingOfX 411 .getParentClassMapping(parent[0].getFQName()); 412 413 if (pcmOfX == null) { 415 throw new PException( 416 "Could not find a parent class mapping" 417 + " for class " + classX.getName() 418 + " to super class" + classA.getName()); 419 } 420 421 String ruleName = pcmOfX.getRuleName(); 423 if (debug) 424 logger.log(BasicLevel.DEBUG, " inherits mapping from : " 425 + ((Class ) pcmOfX.getLinkedMO()).getFQName() 426 + " with rule=" + ruleName); 427 428 if ((RdbClassMapping.MAP_NEW_FIELDS_TO_EXTENDED_STRUCTURES.equalsIgnoreCase(ruleName)) 432 || 433 ((RdbClassMapping.MAP_NEW_FIELDS_TO_ADDED_STRUCTURES.equalsIgnoreCase(ruleName)) && !prefetch) ) { 434 if (emiParent.hasUnmappedFields) { 439 if (debug) 440 logger 441 .log(BasicLevel.DEBUG, 442 "Parent class has unmapped fields, create new EMI"); 443 emi = new RdbExtentMappingInfos(classX, classX.getName(), 444 primEls.size()); 445 extMappingInfos.add(emi); 446 emi.addFilters = emiParent.addFilters; 447 emi.hasUnmappedFields = classMappingOfX 448 .hasUnmappedPrimitiveElements(primElsOfA); 449 } else { 450 if (debug) 451 logger 452 .log(BasicLevel.DEBUG, 453 "Parent class has all its fields mapped, complement its EMI"); 454 emi = emiParent; 455 } 456 457 if (emi.addFilters && (!classX.isAbstract())) { 460 emi.filters.add(classX.getFQName()); 461 } 462 } else if (RdbClassMapping.REMAP_FIELDS_TO_NEW_STRUCTURES.equalsIgnoreCase(ruleName) 463 || 464 ((RdbClassMapping.MAP_NEW_FIELDS_TO_ADDED_STRUCTURES.equalsIgnoreCase(ruleName)) && prefetch)) { 465 emi = new RdbExtentMappingInfos(classX, classX.getName(), 470 primEls.size()); 471 emi.addFilters = true; 475 extMappingInfos.add(emi); 476 emi.hasUnmappedFields = classMappingOfX 477 .hasUnmappedPrimitiveElements(primElsOfA); 478 } else { 479 throw new InternalError ("Unexpected inheritance rule: " 480 + ruleName); 481 } 482 extMappingInfosMap.put(classX, emi); 484 485 if (classX.isAbstract()) { 489 if (debug) 490 logger.log(BasicLevel.DEBUG, 491 "Class is abstract, next one"); 492 continue; 493 } 494 495 } else { emi = new RdbExtentMappingInfos(classX, classX.getName(), 497 primEls.size()); 498 extMappingInfos.add(emi); 499 extMappingInfosMap.put(classX, emi); 500 501 emi.addFilters = true; 508 emi.hasUnmappedFields = classMappingOfX 509 .hasUnmappedPrimitiveElements(primElsOfA); 510 if (debug) 511 logger.log(BasicLevel.DEBUG, " should add filters ? " 512 + (emi.addFilters ? "yes" : "no")); 513 514 if (classX.isAbstract()) { 518 if (debug) 519 logger.log(BasicLevel.DEBUG, 520 "Class is abstract, next one"); 521 continue; 522 } 523 if (emi.addFilters) { 524 emi.filters.add(classX.getFQName()); 525 } 526 } 527 528 int pos = 0; 532 for (Iterator it = primEls.iterator(); it.hasNext(); pos++) { 533 PrimitiveElement pe = (PrimitiveElement) it.next(); 534 if (debug) 535 logger.log(BasicLevel.DEBUG, " find mapping for " 536 + "primitive element " + pe.getName()); 537 if (emi.mappingDone(pos) && !emi.mappingNull(pos)) { 540 if (debug) 541 logger.log(BasicLevel.DEBUG, " already done"); 542 continue; 543 } 544 RdbPrimitiveElementMapping mappingOfpeInX = (RdbPrimitiveElementMapping) classMappingOfX 546 .getPrimitiveElementMapping(pe.getName(), true); 547 String tableName = ""; 548 if(prefetch && mappingOfpeInX == null){ 549 emi.addProjection(tableName, RdbExtentMappingInfos.NULL_COLUMN, pe.getName(), ((Class ) pe.getParent()).getFQName(), pos); 554 } 555 else{ 556 RdbJoin join = mappingOfpeInX.getJoinByPrimitiveElement(pe); 559 if (join != null) { 560 if (debug) 561 logger.log(BasicLevel.DEBUG," mapped to external table"); 562 tableName = join.getExternalTable().getName(); 563 emi.addJoin(join); 564 } else { 565 if (debug) 566 logger.log(BasicLevel.DEBUG," mapped to main table"); 567 emi.setMainTable((RdbTable) mappingOfpeInX.getParent()); 568 tableName = emi.getMainTable().getName(); 569 } 570 emi.addProjection(tableName, mappingOfpeInX.getName(), pe.getName(), ((Class ) pe.getParent()).getFQName(), pos); 571 } 572 } 573 } 575 for (Iterator emiIt = extMappingInfos.iterator(); emiIt.hasNext();) { 577 RdbExtentMappingInfos emi = (RdbExtentMappingInfos) emiIt.next(); 578 if (emi.isEmpty()) { 579 emiIt.remove(); 580 } 581 } 582 583 return extMappingInfos; 584 } 585 586 592 public ArrayList getAllPrimitiveElementsInGraph(Class classA, String projectName){ 593 Collection ancestors = classA.getAllAncestors(); 595 if (ancestors == Collections.EMPTY_LIST) 596 ancestors = new ArrayList (1); 597 ancestors.add(classA); 599 ArrayList primEls = new ArrayList (); 601 Iterator it = ancestors.iterator(); 602 while (it.hasNext()) { 604 Class currentClass = (Class ) it.next(); 605 boolean withSubclasses = false; 606 if (currentClass == classA) 607 withSubclasses = true; 608 ArrayList primElsOfCurrent = getPrimitiveElements(withSubclasses, currentClass, projectName, null); 611 Iterator peIt = primElsOfCurrent.iterator(); 612 while (peIt.hasNext()) { 613 PrimitiveElement pe = (PrimitiveElement) peIt.next(); 614 if (!primEls.contains(pe)) { 615 primEls.add(pe); 617 } 618 } 619 } 620 621 return primEls; 622 } 623 624 630 private ArrayList getPrimitiveElements(boolean withSubtypes, Class classA, String projectName, ArrayList primElsOfA){ 631 ArrayList primEls = new ArrayList (); 633 ArrayList remClasses = new ArrayList (); 635 remClasses.add(classA); 637 638 while(!remClasses.isEmpty()){ 639 Class currentClass = (Class ) remClasses.remove(0); 640 641 if(withSubtypes) 644 remClasses.addAll(currentClass.getSubClasses()); 645 646 NameDef ndef = currentClass.getNameDef(projectName); 647 if (debug) 648 logger.log(BasicLevel.DEBUG, "Primitive elements are: "); 649 for (Iterator itTE = currentClass.getAllFields().iterator(); itTE.hasNext();) { 650 Object te = itTE.next(); 651 if (te instanceof PrimitiveElement) { 652 if(!primEls.contains(te)) 654 primEls.add(te); 655 if (debug) 656 logger.log(BasicLevel.DEBUG, " " + ((PrimitiveElement) te).getName()); 657 } 658 } 659 for (Iterator itTE = currentClass.getAllHiddenFields().iterator(); itTE.hasNext();) { 661 Object te = itTE.next(); 662 if (te instanceof PrimitiveElement) { 663 if(!primEls.contains(te)) 665 primEls.add(te); 666 if (debug) 667 logger.log(BasicLevel.DEBUG, " " + ((PrimitiveElement) te).getName() + " (hidden)"); 668 } 669 } 670 671 if(primElsOfA != null && currentClass == classA) 672 primElsOfA.addAll(primEls); 673 } 674 return primEls; 675 } 676 677 683 private RdbExtentMappingInfos getParentEMI(Class clazz, Map EMIMap, Class [] parent) { 684 logger.log(BasicLevel.DEBUG, "Get parent's EMI"); 685 if (parent != null) { 686 parent[0] = null; 687 } 688 RdbExtentMappingInfos emiOfParent = null; 689 Collection parentsOfX = clazz.getSuperClasses(); 690 for (Iterator itP = parentsOfX.iterator(); itP.hasNext();) { 691 Class superClass = (Class ) itP.next(); 692 emiOfParent = (RdbExtentMappingInfos) 693 EMIMap.get(superClass); 694 if (emiOfParent != null) { 695 if (parent != null) { 696 logger.log(BasicLevel.DEBUG, "Return parent=" + superClass.getFQName()); 697 parent[0] = superClass; 698 } 699 return emiOfParent; 700 } 701 } 702 logger.log(BasicLevel.DEBUG, "Found none"); 703 return null; 704 } 705 706 } | Popular Tags |