1 16 package org.ofbiz.entity.model; 17 18 import java.io.Serializable ; 19 import java.util.Arrays ; 20 import java.util.HashSet ; 21 import java.util.Iterator ; 22 import java.util.List ; 23 import java.util.Map ; 24 import java.util.Set ; 25 26 import javolution.util.FastList; 27 import javolution.util.FastMap; 28 29 import org.ofbiz.base.util.Debug; 30 import org.ofbiz.base.util.UtilTimer; 31 import org.ofbiz.base.util.UtilValidate; 32 import org.ofbiz.base.util.UtilXml; 33 import org.ofbiz.entity.condition.EntityOperator; 34 import org.ofbiz.entity.jdbc.SqlJdbcUtil; 35 import org.w3c.dom.Element ; 36 import org.w3c.dom.NodeList ; 37 38 41 public class ModelViewEntity extends ModelEntity { 42 public static final String module = ModelViewEntity.class.getName(); 43 44 public static Map functionPrefixMap = FastMap.newInstance(); 45 static { 46 functionPrefixMap.put("min", "MIN("); 47 functionPrefixMap.put("max", "MAX("); 48 functionPrefixMap.put("sum", "SUM("); 49 functionPrefixMap.put("avg", "AVG("); 50 functionPrefixMap.put("count", "COUNT("); 51 functionPrefixMap.put("count-distinct", "COUNT(DISTINCT "); 52 functionPrefixMap.put("upper", "UPPER("); 53 functionPrefixMap.put("lower", "LOWER("); 54 } 55 56 57 protected Map memberModelMemberEntities = FastMap.newInstance(); 58 59 60 protected List allModelMemberEntities = FastList.newInstance(); 61 62 63 protected Map memberModelEntities = null; 64 65 66 protected List aliasAlls = FastList.newInstance(); 67 68 69 protected List aliases = FastList.newInstance(); 70 71 72 protected List viewLinks = FastList.newInstance(); 73 74 75 protected List groupBys = FastList.newInstance(); 76 77 protected Map conversions = FastMap.newInstance(); 78 79 public ModelViewEntity(ModelReader reader, Element entityElement, UtilTimer utilTimer, ModelInfo def) { 80 super(reader, entityElement, def); 81 82 if (utilTimer != null) utilTimer.timerString(" createModelViewEntity: before general/basic info"); 83 this.populateBasicInfo(entityElement); 84 85 if (utilTimer != null) utilTimer.timerString(" createModelViewEntity: before \"member-entity\"s"); 86 List memberEntityList = UtilXml.childElementList(entityElement, "member-entity"); 87 Iterator memberEntityIter = memberEntityList.iterator(); 88 while (memberEntityIter.hasNext()) { 89 Element memberEntityElement = (Element ) memberEntityIter.next(); 90 String alias = UtilXml.checkEmpty(memberEntityElement.getAttribute("entity-alias")); 91 String name = UtilXml.checkEmpty(memberEntityElement.getAttribute("entity-name")); 92 if (name.length() <= 0 || alias.length() <= 0) { 93 Debug.logError("[new ModelViewEntity] entity-alias or entity-name missing on member-entity element of the view-entity " + this.entityName, module); 94 } else { 95 ModelMemberEntity modelMemberEntity = new ModelMemberEntity(alias, name); 96 this.addMemberModelMemberEntity(modelMemberEntity); 97 } 98 } 99 100 List aliasAllList = UtilXml.childElementList(entityElement, "alias-all"); 103 Iterator aliasAllIter = aliasAllList.iterator(); 104 while (aliasAllIter.hasNext()) { 105 Element aliasElement = (Element ) aliasAllIter.next(); 106 ModelViewEntity.ModelAliasAll aliasAll = new ModelAliasAll(aliasElement); 107 this.aliasAlls.add(aliasAll); 108 } 109 110 if (utilTimer != null) utilTimer.timerString(" createModelViewEntity: before aliases"); 111 List aliasList = UtilXml.childElementList(entityElement, "alias"); 112 Iterator aliasIter = aliasList.iterator(); 113 while (aliasIter.hasNext()) { 114 Element aliasElement = (Element ) aliasIter.next(); 115 ModelViewEntity.ModelAlias alias = new ModelAlias(aliasElement); 116 this.aliases.add(alias); 117 } 118 119 List viewLinkList = UtilXml.childElementList(entityElement, "view-link"); 120 Iterator viewLinkIter = viewLinkList.iterator(); 121 while (viewLinkIter.hasNext()) { 122 Element viewLinkElement = (Element ) viewLinkIter.next(); 123 ModelViewLink viewLink = new ModelViewLink(viewLinkElement); 124 this.addViewLink(viewLink); 125 } 126 127 if (utilTimer != null) utilTimer.timerString(" createModelEntity: before relations"); 128 this.populateRelated(reader, entityElement); 129 130 this.tableName = null; 132 } 133 134 public ModelViewEntity(DynamicViewEntity dynamicViewEntity, ModelReader modelReader) { 135 this.entityName = dynamicViewEntity.getEntityName(); 136 this.packageName = dynamicViewEntity.getPackageName(); 137 this.title = dynamicViewEntity.getTitle(); 138 this.defaultResourceName = dynamicViewEntity.getDefaultResourceName(); 139 140 Iterator modelMemberEntitiesEntryIter = dynamicViewEntity.getModelMemberEntitiesEntryIter(); 142 while (modelMemberEntitiesEntryIter.hasNext()) { 143 Map.Entry entry = (Map.Entry ) modelMemberEntitiesEntryIter.next(); 144 this.addMemberModelMemberEntity((ModelMemberEntity) entry.getValue()); 145 } 146 147 dynamicViewEntity.addAllAliasAllsToList(this.aliasAlls); 149 150 dynamicViewEntity.addAllAliasesToList(this.aliases); 152 153 dynamicViewEntity.addAllViewLinksToList(this.viewLinks); 155 156 dynamicViewEntity.addAllRelationsToList(this.relations); 158 159 this.populateFieldsBasic(modelReader); 162 } 163 164 public Map getMemberModelMemberEntities() { 165 return this.memberModelMemberEntities; 166 } 167 168 public List getAllModelMemberEntities() { 169 return this.allModelMemberEntities; 170 } 171 172 public ModelMemberEntity getMemberModelMemberEntity(String alias) { 173 return (ModelMemberEntity) this.memberModelMemberEntities.get(alias); 174 } 175 176 public ModelEntity getMemberModelEntity(String alias) { 177 if (this.memberModelEntities == null) { 178 this.memberModelEntities = FastMap.newInstance(); 179 populateFields(this.getModelReader()); 180 } 181 return (ModelEntity) this.memberModelEntities.get(alias); 182 } 183 184 public void addMemberModelMemberEntity(ModelMemberEntity modelMemberEntity) { 185 this.memberModelMemberEntities.put(modelMemberEntity.getEntityAlias(), modelMemberEntity); 186 this.allModelMemberEntities.add(modelMemberEntity); 187 } 188 189 public void removeMemberModelMemberEntity(String alias) { 190 ModelMemberEntity modelMemberEntity = (ModelMemberEntity) this.memberModelMemberEntities.remove(alias); 191 192 if (modelMemberEntity == null) return; 193 this.allModelMemberEntities.remove(modelMemberEntity); 194 } 195 196 197 public String getColNameOrAlias(String fieldName) { 198 ModelField modelField = this.getField(fieldName); 199 String fieldString = modelField.getColName(); 200 ModelViewEntity.ModelAlias alias = getAlias(fieldName); 201 if (alias != null) { 202 fieldString = alias.getColAlias(); 203 } 204 return fieldString; 205 } 206 207 208 public ModelAlias getAlias(int index) { 209 return (ModelAlias) this.aliases.get(index); 210 } 211 212 public ModelAlias getAlias(String name) { 213 Iterator aliasIter = getAliasesIterator(); 214 while (aliasIter.hasNext()) { 215 ModelAlias alias = (ModelAlias) aliasIter.next(); 216 if (alias.name.equals(name)) { 217 return alias; 218 } 219 } 220 return null; 221 } 222 223 public int getAliasesSize() { 224 return this.aliases.size(); 225 } 226 227 public Iterator getAliasesIterator() { 228 return this.aliases.iterator(); 229 } 230 231 public List getAliasesCopy() { 232 List newList = FastList.newInstance(); 233 newList.addAll(this.aliases); 234 return newList; 235 } 236 237 public List getGroupBysCopy() { 238 List newList = FastList.newInstance(); 239 newList.addAll(this.groupBys); 240 return newList; 241 } 242 243 244 public ModelViewLink getViewLink(int index) { 245 return (ModelViewLink) this.viewLinks.get(index); 246 } 247 248 public int getViewLinksSize() { 249 return this.viewLinks.size(); 250 } 251 252 public Iterator getViewLinksIterator() { 253 return this.viewLinks.iterator(); 254 } 255 256 public List getViewLinksCopy() { 257 List newList = FastList.newInstance(); 258 newList.addAll(this.viewLinks); 259 return newList; 260 } 261 262 public void addViewLink(ModelViewLink viewLink) { 263 this.viewLinks.add(viewLink); 264 } 265 266 public String colNameString(List flds, String separator, String afterLast, boolean alias) { 267 StringBuffer returnString = new StringBuffer (); 268 269 if (flds.size() < 1) { 270 return ""; 271 } 272 273 Iterator fldsIt = flds.iterator(); 274 while (fldsIt.hasNext()) { 275 ModelField field = (ModelField) fldsIt.next(); 276 returnString.append(field.colName); 277 if (alias) { 278 ModelAlias modelAlias = this.getAlias(field.name); 279 if (modelAlias != null) { 280 returnString.append(" AS " + modelAlias.getColAlias()); 281 } 282 } 283 if (fldsIt.hasNext()) { 284 returnString.append(separator); 285 } 286 } 287 288 returnString.append(afterLast); 289 return returnString.toString(); 290 } 291 292 protected ModelEntity aliasedModelEntity = new ModelEntity(); 293 294 public ModelEntity getAliasedModelEntity() { 295 return this.aliasedModelEntity; 296 } 297 298 public ModelEntity getAliasedEntity(String entityAlias, ModelReader modelReader) { 299 ModelMemberEntity modelMemberEntity = (ModelMemberEntity) this.memberModelMemberEntities.get(entityAlias); 300 if (modelMemberEntity == null) { 301 Debug.logError("No member entity with alias " + entityAlias + " found in view-entity " + this.getEntityName() + "; this view-entity will NOT be usable...", module); 302 return null; 303 } 304 305 String aliasedEntityName = modelMemberEntity.getEntityName(); 306 ModelEntity aliasedEntity = modelReader.getModelEntityNoCheck(aliasedEntityName); 307 if (aliasedEntity == null) { 308 Debug.logError("[ModelViewEntity.populateFields] ERROR: could not find ModelEntity for entity name: " + aliasedEntityName, module); 309 return null; 310 } 311 312 return aliasedEntity; 313 } 314 315 public ModelField getAliasedField(ModelEntity aliasedEntity, String field, ModelReader modelReader) { 316 ModelField aliasedField = aliasedEntity.getField(field); 317 if (aliasedEntity == null) { 318 Debug.logError("[ModelViewEntity.populateFields] ERROR: could not find ModelEntity for entity name: " + aliasedEntity.getEntityName(), module); 319 return null; 320 } 321 return aliasedField; 322 } 323 324 public void populateFields(ModelReader modelReader) { 325 populateFieldsBasic(modelReader); 326 populateReverseLinks(); 327 } 328 329 public void populateFieldsBasic(ModelReader modelReader) { 330 if (this.memberModelEntities == null) { 331 this.memberModelEntities = FastMap.newInstance(); 332 } 333 334 Iterator meIter = memberModelMemberEntities.entrySet().iterator(); 335 while (meIter.hasNext()) { 336 Map.Entry entry = (Map.Entry ) meIter.next(); 337 338 ModelMemberEntity modelMemberEntity = (ModelMemberEntity) entry.getValue(); 339 String aliasedEntityName = modelMemberEntity.getEntityName(); 340 ModelEntity aliasedEntity = modelReader.getModelEntityNoCheck(aliasedEntityName); 341 if (aliasedEntity == null) { 342 continue; 343 } 344 memberModelEntities.put(entry.getKey(), aliasedEntity); 345 Iterator aliasedFieldIterator = aliasedEntity.getFieldsIterator(); 346 while (aliasedFieldIterator.hasNext()) { 347 ModelField aliasedModelField = (ModelField) aliasedFieldIterator.next(); 348 ModelField newModelField = new ModelField(); 349 for (int i = 0; i < aliasedModelField.getValidatorsSize(); i++) { 350 newModelField.addValidator(aliasedModelField.getValidator(i)); 351 } 352 newModelField.setColName(modelMemberEntity.getEntityAlias() + "." + aliasedModelField.getColName()); 353 newModelField.setName(modelMemberEntity.getEntityAlias() + "." + aliasedModelField.getName()); 354 newModelField.setType(aliasedModelField.getType()); 355 newModelField.setIsPk(false); 356 aliasedModelEntity.addField(newModelField); 357 } 358 } 359 360 expandAllAliasAlls(modelReader); 361 362 for (int i = 0; i < aliases.size(); i++) { 363 ModelAlias alias = (ModelAlias) aliases.get(i); 364 ModelField field = new ModelField(); 365 field.setModelEntity(this); 366 field.name = alias.name; 367 368 if (alias.groupBy) { 370 this.groupBys.add(field); 371 } 372 373 if (UtilValidate.isNotEmpty(alias.function) && alias.groupBy) { 375 Debug.logWarning("The view-entity alias with name=" + alias.name + " has a function value and is specified as a group-by field; this may be an error, but is not necessarily.", module); 376 } 377 378 if (alias.isComplexAlias()) { 379 StringBuffer colNameBuffer = new StringBuffer (); 381 StringBuffer fieldTypeBuffer = new StringBuffer (); 382 alias.makeAliasColName(colNameBuffer, fieldTypeBuffer, this, modelReader); 383 field.colName = colNameBuffer.toString(); 384 field.type = fieldTypeBuffer.toString(); 385 field.isPk = false; 386 } else { 387 ModelEntity aliasedEntity = getAliasedEntity(alias.entityAlias, modelReader); 388 ModelField aliasedField = getAliasedField(aliasedEntity, alias.field, modelReader); 389 if (aliasedField == null) { 390 Debug.logError("[ModelViewEntity.populateFields (" + this.getEntityName() + ")] ERROR: could not find ModelField for field name \"" + 391 alias.field + "\" on entity with name: " + aliasedEntity.getEntityName(), module); 392 continue; 393 } 394 395 if (alias.isPk != null) { 396 field.isPk = alias.isPk.booleanValue(); 397 } else { 398 field.isPk = aliasedField.isPk; 399 } 400 401 field.type = aliasedField.type; 402 field.validators = aliasedField.validators; 403 404 field.colName = alias.entityAlias + "." + SqlJdbcUtil.filterColName(aliasedField.colName); 405 } 406 407 this.fields.add(field); 408 if (field.isPk) { 409 this.pks.add(field); 410 } else { 411 this.nopks.add(field); 412 } 413 414 if ("count".equals(alias.function) || "count-distinct".equals(alias.function)) { 415 field.type = "numeric"; 417 } 418 419 if (UtilValidate.isNotEmpty(alias.function)) { 420 String prefix = (String ) functionPrefixMap.get(alias.function); 421 if (prefix == null) { 422 Debug.logWarning("Specified alias function [" + alias.function + "] not valid; must be: min, max, sum, avg, count or count-distinct; using a column name with no function function", module); 423 } else { 424 field.colName = prefix + field.colName + ")"; 425 } 426 } 427 } 428 } 429 430 protected ModelConversion getOrCreateModelConversion(String aliasName) { 431 ModelEntity member = getMemberModelEntity(aliasName); 432 if (member == null) { 433 String errMsg = "No member found for aliasName - " + aliasName; 434 Debug.logWarning(errMsg, module); 435 throw new RuntimeException ("Cannot create View Entity: " + errMsg); 436 } 437 438 Map aliasConversions = (Map ) conversions.get(member.getEntityName()); 439 if (aliasConversions == null) { 440 aliasConversions = FastMap.newInstance(); 441 conversions.put(member.getEntityName(), aliasConversions); 442 } 443 ModelConversion conversion = (ModelConversion) aliasConversions.get(aliasName); 444 if (conversion == null) { 445 conversion = new ModelConversion(aliasName, member); 446 aliasConversions.put(aliasName, conversion); 447 } 448 return conversion; 449 } 450 451 public void populateReverseLinks() { 452 Map containedModelFields = FastMap.newInstance(); 453 Iterator it = getAliasesIterator(); 454 while (it.hasNext()) { 455 ModelViewEntity.ModelAlias alias = (ModelViewEntity.ModelAlias) it.next(); 456 if (alias.isComplexAlias()) { 457 Debug.logWarning("Conversion for complex-alias needs to be implemented for cache and in-memory eval stuff to work correctly, will not work for alias: " + alias.getName() + " of view-entity " + this.getEntityName(), module); 459 } else { 460 ModelConversion conversion = getOrCreateModelConversion(alias.getEntityAlias()); 461 conversion.addConversion(alias.getField(), alias.getName()); 462 } 463 464 List aliases = (List ) containedModelFields.get(alias.getField()); 465 if (aliases == null) { 466 aliases = FastList.newInstance(); 467 containedModelFields.put(alias.getField(), aliases); 468 } 469 aliases.add(alias.getName()); 470 } 471 472 it = getViewLinksIterator(); 473 while (it.hasNext()) { 474 ModelViewEntity.ModelViewLink link = (ModelViewEntity.ModelViewLink) it.next(); 475 476 String leftAlias = link.getEntityAlias(); 477 String rightAlias = link.getRelEntityAlias(); 478 ModelConversion leftConversion = getOrCreateModelConversion(leftAlias); 479 ModelConversion rightConversion = getOrCreateModelConversion(rightAlias); 480 Iterator it2 = link.getKeyMapsIterator(); 481 Debug.logVerbose(leftAlias + "<->" + rightAlias, module); 482 while (it2.hasNext()) { 483 ModelKeyMap mkm = (ModelKeyMap) it2.next(); 484 String leftFieldName = mkm.getFieldName(); 485 String rightFieldName = mkm.getRelFieldName(); 486 rightConversion.addAllAliasConversions((List ) containedModelFields.get(leftFieldName), rightFieldName); 487 leftConversion.addAllAliasConversions((List ) containedModelFields.get(rightFieldName), leftFieldName); 488 } 489 } 490 it = conversions.entrySet().iterator(); 491 int[] currentIndex = new int[conversions.size()]; 492 int[] maxIndex = new int[conversions.size()]; 493 ModelConversion[][] allConversions = new ModelConversion[conversions.size()][]; 494 int i = 0; 495 while (it.hasNext()) { 496 Map.Entry entry = (Map.Entry ) it.next(); 497 Map aliasConversions = (Map ) entry.getValue(); 498 currentIndex[i] = 0; 499 maxIndex[i] = aliasConversions.size(); 500 allConversions[i] = new ModelConversion[aliasConversions.size()]; 501 Iterator it2 = aliasConversions.values().iterator(); 502 for (int j = 0; it2.hasNext() && j < aliasConversions.size(); j++) { 503 allConversions[i][j] = (ModelConversion) it2.next(); 504 } 505 i++; 506 } 507 int ptr = 0; 508 ModelConversion[] currentConversions = new ModelConversion[conversions.size()]; 509 for (int j = 0, k; j < currentIndex.length; j++) { 510 for (int l = 0; l < maxIndex[ j ]; l++ ) { 511 while (true) { 512 for (i = 0, k = 0; i < currentIndex.length; i++) { 513 if (i == j && currentIndex[i] == l) continue; 514 currentConversions[k++] = allConversions[i][currentIndex[i]]; 515 } 516 Debug.logVerbose(j + "," + l + ":" + Arrays.asList(currentConversions), module); 517 while (ptr < currentIndex.length && ++currentIndex[ptr] == maxIndex[ptr]) { 518 currentIndex[ptr] = 0; 519 ptr++; 520 } 521 if (ptr == currentIndex.length) break; 522 ptr = 0; 523 } 524 } 525 } 526 Debug.logVerbose(this + ":" + conversions, module); 527 } 528 529 public List convert(String fromEntityName, Map data) { 530 Map foo = (Map ) conversions.get(fromEntityName); 531 if (foo == null) return null; 532 Iterator it = foo.values().iterator(); 533 List values = FastList.newInstance(); 534 while (it.hasNext()) { 535 ModelConversion conversion = (ModelConversion) it.next(); 536 values.add(conversion.convert(data)); 537 } 538 return values; 539 } 540 541 544 private void expandAllAliasAlls(ModelReader modelReader) { 545 Iterator aliasAllIter = aliasAlls.iterator(); 546 while (aliasAllIter.hasNext()) { 547 ModelAliasAll aliasAll = (ModelAliasAll) aliasAllIter.next(); 548 String prefix = aliasAll.getPrefix(); 549 550 ModelMemberEntity modelMemberEntity = (ModelMemberEntity) memberModelMemberEntities.get(aliasAll.getEntityAlias()); 551 if (modelMemberEntity == null) { 552 Debug.logError("Member entity referred to in alias-all not found, ignoring: " + aliasAll.getEntityAlias(), module); 553 continue; 554 } 555 556 String aliasedEntityName = modelMemberEntity.getEntityName(); 557 ModelEntity aliasedEntity = modelReader.getModelEntityNoCheck(aliasedEntityName); 558 if (aliasedEntity == null) { 559 Debug.logError("Entity referred to in member-entity " + aliasAll.getEntityAlias() + " not found, ignoring: " + aliasedEntityName, module); 560 continue; 561 } 562 563 List entFieldList = aliasedEntity.getAllFieldNames(); 564 if (entFieldList == null) { 565 Debug.logError("Entity referred to in member-entity " + aliasAll.getEntityAlias() + " has no fields, ignoring: " + aliasedEntityName, module); 566 continue; 567 } 568 569 Iterator fieldnamesIterator = entFieldList.iterator(); 570 while (fieldnamesIterator.hasNext()) { 571 String fieldName = (String ) fieldnamesIterator.next(); 573 String aliasName = fieldName; 574 ModelField modelField = aliasedEntity.getField(fieldName); 575 if (modelField.getIsAutoCreatedInternal()) { 576 continue; 578 } 579 if (aliasAll.shouldExclude(fieldName)) { 580 continue; 582 } 583 584 if (UtilValidate.isNotEmpty(prefix)) { 585 StringBuffer newAliasBuffer = new StringBuffer (prefix); 586 newAliasBuffer.append(Character.toUpperCase(aliasName.charAt(0))); 588 newAliasBuffer.append(aliasName.substring(1)); 589 aliasName = newAliasBuffer.toString(); 590 } 591 592 ModelAlias existingAlias = this.getAlias(aliasName); 593 if (existingAlias != null) { 594 boolean isInViewLink = false; 596 Iterator viewLinkIter = this.getViewLinksIterator(); 597 while (viewLinkIter.hasNext() && !isInViewLink) { 598 ModelViewLink modelViewLink = (ModelViewLink) viewLinkIter.next(); 599 boolean isRel = false; 600 if (modelViewLink.getRelEntityAlias().equals(aliasAll.getEntityAlias())) { 601 isRel = true; 602 } else if (!modelViewLink.getEntityAlias().equals(aliasAll.getEntityAlias())) { 603 continue; 605 } 606 Iterator keyMapIter = modelViewLink.getKeyMapsIterator(); 607 while (keyMapIter.hasNext() && !isInViewLink) { 608 ModelKeyMap modelKeyMap = (ModelKeyMap) keyMapIter.next(); 609 if (!isRel && modelKeyMap.getFieldName().equals(fieldName)) { 610 isInViewLink = true; 611 } else if (isRel && modelKeyMap.getRelFieldName().equals(fieldName)) { 612 isInViewLink = true; 613 } 614 } 615 } 616 617 String warnMsg = "Throwing out field alias in view entity " + this.getEntityName() + " because one already exists with the alias name [" + aliasName + "] and field name [" + modelMemberEntity.getEntityAlias() + "(" + aliasedEntity.getEntityName() + ")." + fieldName + "], existing field name is [" + existingAlias.getEntityAlias() + "." + existingAlias.getField() + "]"; 619 if (isInViewLink) { 620 Debug.logVerbose(warnMsg, module); 621 } else { 622 Debug.logInfo(warnMsg, module); 623 } 624 continue; 625 } 626 627 ModelAlias expandedAlias = new ModelAlias(); 628 expandedAlias.name = aliasName; 629 expandedAlias.field = fieldName; 630 expandedAlias.entityAlias = aliasAll.getEntityAlias(); 631 expandedAlias.isFromAliasAll = true; 632 expandedAlias.colAlias = ModelUtil.javaNameToDbName(UtilXml.checkEmpty(expandedAlias.name)); 633 aliases.add(expandedAlias); 634 } 635 } 636 } 637 638 public String toString() { 639 return "ModelViewEntity[" + getEntityName() + "]"; 640 } 641 642 public static class ModelMemberEntity implements Serializable { 643 protected String entityAlias = ""; 644 protected String entityName = ""; 645 646 public ModelMemberEntity(String entityAlias, String entityName) { 647 this.entityAlias = entityAlias; 648 this.entityName = entityName; 649 } 650 651 public String getEntityAlias() { 652 return this.entityAlias; 653 } 654 655 public String getEntityName() { 656 return this.entityName; 657 } 658 } 659 660 public static class ModelAliasAll implements Serializable { 661 protected String entityAlias = ""; 662 protected String prefix = ""; 663 protected Set fieldsToExclude = null; 664 665 protected ModelAliasAll() {} 666 667 public ModelAliasAll(String entityAlias, String prefix) { 668 this.entityAlias = entityAlias; 669 this.prefix = prefix; 670 } 671 672 public ModelAliasAll(Element aliasAllElement) { 673 this.entityAlias = UtilXml.checkEmpty(aliasAllElement.getAttribute("entity-alias")); 674 this.prefix = UtilXml.checkEmpty(aliasAllElement.getAttribute("prefix")); 675 676 List excludes = UtilXml.childElementList(aliasAllElement, "exclude"); 677 if (excludes != null && excludes.size() > 0) { 678 this.fieldsToExclude = new HashSet (); 679 Iterator excludeIter = excludes.iterator(); 680 while (excludeIter.hasNext()) { 681 Element excludeElement = (Element ) excludeIter.next(); 682 this.fieldsToExclude.add(excludeElement.getAttribute("field")); 683 } 684 } 685 686 } 687 688 public String getEntityAlias() { 689 return this.entityAlias; 690 } 691 692 public String getPrefix() { 693 return this.prefix; 694 } 695 696 public boolean shouldExclude(String fieldName) { 697 if (this.fieldsToExclude == null) { 698 return false; 699 } else { 700 return this.fieldsToExclude.contains(fieldName); 701 } 702 } 703 } 704 705 public static class ModelAlias implements Serializable { 706 protected String entityAlias = ""; 707 protected String name = ""; 708 protected String field = ""; 709 protected String colAlias = ""; 710 protected Boolean isPk = null; 712 protected boolean groupBy = false; 713 protected String function = null; 715 protected boolean isFromAliasAll = false; 716 protected ComplexAliasMember complexAliasMember = null; 717 718 protected ModelAlias() {} 719 720 public ModelAlias(Element aliasElement) { 721 this.entityAlias = UtilXml.checkEmpty(aliasElement.getAttribute("entity-alias")); 722 this.name = UtilXml.checkEmpty(aliasElement.getAttribute("name")); 723 this.field = UtilXml.checkEmpty(aliasElement.getAttribute("field"), this.name); 724 this.colAlias = UtilXml.checkEmpty(aliasElement.getAttribute("col-alias"), ModelUtil.javaNameToDbName(UtilXml.checkEmpty(this.name))); 725 String primKeyValue = UtilXml.checkEmpty(aliasElement.getAttribute("prim-key")); 726 727 if (UtilValidate.isNotEmpty(primKeyValue)) { 728 this.isPk = new Boolean ("true".equals(primKeyValue)); 729 } else { 730 this.isPk = null; 731 } 732 this.groupBy = "true".equals(UtilXml.checkEmpty(aliasElement.getAttribute("group-by"))); 733 this.function = UtilXml.checkEmpty(aliasElement.getAttribute("function")); 734 735 Element complexAliasElement = UtilXml.firstChildElement(aliasElement, "complex-alias"); 736 if (complexAliasElement != null) { 737 complexAliasMember = new ComplexAlias(complexAliasElement); 738 } 739 } 740 741 public ModelAlias(String entityAlias, String name, String field, String colAlias, Boolean isPk, Boolean groupBy, String function) { 742 this.entityAlias = entityAlias; 743 this.name = name; 744 this.field = UtilXml.checkEmpty(field, this.name); 745 this.colAlias = UtilXml.checkEmpty(colAlias, ModelUtil.javaNameToDbName(UtilXml.checkEmpty(this.name))); 746 this.isPk = isPk; 747 if (groupBy != null) { 748 this.groupBy = groupBy.booleanValue(); 749 } else { 750 this.groupBy = false; 751 } 752 this.function = function; 753 } 754 755 public void setComplexAliasMember(ComplexAliasMember complexAliasMember) { 756 this.complexAliasMember = complexAliasMember; 757 } 758 759 public boolean isComplexAlias() { 760 return complexAliasMember != null; 761 } 762 763 public void makeAliasColName(StringBuffer colNameBuffer, StringBuffer fieldTypeBuffer, ModelViewEntity modelViewEntity, ModelReader modelReader) { 764 if (complexAliasMember != null) { 765 complexAliasMember.makeAliasColName(colNameBuffer, fieldTypeBuffer, modelViewEntity, modelReader); 766 } 767 } 768 769 public String getEntityAlias() { 770 return this.entityAlias; 771 } 772 773 public String getName() { 774 return this.name; 775 } 776 777 public String getColAlias() { 778 return this.colAlias; 779 } 780 781 public String getField() { 782 return this.field; 783 } 784 785 public Boolean getIsPk() { 786 return this.isPk; 787 } 788 789 public boolean getGroupBy() { 790 return this.groupBy; 791 } 792 793 public String getFunction() { 794 return this.function; 795 } 796 797 public boolean getIsFromAliasAll() { 798 return this.isFromAliasAll; 799 } 800 } 801 802 public static interface ComplexAliasMember extends Serializable { 803 public void makeAliasColName(StringBuffer colNameBuffer, StringBuffer fieldTypeBuffer, ModelViewEntity modelViewEntity, ModelReader modelReader); 804 } 805 806 public static class ComplexAlias implements ComplexAliasMember { 807 protected List complexAliasMembers = FastList.newInstance(); 808 protected String operator; 809 810 public ComplexAlias(String operator) { 811 this.operator = operator; 812 } 813 814 public ComplexAlias(Element complexAliasElement) { 815 this.operator = complexAliasElement.getAttribute("operator"); 816 List subElements = UtilXml.childElementList(complexAliasElement); 818 Iterator subElementIter = subElements.iterator(); 819 while (subElementIter.hasNext()) { 820 Element subElement = (Element ) subElementIter.next(); 821 String nodeName = subElement.getNodeName(); 822 if ("complex-alias".equals(nodeName)) { 823 this.addComplexAliasMember(new ComplexAlias(subElement)); 824 } else if ("complex-alias-field".equals(nodeName)) { 825 this.addComplexAliasMember(new ComplexAliasField(subElement)); 826 } 827 } 828 } 829 830 public void addComplexAliasMember(ComplexAliasMember complexAliasMember) { 831 this.complexAliasMembers.add(complexAliasMember); 832 } 833 834 public void makeAliasColName(StringBuffer colNameBuffer, StringBuffer fieldTypeBuffer, ModelViewEntity modelViewEntity, ModelReader modelReader) { 835 if (complexAliasMembers.size() == 0) { 836 return; 837 } else if (complexAliasMembers.size() == 1) { 838 ComplexAliasMember complexAliasMember = (ComplexAliasMember) complexAliasMembers.iterator().next(); 839 complexAliasMember.makeAliasColName(colNameBuffer, fieldTypeBuffer, modelViewEntity, modelReader); 840 } else { 841 colNameBuffer.append('('); 842 Iterator complexAliasMemberIter = complexAliasMembers.iterator(); 843 while (complexAliasMemberIter.hasNext()) { 844 ComplexAliasMember complexAliasMember = (ComplexAliasMember) complexAliasMemberIter.next(); 845 complexAliasMember.makeAliasColName(colNameBuffer, fieldTypeBuffer, modelViewEntity, modelReader); 846 if (complexAliasMemberIter.hasNext()) { 847 colNameBuffer.append(' '); 848 colNameBuffer.append(this.operator); 849 colNameBuffer.append(' '); 850 } 851 } 852 colNameBuffer.append(')'); 853 } 854 } 855 } 856 857 public static class ComplexAliasField implements ComplexAliasMember { 858 protected String entityAlias = ""; 859 protected String field = ""; 860 protected String defaultValue = null; 861 protected String function = null; 862 863 public ComplexAliasField(Element complexAliasFieldElement) { 864 this.entityAlias = complexAliasFieldElement.getAttribute("entity-alias"); 865 this.field = complexAliasFieldElement.getAttribute("field"); 866 this.defaultValue = complexAliasFieldElement.getAttribute("default-value"); 867 this.function = complexAliasFieldElement.getAttribute("function"); 868 } 869 870 public ComplexAliasField(String entityAlias, String field, String defaultValue, String function) { 871 this.entityAlias = entityAlias; 872 this.field = field; 873 this.defaultValue = defaultValue; 874 this.function = function; 875 } 876 877 880 public void makeAliasColName(StringBuffer colNameBuffer, StringBuffer fieldTypeBuffer, ModelViewEntity modelViewEntity, ModelReader modelReader) { 881 ModelEntity modelEntity = modelViewEntity.getAliasedEntity(entityAlias, modelReader); 882 ModelField modelField = modelViewEntity.getAliasedField(modelEntity, field, modelReader); 883 884 String colName = entityAlias + "." + modelField.getColName(); 885 886 if (UtilValidate.isNotEmpty(defaultValue)) { 887 colName = "COALESCE(" + colName + "," + defaultValue + ")"; 888 } 889 890 if (UtilValidate.isNotEmpty(function)) { 891 String prefix = (String ) functionPrefixMap.get(function); 892 if (prefix == null) { 893 Debug.logWarning("Specified alias function [" + function + "] not valid; must be: min, max, sum, avg, count or count-distinct; using a column name with no function function", module); 894 } else { 895 colName = prefix + colName + ")"; 896 } 897 } 898 899 colNameBuffer.append(colName); 900 901 if (fieldTypeBuffer.length() == 0) { 903 fieldTypeBuffer.append(modelField.type); 904 } 905 } 906 } 907 908 public static class ModelViewLink implements Serializable { 909 protected String entityAlias = ""; 910 protected String relEntityAlias = ""; 911 protected boolean relOptional = false; 912 protected List keyMaps = FastList.newInstance(); 913 914 protected ModelViewLink() {} 915 916 public ModelViewLink(Element viewLinkElement) { 917 this.entityAlias = UtilXml.checkEmpty(viewLinkElement.getAttribute("entity-alias")); 918 this.relEntityAlias = UtilXml.checkEmpty(viewLinkElement.getAttribute("rel-entity-alias")); 919 this.relOptional = "true".equals(viewLinkElement.getAttribute("rel-optional")); 921 922 NodeList keyMapList = viewLinkElement.getElementsByTagName("key-map"); 923 for (int j = 0; j < keyMapList.getLength(); j++) { 924 Element keyMapElement = (Element ) keyMapList.item(j); 925 ModelKeyMap keyMap = new ModelKeyMap(keyMapElement); 926 927 if (keyMap != null) keyMaps.add(keyMap); 928 } 929 } 930 931 public ModelViewLink(String entityAlias, String relEntityAlias, Boolean relOptional, List keyMaps) { 932 this.entityAlias = entityAlias; 933 this.relEntityAlias = relEntityAlias; 934 if (relOptional != null) { 935 this.relOptional = relOptional.booleanValue(); 936 } 937 this.keyMaps.addAll(keyMaps); 938 } 939 940 public String getEntityAlias() { 941 return this.entityAlias; 942 } 943 944 public String getRelEntityAlias() { 945 return this.relEntityAlias; 946 } 947 948 public boolean isRelOptional() { 949 return this.relOptional; 950 } 951 952 public ModelKeyMap getKeyMap(int index) { 953 return (ModelKeyMap) this.keyMaps.get(index); 954 } 955 956 public int getKeyMapsSize() { 957 return this.keyMaps.size(); 958 } 959 960 public Iterator getKeyMapsIterator() { 961 return this.keyMaps.iterator(); 962 } 963 964 public List getKeyMapsCopy() { 965 List newList = FastList.newInstance(); 966 newList.addAll(this.keyMaps); 967 return newList; 968 } 969 } 970 971 public class ModelConversion implements Serializable { 972 protected String aliasName; 973 protected ModelEntity fromModelEntity; 974 protected Map fieldMap = FastMap.newInstance(); 975 protected Set wildcards = new HashSet (); 976 977 public ModelConversion(String aliasName, ModelEntity fromModelEntity) { 978 this.aliasName = aliasName; 979 this.fromModelEntity = fromModelEntity; 980 Iterator it = getFieldsIterator(); 981 while (it.hasNext()) { 982 ModelField field = (ModelField) it.next(); 983 wildcards.add(field.getName()); 984 } 985 } 986 987 public int hashCode() { 988 return fromModelEntity.hashCode(); 989 } 990 991 public boolean equals(Object obj) { 992 if (!(obj instanceof ModelConversion)) return false; 993 ModelConversion other = (ModelConversion) obj; 994 return fromModelEntity.equals(other.fromModelEntity); 995 } 996 997 public void addConversion(String fromFieldName, String toFieldName) { 998 wildcards.remove(toFieldName); 999 fieldMap.put(fromFieldName, toFieldName); 1000 } 1001 1002 public String toString() { 1003 return aliasName + "(" + fromModelEntity.getEntityName() + ")"; 1005 } 1006 1007 public Map convert(Map values) { 1008 Map newValues = FastMap.newInstance(); 1009 Iterator it = fieldMap.entrySet().iterator(); 1010 while (it.hasNext()) { 1011 Map.Entry entry = (Map.Entry ) it.next(); 1012 newValues.put(entry.getValue(), values.get((String ) entry.getKey())); 1013 } 1014 it = wildcards.iterator(); 1015 while (it.hasNext()) { 1016 newValues.put((String ) it.next(), EntityOperator.WILDCARD); 1017 } 1018 return newValues; 1019 } 1020 1021 public void addAllAliasConversions(List aliases, String fieldName) { 1022 if (aliases != null) { 1023 Iterator it3 = aliases.iterator(); 1024 while (it3.hasNext()) { 1025 addConversion(fieldName, (String ) it3.next()); 1026 } 1027 } 1028 } 1029 } 1030} 1031 | Popular Tags |