1 24 package org.ofbiz.entity.finder; 25 26 import java.io.Serializable ; 27 import java.util.Collection ; 28 import java.util.HashMap ; 29 import java.util.HashSet ; 30 import java.util.Iterator ; 31 import java.util.LinkedList ; 32 import java.util.List ; 33 import java.util.Map ; 34 import java.util.Set ; 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 ; 55 56 63 public class EntityFinderUtil { 64 65 public static final String module = EntityFinderUtil.class.getName(); 66 67 public static Map makeFieldMap(Element element) { 68 Map fieldMap = null; 69 List fieldMapElementList = UtilXml.childElementList(element, "field-map"); 70 if (fieldMapElementList.size() > 0) { 71 fieldMap = new HashMap (); 72 Iterator fieldMapElementIter = fieldMapElementList.iterator(); 73 while (fieldMapElementIter.hasNext()) { 74 Element fieldMapElement = (Element ) fieldMapElementIter.next(); 75 String fieldName = fieldMapElement.getAttribute("field-name"); 77 String envName = fieldMapElement.getAttribute("env-name"); 78 String value = fieldMapElement.getAttribute("value"); 79 if (UtilValidate.isEmpty(fieldName)) { 80 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 if (UtilValidate.isNotEmpty(envName)) { 88 fieldMap.put(new FlexibleMapAccessor(fieldName), new FlexibleMapAccessor(envName)); 89 } else { 90 fieldMap.put(new FlexibleMapAccessor(fieldName), new FlexibleMapAccessor(fieldName)); 92 } 93 } 94 } 95 } 96 } 97 return fieldMap; 98 } 99 100 public static void expandFieldMapToContext(Map fieldMap, Map context, Map outContext) { 101 if (fieldMap != null) { 103 Iterator fieldMapEntryIter = fieldMap.entrySet().iterator(); 104 while (fieldMapEntryIter.hasNext()) { 105 Map.Entry entry = (Map.Entry ) fieldMapEntryIter.next(); 106 FlexibleMapAccessor serviceContextFieldAcsr = (FlexibleMapAccessor) entry.getKey(); 107 Object 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 } 117 } 118 } 119 } 120 121 public static List makeSelectFieldExpanderList(Element element) { 122 List selectFieldExpanderList = null; 123 List selectFieldElementList = UtilXml.childElementList(element, "select-field"); 124 if (selectFieldElementList.size() > 0) { 125 selectFieldExpanderList = new LinkedList (); 126 Iterator selectFieldElementIter = selectFieldElementList.iterator(); 127 while (selectFieldElementIter.hasNext()) { 128 Element selectFieldElement = (Element ) selectFieldElementIter.next(); 129 selectFieldExpanderList.add(new FlexibleStringExpander(selectFieldElement.getAttribute("field-name"))); 130 } 131 } 132 return selectFieldExpanderList; 133 } 134 135 public static Set makeFieldsToSelect(List selectFieldExpanderList, Map context) { 136 Set fieldsToSelect = null; 137 if (selectFieldExpanderList != null && selectFieldExpanderList.size() > 0) { 138 fieldsToSelect = new HashSet (); 139 Iterator 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 makeOrderByFieldList(List orderByExpanderList, Map context) { 149 List orderByFields = null; 150 if (orderByExpanderList != null && orderByExpanderList.size() > 0) { 151 orderByFields = new LinkedList (); 152 Iterator 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 { 162 public EntityCondition createCondition(Map context, String 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 conditionExprElement) { 173 this.fieldNameExdr = new FlexibleStringExpander(conditionExprElement.getAttribute("field-name")); 174 if (this.fieldNameExdr.isEmpty()) { 175 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 context, String entityName, GenericDelegator delegator) { 187 ModelEntity modelEntity = delegator.getModelEntity(entityName); 188 if (modelEntity == null) { 189 throw new IllegalArgumentException ("Error in Entity Find: could not find entity with name [" + entityName + "]"); 190 } 191 192 String fieldName = fieldNameExdr.expandString(context); 193 194 Object value = null; 195 if (envNameAcsr != null) { 197 value = envNameAcsr.get(context); 198 } 199 if (value == null && valueExdr != null) { 201 value = valueExdr.expandString(context); 202 } 203 204 String operatorName = operatorExdr.expandString(context); 205 EntityOperator operator = EntityOperator.lookup(operatorName); 206 if (operator == null) { 207 throw new IllegalArgumentException ("Could not find an entity operator for the name: " + operatorName); 208 } 209 210 if (operator == EntityOperator.IN && value instanceof String ) { 212 String delim = null; 213 if (((String )value).indexOf("|") >= 0) { 214 delim = "|"; 215 } else if (((String )value).indexOf(",") >= 0) { 216 delim = ","; 217 } 218 if (UtilValidate.isNotEmpty(delim)) { 219 value = StringUtil.split((String )value, delim); 220 } 221 } 222 223 if (!(operator == EntityOperator.IN && value instanceof Collection )) { 225 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 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 conditionList = new LinkedList (); 252 FlexibleStringExpander combineExdr; 253 254 public ConditionList(Element conditionListElement) { 255 this.combineExdr = new FlexibleStringExpander(conditionListElement.getAttribute("combine")); 256 257 List subElements = UtilXml.childElementList(conditionListElement); 258 Iterator subElementIter = subElements.iterator(); 259 while (subElementIter.hasNext()) { 260 Element subElement = (Element ) 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 ("Invalid element with name [" + subElement.getNodeName() + "] found under a condition-list element."); 269 } 270 } 271 } 272 273 public EntityCondition createCondition(Map context, String 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 entityConditionList = new LinkedList (); 283 Iterator 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 operatorName = combineExdr.expandString(context); 293 EntityOperator operator = EntityOperator.lookup(operatorName); 294 if (operator == null) { 295 throw new IllegalArgumentException ("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 conditionExprElement) { 305 this.fieldNameAcsr = new FlexibleMapAccessor(conditionExprElement.getAttribute("field-name")); 306 if (this.fieldNameAcsr.isEmpty()) { 307 this.fieldNameAcsr = new FlexibleMapAccessor(conditionExprElement.getAttribute("name")); 309 } 310 } 311 312 public EntityCondition createCondition(Map context, String entityName, GenericDelegator delegator) { 313 EntityCondition condition = (EntityCondition) fieldNameAcsr.get(context); 314 return condition; 315 } 316 } 317 318 public static interface OutputHandler extends Serializable { 319 public void handleOutput(EntityListIterator eli, Map context, FlexibleMapAccessor listAcsr); 320 public void handleOutput(List results, Map context, FlexibleMapAccessor listAcsr); 321 } 322 public static class LimitRange implements OutputHandler { 323 FlexibleStringExpander startExdr; 324 FlexibleStringExpander sizeExdr; 325 326 public LimitRange(Element limitRangeElement) { 327 this.startExdr = new FlexibleStringExpander(limitRangeElement.getAttribute("start")); 328 this.sizeExdr = new FlexibleStringExpander(limitRangeElement.getAttribute("size")); 329 } 330 331 int getStart(Map context) { 332 String startStr = this.startExdr.expandString(context); 333 try { 334 return Integer.parseInt(startStr); 335 } catch (NumberFormatException e) { 336 String errMsg = "The limit-range start number \"" + startStr + "\" was not valid: " + e.toString(); 337 Debug.logError(e, errMsg, module); 338 throw new IllegalArgumentException (errMsg); 339 } 340 } 341 342 int getSize(Map context) { 343 String sizeStr = this.sizeExdr.expandString(context); 344 try { 345 return Integer.parseInt(sizeStr); 346 } catch (NumberFormatException e) { 347 String errMsg = "The limit-range size number \"" + sizeStr + "\" was not valid: " + e.toString(); 348 Debug.logError(e, errMsg, module); 349 throw new IllegalArgumentException (errMsg); 350 } 351 } 352 353 public void handleOutput(EntityListIterator eli, Map 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 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 (errMsg); 362 } 363 } 364 365 public void handleOutput(List results, Map 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 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 context) { 385 String viewIndexStr = this.viewIndexExdr.expandString(context); 386 try { 387 return Integer.parseInt(viewIndexStr); 388 } catch (NumberFormatException e) { 389 String errMsg = "The limit-view view-index number \"" + viewIndexStr + "\" was not valid: " + e.toString(); 390 Debug.logError(e, errMsg, module); 391 throw new IllegalArgumentException (errMsg); 392 } 393 } 394 395 int getSize(Map context) { 396 String viewSizeStr = this.viewSizeExdr.expandString(context); 397 try { 398 return Integer.parseInt(viewSizeStr); 399 } catch (NumberFormatException e) { 400 String errMsg = "The limit-view view-size number \"" + viewSizeStr + "\" was not valid: " + e.toString(); 401 Debug.logError(e, errMsg, module); 402 throw new IllegalArgumentException (errMsg); 403 } 404 } 405 406 public void handleOutput(EntityListIterator eli, Map 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 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 (errMsg); 416 } 417 } 418 419 public void handleOutput(List results, Map 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 useIteratorElement) { 432 } 434 435 public void handleOutput(EntityListIterator eli, Map context, FlexibleMapAccessor listAcsr) { 436 listAcsr.put(context, eli); 437 } 438 439 public void handleOutput(List results, Map context, FlexibleMapAccessor listAcsr) { 440 throw new IllegalArgumentException ("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 } 447 448 public void handleOutput(EntityListIterator eli, Map context, FlexibleMapAccessor listAcsr) { 449 try { 450 listAcsr.put(context, eli.getCompleteList()); 451 eli.close(); 452 } catch (GenericEntityException e) { 453 String errorMsg = "Error getting list from EntityListIterator: " + e.toString(); 454 Debug.logError(e, errorMsg, module); 455 throw new IllegalArgumentException (errorMsg); 456 } 457 } 458 459 public void handleOutput(List results, Map context, FlexibleMapAccessor listAcsr) { 460 listAcsr.put(context, results); 461 } 462 } 463 } 464 465 | Popular Tags |