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/05 19:00:37 UTC

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

Author: adrianc
Date: Sat May  5 17:00:36 2012
New Revision: 1334450

URL: http://svn.apache.org/viewvc?rev=1334450&view=rev
Log:
Overhauled Mini-language <set-service-fields> element. This commit includes some minor behavior changes.

In the previous version, if the source Map was not found, the target Map was not created. Now the target Map is always created if it doesn't already exist.

In the previous version, any errors encountered during the copying process were added to the error message list and script execution continued. Now the error messages are added to the error message list and script execution is stopped.

Modified:
    ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/SetServiceFields.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=1334450&r1=1334449&r2=1334450&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original)
+++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Sat May  5 17:00:36 2012
@@ -246,19 +246,6 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute type="xs:string" name="parameter-map-name">
-                <xs:annotation>
-                    <xs:documentation>
-                        The name of the field containing the parameters map. Defaults to "parameters".
-                        &lt;br/&gt;&lt;br/&gt;
-                        When the simple method is invoked as an event, the parameters map contains the request parameters.
-                        When the simple method is invoked as a service, the parameters map contains the service IN attributes.
-                        The parameters map should not be modified, but modification is permitted for backward compatibility.
-                        &lt;br/&gt;&lt;br/&gt;
-                        Optional. Attribute type: constant.
-                    </xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
             <xs:attribute type="xs:string" name="event-request-object-name">
                 <xs:annotation>
                     <xs:documentation>
@@ -380,51 +367,6 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute type="xs:string" name="locale-name">
-                <xs:annotation>
-                    <xs:documentation>
-                        The name of the field containing the java.util.Locale object. Defaults to "locale".
-                        &lt;br/&gt;&lt;br/&gt;
-                        Optional. Attribute type: constant.
-                    </xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="delegator-name">
-                <xs:annotation>
-                    <xs:documentation>
-                        The name of the field containing the org.ofbiz.entity.Delegator object. Defaults to "delegator".
-                        &lt;br/&gt;&lt;br/&gt;
-                        Optional. Attribute type: constant.
-                    </xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="security-name">
-                <xs:annotation>
-                    <xs:documentation>
-                        The name of the field containing the org.ofbiz.security.Security object. Defaults to "security".
-                        &lt;br/&gt;&lt;br/&gt;
-                        Optional. Attribute type: constant.
-                    </xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="dispatcher-name">
-                <xs:annotation>
-                    <xs:documentation>
-                        The name of the field containing the org.ofbiz.service.LocalDispatcher object. Defaults to "dispatcher".
-                        &lt;br/&gt;&lt;br/&gt;
-                        Optional. Attribute type: constant.
-                    </xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="user-login-name">
-                <xs:annotation>
-                    <xs:documentation>
-                        The name of the field containing the UserLogin GenericValue. Defaults to "userLogin".
-                        &lt;br/&gt;&lt;br/&gt;
-                        Optional. Attribute type: constant.
-                    </xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
         </xs:complexType>
     </xs:element>
     <xs:element name="call-map-processor" substitutionGroup="CallOperations">
@@ -500,34 +442,41 @@ under the License.
     <xs:element name="set-service-fields" substitutionGroup="CallOperations">
         <xs:annotation>
             <xs:documentation>
-                Take all the incoming files for this service, or all the incoming service attributes,
-                and look for fields with the same name in the incoming map and copy those onto the outgoing map.
+                Copies elements from a source map that match a service's IN attributes to a target map.
+                If the target map does not exist, one will be created.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.set-service-fields"/>
+            <xs:attribute type="xs:string" name="service-name" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the service to get the IN attributes from.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: constant+expr.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="map" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The map to copy the matching IN attributes from.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="to-map" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The map to copy the matching IN attributes to.
+                        If the map does not exist, one will be created.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.set-service-fields">
-        <xs:attribute type="xs:string" name="service-name" use="required">
-            <xs:annotation><xs:documentation>Name of the service to get all the incoming attributes (parameters) from.</xs:documentation></xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="map" use="required">
-            <xs:annotation><xs:documentation>Incoming map to copy fields from.</xs:documentation></xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="to-map" use="required">
-            <xs:annotation><xs:documentation>Map to copy to fields to.</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="call-service" substitutionGroup="CallOperations">
         <xs:annotation>
             <xs:documentation>

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/SetServiceFields.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/SetServiceFields.java?rev=1334450&r1=1334449&r2=1334450&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/SetServiceFields.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/SetServiceFields.java Sat May  5 17:00:36 2012
@@ -25,82 +25,119 @@ import javolution.util.FastList;
 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.minilang.MiniLangException;
+import org.ofbiz.minilang.MiniLangRuntimeException;
+import org.ofbiz.minilang.MiniLangUtil;
+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;
-import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ModelService;
 import org.w3c.dom.Element;
 
 /**
- * Sets all Service parameters/attributes in the to-map using the map as a source
+ * Sets all Service parameters/attributes in the to-map using the map as a source.
  */
-public class SetServiceFields extends MethodOperation {
+public final class SetServiceFields extends MethodOperation {
 
     public static final String module = SetServiceFields.class.getName();
 
-    ContextAccessor<List<Object>> errorListAcsr;
-    ContextAccessor<Map<String, ? extends Object>> mapAcsr;
-    String serviceName;
-    ContextAccessor<Map<String, Object>> toMapAcsr;
+    // This method is needed only during the v1 to v2 transition
+    private static boolean autoCorrect(Element element) {
+        String errorListAttr = element.getAttribute("error-list-name");
+        if (!errorListAttr.isEmpty()) {
+            element.removeAttribute("error-list-name");
+            return true;
+        }
+        return false;
+    }
+
+    private final FlexibleMapAccessor<Map<String, ? extends Object>> mapFma;
+    private final FlexibleStringExpander serviceNameFse;
+    private final FlexibleMapAccessor<Map<String, Object>> toMapFma;
 
     public SetServiceFields(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        serviceName = element.getAttribute("service-name");
-        mapAcsr = new ContextAccessor<Map<String, ? extends Object>>(element.getAttribute("map"), element.getAttribute("map-name"));
-        toMapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("to-map"), element.getAttribute("to-map-name"));
-        errorListAcsr = new ContextAccessor<List<Object>>(element.getAttribute("error-list-name"), "error_list");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "service-name", "map", "to-map");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "service-name", "map", "to-map");
+            MiniLangValidate.constantPlusExpressionAttributes(simpleMethod, element, "service-name");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "map", "to-map");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        boolean elementModified = autoCorrect(element);
+        if (elementModified && MiniLangUtil.autoCorrectOn()) {
+            MiniLangUtil.flagDocumentAsCorrected(element);
+        }
+        serviceNameFse = FlexibleStringExpander.getInstance(element.getAttribute("service-name"));
+        mapFma = FlexibleMapAccessor.getInstance(element.getAttribute("map"));
+        toMapFma = FlexibleMapAccessor.getInstance(element.getAttribute("to-map"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        List<Object> messages = errorListAcsr.get(methodContext);
-        if (messages == null) {
-            messages = FastList.newInstance();
-            errorListAcsr.put(methodContext, messages);
-        }
-        String serviceName = methodContext.expandString(this.serviceName);
-        Map<String, ? extends Object> fromMap = mapAcsr.get(methodContext);
-        if (fromMap == null) {
-            Debug.logWarning("The from map in set-service-field was not found with name: " + mapAcsr, module);
-            return true;
+        String serviceName = serviceNameFse.expandString(methodContext.getEnvMap());
+        ModelService modelService = null;
+        try {
+            modelService = methodContext.getDispatcher().getDispatchContext().getModelService(serviceName);
+        } catch (GenericServiceException e) {
+            throw new MiniLangRuntimeException("Could not get service definition for service name \"" + serviceName + "\": " + e.getMessage(), this);
         }
-        Map<String, Object> toMap = toMapAcsr.get(methodContext);
+        Map<String, Object> toMap = toMapFma.get(methodContext.getEnvMap());
         if (toMap == null) {
             toMap = FastMap.newInstance();
-            toMapAcsr.put(methodContext, toMap);
+            toMapFma.put(methodContext.getEnvMap(), toMap);
         }
-        LocalDispatcher dispatcher = methodContext.getDispatcher();
-        ModelService modelService = null;
-        try {
-            modelService = dispatcher.getDispatchContext().getModelService(serviceName);
-        } catch (GenericServiceException e) {
-            String errMsg = "In set-service-fields could not get service definition for service name [" + serviceName + "]: " + e.toString();
-            Debug.logError(e, errMsg, module);
-            methodContext.setErrorReturn(errMsg, simpleMethod);
-            return false;
+        Map<String, ? extends Object> fromMap = mapFma.get(methodContext.getEnvMap());
+        if (fromMap == null) {
+            if (Debug.verboseOn()) {
+                Debug.logVerbose("The from map in set-service-field was not found with name: " + mapFma, module);
+            }
+            return true;
+        }
+        List<Object> errorMessages = FastList.newInstance();
+        Map<String, Object> validAttributes = modelService.makeValid(fromMap, "IN", true, errorMessages, methodContext.getTimeZone(), methodContext.getLocale());
+        if (errorMessages.size() > 0) {
+            for (Object obj : errorMessages) {
+                simpleMethod.addErrorMessage(methodContext, (String) obj);
+            }
+            throw new MiniLangRuntimeException("Errors encountered while setting service attributes for service name \"" + serviceName + "\"", this);
         }
-        toMap.putAll(modelService.makeValid(fromMap, "IN", true, messages, methodContext.getTimeZone(), methodContext.getLocale()));
+        toMap.putAll(validAttributes);
         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 "<set-service-fields/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<set-service-fields ");
+        if (!this.serviceNameFse.isEmpty()) {
+            sb.append("service-name=\"").append(this.serviceNameFse).append("\" ");
+        }
+        if (!this.mapFma.isEmpty()) {
+            sb.append("map=\"").append(this.mapFma).append("\" ");
+        }
+        if (this.toMapFma != null) {
+            sb.append("to-map=\"").append(this.toMapFma).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
     public static final class SetServiceFieldsFactory implements Factory<SetServiceFields> {