KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > entity > finder > EntityFinderUtil


1 /*
2  * $Id: EntityFinderUtil.java 6047 2005-10-31 13:18:56Z jonesde $
3  *
4  * Copyright (c) 2004-2005 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */

24 package org.ofbiz.entity.finder;
25
26 import java.io.Serializable JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.LinkedList JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.Set JavaDoc;
35
36 import org.ofbiz.base.util.Debug;
37 import org.ofbiz.base.util.UtilValidate;
38 import org.ofbiz.base.util.StringUtil;
39 import org.ofbiz.base.util.ObjectType;
40 import org.ofbiz.base.util.UtilFormatOut;
41 import org.ofbiz.base.util.UtilXml;
42 import org.ofbiz.base.util.collections.FlexibleMapAccessor;
43 import org.ofbiz.base.util.string.FlexibleStringExpander;
44 import org.ofbiz.entity.GenericDelegator;
45 import org.ofbiz.entity.GenericEntityException;
46 import org.ofbiz.entity.condition.EntityComparisonOperator;
47 import org.ofbiz.entity.condition.EntityCondition;
48 import org.ofbiz.entity.condition.EntityConditionList;
49 import org.ofbiz.entity.condition.EntityExpr;
50 import org.ofbiz.entity.condition.EntityJoinOperator;
51 import org.ofbiz.entity.condition.EntityOperator;
52 import org.ofbiz.entity.model.ModelEntity;
53 import org.ofbiz.entity.util.EntityListIterator;
54 import org.w3c.dom.Element JavaDoc;
55
56 /**
57  * Uses the delegator to find entity values by a condition
58  *
59  * @author <a HREF="mailto:jonesde@ofbiz.org">David E. Jones</a>
60  * @version $Rev: 6047 $
61  * @since 3.1
62  */

63 public class EntityFinderUtil {
64     
65     public static final String JavaDoc module = EntityFinderUtil.class.getName();
66     
67     public static Map JavaDoc makeFieldMap(Element JavaDoc element) {
68         Map JavaDoc fieldMap = null;
69         List JavaDoc fieldMapElementList = UtilXml.childElementList(element, "field-map");
70         if (fieldMapElementList.size() > 0) {
71             fieldMap = new HashMap JavaDoc();
72             Iterator JavaDoc fieldMapElementIter = fieldMapElementList.iterator();
73             while (fieldMapElementIter.hasNext()) {
74                 Element JavaDoc fieldMapElement = (Element JavaDoc) fieldMapElementIter.next();
75                 // set the env-name for each field-name, noting that if no field-name is specified it defaults to the env-name
76
String JavaDoc fieldName = fieldMapElement.getAttribute("field-name");
77                 String JavaDoc envName = fieldMapElement.getAttribute("env-name");
78                 String JavaDoc value = fieldMapElement.getAttribute("value");
79                 if (UtilValidate.isEmpty(fieldName)) {
80                     // no fieldName, use envName for both
81
fieldMap.put(new FlexibleMapAccessor(envName), new FlexibleMapAccessor(envName));
82                 } else {
83                     if (UtilValidate.isNotEmpty(value)) {
84                         fieldMap.put(new FlexibleMapAccessor(fieldName), new FlexibleStringExpander(value));
85                     } else {
86                         // at this point we have a fieldName and no value, do we have a envName?
87
if (UtilValidate.isNotEmpty(envName)) {
88                             fieldMap.put(new FlexibleMapAccessor(fieldName), new FlexibleMapAccessor(envName));
89                         } else {
90                             // no envName, use fieldName for both
91
fieldMap.put(new FlexibleMapAccessor(fieldName), new FlexibleMapAccessor(fieldName));
92                         }
93                     }
94                 }
95             }
96         }
97         return fieldMap;
98     }
99
100     public static void expandFieldMapToContext(Map JavaDoc fieldMap, Map JavaDoc context, Map JavaDoc outContext) {
101         //Debug.logInfo("fieldMap: " + fieldMap, module);
102
if (fieldMap != null) {
103             Iterator JavaDoc fieldMapEntryIter = fieldMap.entrySet().iterator();
104             while (fieldMapEntryIter.hasNext()) {
105                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) fieldMapEntryIter.next();
106                 FlexibleMapAccessor serviceContextFieldAcsr = (FlexibleMapAccessor) entry.getKey();
107                 Object JavaDoc valueSrc = entry.getValue();
108                 if (valueSrc instanceof FlexibleMapAccessor) {
109                     FlexibleMapAccessor contextEnvAcsr = (FlexibleMapAccessor) valueSrc;
110                     serviceContextFieldAcsr.put(outContext, contextEnvAcsr.get(context));
111                 } else if (valueSrc instanceof FlexibleStringExpander) {
112                     FlexibleStringExpander valueExdr = (FlexibleStringExpander) valueSrc;
113                     serviceContextFieldAcsr.put(outContext, valueExdr.expandString(context));
114                 } else {
115                     // hmmmm...
116
}
117             }
118         }
119     }
120     
121     public static List JavaDoc makeSelectFieldExpanderList(Element JavaDoc element) {
122         List JavaDoc selectFieldExpanderList = null;
123         List JavaDoc selectFieldElementList = UtilXml.childElementList(element, "select-field");
124         if (selectFieldElementList.size() > 0) {
125             selectFieldExpanderList = new LinkedList JavaDoc();
126             Iterator JavaDoc selectFieldElementIter = selectFieldElementList.iterator();
127             while (selectFieldElementIter.hasNext()) {
128                 Element JavaDoc selectFieldElement = (Element JavaDoc) selectFieldElementIter.next();
129                 selectFieldExpanderList.add(new FlexibleStringExpander(selectFieldElement.getAttribute("field-name")));
130             }
131         }
132         return selectFieldExpanderList;
133     }
134     
135     public static Set JavaDoc makeFieldsToSelect(List JavaDoc selectFieldExpanderList, Map JavaDoc context) {
136         Set JavaDoc fieldsToSelect = null;
137         if (selectFieldExpanderList != null && selectFieldExpanderList.size() > 0) {
138             fieldsToSelect = new HashSet JavaDoc();
139             Iterator JavaDoc selectFieldExpanderIter = selectFieldExpanderList.iterator();
140             while (selectFieldExpanderIter.hasNext()) {
141                 FlexibleStringExpander selectFieldExpander = (FlexibleStringExpander) selectFieldExpanderIter.next();
142                 fieldsToSelect.add(selectFieldExpander.expandString(context));
143             }
144         }
145         return fieldsToSelect;
146     }
147     
148     public static List JavaDoc makeOrderByFieldList(List JavaDoc orderByExpanderList, Map JavaDoc context) {
149         List JavaDoc orderByFields = null;
150         if (orderByExpanderList != null && orderByExpanderList.size() > 0) {
151             orderByFields = new LinkedList JavaDoc();
152             Iterator JavaDoc orderByExpanderIter = orderByExpanderList.iterator();
153             while (orderByExpanderIter.hasNext()) {
154                 FlexibleStringExpander orderByExpander = (FlexibleStringExpander) orderByExpanderIter.next();
155                 orderByFields.add(orderByExpander.expandString(context));
156             }
157         }
158         return orderByFields;
159     }
160     
161     public static interface Condition extends Serializable JavaDoc {
162         public EntityCondition createCondition(Map JavaDoc context, String JavaDoc entityName, GenericDelegator delegator);
163     }
164     public static class ConditionExpr implements Condition {
165         protected FlexibleStringExpander fieldNameExdr;
166         protected FlexibleStringExpander operatorExdr;
167         protected FlexibleMapAccessor envNameAcsr;
168         protected FlexibleStringExpander valueExdr;
169         protected boolean ignoreIfNull;
170         protected boolean ignoreIfEmpty;
171         
172         public ConditionExpr(Element JavaDoc conditionExprElement) {
173             this.fieldNameExdr = new FlexibleStringExpander(conditionExprElement.getAttribute("field-name"));
174             if (this.fieldNameExdr.isEmpty()) {
175                 // no "field-name"? try "name"
176
this.fieldNameExdr = new FlexibleStringExpander(conditionExprElement.getAttribute("name"));
177             }
178
179             this.operatorExdr = new FlexibleStringExpander(UtilFormatOut.checkEmpty(conditionExprElement.getAttribute("operator"), "equals"));
180             this.envNameAcsr = new FlexibleMapAccessor(conditionExprElement.getAttribute("env-name"));
181             this.valueExdr = new FlexibleStringExpander(conditionExprElement.getAttribute("value"));
182             this.ignoreIfNull = "true".equals(conditionExprElement.getAttribute("ignore-if-null"));
183             this.ignoreIfEmpty = "true".equals(conditionExprElement.getAttribute("ignore-if-empty"));
184         }
185         
186         public EntityCondition createCondition(Map JavaDoc context, String JavaDoc entityName, GenericDelegator delegator) {
187             ModelEntity modelEntity = delegator.getModelEntity(entityName);
188             if (modelEntity == null) {
189                 throw new IllegalArgumentException JavaDoc("Error in Entity Find: could not find entity with name [" + entityName + "]");
190             }
191             
192             String JavaDoc fieldName = fieldNameExdr.expandString(context);
193             
194             Object JavaDoc value = null;
195             // start with the environment variable, will override if exists and a value is specified
196
if (envNameAcsr != null) {
197                 value = envNameAcsr.get(context);
198             }
199             // no value so far, and a string value is specified, use that
200
if (value == null && valueExdr != null) {
201                 value = valueExdr.expandString(context);
202             }
203
204             String JavaDoc operatorName = operatorExdr.expandString(context);
205             EntityOperator operator = EntityOperator.lookup(operatorName);
206             if (operator == null) {
207                 throw new IllegalArgumentException JavaDoc("Could not find an entity operator for the name: " + operatorName);
208             }
209
210             // If IN operator, see if value is a literal list and split it
211
if (operator == EntityOperator.IN && value instanceof String JavaDoc) {
212                 String JavaDoc delim = null;
213                 if (((String JavaDoc)value).indexOf("|") >= 0) {
214                     delim = "|";
215                 } else if (((String JavaDoc)value).indexOf(",") >= 0) {
216                     delim = ",";
217                 }
218                 if (UtilValidate.isNotEmpty(delim)) {
219                     value = StringUtil.split((String JavaDoc)value, delim);
220                 }
221             }
222             
223             // don't convert the field to the desired type if this is an IN operator and we have a Collection
224
if (!(operator == EntityOperator.IN && value instanceof Collection JavaDoc)) {
225                 // now to a type conversion for the target fieldName
226
value = modelEntity.convertFieldValue(fieldName, value, delegator);
227             }
228             
229             if (Debug.verboseOn()) Debug.logVerbose("Got value for fieldName [" + fieldName + "]: " + value, module);
230
231             if (this.ignoreIfNull && value == null) {
232                 return null;
233             }
234             if (this.ignoreIfEmpty && ObjectType.isEmpty(value)) {
235                 return null;
236             }
237
238             if (operator == EntityOperator.NOT_EQUAL && value != null) {
239                 // since some databases don't consider nulls in != comparisons, explicitly include them
240
// this makes more sense logically, but if anyone ever needs it to not behave this way we should add an "or-null" attribute that is true by default
241
return new EntityExpr(
242                         new EntityExpr(fieldName, (EntityComparisonOperator) operator, value),
243                         EntityOperator.OR,
244                         new EntityExpr(fieldName, EntityOperator.EQUALS, null));
245             } else {
246                 return new EntityExpr(fieldName, (EntityComparisonOperator) operator, value);
247             }
248         }
249     }
250     public static class ConditionList implements Condition {
251         List JavaDoc conditionList = new LinkedList JavaDoc();
252         FlexibleStringExpander combineExdr;
253         
254         public ConditionList(Element JavaDoc conditionListElement) {
255             this.combineExdr = new FlexibleStringExpander(conditionListElement.getAttribute("combine"));
256             
257             List JavaDoc subElements = UtilXml.childElementList(conditionListElement);
258             Iterator JavaDoc subElementIter = subElements.iterator();
259             while (subElementIter.hasNext()) {
260                 Element JavaDoc subElement = (Element JavaDoc) subElementIter.next();
261                 if ("condition-expr".equals(subElement.getNodeName())) {
262                     conditionList.add(new ConditionExpr(subElement));
263                 } else if ("condition-list".equals(subElement.getNodeName())) {
264                     conditionList.add(new ConditionList(subElement));
265                 } else if ("condition-object".equals(subElement.getNodeName())) {
266                     conditionList.add(new ConditionObject(subElement));
267                 } else {
268                     throw new IllegalArgumentException JavaDoc("Invalid element with name [" + subElement.getNodeName() + "] found under a condition-list element.");
269                 }
270             }
271         }
272         
273         public EntityCondition createCondition(Map JavaDoc context, String JavaDoc entityName, GenericDelegator delegator) {
274             if (this.conditionList.size() == 0) {
275                 return null;
276             }
277             if (this.conditionList.size() == 1) {
278                 Condition condition = (Condition) this.conditionList.get(0);
279                 return condition.createCondition(context, entityName, delegator);
280             }
281             
282             List JavaDoc entityConditionList = new LinkedList JavaDoc();
283             Iterator JavaDoc conditionIter = conditionList.iterator();
284             while (conditionIter.hasNext()) {
285                 Condition curCondition = (Condition) conditionIter.next();
286                 EntityCondition econd = curCondition.createCondition(context, entityName, delegator);
287                 if (econd != null) {
288                     entityConditionList.add(econd);
289                 }
290             }
291             
292             String JavaDoc operatorName = combineExdr.expandString(context);
293             EntityOperator operator = EntityOperator.lookup(operatorName);
294             if (operator == null) {
295                 throw new IllegalArgumentException JavaDoc("Could not find an entity operator for the name: " + operatorName);
296             }
297             
298             return new EntityConditionList(entityConditionList, (EntityJoinOperator) operator);
299         }
300     }
301     public static class ConditionObject implements Condition {
302         protected FlexibleMapAccessor fieldNameAcsr;
303         
304         public ConditionObject(Element JavaDoc conditionExprElement) {
305             this.fieldNameAcsr = new FlexibleMapAccessor(conditionExprElement.getAttribute("field-name"));
306             if (this.fieldNameAcsr.isEmpty()) {
307                 // no "field-name"? try "name"
308
this.fieldNameAcsr = new FlexibleMapAccessor(conditionExprElement.getAttribute("name"));
309             }
310         }
311         
312         public EntityCondition createCondition(Map JavaDoc context, String JavaDoc entityName, GenericDelegator delegator) {
313             EntityCondition condition = (EntityCondition) fieldNameAcsr.get(context);
314             return condition;
315         }
316     }
317     
318     public static interface OutputHandler extends Serializable JavaDoc {
319         public void handleOutput(EntityListIterator eli, Map JavaDoc context, FlexibleMapAccessor listAcsr);
320         public void handleOutput(List JavaDoc results, Map JavaDoc context, FlexibleMapAccessor listAcsr);
321     }
322     public static class LimitRange implements OutputHandler {
323         FlexibleStringExpander startExdr;
324         FlexibleStringExpander sizeExdr;
325         
326         public LimitRange(Element JavaDoc limitRangeElement) {
327             this.startExdr = new FlexibleStringExpander(limitRangeElement.getAttribute("start"));
328             this.sizeExdr = new FlexibleStringExpander(limitRangeElement.getAttribute("size"));
329         }
330         
331         int getStart(Map JavaDoc context) {
332             String JavaDoc startStr = this.startExdr.expandString(context);
333             try {
334                 return Integer.parseInt(startStr);
335             } catch (NumberFormatException JavaDoc e) {
336                 String JavaDoc errMsg = "The limit-range start number \"" + startStr + "\" was not valid: " + e.toString();
337                 Debug.logError(e, errMsg, module);
338                 throw new IllegalArgumentException JavaDoc(errMsg);
339             }
340         }
341         
342         int getSize(Map JavaDoc context) {
343             String JavaDoc sizeStr = this.sizeExdr.expandString(context);
344             try {
345                 return Integer.parseInt(sizeStr);
346             } catch (NumberFormatException JavaDoc e) {
347                 String JavaDoc errMsg = "The limit-range size number \"" + sizeStr + "\" was not valid: " + e.toString();
348                 Debug.logError(e, errMsg, module);
349                 throw new IllegalArgumentException JavaDoc(errMsg);
350             }
351         }
352         
353         public void handleOutput(EntityListIterator eli, Map JavaDoc context, FlexibleMapAccessor listAcsr) {
354             int start = getStart(context);
355             int size = getSize(context);
356             try {
357                 listAcsr.put(context, eli.getPartialList(start, size));
358             } catch (GenericEntityException e) {
359                 String JavaDoc errMsg = "Error getting partial list in limit-range with start=" + start + " and size=" + size + ": " + e.toString();
360                 Debug.logError(e, errMsg, module);
361                 throw new IllegalArgumentException JavaDoc(errMsg);
362             }
363         }
364
365         public void handleOutput(List JavaDoc results, Map JavaDoc context, FlexibleMapAccessor listAcsr) {
366             int start = getStart(context);
367             int size = getSize(context);
368             
369             int end = start + size;
370             if (end > results.size()) end = results.size();
371             
372             listAcsr.put(context, results.subList(start, end));
373         }
374     }
375     public static class LimitView implements OutputHandler {
376         FlexibleStringExpander viewIndexExdr;
377         FlexibleStringExpander viewSizeExdr;
378         
379         public LimitView(Element JavaDoc limitViewElement) {
380             this.viewIndexExdr = new FlexibleStringExpander(limitViewElement.getAttribute("view-index"));
381             this.viewSizeExdr = new FlexibleStringExpander(limitViewElement.getAttribute("view-size"));
382         }
383         
384         int getIndex(Map JavaDoc context) {
385             String JavaDoc viewIndexStr = this.viewIndexExdr.expandString(context);
386             try {
387                 return Integer.parseInt(viewIndexStr);
388             } catch (NumberFormatException JavaDoc e) {
389                 String JavaDoc errMsg = "The limit-view view-index number \"" + viewIndexStr + "\" was not valid: " + e.toString();
390                 Debug.logError(e, errMsg, module);
391                 throw new IllegalArgumentException JavaDoc(errMsg);
392             }
393         }
394         
395         int getSize(Map JavaDoc context) {
396             String JavaDoc viewSizeStr = this.viewSizeExdr.expandString(context);
397             try {
398                 return Integer.parseInt(viewSizeStr);
399             } catch (NumberFormatException JavaDoc e) {
400                 String JavaDoc errMsg = "The limit-view view-size number \"" + viewSizeStr + "\" was not valid: " + e.toString();
401                 Debug.logError(e, errMsg, module);
402                 throw new IllegalArgumentException JavaDoc(errMsg);
403             }
404         }
405         
406         public void handleOutput(EntityListIterator eli, Map JavaDoc context, FlexibleMapAccessor listAcsr) {
407             int index = this.getIndex(context);
408             int size = this.getSize(context);
409             
410             try {
411                 listAcsr.put(context, eli.getPartialList(((index - 1) * size) + 1, size));
412             } catch (GenericEntityException e) {
413                 String JavaDoc errMsg = "Error getting partial list in limit-view with index=" + index + " and size=" + size + ": " + e.toString();
414                 Debug.logError(e, errMsg, module);
415                 throw new IllegalArgumentException JavaDoc(errMsg);
416             }
417         }
418
419         public void handleOutput(List JavaDoc results, Map JavaDoc context, FlexibleMapAccessor listAcsr) {
420             int index = this.getIndex(context);
421             int size = this.getSize(context);
422             
423             int begin = index * size;
424             int end = index * size + size;
425             if (end > results.size()) end = results.size();
426             
427             listAcsr.put(context, results.subList(begin, end));
428         }
429     }
430     public static class UseIterator implements OutputHandler {
431         public UseIterator(Element JavaDoc useIteratorElement) {
432             // no parameters, nothing to do
433
}
434         
435         public void handleOutput(EntityListIterator eli, Map JavaDoc context, FlexibleMapAccessor listAcsr) {
436             listAcsr.put(context, eli);
437         }
438
439         public void handleOutput(List JavaDoc results, Map JavaDoc context, FlexibleMapAccessor listAcsr) {
440             throw new IllegalArgumentException JavaDoc("Cannot handle output with use-iterator when the query is cached, or the result in general is not an EntityListIterator");
441         }
442     }
443     public static class GetAll implements OutputHandler {
444         public GetAll() {
445             // no parameters, nothing to do
446
}
447         
448         public void handleOutput(EntityListIterator eli, Map JavaDoc context, FlexibleMapAccessor listAcsr) {
449             try {
450                 listAcsr.put(context, eli.getCompleteList());
451                 eli.close();
452             } catch (GenericEntityException e) {
453                 String JavaDoc errorMsg = "Error getting list from EntityListIterator: " + e.toString();
454                 Debug.logError(e, errorMsg, module);
455                 throw new IllegalArgumentException JavaDoc(errorMsg);
456             }
457         }
458
459         public void handleOutput(List JavaDoc results, Map JavaDoc context, FlexibleMapAccessor listAcsr) {
460             listAcsr.put(context, results);
461         }
462     }
463 }
464
465
Popular Tags