KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > entity > model > ModelViewEntity


1 /*
2  * Copyright 2001-2006 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations
14  * under the License.
15  */

16 package org.ofbiz.entity.model;
17
18 import java.io.Serializable JavaDoc;
19 import java.util.Arrays JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.Set JavaDoc;
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 JavaDoc;
36 import org.w3c.dom.NodeList JavaDoc;
37
38 /**
39  * This class extends ModelEntity and provides additional information appropriate to view entities
40  */

41 public class ModelViewEntity extends ModelEntity {
42     public static final String JavaDoc module = ModelViewEntity.class.getName();
43
44     public static Map JavaDoc 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     /** Contains member-entity alias name definitions: key is alias, value is ModelMemberEntity */
57     protected Map JavaDoc memberModelMemberEntities = FastMap.newInstance();
58
59     /** A list of all ModelMemberEntity entries; this is mainly used to preserve the original order of member entities from the XML file */
60     protected List JavaDoc allModelMemberEntities = FastList.newInstance();
61
62     /** Contains member-entity ModelEntities: key is alias, value is ModelEntity; populated with fields */
63     protected Map JavaDoc memberModelEntities = null;
64
65     /** List of alias-alls which act as a shortcut for easily pulling over member entity fields */
66     protected List JavaDoc aliasAlls = FastList.newInstance();
67
68     /** List of aliases with information in addition to what is in the standard field list */
69     protected List JavaDoc aliases = FastList.newInstance();
70
71     /** List of view links to define how entities are connected (or "joined") */
72     protected List JavaDoc viewLinks = FastList.newInstance();
73
74     /** A List of the Field objects for the View Entity, one for each GROUP BY field */
75     protected List JavaDoc groupBys = FastList.newInstance();
76
77     protected Map JavaDoc conversions = FastMap.newInstance();
78
79     public ModelViewEntity(ModelReader reader, Element JavaDoc 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 JavaDoc memberEntityList = UtilXml.childElementList(entityElement, "member-entity");
87         Iterator JavaDoc memberEntityIter = memberEntityList.iterator();
88         while (memberEntityIter.hasNext()) {
89             Element JavaDoc memberEntityElement = (Element JavaDoc) memberEntityIter.next();
90             String JavaDoc alias = UtilXml.checkEmpty(memberEntityElement.getAttribute("entity-alias"));
91             String JavaDoc 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         // when reading aliases and alias-alls, just read them into the alias list, there will be a pass
101
// after loading all entities to go back and fill in all of the ModelField entries
102
List JavaDoc aliasAllList = UtilXml.childElementList(entityElement, "alias-all");
103         Iterator JavaDoc aliasAllIter = aliasAllList.iterator();
104         while (aliasAllIter.hasNext()) {
105             Element JavaDoc aliasElement = (Element JavaDoc) 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 JavaDoc aliasList = UtilXml.childElementList(entityElement, "alias");
112         Iterator JavaDoc aliasIter = aliasList.iterator();
113         while (aliasIter.hasNext()) {
114             Element JavaDoc aliasElement = (Element JavaDoc) aliasIter.next();
115             ModelViewEntity.ModelAlias alias = new ModelAlias(aliasElement);
116             this.aliases.add(alias);
117         }
118         
119         List JavaDoc viewLinkList = UtilXml.childElementList(entityElement, "view-link");
120         Iterator JavaDoc viewLinkIter = viewLinkList.iterator();
121         while (viewLinkIter.hasNext()) {
122             Element JavaDoc viewLinkElement = (Element JavaDoc) 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         // before finishing, make sure the table name is null, this should help bring up errors early...
131
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         // member-entities
141
Iterator JavaDoc modelMemberEntitiesEntryIter = dynamicViewEntity.getModelMemberEntitiesEntryIter();
142         while (modelMemberEntitiesEntryIter.hasNext()) {
143             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) modelMemberEntitiesEntryIter.next();
144             this.addMemberModelMemberEntity((ModelMemberEntity) entry.getValue());
145         }
146         
147         // alias-alls
148
dynamicViewEntity.addAllAliasAllsToList(this.aliasAlls);
149         
150         // aliases
151
dynamicViewEntity.addAllAliasesToList(this.aliases);
152         
153         // view-links
154
dynamicViewEntity.addAllViewLinksToList(this.viewLinks);
155         
156         // relations
157
dynamicViewEntity.addAllRelationsToList(this.relations);
158         
159         // finalize stuff
160
// note that this doesn't result in a call to populateReverseLinks because a DynamicViewEntity should never be cached anyway, and will blow up when attempting to make the reverse links to the DynamicViewEntity
161
this.populateFieldsBasic(modelReader);
162     }
163
164     public Map JavaDoc getMemberModelMemberEntities() {
165         return this.memberModelMemberEntities;
166     }
167
168     public List JavaDoc getAllModelMemberEntities() {
169         return this.allModelMemberEntities;
170     }
171
172     public ModelMemberEntity getMemberModelMemberEntity(String JavaDoc alias) {
173         return (ModelMemberEntity) this.memberModelMemberEntities.get(alias);
174     }
175
176     public ModelEntity getMemberModelEntity(String JavaDoc 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 JavaDoc alias) {
190         ModelMemberEntity modelMemberEntity = (ModelMemberEntity) this.memberModelMemberEntities.remove(alias);
191
192         if (modelMemberEntity == null) return;
193         this.allModelMemberEntities.remove(modelMemberEntity);
194     }
195
196     /** The col-name of the Field, the alias of the field if this is on a view-entity */
197     public String JavaDoc getColNameOrAlias(String JavaDoc fieldName) {
198         ModelField modelField = this.getField(fieldName);
199         String JavaDoc fieldString = modelField.getColName();
200         ModelViewEntity.ModelAlias alias = getAlias(fieldName);
201         if (alias != null) {
202             fieldString = alias.getColAlias();
203         }
204         return fieldString;
205     }
206
207     /** List of aliases with information in addition to what is in the standard field list */
208     public ModelAlias getAlias(int index) {
209         return (ModelAlias) this.aliases.get(index);
210     }
211     
212     public ModelAlias getAlias(String JavaDoc name) {
213         Iterator JavaDoc 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 JavaDoc getAliasesIterator() {
228         return this.aliases.iterator();
229     }
230
231     public List JavaDoc getAliasesCopy() {
232         List JavaDoc newList = FastList.newInstance();
233         newList.addAll(this.aliases);
234         return newList;
235     }
236
237     public List JavaDoc getGroupBysCopy() {
238         List JavaDoc newList = FastList.newInstance();
239         newList.addAll(this.groupBys);
240         return newList;
241     }
242
243     /** List of view links to define how entities are connected (or "joined") */
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 JavaDoc getViewLinksIterator() {
253         return this.viewLinks.iterator();
254     }
255
256     public List JavaDoc getViewLinksCopy() {
257         List JavaDoc 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 JavaDoc colNameString(List JavaDoc flds, String JavaDoc separator, String JavaDoc afterLast, boolean alias) {
267         StringBuffer JavaDoc returnString = new StringBuffer JavaDoc();
268
269         if (flds.size() < 1) {
270             return "";
271         }
272
273         Iterator JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc meIter = memberModelMemberEntities.entrySet().iterator();
335         while (meIter.hasNext()) {
336             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) meIter.next();
337
338             ModelMemberEntity modelMemberEntity = (ModelMemberEntity) entry.getValue();
339             String JavaDoc aliasedEntityName = modelMemberEntity.getEntityName();
340             ModelEntity aliasedEntity = modelReader.getModelEntityNoCheck(aliasedEntityName);
341             if (aliasedEntity == null) {
342                 continue;
343             }
344             memberModelEntities.put(entry.getKey(), aliasedEntity);
345             Iterator JavaDoc 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 this is a groupBy field, add it to the groupBys list
369
if (alias.groupBy) {
370                 this.groupBys.add(field);
371             }
372
373             // show a warning if function is specified and groupBy is true
374
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                 // if this is a complex alias, make a complex column name...
380
StringBuffer JavaDoc colNameBuffer = new StringBuffer JavaDoc();
381                 StringBuffer JavaDoc fieldTypeBuffer = new StringBuffer JavaDoc();
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                 // if we have a "count" function we have to change the type
416
field.type = "numeric";
417             }
418
419             if (UtilValidate.isNotEmpty(alias.function)) {
420                 String JavaDoc prefix = (String JavaDoc) 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 JavaDoc aliasName) {
431         ModelEntity member = getMemberModelEntity(aliasName);
432         if (member == null) {
433             String JavaDoc errMsg = "No member found for aliasName - " + aliasName;
434             Debug.logWarning(errMsg, module);
435             throw new RuntimeException JavaDoc("Cannot create View Entity: " + errMsg);
436         }
437         
438         Map JavaDoc aliasConversions = (Map JavaDoc) 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 JavaDoc containedModelFields = FastMap.newInstance();
453         Iterator JavaDoc it = getAliasesIterator();
454         while (it.hasNext()) {
455             ModelViewEntity.ModelAlias alias = (ModelViewEntity.ModelAlias) it.next();
456             if (alias.isComplexAlias()) {
457                 // TODO: conversion for complex-alias needs to be implemented for cache and in-memory eval stuff to work correctly
458
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 JavaDoc aliases = (List JavaDoc) 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 JavaDoc leftAlias = link.getEntityAlias();
477             String JavaDoc rightAlias = link.getRelEntityAlias();
478             ModelConversion leftConversion = getOrCreateModelConversion(leftAlias);
479             ModelConversion rightConversion = getOrCreateModelConversion(rightAlias);
480             Iterator JavaDoc it2 = link.getKeyMapsIterator();
481             Debug.logVerbose(leftAlias + "<->" + rightAlias, module);
482             while (it2.hasNext()) {
483                 ModelKeyMap mkm = (ModelKeyMap) it2.next();
484                 String JavaDoc leftFieldName = mkm.getFieldName();
485                 String JavaDoc rightFieldName = mkm.getRelFieldName();
486                 rightConversion.addAllAliasConversions((List JavaDoc) containedModelFields.get(leftFieldName), rightFieldName);
487                 leftConversion.addAllAliasConversions((List JavaDoc) 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 JavaDoc entry = (Map.Entry JavaDoc) it.next();
497             Map JavaDoc aliasConversions = (Map JavaDoc) entry.getValue();
498             currentIndex[i] = 0;
499             maxIndex[i] = aliasConversions.size();
500             allConversions[i] = new ModelConversion[aliasConversions.size()];
501             Iterator JavaDoc 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 JavaDoc convert(String JavaDoc fromEntityName, Map JavaDoc data) {
530         Map JavaDoc foo = (Map JavaDoc) conversions.get(fromEntityName);
531         if (foo == null) return null;
532         Iterator JavaDoc it = foo.values().iterator();
533         List JavaDoc 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     /**
542      * Go through all aliasAlls and create an alias for each field of each member entity
543      */

544     private void expandAllAliasAlls(ModelReader modelReader) {
545         Iterator JavaDoc aliasAllIter = aliasAlls.iterator();
546         while (aliasAllIter.hasNext()) {
547             ModelAliasAll aliasAll = (ModelAliasAll) aliasAllIter.next();
548             String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc fieldnamesIterator = entFieldList.iterator();
570             while (fieldnamesIterator.hasNext()) {
571                 // now merge the lists, leaving out any that duplicate an existing alias name
572
String JavaDoc fieldName = (String JavaDoc) fieldnamesIterator.next();
573                 String JavaDoc aliasName = fieldName;
574                 ModelField modelField = aliasedEntity.getField(fieldName);
575                 if (modelField.getIsAutoCreatedInternal()) {
576                     // never auto-alias these
577
continue;
578                 }
579                 if (aliasAll.shouldExclude(fieldName)) {
580                     // if specified as excluded, leave it out
581
continue;
582                 }
583                 
584                 if (UtilValidate.isNotEmpty(prefix)) {
585                     StringBuffer JavaDoc newAliasBuffer = new StringBuffer JavaDoc(prefix);
586                     //make sure the first letter is uppercase to delineate the field name
587
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                     //log differently if this is part of a view-link key-map because that is a common case when a field will be auto-expanded multiple times
595
boolean isInViewLink = false;
596                     Iterator JavaDoc 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                             // not the rel-entity-alias or the entity-alias, so move along
604
continue;
605                         }
606                         Iterator JavaDoc 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                     //already exists, oh well... probably an override, but log just in case
618
String JavaDoc 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 JavaDoc toString() {
639         return "ModelViewEntity[" + getEntityName() + "]";
640     }
641
642     public static class ModelMemberEntity implements Serializable JavaDoc {
643         protected String JavaDoc entityAlias = "";
644         protected String JavaDoc entityName = "";
645
646         public ModelMemberEntity(String JavaDoc entityAlias, String JavaDoc entityName) {
647             this.entityAlias = entityAlias;
648             this.entityName = entityName;
649         }
650
651         public String JavaDoc getEntityAlias() {
652             return this.entityAlias;
653         }
654
655         public String JavaDoc getEntityName() {
656             return this.entityName;
657         }
658     }
659
660     public static class ModelAliasAll implements Serializable JavaDoc {
661         protected String JavaDoc entityAlias = "";
662         protected String JavaDoc prefix = "";
663         protected Set JavaDoc fieldsToExclude = null;
664
665         protected ModelAliasAll() {}
666
667         public ModelAliasAll(String JavaDoc entityAlias, String JavaDoc prefix) {
668             this.entityAlias = entityAlias;
669             this.prefix = prefix;
670         }
671
672         public ModelAliasAll(Element JavaDoc aliasAllElement) {
673             this.entityAlias = UtilXml.checkEmpty(aliasAllElement.getAttribute("entity-alias"));
674             this.prefix = UtilXml.checkEmpty(aliasAllElement.getAttribute("prefix"));
675             
676             List JavaDoc excludes = UtilXml.childElementList(aliasAllElement, "exclude");
677             if (excludes != null && excludes.size() > 0) {
678                 this.fieldsToExclude = new HashSet JavaDoc();
679                 Iterator JavaDoc excludeIter = excludes.iterator();
680                 while (excludeIter.hasNext()) {
681                     Element JavaDoc excludeElement = (Element JavaDoc) excludeIter.next();
682                     this.fieldsToExclude.add(excludeElement.getAttribute("field"));
683                 }
684             }
685             
686         }
687
688         public String JavaDoc getEntityAlias() {
689             return this.entityAlias;
690         }
691
692         public String JavaDoc getPrefix() {
693             return this.prefix;
694         }
695
696         public boolean shouldExclude(String JavaDoc 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 JavaDoc {
706         protected String JavaDoc entityAlias = "";
707         protected String JavaDoc name = "";
708         protected String JavaDoc field = "";
709         protected String JavaDoc colAlias = "";
710         // this is a Boolean object for a tri-state: null, true or false
711
protected Boolean JavaDoc isPk = null;
712         protected boolean groupBy = false;
713         // is specified this alias is a calculated value; can be: min, max, sum, avg, count, count-distinct
714
protected String JavaDoc function = null;
715         protected boolean isFromAliasAll = false;
716         protected ComplexAliasMember complexAliasMember = null;
717
718         protected ModelAlias() {}
719
720         public ModelAlias(Element JavaDoc 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 JavaDoc primKeyValue = UtilXml.checkEmpty(aliasElement.getAttribute("prim-key"));
726
727             if (UtilValidate.isNotEmpty(primKeyValue)) {
728                 this.isPk = new Boolean JavaDoc("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 JavaDoc complexAliasElement = UtilXml.firstChildElement(aliasElement, "complex-alias");
736             if (complexAliasElement != null) {
737                 complexAliasMember = new ComplexAlias(complexAliasElement);
738             }
739         }
740         
741         public ModelAlias(String JavaDoc entityAlias, String JavaDoc name, String JavaDoc field, String JavaDoc colAlias, Boolean JavaDoc isPk, Boolean JavaDoc groupBy, String JavaDoc 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 JavaDoc colNameBuffer, StringBuffer JavaDoc fieldTypeBuffer, ModelViewEntity modelViewEntity, ModelReader modelReader) {
764             if (complexAliasMember != null) {
765                 complexAliasMember.makeAliasColName(colNameBuffer, fieldTypeBuffer, modelViewEntity, modelReader);
766             }
767         }
768
769         public String JavaDoc getEntityAlias() {
770             return this.entityAlias;
771         }
772
773         public String JavaDoc getName() {
774             return this.name;
775         }
776         
777         public String JavaDoc getColAlias() {
778             return this.colAlias;
779         }
780
781         public String JavaDoc getField() {
782             return this.field;
783         }
784
785         public Boolean JavaDoc getIsPk() {
786             return this.isPk;
787         }
788
789         public boolean getGroupBy() {
790             return this.groupBy;
791         }
792
793         public String JavaDoc 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 JavaDoc {
803         public void makeAliasColName(StringBuffer JavaDoc colNameBuffer, StringBuffer JavaDoc fieldTypeBuffer, ModelViewEntity modelViewEntity, ModelReader modelReader);
804     }
805     
806     public static class ComplexAlias implements ComplexAliasMember {
807         protected List JavaDoc complexAliasMembers = FastList.newInstance();
808         protected String JavaDoc operator;
809         
810         public ComplexAlias(String JavaDoc operator) {
811             this.operator = operator;
812         }
813         
814         public ComplexAlias(Element JavaDoc complexAliasElement) {
815             this.operator = complexAliasElement.getAttribute("operator");
816             // handle all complex-alias and complex-alias-field sub-elements
817
List JavaDoc subElements = UtilXml.childElementList(complexAliasElement);
818             Iterator JavaDoc subElementIter = subElements.iterator();
819             while (subElementIter.hasNext()) {
820                 Element JavaDoc subElement = (Element JavaDoc) subElementIter.next();
821                 String JavaDoc 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 JavaDoc colNameBuffer, StringBuffer JavaDoc 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 JavaDoc 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 JavaDoc entityAlias = "";
859         protected String JavaDoc field = "";
860         protected String JavaDoc defaultValue = null;
861         protected String JavaDoc function = null;
862         
863         public ComplexAliasField(Element JavaDoc 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 JavaDoc entityAlias, String JavaDoc field, String JavaDoc defaultValue, String JavaDoc function) {
871             this.entityAlias = entityAlias;
872             this.field = field;
873             this.defaultValue = defaultValue;
874             this.function = function;
875         }
876
877         /**
878          * Make the alias as follows: function(coalesce(entityAlias.field, defaultValue))
879          */

880         public void makeAliasColName(StringBuffer JavaDoc colNameBuffer, StringBuffer JavaDoc fieldTypeBuffer, ModelViewEntity modelViewEntity, ModelReader modelReader) {
881             ModelEntity modelEntity = modelViewEntity.getAliasedEntity(entityAlias, modelReader);
882             ModelField modelField = modelViewEntity.getAliasedField(modelEntity, field, modelReader);
883             
884             String JavaDoc colName = entityAlias + "." + modelField.getColName();
885             
886             if (UtilValidate.isNotEmpty(defaultValue)) {
887                 colName = "COALESCE(" + colName + "," + defaultValue + ")";
888             }
889
890             if (UtilValidate.isNotEmpty(function)) {
891                 String JavaDoc prefix = (String JavaDoc) 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             //set fieldTypeBuffer if not already set
902
if (fieldTypeBuffer.length() == 0) {
903                 fieldTypeBuffer.append(modelField.type);
904             }
905         }
906     }
907
908     public static class ModelViewLink implements Serializable JavaDoc {
909         protected String JavaDoc entityAlias = "";
910         protected String JavaDoc relEntityAlias = "";
911         protected boolean relOptional = false;
912         protected List JavaDoc keyMaps = FastList.newInstance();
913
914         protected ModelViewLink() {}
915
916         public ModelViewLink(Element JavaDoc viewLinkElement) {
917             this.entityAlias = UtilXml.checkEmpty(viewLinkElement.getAttribute("entity-alias"));
918             this.relEntityAlias = UtilXml.checkEmpty(viewLinkElement.getAttribute("rel-entity-alias"));
919             // if anything but true will be false; ie defaults to false
920
this.relOptional = "true".equals(viewLinkElement.getAttribute("rel-optional"));
921
922             NodeList JavaDoc keyMapList = viewLinkElement.getElementsByTagName("key-map");
923             for (int j = 0; j < keyMapList.getLength(); j++) {
924                 Element JavaDoc keyMapElement = (Element JavaDoc) keyMapList.item(j);
925                 ModelKeyMap keyMap = new ModelKeyMap(keyMapElement);
926
927                 if (keyMap != null) keyMaps.add(keyMap);
928             }
929         }
930
931         public ModelViewLink(String JavaDoc entityAlias, String JavaDoc relEntityAlias, Boolean JavaDoc relOptional, List JavaDoc 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 JavaDoc getEntityAlias() {
941             return this.entityAlias;
942         }
943
944         public String JavaDoc 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 JavaDoc getKeyMapsIterator() {
961             return this.keyMaps.iterator();
962         }
963
964         public List JavaDoc getKeyMapsCopy() {
965             List JavaDoc newList = FastList.newInstance();
966             newList.addAll(this.keyMaps);
967             return newList;
968         }
969     }
970
971     public class ModelConversion implements Serializable JavaDoc {
972         protected String JavaDoc aliasName;
973         protected ModelEntity fromModelEntity;
974         protected Map JavaDoc fieldMap = FastMap.newInstance();
975         protected Set JavaDoc wildcards = new HashSet JavaDoc();
976
977         public ModelConversion(String JavaDoc aliasName, ModelEntity fromModelEntity) {
978             this.aliasName = aliasName;
979             this.fromModelEntity = fromModelEntity;
980             Iterator JavaDoc 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 JavaDoc 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 JavaDoc fromFieldName, String JavaDoc toFieldName) {
998             wildcards.remove(toFieldName);
999             fieldMap.put(fromFieldName, toFieldName);
1000        }
1001
1002        public String JavaDoc toString() {
1003            //return fromModelEntity.getEntityName() + ":" + fieldMap + ":" + wildcards;
1004
return aliasName + "(" + fromModelEntity.getEntityName() + ")";
1005        }
1006
1007        public Map JavaDoc convert(Map JavaDoc values) {
1008            Map JavaDoc newValues = FastMap.newInstance();
1009            Iterator JavaDoc it = fieldMap.entrySet().iterator();
1010            while (it.hasNext()) {
1011                Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
1012                newValues.put(entry.getValue(), values.get((String JavaDoc) entry.getKey()));
1013            }
1014            it = wildcards.iterator();
1015            while (it.hasNext()) {
1016                newValues.put((String JavaDoc) it.next(), EntityOperator.WILDCARD);
1017            }
1018            return newValues;
1019        }
1020
1021        public void addAllAliasConversions(List JavaDoc aliases, String JavaDoc fieldName) {
1022            if (aliases != null) {
1023                Iterator JavaDoc it3 = aliases.iterator();
1024                while (it3.hasNext()) {
1025                    addConversion(fieldName, (String JavaDoc) it3.next());
1026                }
1027            }
1028        }
1029    }
1030}
1031
Popular Tags