svn commit: r1339149 - in /ofbiz/trunk/framework/minilang: dtd/simple-methods-v2.xsd src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r1339149 - in /ofbiz/trunk/framework/minilang: dtd/simple-methods-v2.xsd src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.java

adrianc
Author: adrianc
Date: Wed May 16 13:09:30 2012
New Revision: 1339149

URL: http://svn.apache.org/viewvc?rev=1339149&view=rev
Log:
Overhauled Mini-language <call-service-asynch> and <call-map-processor> elements.

Modified:
    ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.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=1339149&r1=1339148&r2=1339149&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original)
+++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Wed May 16 13:09:30 2012
@@ -466,71 +466,70 @@ under the License.
             <xs:documentation>
                 The call-map-processor tag invokes a simple map processor from an existing map, creating a new map or adding to an existing one
                 if the named out-map already exists. Resulting messages are added to the named list, and a new list is created if a list with
-                the given name does not yet exist. Note that all lists and maps exist in the same context and must have unique names.
-
+                the given name does not yet exist. All lists and maps exist in the same context and must have unique names.
+                &lt;br/&gt;&lt;br/&gt;
                 An inline simple-map-processor can be used by putting a simple-map-processor tag under the call-map-processor tag.
-
                 If both an external and an inline map-processor are specified, the external
                 one will be called first, allowing the inline one to override its behavior.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" ref="simple-map-processor">
-                    <xs:annotation>
-                        <xs:documentation>
-                            Uses the same definition as the simple-map-processor in the context of a simple-map-processors XML file.
-                            Allows for an inlined simple-map-processor.
-                        </xs:documentation>
-                    </xs:annotation>
-                </xs:element>
+                <xs:element minOccurs="0" ref="simple-map-processor" />
             </xs:sequence>
-            <xs:attributeGroup ref="attlist.call-map-processor"/>
+            <xs:attribute type="xs:string" name="processor-name">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the external map processor to execute in the specified xml-resource.
+                        This is only required if an external map processor is desired.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute type: constant.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="xml-resource">
+                <xs:annotation>
+                    <xs:documentation>
+                        The full path and filename on the classpath of the XML file which contains an external map processor to execute.
+                        This is only required if an external map processor is desired.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute type: constant.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="in-map-name" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of a map in the method environment to use as the input map.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="out-map-name" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of a map in the method environment to use as the output map.
+                        Will be created if it does not exist already.
+                        If already exists will be added to in place.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="error-list-name">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of a list in the method environment that the error messages will be added to.
+                        Will be created if it does not exist.
+                        Defaults to "error_list".
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute type: constant.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.call-map-processor">
-        <xs:attribute type="xs:string" name="xml-resource">
-            <xs:annotation>
-                <xs:documentation>
-                    The full path and filename on the classpath of the XML file which contains an external map processor to execute.
-                    This is only required if an external map processor is desired.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="processor-name">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the external map processor to execute in the specified xml-resource.
-                    This is only required if an external map processor is desired.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="in-map-name" use="required">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of a map in the method environment to use as the input map.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="out-map-name" use="required">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of a map in the method environment to use as the output map.
-                    Will be created if it does not exist already.
-                    If already exists will be added to in place.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="error-list-name" default="error_list">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of a list in the method environment that the error messages will be added to.
-                    Will be created if it does not exist.
-                    Defaults to "error_list".
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="set-service-fields" substitutionGroup="CallOperations">
         <xs:annotation>
             <xs:documentation>
@@ -911,38 +910,47 @@ under the License.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.call-service-asynch"/>
+            <xs:attribute type="xs:string" name="service-name" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        Name of the service to call.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: constant, expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="in-map-name">
+                <xs:annotation>
+                    <xs:documentation>
+                        A map in the method environment to use as the input map.
+                        If you're not going to pass any parameters to the service than you can just
+                        omit the in-map attribute, although typically in a call-service-asynch element
+                        you will see the in-map-name attribute included.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="include-user-login">
+                <xs:annotation>
+                    <xs:documentation>
+                        Include the current UserLogin GenericValue in the called service IN attributes.
+                        Defaults to "true".
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute type: constant.
+                    </xs:documentation>
+                </xs:annotation>
+                <xs:simpleType>
+                    <xs:annotation>
+                    </xs:annotation>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="true" />
+                        <xs:enumeration value="false" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.call-service-asynch">
-        <xs:attribute type="xs:string" name="service-name" use="required">
-            <xs:annotation>
-                <xs:documentation>
-                    Name of the service called asynchronously.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="in-map-name">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of a map in the method environment to use as the input map.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute name="include-user-login" default="true">
-            <xs:annotation>
-                <xs:documentation>
-                    Defaults to "true".
-                </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:attributeGroup>
     <xs:element name="script" substitutionGroup="CallOperations">
         <xs:annotation>
             <xs:documentation>

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java?rev=1339149&r1=1339148&r2=1339149&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java Wed May 16 13:09:30 2012
@@ -24,10 +24,12 @@ import java.util.Map;
 import javolution.util.FastMap;
 
 import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.GenericValue;
 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.method.MethodContext;
 import org.ofbiz.minilang.method.MethodOperation;
 import org.ofbiz.service.GenericServiceException;
@@ -36,80 +38,100 @@ import org.w3c.dom.Element;
 /**
  * Calls a service using the given parameters
  */
-public class CallServiceAsynch extends MethodOperation {
+public final class CallServiceAsynch extends MethodOperation {
 
     public static final String module = CallServiceAsynch.class.getName();
 
-    protected String includeUserLoginStr;
-    protected ContextAccessor<Map<String, Object>> inMapAcsr;
-    protected String serviceName;
+    private final boolean includeUserLogin;
+    private final FlexibleMapAccessor<Map<String, Object>> inMapFma;
+    private final FlexibleStringExpander serviceNameFse;
 
     public CallServiceAsynch(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        serviceName = element.getAttribute("service-name");
-        inMapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("in-map-name"));
-        includeUserLoginStr = element.getAttribute("include-user-login");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "serviceName", "in-map-name", "include-user-login");
+            MiniLangValidate.constantAttributes(simpleMethod, element, "include-user-login");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "service-name", "in-map-name");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "service-name");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        serviceNameFse = FlexibleStringExpander.getInstance(element.getAttribute("service-name"));
+        inMapFma = FlexibleMapAccessor.getInstance(element.getAttribute("in-map-name"));
+        includeUserLogin = !"false".equals(element.getAttribute("include-user-login"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        String serviceName = methodContext.expandString(this.serviceName);
-        boolean includeUserLogin = !"false".equals(methodContext.expandString(includeUserLoginStr));
-        Map<String, Object> inMap = null;
-        if (inMapAcsr.isEmpty()) {
+        if (methodContext.isTraceOn()) {
+            outputTraceMessage(methodContext, "Begin call-service-asynch.");
+        }
+        String serviceName = serviceNameFse.expandString(methodContext.getEnvMap());
+        Map<String, Object> inMap = inMapFma.get(methodContext.getEnvMap());
+        if (inMap == null) {
             inMap = FastMap.newInstance();
-        } else {
-            inMap = inMapAcsr.get(methodContext);
-            if (inMap == null) {
-                inMap = FastMap.newInstance();
-                inMapAcsr.put(methodContext, inMap);
-            }
         }
-        // add UserLogin to context if expected
         if (includeUserLogin) {
             GenericValue userLogin = methodContext.getUserLogin();
-
             if (userLogin != null && inMap.get("userLogin") == null) {
                 inMap.put("userLogin", userLogin);
             }
         }
-        // always add Locale to context unless null
         Locale locale = methodContext.getLocale();
         if (locale != null) {
             inMap.put("locale", locale);
         }
-        // invoke the service
         try {
+            if (methodContext.isTraceOn()) {
+                outputTraceMessage(methodContext, "Invoking service \"" + serviceName + "\", IN attributes:", inMap.toString());
+            }
             methodContext.getDispatcher().runAsync(serviceName, inMap);
         } catch (GenericServiceException e) {
+            if (methodContext.isTraceOn()) {
+                outputTraceMessage(methodContext, "Service engine threw an exception: " + e.getMessage() + ", halting script execution. End call-service-asynch.");
+            }
             Debug.logError(e, module);
             String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [problem invoking the " + serviceName + " service: " + e.getMessage() + "]";
             if (methodContext.getMethodType() == MethodContext.EVENT) {
                 methodContext.putEnv(simpleMethod.getEventErrorMessageName(), errMsg);
                 methodContext.putEnv(simpleMethod.getEventResponseCodeName(), simpleMethod.getDefaultErrorCode());
-            } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
+            } else {
                 methodContext.putEnv(simpleMethod.getServiceErrorMessageName(), errMsg);
                 methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), simpleMethod.getDefaultErrorCode());
             }
             return false;
         }
+        if (methodContext.isTraceOn()) {
+            outputTraceMessage(methodContext, "End call-service-asynch.");
+        }
         return true;
     }
 
     @Override
     public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
+        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
     }
 
     public String getServiceName() {
-        return this.serviceName;
+        return this.serviceNameFse.getOriginal();
     }
 
     @Override
     public String rawString() {
-        // TODO: something more than the empty tag
-        return "<call-service-asynch/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<call-service-asynch ");
+        sb.append("service-name=\"").append(this.serviceNameFse).append("\" ");
+        if (!this.inMapFma.isEmpty()) {
+            sb.append("in-map-name=\"").append(this.inMapFma).append("\" ");
+        }
+        if (!this.includeUserLogin) {
+            sb.append("include-user-login=\"false\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
     public static final class CallServiceAsynchFactory implements Factory<CallServiceAsynch> {

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.java?rev=1339149&r1=1339148&r2=1339149&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.java Wed May 16 13:09:30 2012
@@ -24,11 +24,13 @@ import java.util.Map;
 import javolution.util.FastList;
 import javolution.util.FastMap;
 
-import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.minilang.MiniLangException;
+import org.ofbiz.minilang.MiniLangValidate;
+import org.ofbiz.minilang.SimpleMapProcessor;
 import org.ofbiz.minilang.SimpleMethod;
-import org.ofbiz.minilang.method.ContextAccessor;
 import org.ofbiz.minilang.method.MethodContext;
 import org.ofbiz.minilang.method.MethodOperation;
 import org.ofbiz.minilang.operation.MapProcessor;
@@ -39,54 +41,60 @@ import org.w3c.dom.Element;
  */
 public class CallSimpleMapProcessor extends MethodOperation {
 
-    ContextAccessor<List<Object>> errorListAcsr;
-    MapProcessor inlineMapProcessor = null;
-    ContextAccessor<Map<String, Object>> inMapAcsr;
-    ContextAccessor<Map<String, Object>> outMapAcsr;
-    String processorName;
-    String xmlResource;
+    private final FlexibleMapAccessor<List<Object>> errorListFma;
+    private final MapProcessor inlineMapProcessor;
+    private final FlexibleMapAccessor<Map<String, Object>> inMapFma;
+    private final FlexibleMapAccessor<Map<String, Object>> outMapFma;
+    private final String processorName;
+    private final String xmlResource;
 
     public CallSimpleMapProcessor(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        xmlResource = element.getAttribute("xml-resource");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "processor-name", "xml-resource", "in-map-name", "out-map-name", "error-list-name");
+            MiniLangValidate.constantAttributes(simpleMethod, element, "processor-name", "xml-resource", "error-list-name");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "in-map-name", "out-map-name");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "in-map-name", "out-map-name");
+            MiniLangValidate.childElements(simpleMethod, element, "simple-map-processor");
+        }
         processorName = element.getAttribute("processor-name");
-        inMapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("in-map-name"));
-        outMapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("out-map-name"));
-        errorListAcsr = new ContextAccessor<List<Object>>(element.getAttribute("error-list-name"), "error_list");
+        xmlResource = element.getAttribute("xml-resource");
+        errorListFma = FlexibleMapAccessor.getInstance(MiniLangValidate.checkAttribute(element.getAttribute("error-list-name"), "error_list"));
+        inMapFma = FlexibleMapAccessor.getInstance(element.getAttribute("in-map-name"));
+        outMapFma = FlexibleMapAccessor.getInstance(element.getAttribute("out-map-name"));
         Element simpleMapProcessorElement = UtilXml.firstChildElement(element, "simple-map-processor");
         if (simpleMapProcessorElement != null) {
             inlineMapProcessor = new MapProcessor(simpleMapProcessorElement);
+        } else {
+            inlineMapProcessor = null;
         }
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        List<Object> messages = errorListAcsr.get(methodContext);
+        List<Object> messages = errorListFma.get(methodContext.getEnvMap());
         if (messages == null) {
             messages = FastList.newInstance();
-            errorListAcsr.put(methodContext, messages);
+            errorListFma.put(methodContext.getEnvMap(), messages);
         }
-        Map<String, Object> inMap = inMapAcsr.get(methodContext);
+        Map<String, Object> inMap = inMapFma.get(methodContext.getEnvMap());
         if (inMap == null) {
             inMap = FastMap.newInstance();
-            inMapAcsr.put(methodContext, inMap);
         }
-        Map<String, Object> outMap = outMapAcsr.get(methodContext);
+        Map<String, Object> outMap = outMapFma.get(methodContext.getEnvMap());
         if (outMap == null) {
             outMap = FastMap.newInstance();
-            outMapAcsr.put(methodContext, outMap);
+            outMapFma.put(methodContext.getEnvMap(), outMap);
         }
         // run external map processor first
-        if (UtilValidate.isNotEmpty(this.xmlResource) && UtilValidate.isNotEmpty(this.processorName)) {
-            String xmlResource = methodContext.expandString(this.xmlResource);
-            String processorName = methodContext.expandString(this.processorName);
+        if (!this.xmlResource.isEmpty() && !this.processorName.isEmpty()) {
             try {
-                org.ofbiz.minilang.SimpleMapProcessor.runSimpleMapProcessor(xmlResource, processorName, inMap, outMap, messages, methodContext.getLocale(), methodContext.getLoader());
+                SimpleMapProcessor.runSimpleMapProcessor(xmlResource, processorName, inMap, outMap, messages, methodContext.getLocale(), methodContext.getLoader());
             } catch (MiniLangException e) {
                 messages.add("Error running SimpleMapProcessor in XML file \"" + xmlResource + "\": " + e.toString());
             }
         }
-        // run inlined map processor last so it can override the external map processor
+        // run inline map processor last so it can override the external map processor
         if (inlineMapProcessor != null) {
             inlineMapProcessor.exec(inMap, outMap, messages, methodContext.getLocale(), methodContext.getLoader());
         }
@@ -95,14 +103,34 @@ public class CallSimpleMapProcessor exte
 
     @Override
     public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
+        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
     }
 
     @Override
     public String rawString() {
-        // TODO: something more than the empty tag
-        return "<call-simple-map-processor/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<call-map-processor ");
+        if (!this.processorName.isEmpty()) {
+            sb.append("processor-name=\"").append(this.processorName).append("\" ");
+        }
+        if (!this.xmlResource.isEmpty()) {
+            sb.append("xml-resource=\"").append(this.xmlResource).append("\" ");
+        }
+        if (!this.inMapFma.isEmpty()) {
+            sb.append("in-map-name=\"").append(this.inMapFma).append("\" ");
+        }
+        if (!this.outMapFma.isEmpty()) {
+            sb.append("out-map-name=\"").append(this.outMapFma).append("\" ");
+        }
+        if (!"error_list".equals(errorListFma.toString())) {
+            sb.append("error-list-name=\"").append(errorListFma).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
     public static final class CallSimpleMapProcessorFactory implements Factory<CallSimpleMapProcessor> {