1 24 package org.ofbiz.entity.finder; 25 26 import java.io.Serializable ; 27 import java.sql.ResultSet ; 28 import java.util.Iterator ; 29 import java.util.LinkedList ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.Set ; 33 34 import org.ofbiz.base.util.Debug; 35 import org.ofbiz.base.util.GeneralException; 36 import org.ofbiz.base.util.UtilXml; 37 import org.ofbiz.base.util.collections.FlexibleMapAccessor; 38 import org.ofbiz.base.util.string.FlexibleStringExpander; 39 import org.ofbiz.base.util.UtilMisc; 40 import org.ofbiz.entity.GenericDelegator; 41 import org.ofbiz.entity.GenericEntityException; 42 import org.ofbiz.entity.condition.EntityCondition; 43 import org.ofbiz.entity.condition.EntityConditionList; 44 import org.ofbiz.entity.condition.EntityJoinOperator; 45 import org.ofbiz.entity.finder.EntityFinderUtil.Condition; 46 import org.ofbiz.entity.finder.EntityFinderUtil.ConditionExpr; 47 import org.ofbiz.entity.finder.EntityFinderUtil.ConditionList; 48 import org.ofbiz.entity.finder.EntityFinderUtil.ConditionObject; 49 import org.ofbiz.entity.finder.EntityFinderUtil.GetAll; 50 import org.ofbiz.entity.finder.EntityFinderUtil.LimitRange; 51 import org.ofbiz.entity.finder.EntityFinderUtil.LimitView; 52 import org.ofbiz.entity.finder.EntityFinderUtil.OutputHandler; 53 import org.ofbiz.entity.finder.EntityFinderUtil.UseIterator; 54 import org.ofbiz.entity.transaction.TransactionUtil; 55 import org.ofbiz.entity.util.EntityFindOptions; 56 import org.ofbiz.entity.util.EntityListIterator; 57 import org.ofbiz.entity.util.EntityUtil; 58 import org.w3c.dom.Element ; 59 60 67 public class ByConditionFinder implements Serializable { 68 public static final String module = ByConditionFinder.class.getName(); 69 70 protected FlexibleStringExpander entityNameExdr; 71 protected FlexibleStringExpander useCacheStrExdr; 72 protected FlexibleStringExpander filterByDateStrExdr; 73 protected FlexibleStringExpander distinctStrExdr; 74 protected FlexibleStringExpander delegatorNameExdr; 75 protected FlexibleMapAccessor listAcsr; 76 protected FlexibleStringExpander resultSetTypeExdr; 77 78 protected Condition whereCondition; 79 protected Condition havingCondition; 80 protected List selectFieldExpanderList; 81 protected List orderByExpanderList; 82 protected OutputHandler outputHandler; 83 84 public ByConditionFinder(Element element) { 85 this.entityNameExdr = new FlexibleStringExpander(element.getAttribute("entity-name")); 86 this.useCacheStrExdr = new FlexibleStringExpander(element.getAttribute("use-cache")); 87 this.filterByDateStrExdr = new FlexibleStringExpander(element.getAttribute("filter-by-date")); 88 this.distinctStrExdr = new FlexibleStringExpander(element.getAttribute("distinct")); 89 this.delegatorNameExdr = new FlexibleStringExpander(element.getAttribute("delegator-name")); 90 this.listAcsr = new FlexibleMapAccessor(element.getAttribute("list-name")); 91 this.resultSetTypeExdr = new FlexibleStringExpander(element.getAttribute("result-set-type")); 92 93 Element conditionExprElement = UtilXml.firstChildElement(element, "condition-expr"); 96 Element conditionListElement = UtilXml.firstChildElement(element, "condition-list"); 97 Element conditionObjectElement = UtilXml.firstChildElement(element, "condition-object"); 98 if (conditionExprElement != null) { 99 this.whereCondition = new ConditionExpr(conditionExprElement); 100 } else if (conditionListElement != null) { 101 this.whereCondition = new ConditionList(conditionListElement); 102 } else if (conditionObjectElement != null) { 103 this.whereCondition = new ConditionObject(conditionObjectElement); 104 } 105 106 Element havingConditionListElement = UtilXml.firstChildElement(element, "having-condition-list"); 108 if (havingConditionListElement != null) { 109 this.havingCondition = new ConditionList(havingConditionListElement); 110 } 111 112 selectFieldExpanderList = EntityFinderUtil.makeSelectFieldExpanderList(element); 114 115 List orderByElementList = UtilXml.childElementList(element, "order-by"); 117 if (orderByElementList.size() > 0) { 118 orderByExpanderList = new LinkedList (); 119 Iterator orderByElementIter = orderByElementList.iterator(); 120 while (orderByElementIter.hasNext()) { 121 Element orderByElement = (Element ) orderByElementIter.next(); 122 orderByExpanderList.add(new FlexibleStringExpander(orderByElement.getAttribute("field-name"))); 123 } 124 } 125 126 Element limitRangeElement = UtilXml.firstChildElement(element, "limit-range"); 128 Element limitViewElement = UtilXml.firstChildElement(element, "limit-view"); 129 Element useIteratorElement = UtilXml.firstChildElement(element, "use-iterator"); 130 if ((limitRangeElement != null && limitViewElement != null) || (limitRangeElement != null && useIteratorElement != null) || (limitViewElement != null && useIteratorElement != null)) { 131 throw new IllegalArgumentException ("In entity find by condition element, cannot have more than one of the following: limit-range, limit-view, and use-iterator"); 132 } 133 if (limitRangeElement != null) { 134 outputHandler = new LimitRange(limitRangeElement); 135 } else if (limitViewElement != null) { 136 outputHandler = new LimitView(limitViewElement); 137 } else if (useIteratorElement != null) { 138 outputHandler = new UseIterator(useIteratorElement); 139 } else { 140 outputHandler = new GetAll(); 142 } 143 } 144 145 public void runFind(Map context, GenericDelegator delegator) throws GeneralException { 146 String entityName = this.entityNameExdr.expandString(context); 147 String useCacheStr = this.useCacheStrExdr.expandString(context); 148 String filterByDateStr = this.filterByDateStrExdr.expandString(context); 149 String distinctStr = this.distinctStrExdr.expandString(context); 150 String delegatorName = this.delegatorNameExdr.expandString(context); 151 String resultSetTypeString = this.resultSetTypeExdr.expandString(context); 152 153 boolean useCache = "true".equals(useCacheStr); 154 boolean filterByDate = "true".equals(filterByDateStr); 155 boolean distinct = "true".equals(distinctStr); 156 int resultSetType = ResultSet.TYPE_SCROLL_INSENSITIVE; 157 if ("forward".equals(resultSetTypeString)) 158 resultSetType = ResultSet.TYPE_FORWARD_ONLY; 159 160 if (delegatorName != null && delegatorName.length() > 0) { 161 delegator = GenericDelegator.getGenericDelegator(delegatorName); 162 } 163 164 EntityCondition whereEntityCondition = null; 166 if (this.whereCondition != null) { 167 whereEntityCondition = this.whereCondition.createCondition(context, entityName, delegator); 168 } 169 170 EntityCondition havingEntityCondition = null; 172 if (this.havingCondition != null) { 173 havingEntityCondition = this.havingCondition.createCondition(context, entityName, delegator); 174 } 175 176 if (useCache) { 177 if (outputHandler instanceof UseIterator) { 179 throw new IllegalArgumentException ("In find entity by condition cannot have use-cache set to true and select use-iterator for the output type."); 180 } 181 if (distinct) { 182 throw new IllegalArgumentException ("In find entity by condition cannot have use-cache set to true and set distinct to true."); 183 } 184 if (havingEntityCondition != null) { 185 throw new IllegalArgumentException ("In find entity by condition cannot have use-cache set to true and specify a having-condition-list (can only use a where condition with condition-expr or condition-list)."); 186 } 187 } 188 189 Set fieldsToSelect = EntityFinderUtil.makeFieldsToSelect(selectFieldExpanderList, context); 191 192 if (fieldsToSelect != null && useCache) { 194 throw new IllegalArgumentException ("Error in entity query by condition definition, cannot specify select-field elements when use-cache is set to true"); 195 } 196 197 List orderByFields = EntityFinderUtil.makeOrderByFieldList(this.orderByExpanderList, context); 199 200 try { 201 if (filterByDate) { 203 EntityCondition filterByDateCondition = EntityUtil.getFilterByDateExpr(); 204 if (whereEntityCondition != null) { 205 whereEntityCondition = new EntityConditionList(UtilMisc.toList(whereEntityCondition, filterByDateCondition), EntityJoinOperator.AND); 206 } else { 207 whereEntityCondition = filterByDateCondition; 208 } 209 } 210 211 if (useCache) { 212 List results = delegator.findByConditionCache(entityName, whereEntityCondition, fieldsToSelect, orderByFields); 213 this.outputHandler.handleOutput(results, context, listAcsr); 214 } else { 215 boolean useTransaction = true; 216 if (this.outputHandler instanceof UseIterator && !TransactionUtil.isTransactionInPlace()) { 217 Exception newE = new Exception ("Stack Trace"); 218 Debug.logError(newE, "ERROR: Cannot do a by condition find that returns an EntityListIterator with no transaction in place. Wrap this call in a transaction.", module); 219 useTransaction = false; 220 } 221 222 EntityFindOptions options = new EntityFindOptions(); 223 options.setDistinct(distinct); 224 options.setResultSetType(resultSetType); 225 boolean beganTransaction = false; 226 try { 227 if (useTransaction) { 228 beganTransaction = TransactionUtil.begin(); 229 } 230 231 EntityListIterator eli = delegator.findListIteratorByCondition(entityName, whereEntityCondition, havingEntityCondition, fieldsToSelect, orderByFields, options); 232 this.outputHandler.handleOutput(eli, context, listAcsr); 233 } catch (GenericEntityException e) { 234 String errMsg = "Failure in by condition find operation, rolling back transaction"; 235 Debug.logError(e, errMsg, module); 236 try { 237 TransactionUtil.rollback(beganTransaction, errMsg, e); 239 } catch (GenericEntityException e2) { 240 Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), module); 241 } 242 throw e; 244 } finally { 245 TransactionUtil.commit(beganTransaction); 247 } 248 } 249 } catch (GenericEntityException e) { 250 String errMsg = "Error doing find by condition: " + e.toString(); 251 Debug.logError(e, module); 252 throw new GeneralException(errMsg, e); 253 } 254 } 255 } 256 257 | Popular Tags |