You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2012/05/27 14:06:41 UTC

svn commit: r1343035 - in /ofbiz/trunk/framework/minilang: dtd/simple-methods-v2.xsd src/org/ofbiz/minilang/method/entityops/FindByAnd.java

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.
+                        &lt;br/&gt;&lt;br/&gt;
+                        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.
+                        &lt;br/&gt;&lt;br/&gt;
+                        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.
+                        &lt;br/&gt;&lt;br/&gt;
+                        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.
+                        &lt;br/&gt;&lt;br/&gt;
+                        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".
+                        &lt;br/&gt;&lt;br/&gt;
+                        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".
+                        &lt;br/&gt;&lt;br/&gt;
+                        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.
+                        &lt;br/&gt;&lt;br/&gt;
+                        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 &lt;find-by-and&gt; 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 &lt;find-by-and&gt; 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";
         }