|
Author: adrianc
Date: Sun Jul 1 20:54:23 2012 New Revision: 1356024 URL: http://svn.apache.org/viewvc?rev=1356024&view=rev Log: Some optimizations in EntityFinderUtil.java: 1. Made the Condition implementations immutable and thread-safe. 2. Moved operator lookup from run-time to parse-time. 3. Removed unnecessary calls to UtilValidate. 4. Replaced LinkedList with ArrayList. 5. Optimized code in the ConditionExpr.createCondition method. Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/finder/EntityFinderUtil.java Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/finder/EntityFinderUtil.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/finder/EntityFinderUtil.java?rev=1356024&r1=1356023&r2=1356024&view=diff ============================================================================== --- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/finder/EntityFinderUtil.java (original) +++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/finder/EntityFinderUtil.java Sun Jul 1 20:54:23 2012 @@ -21,19 +21,18 @@ package org.ofbiz.entity.finder; import static org.ofbiz.base.util.UtilGenerics.cast; import java.io.Serializable; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; -import javolution.util.FastMap; - import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.ObjectType; import org.ofbiz.base.util.StringUtil; -import org.ofbiz.base.util.UtilFormatOut; import org.ofbiz.base.util.UtilGenerics; import org.ofbiz.base.util.UtilValidate; import org.ofbiz.base.util.UtilXml; @@ -63,24 +62,24 @@ public class EntityFinderUtil { Map<FlexibleMapAccessor<Object>, Object> fieldMap = null; List<? extends Element> fieldMapElementList = UtilXml.childElementList(element, "field-map"); if (fieldMapElementList.size() > 0) { - fieldMap = FastMap.newInstance(); + fieldMap = new HashMap<FlexibleMapAccessor<Object>, Object>(fieldMapElementList.size()); for (Element fieldMapElement: fieldMapElementList) { // set the env-name for each field-name, noting that if no field-name is specified it defaults to the env-name String fieldName = fieldMapElement.getAttribute("field-name"); String envName = fieldMapElement.getAttribute("from-field"); - if (UtilValidate.isEmpty(envName)) { + if (envName.isEmpty()) { envName = fieldMapElement.getAttribute("env-name"); } String value = fieldMapElement.getAttribute("value"); - if (UtilValidate.isEmpty(fieldName)) { + if (fieldName.isEmpty()) { // no fieldName, use envName for both fieldMap.put(FlexibleMapAccessor.getInstance(envName), FlexibleMapAccessor.getInstance(envName)); } else { - if (UtilValidate.isNotEmpty(value)) { + if (!value.isEmpty()) { fieldMap.put(FlexibleMapAccessor.getInstance(fieldName), FlexibleStringExpander.getInstance(value)); } else { // at this point we have a fieldName and no value, do we have a envName? - if (UtilValidate.isNotEmpty(envName)) { + if (!envName.isEmpty()) { fieldMap.put(FlexibleMapAccessor.getInstance(fieldName), FlexibleMapAccessor.getInstance(envName)); } else { // no envName, use fieldName for both @@ -116,7 +115,7 @@ public class EntityFinderUtil { List<FlexibleStringExpander> selectFieldExpanderList = null; List<? extends Element> selectFieldElementList = UtilXml.childElementList(element, "select-field"); if (selectFieldElementList.size() > 0) { - selectFieldExpanderList = new LinkedList<FlexibleStringExpander>(); + selectFieldExpanderList = new ArrayList<FlexibleStringExpander>(selectFieldElementList.size()); for (Element selectFieldElement: selectFieldElementList) { selectFieldExpanderList.add(FlexibleStringExpander.getInstance(selectFieldElement.getAttribute("field-name"))); } @@ -138,7 +137,7 @@ public class EntityFinderUtil { public static List<String> makeOrderByFieldList(List<FlexibleStringExpander> orderByExpanderList, Map<String, Object> context) { List<String> orderByFields = null; if (UtilValidate.isNotEmpty(orderByExpanderList)) { - orderByFields = new LinkedList<String>(); + orderByFields = new ArrayList<String>(orderByExpanderList.size()); for (FlexibleStringExpander orderByExpander: orderByExpanderList) { orderByFields.add(orderByExpander.expandString(context)); } @@ -149,30 +148,37 @@ public class EntityFinderUtil { public static interface Condition extends Serializable { public EntityCondition createCondition(Map<String, ? extends Object> context, ModelEntity modelEntity, ModelFieldTypeReader modelFieldTypeReader); } + @SuppressWarnings("serial") - public static class ConditionExpr implements Condition { - protected FlexibleStringExpander fieldNameExdr; - protected FlexibleStringExpander operatorExdr; - protected FlexibleMapAccessor<Object> envNameAcsr; - protected FlexibleStringExpander valueExdr; - protected FlexibleStringExpander ignoreExdr; - protected boolean ignoreIfNull; - protected boolean ignoreIfEmpty; - protected boolean ignoreCase; + public static final class ConditionExpr implements Condition { + private final String fieldName; + private final EntityOperator<?,?,?> operator; + private final FlexibleMapAccessor<Object> envNameAcsr; + private final FlexibleStringExpander valueExdr; + private final FlexibleStringExpander ignoreExdr; + private final boolean ignoreIfNull; + private final boolean ignoreIfEmpty; + private final boolean ignoreCase; public ConditionExpr(Element conditionExprElement) { - this.fieldNameExdr = FlexibleStringExpander.getInstance(conditionExprElement.getAttribute("field-name")); - if (this.fieldNameExdr.isEmpty()) { - // no "field-name"? try "name" - this.fieldNameExdr = FlexibleStringExpander.getInstance(conditionExprElement.getAttribute("name")); - } - - this.operatorExdr = FlexibleStringExpander.getInstance(UtilFormatOut.checkEmpty(conditionExprElement.getAttribute("operator"), "equals")); - if (UtilValidate.isNotEmpty(conditionExprElement.getAttribute("from-field"))) { - this.envNameAcsr = FlexibleMapAccessor.getInstance(conditionExprElement.getAttribute("from-field")); - } else { - this.envNameAcsr = FlexibleMapAccessor.getInstance(conditionExprElement.getAttribute("env-name")); + String fieldNameAttribute = conditionExprElement.getAttribute("field-name"); + if (fieldNameAttribute.isEmpty()) { + fieldNameAttribute = conditionExprElement.getAttribute("name"); + } + this.fieldName = fieldNameAttribute; + String operatorAttribute = conditionExprElement.getAttribute("operator"); + if (operatorAttribute.isEmpty()) { + operatorAttribute = "equals"; + } + this.operator = EntityOperator.lookup(operatorAttribute); + if (this.operator == null) { + throw new IllegalArgumentException("Could not find an entity operator for the name: " + operatorAttribute); + } + String fromFieldAttribute = conditionExprElement.getAttribute("from-field"); + if (fromFieldAttribute.isEmpty()) { + fromFieldAttribute = conditionExprElement.getAttribute("env-name"); } + this.envNameAcsr = FlexibleMapAccessor.getInstance(fromFieldAttribute); this.valueExdr = FlexibleStringExpander.getInstance(conditionExprElement.getAttribute("value")); this.ignoreIfNull = "true".equals(conditionExprElement.getAttribute("ignore-if-null")); this.ignoreIfEmpty = "true".equals(conditionExprElement.getAttribute("ignore-if-empty")); @@ -181,22 +187,19 @@ public class EntityFinderUtil { } public EntityCondition createCondition(Map<String, ? extends Object> context, ModelEntity modelEntity, ModelFieldTypeReader modelFieldTypeReader) { - String fieldName = fieldNameExdr.expandString(context); - - Object value = null; - // start with the environment variable, will override if exists and a value is specified - if (envNameAcsr != null) { - value = envNameAcsr.get(context); + if ("true".equals(this.ignoreExdr.expandString(context))) { + return null; } - // no value so far, and a string value is specified, use that - if (value == null && valueExdr != null) { - value = valueExdr.expandString(context); + if (modelEntity.getField(fieldName) == null) { + throw new IllegalArgumentException("Error in Entity Find: could not find field [" + fieldName + "] in entity with name [" + modelEntity.getEntityName() + "]"); } - String operatorName = operatorExdr.expandString(context); - EntityOperator<?,?,?> operator = EntityOperator.lookup(operatorName); - if (operator == null) { - throw new IllegalArgumentException("Could not find an entity operator for the name: " + operatorName); + Object value = envNameAcsr.get(context); + if (value == null && !valueExdr.isEmpty()) { + value = valueExdr.expandString(context); + } + if (this.ignoreIfNull && value == null) { + return null; } // If IN or BETWEEN operator, see if value is a literal list and split it @@ -208,15 +211,11 @@ public class EntityFinderUtil { } else if (((String)value).indexOf(",") >= 0) { delim = ","; } - if (UtilValidate.isNotEmpty(delim)) { + if (delim != null) { value = StringUtil.split((String)value, delim); } } - if (modelEntity.getField(fieldName) == null) { - throw new IllegalArgumentException("Error in Entity Find: could not find field [" + fieldName + "] in entity with name [" + modelEntity.getEntityName() + "]"); - } - // don't convert the field to the desired type if this is an IN or BETWEEN operator and we have a Collection if (!((operator.equals(EntityOperator.IN) || operator.equals(EntityOperator.BETWEEN) || operator.equals(EntityOperator.NOT_IN)) && value instanceof Collection<?>)) { @@ -226,17 +225,10 @@ public class EntityFinderUtil { if (Debug.verboseOn()) Debug.logVerbose("Got value for fieldName [" + fieldName + "]: " + value, module); - if (this.ignoreIfNull && value == null) { - return null; - } if (this.ignoreIfEmpty && ObjectType.isEmpty(value)) { return null; } - if ("true".equals(this.ignoreExdr.expandString(context))) { - return null; - } - if (operator == EntityOperator.NOT_EQUAL && value != null) { // since some databases don't consider nulls in != comparisons, explicitly include them // 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 @@ -263,68 +255,72 @@ public class EntityFinderUtil { } @SuppressWarnings("serial") - public static class ConditionList implements Condition { - List<Condition> conditionList = new LinkedList<Condition>(); - FlexibleStringExpander combineExdr; + public static final class ConditionList implements Condition { + private final List<Condition> conditionList; + private final EntityOperator<?,?,?> operator; public ConditionList(Element conditionListElement) { - this.combineExdr = FlexibleStringExpander.getInstance(conditionListElement.getAttribute("combine")); - + String operatorAttribute = conditionListElement.getAttribute("combine"); + if (operatorAttribute.isEmpty()) { + operatorAttribute = "equals"; + } + this.operator = EntityOperator.lookup(operatorAttribute); + if (this.operator == null) { + throw new IllegalArgumentException("Could not find an entity operator for the name: " + operatorAttribute); + } List<? extends Element> subElements = UtilXml.childElementList(conditionListElement); - for (Element subElement: subElements) { - if ("condition-expr".equals(subElement.getNodeName())) { - conditionList.add(new ConditionExpr(subElement)); - } else if ("condition-list".equals(subElement.getNodeName())) { - conditionList.add(new ConditionList(subElement)); - } else if ("condition-object".equals(subElement.getNodeName())) { - conditionList.add(new ConditionObject(subElement)); - } else { - throw new IllegalArgumentException("Invalid element with name [" + subElement.getNodeName() + "] found under a condition-list element."); + if (subElements.isEmpty()) { + this.conditionList = null; + } else { + List<Condition> conditionList = new ArrayList<Condition>(subElements.size()); + for (Element subElement : subElements) { + if ("condition-expr".equals(subElement.getNodeName())) { + conditionList.add(new ConditionExpr(subElement)); + } else if ("condition-list".equals(subElement.getNodeName())) { + conditionList.add(new ConditionList(subElement)); + } else if ("condition-object".equals(subElement.getNodeName())) { + conditionList.add(new ConditionObject(subElement)); + } else { + throw new IllegalArgumentException("Invalid element with name [" + subElement.getNodeName() + "] found under a condition-list element."); + } } + this.conditionList = Collections.unmodifiableList(conditionList); } } public EntityCondition createCondition(Map<String, ? extends Object> context, ModelEntity modelEntity, ModelFieldTypeReader modelFieldTypeReader) { - if (this.conditionList.size() == 0) { + if (this.conditionList == null) { return null; } if (this.conditionList.size() == 1) { Condition condition = this.conditionList.get(0); return condition.createCondition(context, modelEntity, modelFieldTypeReader); } - - List<EntityCondition> entityConditionList = new LinkedList<EntityCondition>(); - for (Condition curCondition: conditionList) { + List<EntityCondition> entityConditionList = new ArrayList<EntityCondition>(this.conditionList.size()); + for (Condition curCondition: this.conditionList) { EntityCondition econd = curCondition.createCondition(context, modelEntity, modelFieldTypeReader); if (econd != null) { entityConditionList.add(econd); } } - - String operatorName = combineExdr.expandString(context); - EntityOperator<?,?,?> operator = EntityOperator.lookup(operatorName); - if (operator == null) { - throw new IllegalArgumentException("Could not find an entity operator for the name: " + operatorName); - } - return EntityCondition.makeCondition(entityConditionList, UtilGenerics.<EntityJoinOperator>cast(operator)); } } + @SuppressWarnings("serial") - public static class ConditionObject implements Condition { - protected FlexibleMapAccessor<Object> fieldNameAcsr; + public static final class ConditionObject implements Condition { + private final FlexibleMapAccessor<Object> fieldNameAcsr; public ConditionObject(Element conditionExprElement) { - this.fieldNameAcsr = FlexibleMapAccessor.getInstance(conditionExprElement.getAttribute("field")); - if (this.fieldNameAcsr.isEmpty()) { - // no "field"? try "field-name" - this.fieldNameAcsr = FlexibleMapAccessor.getInstance(conditionExprElement.getAttribute("field-name")); + String fieldNameAttribute = conditionExprElement.getAttribute("field"); + if (fieldNameAttribute.isEmpty()) { + fieldNameAttribute = conditionExprElement.getAttribute("field-name"); } + this.fieldNameAcsr = FlexibleMapAccessor.getInstance(fieldNameAttribute); } public EntityCondition createCondition(Map<String, ? extends Object> context, ModelEntity modelEntity, ModelFieldTypeReader modelFieldTypeReader) { - EntityCondition condition = (EntityCondition) fieldNameAcsr.get(context); - return condition; + return (EntityCondition) fieldNameAcsr.get(context); } } |
| Free forum by Nabble | Edit this page |
