|
Author: adrianc
Date: Sun May 27 12:06:41 2012 New Revision: 1343035 URL: http://svn.apache.org/viewvc?rev=1343035&view=rev Log: Overhauled Mini-language <find-by-and> element. Modified: ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByAnd.java Modified: ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd?rev=1343035&r1=1343034&r2=1343035&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original) +++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Sun May 27 12:06:41 2012 @@ -2114,81 +2114,91 @@ under the License. <xs:element name="find-by-and" substitutionGroup="EntityFindOperations"> <xs:annotation> <xs:documentation> - The find-by-and tag uses the delegator to find entity values by anding the fields passed in the map. - The resulting GenericValue objects will be placed in the method environment using the specified list-name. + Does a find-by-and, returns a list of entity values if any are found, otherwise returns an empty list. + Uses a map of name/value pairs that will be combined using a boolean AND. </xs:documentation> </xs:annotation> <xs:complexType> - <xs:attributeGroup ref="attlist.find-by-and"/> + <xs:attribute type="xs:string" name="entity-name" use="required"> + <xs:annotation> + <xs:documentation> + The name of the entity to search in. + <br/><br/> + Required. Attribute type: constant, ${expression}. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="list" use="required"> + <xs:annotation> + <xs:documentation> + The name of the field that will contain the list of entity values. + <br/><br/> + Required. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="map" use="required"> + <xs:annotation> + <xs:documentation> + The name of the field containing a map that will be used for the entity fields. + <br/><br/> + Required. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="order-by-list"> + <xs:annotation> + <xs:documentation> + The name of the field containing a list that contains field names that you want the find operation to order the results by. + Each entry in the list is a field name. The field name can be preceded by a plus or a minus sign to specify an + ascending or descending sort for that field. The default is ascending sort. + <br/><br/> + Optional. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="use-cache"> + <xs:annotation> + <xs:documentation> + Specifies whether or not the delegator's cache should be searched before going to the database. + This results in much faster retrieval times, but can return stale data that is not the most current in the database. + Must be "true" or "false", defaults to "false". + <br/><br/> + Optional. Attribute type: constant, ${expression}. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="use-iterator"> + <xs:annotation> + <xs:documentation> + Specifies whether or not to use the EntityListIterator when doing the query. + This is much more efficient for large data sets because the results are read incrementaly instead of all at once. + Note that when using this the use-cache setting will be ignored. + Also note that an EntityListIterator must be closed when you are finished, but this is done automatically by the iterate operation. + Must be "true" or "false", defaults to "false". + <br/><br/> + Optional. Attribute type: constant, ${expression}. + </xs:documentation> + </xs:annotation> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="false" /> + <xs:enumeration value="true" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute type="xs:string" name="delegator-name"> + <xs:annotation> + <xs:documentation> + By default this operation is done using the delegator that is part of the simple-method calling context. + This allows you to override the default delegator by naming an alternate delegator. + <br/><br/> + Optional. Attribute type: constant, ${expression}. + </xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> - <xs:attributeGroup name="attlist.find-by-and"> - <xs:attribute type="xs:string" name="entity-name" use="required"> - <xs:annotation> - <xs:documentation> - The name of the entity to find instances of. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="map" use="required"> - <xs:annotation> - <xs:documentation> - The name of a map in the method environment that will be used for the entity fields. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="order-by-list"> - <xs:annotation> - <xs:documentation> - This will be a list sitting in the context that has string entries in it for each field that you want it to order by/ - Each field in the list, or each entry in the list, will just be a string with a field name. - It can be preceded by a plus or a minus to specify an ascending or descending sort for that. - The default is ascending sort, so you just put a minus in front of the field-name if you want it to be descending. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="delegator-name"> - <xs:annotation> - <xs:documentation> - By default this operation is done using the delegator that is part of the simple-method calling context. - This allows you to override the default delegator by naming an alternate delegator. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="use-cache" default="false"> - <xs:annotation> - <xs:documentation> - Specifies whether or not the delegator's cache should be searched before going to the database. - This results in much faster retrieval times, but can return stale data that is not the most current in the database. - Must be "true" or "false", defaults to "false". - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute name="use-iterator" default="false"> - <xs:annotation> - <xs:documentation> - Specifies whether or not to use the EntityListIterator when doing the query. - This is much more efficient for large data sets because the results are read incrementaly instead of all at once. - Note that when using this the use-cache setting will be ignored. - Also note that an EntityListIterator must be closed when you are finished, but this is done automatically by the iterate operation. - Must be "true" or "false", defaults to "false". - </xs:documentation> - </xs:annotation> - <xs:simpleType> - <xs:restriction base="xs:token"> - <xs:enumeration value="true"/> - <xs:enumeration value="false"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute type="xs:string" name="list" use="required"> - <xs:annotation> - <xs:documentation> - The name of the method environment field that will contain the list of GenericValue objects. - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:attributeGroup> <xs:element name="entity-one" substitutionGroup="EntityFindOperations"> <xs:annotation> <xs:documentation> Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByAnd.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByAnd.java?rev=1343035&r1=1343034&r2=1343035&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByAnd.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByAnd.java Sun May 27 12:06:41 2012 @@ -21,82 +21,78 @@ package org.ofbiz.minilang.method.entity import java.util.List; import java.util.Map; -import org.ofbiz.minilang.artifact.ArtifactInfoContext; import org.ofbiz.base.util.Debug; -import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.collections.FlexibleMapAccessor; +import org.ofbiz.base.util.string.FlexibleStringExpander; import org.ofbiz.entity.Delegator; import org.ofbiz.entity.DelegatorFactory; import org.ofbiz.entity.GenericEntityException; import org.ofbiz.entity.condition.EntityCondition; import org.ofbiz.minilang.MiniLangException; +import org.ofbiz.minilang.MiniLangValidate; import org.ofbiz.minilang.SimpleMethod; -import org.ofbiz.minilang.method.ContextAccessor; +import org.ofbiz.minilang.artifact.ArtifactInfoContext; import org.ofbiz.minilang.method.MethodContext; import org.ofbiz.minilang.method.MethodOperation; import org.w3c.dom.Element; /** - * Uses the delegator to find entity values by anding the map fields + * Implements the <find-by-and> element. */ -public class FindByAnd extends MethodOperation { +public final class FindByAnd extends MethodOperation { public static final String module = FindByAnd.class.getName(); - String delegatorName; + private final FlexibleStringExpander delegatorNameFse; + private final FlexibleStringExpander entityNameFse; + private final FlexibleMapAccessor<Object> listFma; + private final FlexibleMapAccessor<Map<String, ? extends Object>> mapFma; + private final FlexibleMapAccessor<List<String>> orderByListFma; + private final FlexibleStringExpander useCacheFse; + private final FlexibleStringExpander useIteratorFse; - String entityName; - ContextAccessor<Object> listAcsr; - ContextAccessor<Map<String, ? extends Object>> mapAcsr; - ContextAccessor<List<String>> orderByListAcsr; - String useCacheStr; - String useIteratorStr; public FindByAnd(Element element, SimpleMethod simpleMethod) throws MiniLangException { super(element, simpleMethod); - listAcsr = new ContextAccessor<Object>(element.getAttribute("list"), element.getAttribute("list-name")); - entityName = element.getAttribute("entity-name"); - mapAcsr = new ContextAccessor<Map<String, ? extends Object>>(element.getAttribute("map"), element.getAttribute("map-name")); - orderByListAcsr = new ContextAccessor<List<String>>(element.getAttribute("order-by-list"), element.getAttribute("order-by-list-name")); - delegatorName = element.getAttribute("delegator-name"); - useCacheStr = element.getAttribute("use-cache"); - useIteratorStr = element.getAttribute("use-iterator"); + if (MiniLangValidate.validationOn()) { + MiniLangValidate.attributeNames(simpleMethod, element, "entity-name", "use-cache", "use-iterator", "list", "map", "order-by-list", "delegator-name"); + MiniLangValidate.requiredAttributes(simpleMethod, element, "entity-name", "list", "map"); + MiniLangValidate.expressionAttributes(simpleMethod, element, "list", "map", "order-by-list"); + MiniLangValidate.noChildElements(simpleMethod, element); + } + entityNameFse = FlexibleStringExpander.getInstance(element.getAttribute("entity-name")); + listFma = FlexibleMapAccessor.getInstance(element.getAttribute("list")); + mapFma = FlexibleMapAccessor.getInstance(element.getAttribute("map")); + orderByListFma = FlexibleMapAccessor.getInstance(element.getAttribute("order-by-list")); + useCacheFse = FlexibleStringExpander.getInstance(element.getAttribute("use-cache")); + useIteratorFse = FlexibleStringExpander.getInstance(element.getAttribute("use-iterator")); + delegatorNameFse = FlexibleStringExpander.getInstance(element.getAttribute("delegator-name")); } @Override public boolean exec(MethodContext methodContext) throws MiniLangException { - String entityName = methodContext.expandString(this.entityName); - String delegatorName = methodContext.expandString(this.delegatorName); - String useCacheStr = methodContext.expandString(this.useCacheStr); - String useIteratorStr = methodContext.expandString(this.useIteratorStr); - boolean useCache = "true".equals(useCacheStr); - boolean useIterator = "true".equals(useIteratorStr); - List<String> orderByNames = null; - if (!orderByListAcsr.isEmpty()) { - orderByNames = orderByListAcsr.get(methodContext); - } + String entityName = entityNameFse.expandString(methodContext.getEnvMap()); + String delegatorName = delegatorNameFse.expandString(methodContext.getEnvMap()); + boolean useCache = "true".equals(useCacheFse.expandString(methodContext.getEnvMap())); + boolean useIterator = "true".equals(useIteratorFse.expandString(methodContext.getEnvMap())); + List<String> orderByNames = orderByListFma.get(methodContext.getEnvMap()); Delegator delegator = methodContext.getDelegator(); - if (UtilValidate.isNotEmpty(delegatorName)) { + if (!delegatorName.isEmpty()) { delegator = DelegatorFactory.getDelegator(delegatorName); } try { if (useIterator) { EntityCondition whereCond = null; - if (!mapAcsr.isEmpty()) { - whereCond = EntityCondition.makeCondition(mapAcsr.get(methodContext)); + if (!mapFma.isEmpty()) { + whereCond = EntityCondition.makeCondition(mapFma.get(methodContext.getEnvMap())); } - listAcsr.put(methodContext, delegator.find(entityName, whereCond, null, null, orderByNames, null)); + listFma.put(methodContext.getEnvMap(), delegator.find(entityName, whereCond, null, null, orderByNames, null)); } else { - listAcsr.put(methodContext, delegator.findByAnd(entityName, mapAcsr.get(methodContext), orderByNames, useCache)); + listFma.put(methodContext.getEnvMap(), delegator.findByAnd(entityName, mapFma.get(methodContext.getEnvMap()), orderByNames, useCache)); } } catch (GenericEntityException e) { - Debug.logError(e, module); - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [problem finding the " + entityName + " entity: " + e.getMessage() + "]"; - if (methodContext.getMethodType() == MethodContext.EVENT) { - methodContext.putEnv(simpleMethod.getEventErrorMessageName(), errMsg); - methodContext.putEnv(simpleMethod.getEventResponseCodeName(), simpleMethod.getDefaultErrorCode()); - } else if (methodContext.getMethodType() == MethodContext.SERVICE) { - methodContext.putEnv(simpleMethod.getServiceErrorMessageName(), errMsg); - methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), simpleMethod.getDefaultErrorCode()); - } + String errMsg = "Exception thrown while performing entity find: " + e.getMessage(); + Debug.logWarning(e, errMsg, module); + simpleMethod.addErrorMessage(methodContext, errMsg); return false; } return true; @@ -104,26 +100,51 @@ public class FindByAnd extends MethodOpe @Override public String expandedString(MethodContext methodContext) { - // TODO: something more than a stub/dummy - return this.rawString(); + return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap()); } @Override public void gatherArtifactInfo(ArtifactInfoContext aic) { - aic.addEntityName(entityName); + aic.addEntityName(entityNameFse.toString()); } @Override public String rawString() { - // TODO: something more than the empty tag - return "<find-by-and/>"; + return toString(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("<find-by-and "); + sb.append("entity-name=\"").append(this.entityNameFse).append("\" "); + sb.append("list=\"").append(this.listFma).append("\" "); + sb.append("map=\"").append(this.mapFma).append("\" "); + if (!orderByListFma.isEmpty()) { + sb.append("order-by-list=\"").append(this.orderByListFma).append("\" "); + } + if (!useCacheFse.isEmpty()) { + sb.append("use-cache=\"").append(this.useCacheFse).append("\" "); + } + if (!useIteratorFse.isEmpty()) { + sb.append("use-iterator=\"").append(this.useIteratorFse).append("\" "); + } + if (!delegatorNameFse.isEmpty()) { + sb.append("delegator-name=\"").append(this.delegatorNameFse).append("\" "); + } + sb.append("/>"); + return sb.toString(); } + /** + * A factory for the <find-by-and> element. + */ public static final class FindByAndFactory implements Factory<FindByAnd> { + @Override public FindByAnd createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException { return new FindByAnd(element, simpleMethod); } + @Override public String getName() { return "find-by-and"; } |
| Free forum by Nabble | Edit this page |
