1 25 26 package org.objectweb.jorm.mapper.rdb.metainfo; 27 28 import java.util.ArrayList ; 29 import java.util.Collection ; 30 import java.util.Collections ; 31 import java.util.HashSet ; 32 import java.util.Iterator ; 33 34 import org.objectweb.jorm.api.PClassMapping; 35 import org.objectweb.jorm.api.PException; 36 import org.objectweb.jorm.api.PMapper; 37 import org.objectweb.jorm.mapper.rdb.adapter.api.JoinedTable; 38 import org.objectweb.jorm.mapper.rdb.adapter.api.RdbAdapter; 39 import org.objectweb.jorm.mapper.rdb.lib.PMapperRdb; 40 import org.objectweb.jorm.mapper.rdb.lib.RdbExtentGenInfos; 41 import org.objectweb.jorm.mapper.rdb.lib.RdbExtentMappingInfos; 42 import org.objectweb.jorm.metainfo.api.Class; 43 import org.objectweb.jorm.metainfo.api.MetaObject; 44 import org.objectweb.jorm.metainfo.api.PrimitiveElement; 45 import org.objectweb.jorm.metainfo.api.PrimitiveElementMapping; 46 import org.objectweb.jorm.metainfo.lib.BasicMetaObject; 47 48 56 public class RdbInheritanceQuery extends BasicMetaObject { 57 58 private static int pkIndex = 0; 60 61 public static final String PK = "pk"; 62 63 private RdbClassMapping rdbClassMapping; 64 private String queryPrefetch; 66 private String queryPKOnly; 68 private String queryPKAndFields; 70 private Collection fieldsPrefetch; 72 private Collection fieldsPKOnly; 73 private Collection fieldsPKAndFields; 74 private Collection prefetchClasses; 76 77 public RdbInheritanceQuery(MetaObject parent) { 78 super(parent); 79 rdbClassMapping = (RdbClassMapping) parent; 80 queryPrefetch = ""; 81 queryPKOnly = ""; 82 queryPKAndFields = ""; 83 fieldsPrefetch = new ArrayList (); 84 fieldsPKOnly = new ArrayList (); 85 fieldsPKAndFields = new ArrayList (); 86 prefetchClasses = new ArrayList (); 87 } 88 89 92 public String getExtentQuery(PMapper mapper, boolean prefetch, boolean pkOnly, String primaryKey, PClassMapping pcm){ 93 if (prefetch) { 94 return getQueryPrefetch(mapper, primaryKey, pcm); 95 } else { 96 if (pkOnly) { 97 return getQueryPKOnly(mapper, primaryKey, pcm); 98 } else { 99 return getQueryPKAndFields(mapper, primaryKey, pcm); 100 } 101 } 102 } 103 104 107 public Collection getExtentFieldsNames(boolean prefetch, boolean pkOnly){ 108 if (prefetch) { 109 return fieldsPrefetch; 110 } else { 111 if (pkOnly) { 112 return fieldsPKOnly; 113 } else { 114 return fieldsPKAndFields; 115 } 116 } 117 } 118 119 123 public void addFieldPKOnly(Collection c){ 124 Iterator itC = c.iterator(); 125 while (itC.hasNext()) { 126 String s = (String ) itC.next(); 127 if (!fieldsPKOnly.contains(s)) 128 fieldsPKOnly.add(s); 129 } 130 } 131 132 137 public void addFieldPrefetch(Collection fields, Collection classes){ 138 Iterator itF = fields.iterator(); 139 Iterator itC = classes.iterator(); 140 while (itF.hasNext()) { 141 String field = (String ) itF.next(); 142 String className = (String ) itC.next(); 143 if (!fieldsPrefetch.contains(field)) { 144 fieldsPrefetch.add(field); 146 prefetchClasses.add(className); 148 } 149 } 150 } 151 152 156 public void addFieldPKAndFields(Collection c){ 157 Iterator itC = c.iterator(); 158 while (itC.hasNext()) { 159 String s = (String ) itC.next(); 160 if (!fieldsPKAndFields.contains(s)) 161 fieldsPKAndFields.add(s); 162 } 163 } 164 165 171 private String getQueryPKOnly(PMapper mapper, String primaryKey, PClassMapping pcm){ 172 if(queryPKOnly.equals("")){ 173 RdbExtentGenInfos extentGenInfos = new RdbExtentGenInfos(logger); 175 176 RdbAdapter adapter; 177 try { 178 adapter = ((PMapperRdb) mapper).getRdbAdapter(); 179 if (adapter == null) { 180 throw new PException("No rdb adapter found on the mapper: " + mapper); 181 } 182 Collection emis = extentGenInfos.getPolymorphicClassExtent((Class )rdbClassMapping.getLinkedMO(), rdbClassMapping.getProjectName(), rdbClassMapping.getMapperName(), false); 185 JoinedTable jt = null; 187 JoinedTable.Join joinCond = null; 188 Iterator itEmis = emis.iterator(); 189 while (itEmis.hasNext()) { 190 RdbExtentMappingInfos emi = (RdbExtentMappingInfos) itEmis.next(); 191 addFieldPKOnly(emi.getColumnAliases(false, primaryKey, null)); 193 jt = new JoinedTable(emi.getMainTable().getName()); 195 HashSet hsJoins = emi.getJoins(); 196 Iterator itJoins = hsJoins.iterator(); 197 while (itJoins.hasNext()) { 198 RdbJoin rdbJoin = (RdbJoin) itJoins.next(); 199 joinCond = jt.createChildren(rdbJoin.getExternalTable().getName()); 200 int pos = 0; 201 Iterator itCName = rdbJoin.getPTJoinColumnNames().iterator(); 202 while (itCName.hasNext()) { 203 String cName = (String ) itCName.next(); 204 joinCond.addJoinColumn(cName, (String ) rdbJoin.getETJoinColumnNames().get(pos)); 205 pos++; 206 } 207 } 208 queryPKOnly += adapter.getQuery(emi.getSelectPKOnly(adapter, primaryKey), Collections.singletonList(jt), null, false, false); 210 queryPKOnly += emi.getWhereParameter(pcm); 212 if(itEmis.hasNext()) 213 queryPKOnly += " UNION "; 214 } 215 } catch (Exception e) { 217 e.printStackTrace(); 218 } 219 } 220 return queryPKOnly; 221 } 222 223 229 private String getQueryPKAndFields(PMapper mapper, String primaryKey, PClassMapping pcm){ 230 if(queryPKAndFields.equals("")){ 231 RdbExtentGenInfos extentGenInfos = new RdbExtentGenInfos(logger); 233 234 RdbAdapter adapter; 235 try { 236 adapter = ((PMapperRdb) mapper).getRdbAdapter(); 237 if (adapter == null) { 238 throw new PException("No rdb adapter found on the mapper: " + mapper); 239 } 240 Collection emis = extentGenInfos.getPolymorphicClassExtent((Class )rdbClassMapping.getLinkedMO(), rdbClassMapping.getProjectName(), rdbClassMapping.getMapperName(), false); 243 JoinedTable jt = null; 245 JoinedTable.Join joinCond = null; 246 Iterator itEmis = emis.iterator(); 247 while (itEmis.hasNext()) { 248 RdbExtentMappingInfos emi = (RdbExtentMappingInfos) itEmis.next(); 249 addFieldPKAndFields(emi.getColumnAliases(false, primaryKey, (Class )rdbClassMapping.getLinkedMO())); 251 jt = new JoinedTable(emi.getMainTable().getName()); 253 HashSet hsJoins = emi.getJoins(); 254 Iterator itJoins = hsJoins.iterator(); 255 while (itJoins.hasNext()) { 256 RdbJoin rdbJoin = (RdbJoin) itJoins.next(); 257 joinCond = jt.createChildren(rdbJoin.getExternalTable().getName()); 258 int pos = 0; 259 Iterator itCName = rdbJoin.getPTJoinColumnNames().iterator(); 260 while(itCName.hasNext()){ 261 String cName = (String ) itCName.next(); 262 joinCond.addJoinColumn(cName, (String ) rdbJoin.getETJoinColumnNames().get(pos)); 263 pos++; 264 } 265 } 266 queryPKAndFields += adapter.getQuery(emi.getSelectPKAndFields(adapter, (Class )rdbClassMapping.getLinkedMO()), Collections.singletonList(jt), null, false, false); 268 queryPKAndFields += emi.getWhereParameter(pcm); 270 if (itEmis.hasNext()) 271 queryPKAndFields += " UNION "; 272 } 273 } catch (Exception e) { 275 e.printStackTrace(); 276 } 277 } 278 return queryPKAndFields; 279 } 280 281 287 private String getQueryPrefetch(PMapper mapper, String primaryKey, PClassMapping pcm){ 288 if(queryPrefetch.equals("")){ 289 RdbExtentGenInfos extentGenInfos = new RdbExtentGenInfos(logger); 291 292 RdbAdapter adapter; 293 try { 294 adapter = ((PMapperRdb) mapper).getRdbAdapter(); 295 if (adapter == null) { 296 throw new PException("No rdb adapter found on the mapper: " + mapper); 297 } 298 Collection emis = extentGenInfos.getPolymorphicClassExtent((Class )rdbClassMapping.getLinkedMO(), rdbClassMapping.getProjectName(), rdbClassMapping.getMapperName(), true); 301 JoinedTable jt = null; 303 JoinedTable.Join joinCond = null; 304 Iterator itEmis = emis.iterator(); 305 while (itEmis.hasNext()) { 306 RdbExtentMappingInfos emi = (RdbExtentMappingInfos) itEmis.next(); 307 addFieldPrefetch(emi.getColumnAliases(true, "", null), emi.getColumnClasses()); 309 addFieldPKOnly(emi.getColumnAliases(false, primaryKey, null)); 311 jt = new JoinedTable(emi.getMainTable().getName()); 313 HashSet hsJoins = emi.getJoins(); 314 Iterator itJoins = hsJoins.iterator(); 315 while (itJoins.hasNext()) { 316 RdbJoin rdbJoin = (RdbJoin) itJoins.next(); 317 joinCond = jt.createChildren(rdbJoin.getExternalTable().getName()); 318 int pos = 0; 319 Iterator itCName = rdbJoin.getPTJoinColumnNames().iterator(); 320 while (itCName.hasNext()) { 321 String cName = (String ) itCName.next(); 322 joinCond.addJoinColumn(cName, (String ) rdbJoin.getETJoinColumnNames().get(pos)); 323 pos++; 324 } 325 } 326 queryPrefetch += adapter.getQuery( 328 emi.getSelectPrefetch(adapter, rdbClassMapping.getJormClass()), 329 Collections.singletonList(jt), null, false, false); 330 int fromIndex = queryPrefetch.toUpperCase().indexOf(" FROM "); 333 String tmpQuery = queryPrefetch.substring(0, fromIndex); 334 tmpQuery += ", " + aliasPK(primaryKey, adapter) + " "; 335 tmpQuery += queryPrefetch.substring(fromIndex); 336 queryPrefetch = tmpQuery; 337 queryPrefetch += emi.getWhereParameter(pcm); 339 if (itEmis.hasNext()) 340 queryPrefetch += " UNION "; 341 } 342 } catch (Exception e) { 344 e.printStackTrace(); 345 } 346 setSubTreeFieldAssociationTable(mapper, pcm); 348 } 349 return queryPrefetch; 350 } 351 352 357 public void setSubTreeFieldAssociationTable(PMapper mapper, PClassMapping pcm){ 358 try{ 359 ArrayList pcms = new ArrayList (); 360 pcms.add(pcm); 361 PClassMapping[] subPCMs = pcm.getSubPCMs(); 362 if (subPCMs != null) { 364 for (int indexPCM = 0; indexPCM < subPCMs.length; indexPCM++) { 365 pcms.add(subPCMs[indexPCM]); 366 } 367 } 368 String [] classes = new String [prefetchClasses.size()]; 369 Iterator it = prefetchClasses.iterator(); 370 int i = 0; 371 while (it.hasNext()) { 372 classes[i++] = (String ) it.next(); 373 } 374 String mapperName = mapper.getMapperName(); 376 if (mapperName.indexOf(".") != -1) 377 mapperName = mapperName.substring(0, mapperName.indexOf(".")); 378 Iterator itPCM = pcms.iterator(); 380 while (itPCM.hasNext()) { 381 PClassMapping currentPCM = (PClassMapping) itPCM.next(); 382 ArrayList indexes = new ArrayList (0); 383 RdbMapping rdbm = (RdbMapping) mapper.getMetaInfoManager().getClass(currentPCM.getClassName()).getClassProject(currentPCM.getProjectName()).getMapping(mapperName); 385 RdbClassMapping rdbcm = (RdbClassMapping) rdbm.getClassMapping(); 386 Class cl = rdbcm.getJormClass(); 387 if (cl == null) { 388 return; 389 } 390 Collection superClasses = getSuperClasses(cl); 392 393 for (int indexField = 0; indexField < prefetchClasses.size(); indexField++) { 396 if (superClasses.contains(classes[indexField])) { 397 String fieldName = (String ) ((ArrayList )fieldsPrefetch).get(indexField); 399 PrimitiveElementMapping pem = rdbcm.getPrimitiveElementMapping(fieldName, true); 400 RdbJoin rdbJoin = ((RdbPrimitiveElementMapping) pem).getJoinByPrimitiveElement((PrimitiveElement)cl.getTypedElement(fieldName)); 401 IndexedPEM indexedPem = new IndexedPEM(pem, (rdbJoin != null ? rdbJoin.getName():""), indexField); 403 indexes.add(indexedPem); 405 } 406 } 407 Collections.sort(indexes); 410 int[] table = new int[indexes.size()]; 412 for (int j = 0; j < table.length; j++) { 413 table[j] = ((IndexedPEM) indexes.get(j)).index; 414 } 415 currentPCM.addAssociation(pcm, table); 417 } 418 } catch(PException e){ 419 e.printStackTrace(); 420 } 421 } 422 423 426 private Collection getSuperClasses(Class cl){ 427 Collection superClasses = new ArrayList (1); 428 superClasses.add(cl.getFQName()); 430 Iterator it = cl.getAllAncestors().iterator(); 432 while (it.hasNext()) { 434 Class currentClass = (Class ) it.next(); 435 superClasses.add(currentClass.getFQName()); 436 } 437 return superClasses; 438 } 439 440 441 447 private String aliasPK(String primaryKey, RdbAdapter adapter){ 448 String tmp = primaryKey; 449 String aliasName = PK; 450 String separator = ","; 451 int separatorIndex = tmp.indexOf(separator); 452 while (separatorIndex != -1) { 453 String alias = adapter.getColumnAliasExpr(aliasName + pkIndex++); 454 String beginning = primaryKey.substring(0, separatorIndex); 455 String end = primaryKey.substring(separatorIndex); 456 primaryKey = beginning + alias + end; 457 separatorIndex = primaryKey.indexOf(separator, separatorIndex + alias.length() + 1); 458 } 459 primaryKey += adapter.getColumnAliasExpr(aliasName + pkIndex++); 460 return primaryKey; 461 } 462 463 468 private class IndexedPEM implements Comparable { 469 protected PrimitiveElementMapping pem; 470 protected int index; 471 protected String joinName; 472 473 public IndexedPEM(PrimitiveElementMapping pem, String joinName, int index) { 474 this.pem = pem; 475 this.joinName = joinName; 476 this.index = index; 477 } 478 479 public int compareTo(Object o) { 482 IndexedPEM indexedPem = (IndexedPEM) o; 483 int result = ((RdbPrimitiveElementMapping)pem).compareTo(indexedPem.pem); 484 if (result == 0) 485 result = joinName.compareTo(indexedPem.joinName); 486 return result; 487 } 488 489 } 490 } 491 | Popular Tags |