001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.entity.util;
019:
020: import java.sql.Timestamp;
021: import java.util.Collection;
022: import java.util.Collections;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026: import java.util.Set;
027:
028: import javolution.util.FastList;
029: import javolution.util.FastMap;
030: import javolution.util.FastSet;
031:
032: import org.ofbiz.base.util.Debug;
033: import org.ofbiz.base.util.UtilDateTime;
034: import org.ofbiz.base.util.UtilMisc;
035: import org.ofbiz.entity.GenericDelegator;
036: import org.ofbiz.entity.GenericEntityException;
037: import org.ofbiz.entity.GenericValue;
038: import org.ofbiz.entity.condition.EntityCondition;
039: import org.ofbiz.entity.condition.EntityConditionList;
040: import org.ofbiz.entity.condition.EntityDateFilterCondition;
041: import org.ofbiz.entity.condition.EntityFieldMap;
042: import org.ofbiz.entity.condition.EntityOperator;
043: import org.ofbiz.entity.condition.OrderByList;
044: import org.ofbiz.entity.model.ModelField;
045:
046: /**
047: * Helper methods when dealing with Entities, especially ones that follow certain conventions
048: */
049: public class EntityUtil {
050:
051: public static final String module = EntityUtil.class.getName();
052:
053: public static GenericValue getFirst(List values) {
054: if ((values != null) && (values.size() > 0)) {
055: return (GenericValue) values.get(0);
056: } else {
057: return null;
058: }
059: }
060:
061: public static GenericValue getOnly(List values) {
062: if (values != null) {
063: if (values.size() <= 0) {
064: return null;
065: }
066: if (values.size() == 1) {
067: return (GenericValue) values.get(0);
068: } else {
069: throw new IllegalArgumentException(
070: "Passed List had more than one value.");
071: }
072: } else {
073: return null;
074: }
075: }
076:
077: public static EntityCondition getFilterByDateExpr() {
078: return new EntityDateFilterCondition("fromDate", "thruDate");
079: }
080:
081: public static EntityCondition getFilterByDateExpr(
082: String fromDateName, String thruDateName) {
083: return new EntityDateFilterCondition(fromDateName, thruDateName);
084: }
085:
086: public static EntityCondition getFilterByDateExpr(
087: java.util.Date moment) {
088: return EntityDateFilterCondition.makeCondition(
089: new java.sql.Timestamp(moment.getTime()), "fromDate",
090: "thruDate");
091: }
092:
093: public static EntityCondition getFilterByDateExpr(
094: java.sql.Timestamp moment) {
095: return EntityDateFilterCondition.makeCondition(moment,
096: "fromDate", "thruDate");
097: }
098:
099: public static EntityCondition getFilterByDateExpr(
100: java.sql.Timestamp moment, String fromDateName,
101: String thruDateName) {
102: return EntityDateFilterCondition.makeCondition(moment,
103: fromDateName, thruDateName);
104: }
105:
106: /**
107: *returns the values that are currently active.
108: *
109: *@param datedValues GenericValue's that have "fromDate" and "thruDate" fields
110: *@return List of GenericValue's that are currently active
111: */
112: public static List filterByDate(List datedValues) {
113: return filterByDate(datedValues, UtilDateTime.nowTimestamp(),
114: null, null, true);
115: }
116:
117: /**
118: *returns the values that are currently active.
119: *
120: *@param datedValues GenericValue's that have "fromDate" and "thruDate" fields
121: *@param allAreSame Specifies whether all values in the List are of the same entity; this can help speed things up a fair amount since we only have to see if the from and thru date fields are valid once
122: *@return List of GenericValue's that are currently active
123: */
124: public static List filterByDate(List datedValues, boolean allAreSame) {
125: return filterByDate(datedValues, UtilDateTime.nowTimestamp(),
126: null, null, allAreSame);
127: }
128:
129: /**
130: *returns the values that are active at the moment.
131: *
132: *@param datedValues GenericValue's that have "fromDate" and "thruDate" fields
133: *@param moment the moment in question
134: *@return List of GenericValue's that are active at the moment
135: */
136: public static List filterByDate(List datedValues,
137: java.util.Date moment) {
138: return filterByDate(datedValues, new java.sql.Timestamp(moment
139: .getTime()), null, null, true);
140: }
141:
142: /**
143: *returns the values that are active at the moment.
144: *
145: *@param datedValues GenericValue's that have "fromDate" and "thruDate" fields
146: *@param moment the moment in question
147: *@return List of GenericValue's that are active at the moment
148: */
149: public static List filterByDate(List datedValues,
150: java.sql.Timestamp moment) {
151: return filterByDate(datedValues, moment, null, null, true);
152: }
153:
154: /**
155: *returns the values that are active at the moment.
156: *
157: *@param datedValues GenericValue's that have "fromDate" and "thruDate" fields
158: *@param moment the moment in question
159: *@param allAreSame Specifies whether all values in the List are of the same entity; this can help speed things up a fair amount since we only have to see if the from and thru date fields are valid once
160: *@return List of GenericValue's that are active at the moment
161: */
162: public static List filterByDate(List datedValues,
163: java.sql.Timestamp moment, String fromDateName,
164: String thruDateName, boolean allAreSame) {
165: if (datedValues == null)
166: return null;
167: if (moment == null)
168: return datedValues;
169: if (fromDateName == null)
170: fromDateName = "fromDate";
171: if (thruDateName == null)
172: thruDateName = "thruDate";
173:
174: List result = FastList.newInstance();
175: Iterator iter = datedValues.iterator();
176:
177: if (allAreSame) {
178: ModelField fromDateField = null;
179: ModelField thruDateField = null;
180:
181: if (iter.hasNext()) {
182: GenericValue datedValue = (GenericValue) iter.next();
183:
184: fromDateField = datedValue.getModelEntity().getField(
185: fromDateName);
186: if (fromDateField == null)
187: throw new IllegalArgumentException("\""
188: + fromDateName + "\" is not a field of "
189: + datedValue.getEntityName());
190: thruDateField = datedValue.getModelEntity().getField(
191: thruDateName);
192: if (thruDateField == null)
193: throw new IllegalArgumentException("\""
194: + thruDateName + "\" is not a field of "
195: + datedValue.getEntityName());
196:
197: java.sql.Timestamp fromDate = (java.sql.Timestamp) datedValue
198: .dangerousGetNoCheckButFast(fromDateField);
199: java.sql.Timestamp thruDate = (java.sql.Timestamp) datedValue
200: .dangerousGetNoCheckButFast(thruDateField);
201:
202: if ((thruDate == null || thruDate.after(moment))
203: && (fromDate == null || fromDate.before(moment) || fromDate
204: .equals(moment))) {
205: result.add(datedValue);
206: }// else not active at moment
207: }
208: while (iter.hasNext()) {
209: GenericValue datedValue = (GenericValue) iter.next();
210: java.sql.Timestamp fromDate = (java.sql.Timestamp) datedValue
211: .dangerousGetNoCheckButFast(fromDateField);
212: java.sql.Timestamp thruDate = (java.sql.Timestamp) datedValue
213: .dangerousGetNoCheckButFast(thruDateField);
214:
215: if ((thruDate == null || thruDate.after(moment))
216: && (fromDate == null || fromDate.before(moment) || fromDate
217: .equals(moment))) {
218: result.add(datedValue);
219: }// else not active at moment
220: }
221: } else {
222: // if not all values are known to be of the same entity, must check each one...
223: while (iter.hasNext()) {
224: GenericValue datedValue = (GenericValue) iter.next();
225: java.sql.Timestamp fromDate = datedValue
226: .getTimestamp(fromDateName);
227: java.sql.Timestamp thruDate = datedValue
228: .getTimestamp(thruDateName);
229:
230: if ((thruDate == null || thruDate.after(moment))
231: && (fromDate == null || fromDate.before(moment) || fromDate
232: .equals(moment))) {
233: result.add(datedValue);
234: }// else not active at moment
235: }
236: }
237:
238: return result;
239: }
240:
241: public static boolean isValueActive(GenericValue datedValue,
242: java.sql.Timestamp moment) {
243: return isValueActive(datedValue, moment, "fromDate", "thruDate");
244: }
245:
246: public static boolean isValueActive(GenericValue datedValue,
247: java.sql.Timestamp moment, String fromDateName,
248: String thruDateName) {
249: java.sql.Timestamp fromDate = datedValue
250: .getTimestamp(fromDateName);
251: java.sql.Timestamp thruDate = datedValue
252: .getTimestamp(thruDateName);
253:
254: if ((thruDate == null || thruDate.after(moment))
255: && (fromDate == null || fromDate.before(moment) || fromDate
256: .equals(moment))) {
257: return true;
258: } else {
259: // else not active at moment
260: return false;
261: }
262: }
263:
264: /**
265: *returns the values that match the values in fields
266: *
267: *@param values List of GenericValues
268: *@param fields the field-name/value pairs that must match
269: *@return List of GenericValue's that match the values in fields
270: */
271: public static List filterByAnd(List values, Map fields) {
272: if (values == null)
273: return null;
274:
275: List result = null;
276: if (fields == null || fields.size() == 0) {
277: result = FastList.newInstance();
278: result.addAll(values);
279: } else {
280: result = FastList.newInstance();
281: Iterator iter = values.iterator();
282: while (iter.hasNext()) {
283: GenericValue value = (GenericValue) iter.next();
284: if (value.matchesFields(fields)) {
285: result.add(value);
286: }// else did not match
287: }
288: }
289: return result;
290: }
291:
292: /**
293: *returns the values that match all of the exprs in list
294: *
295: *@param values List of GenericValues
296: *@param exprs the expressions that must validate to true
297: *@return List of GenericValue's that match the values in fields
298: */
299: public static List filterByAnd(List values, List exprs) {
300: if (values == null)
301: return null;
302: if (exprs == null || exprs.size() == 0) {
303: // no constraints... oh well
304: return values;
305: }
306:
307: List result = FastList.newInstance();
308: Iterator iter = values.iterator();
309: while (iter.hasNext()) {
310: GenericValue value = (GenericValue) iter.next();
311: Iterator exprIter = exprs.iterator();
312: boolean include = true;
313:
314: while (exprIter.hasNext()) {
315: EntityCondition condition = (EntityCondition) exprIter
316: .next();
317: include = condition.entityMatches(value);
318: if (!include)
319: break;
320: }
321: if (include) {
322: result.add(value);
323: }
324: }
325: return result;
326: }
327:
328: /**
329: *returns the values that match any of the exprs in list
330: *
331: *@param values List of GenericValues
332: *@param exprs the expressions that must validate to true
333: *@return List of GenericValue's that match the values in fields
334: */
335: public static List filterByOr(List values, List exprs) {
336: if (values == null)
337: return null;
338: if (exprs == null || exprs.size() == 0) {
339: return values;
340: }
341:
342: List result = FastList.newInstance();
343: Iterator iter = values.iterator();
344:
345: while (iter.hasNext()) {
346: GenericValue value = (GenericValue) iter.next();
347: boolean include = false;
348:
349: Iterator exprIter = exprs.iterator();
350: while (exprIter.hasNext()) {
351: EntityCondition condition = (EntityCondition) exprIter
352: .next();
353: include = condition.entityMatches(value);
354: if (include)
355: break;
356: }
357: if (include) {
358: result.add(value);
359: }
360: }
361: return result;
362: }
363:
364: /**
365: *returns the values in the order specified
366: *
367: *@param values List of GenericValues
368: *@param orderBy The fields of the named entity to order the query by;
369: * optionally add a " ASC" for ascending or " DESC" for descending
370: *@return List of GenericValue's in the proper order
371: */
372: public static List orderBy(Collection values, List orderBy) {
373: if (values == null)
374: return null;
375: if (values.size() == 0)
376: return FastList.newInstance();
377: if (orderBy == null || orderBy.size() == 0) {
378: List newList = FastList.newInstance();
379: newList.addAll(values);
380: return newList;
381: }
382:
383: List result = FastList.newInstance();
384: result.addAll(values);
385: if (Debug.verboseOn())
386: Debug.logVerbose("Sorting " + values.size()
387: + " values, orderBy=" + orderBy.toString(), module);
388: Collections.sort(result, new OrderByList(orderBy));
389: return result;
390: }
391:
392: public static List getRelated(String relationName, List values)
393: throws GenericEntityException {
394: if (values == null)
395: return null;
396:
397: List result = FastList.newInstance();
398: Iterator iter = values.iterator();
399: while (iter.hasNext()) {
400: result.addAll(((GenericValue) iter.next())
401: .getRelated(relationName));
402: }
403: return result;
404: }
405:
406: public static List getRelatedCache(String relationName, List values)
407: throws GenericEntityException {
408: if (values == null)
409: return null;
410:
411: List result = FastList.newInstance();
412: Iterator iter = values.iterator();
413: while (iter.hasNext()) {
414: result.addAll(((GenericValue) iter.next())
415: .getRelatedCache(relationName));
416: }
417: return result;
418: }
419:
420: public static List getRelatedByAnd(String relationName, Map fields,
421: List values) throws GenericEntityException {
422: if (values == null)
423: return null;
424:
425: List result = FastList.newInstance();
426: Iterator iter = values.iterator();
427: while (iter.hasNext()) {
428: result.addAll(((GenericValue) iter.next()).getRelatedByAnd(
429: relationName, fields));
430: }
431: return result;
432: }
433:
434: public static List filterByCondition(List values,
435: EntityCondition condition) {
436: if (values == null)
437: return null;
438:
439: List result = FastList.newInstance();
440: Iterator iter = values.iterator();
441: while (iter.hasNext()) {
442: GenericValue value = (GenericValue) iter.next();
443: if (condition.entityMatches(value)) {
444: result.add(value);
445: }
446: }
447: return result;
448: }
449:
450: public static List filterOutByCondition(List values,
451: EntityCondition condition) {
452: if (values == null)
453: return null;
454:
455: List result = FastList.newInstance();
456: Iterator iter = values.iterator();
457: while (iter.hasNext()) {
458: GenericValue value = (GenericValue) iter.next();
459: if (!condition.entityMatches(value)) {
460: result.add(value);
461: }
462: }
463: return result;
464: }
465:
466: public static List findDatedInclusionEntity(
467: GenericDelegator delegator, String entityName, Map search)
468: throws GenericEntityException {
469: return findDatedInclusionEntity(delegator, entityName, search,
470: UtilDateTime.nowTimestamp());
471: }
472:
473: public static List findDatedInclusionEntity(
474: GenericDelegator delegator, String entityName, Map search,
475: Timestamp now) throws GenericEntityException {
476: EntityCondition searchCondition = new EntityConditionList(
477: UtilMisc.toList(new EntityFieldMap(search,
478: EntityOperator.AND), EntityUtil
479: .getFilterByDateExpr(now)), EntityOperator.AND);
480: return delegator.findByCondition(entityName, searchCondition,
481: null, UtilMisc.toList("-fromDate"));
482: }
483:
484: public static GenericValue newDatedInclusionEntity(
485: GenericDelegator delegator, String entityName, Map search)
486: throws GenericEntityException {
487: return newDatedInclusionEntity(delegator, entityName, search,
488: UtilDateTime.nowTimestamp());
489: }
490:
491: public static GenericValue newDatedInclusionEntity(
492: GenericDelegator delegator, String entityName, Map search,
493: Timestamp now) throws GenericEntityException {
494: List entities = findDatedInclusionEntity(delegator, entityName,
495: search, now);
496: if (entities != null && entities.size() > 0) {
497: search = null;
498: for (int i = 0; i < entities.size(); i++) {
499: GenericValue entity = (GenericValue) entities.get(i);
500: if (now.equals(entity.get("fromDate"))) {
501: search = FastMap.newInstance();
502: search.putAll(entity.getPrimaryKey());
503: entity.remove("thruDate");
504: } else {
505: entity.set("thruDate", now);
506: }
507: entity.store();
508: }
509: if (search == null) {
510: search = FastMap.newInstance();
511: search.putAll(EntityUtil.getFirst(entities));
512: }
513: } else {
514: /* why is this being done? leaving out for now...
515: search = new HashMap(search);
516: */
517: }
518: if (now.equals(search.get("fromDate"))) {
519: return EntityUtil.getOnly(delegator.findByAnd(entityName,
520: search));
521: } else {
522: search.put("fromDate", now);
523: search.remove("thruDate");
524: return delegator.makeValue(entityName, search);
525: }
526: }
527:
528: public static void delDatedInclusionEntity(
529: GenericDelegator delegator, String entityName, Map search)
530: throws GenericEntityException {
531: delDatedInclusionEntity(delegator, entityName, search,
532: UtilDateTime.nowTimestamp());
533: }
534:
535: public static void delDatedInclusionEntity(
536: GenericDelegator delegator, String entityName, Map search,
537: Timestamp now) throws GenericEntityException {
538: List entities = findDatedInclusionEntity(delegator, entityName,
539: search, now);
540: for (int i = 0; entities != null && i < entities.size(); i++) {
541: GenericValue entity = (GenericValue) entities.get(i);
542: entity.set("thruDate", now);
543: entity.store();
544: }
545: }
546:
547: public static List getFieldListFromEntityList(
548: List genericValueList, String fieldName, boolean distinct) {
549: if (genericValueList == null || fieldName == null) {
550: return null;
551: }
552: List fieldList = FastList.newInstance();
553: Set distinctSet = null;
554: if (distinct) {
555: distinctSet = FastSet.newInstance();
556: }
557:
558: Iterator genericValueIter = genericValueList.iterator();
559: while (genericValueIter.hasNext()) {
560: GenericValue value = (GenericValue) genericValueIter.next();
561: Object fieldValue = value.get(fieldName);
562: if (fieldValue != null) {
563: if (distinct) {
564: if (!distinctSet.contains(fieldValue)) {
565: fieldList.add(fieldValue);
566: distinctSet.add(fieldValue);
567: }
568: } else {
569: fieldList.add(fieldValue);
570: }
571: }
572: }
573:
574: return fieldList;
575: }
576:
577: public static List getFieldListFromEntityListIterator(
578: EntityListIterator genericValueEli, String fieldName,
579: boolean distinct) {
580: if (genericValueEli == null || fieldName == null) {
581: return null;
582: }
583: List fieldList = FastList.newInstance();
584: Set distinctSet = null;
585: if (distinct) {
586: distinctSet = FastSet.newInstance();
587: }
588:
589: GenericValue value = null;
590: while ((value = (GenericValue) genericValueEli.next()) != null) {
591: Object fieldValue = value.get(fieldName);
592: if (fieldValue != null) {
593: if (distinct) {
594: if (!distinctSet.contains(fieldValue)) {
595: fieldList.add(fieldValue);
596: distinctSet.add(fieldValue);
597: }
598: } else {
599: fieldList.add(fieldValue);
600: }
601: }
602: }
603:
604: return fieldList;
605: }
606: }
|