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/07/10 14:06:00 UTC

svn commit: r1359626 [11/12] - in /ofbiz/branches/release12.04: ./ framework/base/ framework/base/src/org/ofbiz/base/util/collections/ framework/base/src/org/ofbiz/base/util/collections/test/ framework/base/src/org/ofbiz/base/util/string/ framework/ent...

Modified: ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/eventops/SessionToField.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/eventops/SessionToField.java?rev=1359626&r1=1359625&r2=1359626&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/eventops/SessionToField.java (original)
+++ ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/eventops/SessionToField.java Tue Jul 10 12:05:55 2012
@@ -18,91 +18,81 @@
  *******************************************************************************/
 package org.ofbiz.minilang.method.eventops;
 
-import java.util.Map;
-
-import javolution.util.FastMap;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.collections.FlexibleServletAccessor;
+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.SimpleMethod;
-import org.ofbiz.minilang.method.ContextAccessor;
 import org.ofbiz.minilang.method.MethodContext;
 import org.ofbiz.minilang.method.MethodOperation;
 import org.w3c.dom.Element;
 
 /**
- * Copies a Servlet session attribute to a map field
+ * Implements the <session-to-field> element.
+ * 
+ * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Csessiontofield%3E}}">Mini-language Reference</a>
  */
 public class SessionToField extends MethodOperation {
 
-    public static final String module = SessionToField.class.getName();
-
-    String defaultVal;
-    ContextAccessor<Object> fieldAcsr;
-    ContextAccessor<Map<String, Object>> mapAcsr;
-    FlexibleServletAccessor<Object> sessionAcsr;
+    private final FlexibleStringExpander defaultFse;
+    private final FlexibleMapAccessor<Object> fieldFma;
+    private final FlexibleStringExpander attributeNameFse;
 
     public SessionToField(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        // the schema for this element now just has the "field" attribute, though the old "field-name" and "map-name" pair is still supported
-        mapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("map-name"));
-        fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field"), element.getAttribute("field-name"));
-        sessionAcsr = new FlexibleServletAccessor<Object>(element.getAttribute("session-name"), fieldAcsr.toString());
-        defaultVal = element.getAttribute("default");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "field", "session-name", "default");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "field");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "field");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
+        String attributeName = element.getAttribute("session-name");
+        if (!attributeName.isEmpty()) {
+            this.attributeNameFse = FlexibleStringExpander.getInstance(attributeName);
+        } else {
+            this.attributeNameFse = FlexibleStringExpander.getInstance(this.fieldFma.toString());
+        }
+        this.defaultFse = FlexibleStringExpander.getInstance(element.getAttribute("default"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        String defaultVal = methodContext.expandString(this.defaultVal);
-        Object fieldVal = null;
-        // only run this if it is in an EVENT context
         if (methodContext.getMethodType() == MethodContext.EVENT) {
-            fieldVal = sessionAcsr.get(methodContext.getRequest().getSession(), methodContext.getEnvMap());
-            if (fieldVal == null) {
-                Debug.logWarning("Session attribute value not found with name " + sessionAcsr, module);
-            }
-        }
-        // if fieldVal is null, or is a String and has zero length, use defaultVal
-        if (fieldVal == null) {
-            fieldVal = defaultVal;
-        } else if (fieldVal instanceof String) {
-            String strVal = (String) fieldVal;
-            if (strVal.length() == 0) {
-                fieldVal = defaultVal;
+            String attributeName = attributeNameFse.expandString(methodContext.getEnvMap());
+            Object value = methodContext.getRequest().getSession().getAttribute(attributeName);
+            if (value == null || (value instanceof String && ((String) value).isEmpty())) {
+                value = defaultFse.expandString(methodContext.getEnvMap());
             }
-        }
-        if (!mapAcsr.isEmpty()) {
-            Map<String, Object> fromMap = mapAcsr.get(methodContext);
-            if (fromMap == null) {
-                Debug.logWarning("Map not found with name " + mapAcsr + " creating a new map", module);
-                fromMap = FastMap.newInstance();
-                mapAcsr.put(methodContext, fromMap);
-            }
-            fieldAcsr.put(fromMap, fieldVal, methodContext);
-        } else {
-            fieldAcsr.put(methodContext, fieldVal);
+            fieldFma.put(methodContext.getEnvMap(), value);
         }
         return true;
     }
 
     @Override
-    public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
-    }
-
-    @Override
-    public String rawString() {
-        // TODO: add all attributes and other info
-        return "<session-to-field session-name=\"" + this.sessionAcsr + "\" field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<session-to-field ");
+        sb.append("field=\"").append(this.fieldFma).append("\" ");
+        if (!this.attributeNameFse.isEmpty()) {
+            sb.append("session-name=\"").append(this.attributeNameFse).append("\" ");
+        }
+        if (!this.defaultFse.isEmpty()) {
+            sb.append("default=\"").append(this.defaultFse).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;session-to-field&gt; element.
+     */
     public static final class SessionToFieldFactory implements Factory<SessionToField> {
+        @Override
         public SessionToField createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new SessionToField(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "session-to-field";
         }

Modified: ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/eventops/WebappPropertyToField.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/eventops/WebappPropertyToField.java?rev=1359626&r1=1359625&r2=1359626&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/eventops/WebappPropertyToField.java (original)
+++ ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/eventops/WebappPropertyToField.java Tue Jul 10 12:05:55 2012
@@ -19,103 +19,93 @@
 package org.ofbiz.minilang.method.eventops;
 
 import java.net.URL;
-import java.util.Map;
 
 import javax.servlet.ServletContext;
 
-import javolution.util.FastMap;
-
-import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
+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.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.w3c.dom.Element;
 
 /**
- * Copies a property value from a properties file in a ServletContext resource to a field
+ * Implements the &lt;webapp-property-to-field&gt; element.
+ * 
+ * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Cwebapppropertytofield%3E}}">Mini-language Reference</a>
  */
-public class WebappPropertyToField extends MethodOperation {
-
-    public static final String module = WebappPropertyToField.class.getName();
+public final class WebappPropertyToField extends MethodOperation {
 
-    String defaultVal;
-    ContextAccessor<Object> fieldAcsr;
-    ContextAccessor<Map<String, Object>> mapAcsr;
-    String property;
-    String resource;
+    private final FlexibleStringExpander defaultFse;
+    private final FlexibleMapAccessor<Object> fieldFma;
+    private final FlexibleStringExpander propertyFse;
+    private final FlexibleStringExpander resourceFse;
 
     public WebappPropertyToField(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        resource = element.getAttribute("resource");
-        property = element.getAttribute("property");
-        defaultVal = element.getAttribute("default");
-        // the schema for this element now just has the "field" attribute, though the old "field-name" and "map-name" pair is still supported
-        fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field"), element.getAttribute("field-name"));
-        mapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("map-name"));
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "field", "resource", "property", "default");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "field", "resource", "property");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "field");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
+        this.resourceFse = FlexibleStringExpander.getInstance(element.getAttribute("resource"));
+        this.propertyFse = FlexibleStringExpander.getInstance(element.getAttribute("property"));
+        this.defaultFse = FlexibleStringExpander.getInstance(element.getAttribute("default"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        String resource = methodContext.expandString(this.resource);
-        String property = methodContext.expandString(this.property);
-        String defaultVal = methodContext.expandString(this.defaultVal);
-        String fieldVal = null;
-        // only run this if it is in an EVENT context
         if (methodContext.getMethodType() == MethodContext.EVENT) {
+            String resource = resourceFse.expandString(methodContext.getEnvMap());
             ServletContext servletContext = (ServletContext) methodContext.getRequest().getAttribute("servletContext");
             URL propsUrl = null;
             try {
                 propsUrl = servletContext.getResource(resource);
             } catch (java.net.MalformedURLException e) {
-                Debug.logWarning(e, "Error finding webapp resource (properties file) not found with name " + resource, module);
+                throw new MiniLangRuntimeException("Exception thrown while finding properties file " + resource + ": " + e.getMessage(), this);
             }
             if (propsUrl == null) {
-                Debug.logWarning("Webapp resource (properties file) not found with name " + resource, module);
-            } else {
-                fieldVal = UtilProperties.getPropertyValue(propsUrl, property);
-                if (UtilValidate.isEmpty(fieldVal)) {
-                    Debug.logWarning("Webapp resource property value not found with name " + property + " in resource " + resource, module);
-                }
+                throw new MiniLangRuntimeException("Properties file " + resource + " not found.", this);
             }
-        }
-        // if fieldVal is null, or has zero length, use defaultVal
-        if (UtilValidate.isEmpty(fieldVal))
-            fieldVal = defaultVal;
-        if (!mapAcsr.isEmpty()) {
-            Map<String, Object> fromMap = mapAcsr.get(methodContext);
-            if (fromMap == null) {
-                Debug.logWarning("Map not found with name " + mapAcsr + " creating a new map", module);
-                fromMap = FastMap.newInstance();
-                mapAcsr.put(methodContext, fromMap);
+            String property = propertyFse.expandString(methodContext.getEnvMap());
+            String fieldVal = UtilProperties.getPropertyValue(propsUrl, property);
+            if (fieldVal == null) {
+                fieldVal = defaultFse.expandString(methodContext.getEnvMap());
             }
-            fieldAcsr.put(fromMap, fieldVal, methodContext);
-        } else {
-            fieldAcsr.put(methodContext, fieldVal);
+            fieldFma.put(methodContext.getEnvMap(), fieldVal);
         }
         return true;
     }
 
     @Override
-    public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
-    }
-
-    @Override
-    public String rawString() {
-        // TODO: add all attributes and other info
-        return "<webapp-property-to-field field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<webapp-property-to-field ");
+        sb.append("field=\"").append(this.fieldFma).append("\" ");
+        sb.append("resource=\"").append(this.resourceFse).append("\" ");
+        sb.append("property=\"").append(this.propertyFse).append("\" ");
+        if (!this.defaultFse.isEmpty()) {
+            sb.append("default=\"").append(this.defaultFse).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;webapp-property-to-field&gt; element.
+     */
     public static final class WebappPropertyToFieldFactory implements Factory<WebappPropertyToField> {
+        @Override
         public WebappPropertyToField createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new WebappPropertyToField(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "webapp-property-to-field";
         }

Modified: ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckPermission.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckPermission.java?rev=1359626&r1=1359625&r2=1359626&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckPermission.java (original)
+++ ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckPermission.java Tue Jul 10 12:05:55 2012
@@ -18,18 +18,20 @@
  *******************************************************************************/
 package org.ofbiz.minilang.method.ifops;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
 import javolution.util.FastList;
 
-import org.ofbiz.base.util.UtilProperties;
-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.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.MessageElement;
 import org.ofbiz.minilang.method.MethodContext;
 import org.ofbiz.minilang.method.MethodOperation;
 import org.ofbiz.security.Security;
@@ -37,86 +39,50 @@ import org.ofbiz.security.authz.Authoriz
 import org.w3c.dom.Element;
 
 /**
- * If the user does not have the specified permission the fail-message or fail-property sub-elements are used to add a message to the error-list.
+ * Implements the &lt;check-permission&gt; element.
+ * 
+ * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Ccheckpermission%3E}}">Mini-language Reference</a>
  */
-public class CheckPermission extends MethodOperation {
+public final class CheckPermission extends MethodOperation {
 
-    /** If null no partyId env-name will be checked against the userLogin.partyId and accepted as permission */
-    ContextAccessor<String> acceptUlPartyIdEnvNameAcsr = null;
-    List<PermissionInfo> altPermissions = null;
-    ContextAccessor<List<Object>> errorListAcsr;
-    boolean isProperty = false;
-    String message = null;
-    PermissionInfo permissionInfo;
-    String propertyResource = null;
+    private final List<PermissionInfo> altPermissionInfoList;
+    private final FlexibleMapAccessor<List<String>> errorListFma;
+    private final MessageElement messageElement;
+    private final PermissionInfo primaryPermissionInfo;
 
     public CheckPermission(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        permissionInfo = new PermissionInfo(element);
-        this.errorListAcsr = new ContextAccessor<List<Object>>(element.getAttribute("error-list-name"), "error_list");
-        Element acceptUserloginPartyElement = UtilXml.firstChildElement(element, "accept-userlogin-party");
-        if (acceptUserloginPartyElement != null) {
-            acceptUlPartyIdEnvNameAcsr = new ContextAccessor<String>(acceptUserloginPartyElement.getAttribute("party-id-env-name"), "partyId");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "permission", "action", "error-list-name");
+            MiniLangValidate.constantAttributes(simpleMethod, element, "error-list-name");
+            MiniLangValidate.childElements(simpleMethod, element, "alt-permission", "fail-message", "fail-property");
+            MiniLangValidate.requireAnyChildElement(simpleMethod, element, "fail-message", "fail-property");
         }
+        errorListFma = FlexibleMapAccessor.getInstance(MiniLangValidate.checkAttribute(element.getAttribute("error-list-name"), "error_list"));
+        primaryPermissionInfo = new PermissionInfo(element);
         List<? extends Element> altPermElements = UtilXml.childElementList(element, "alt-permission");
         if (!altPermElements.isEmpty()) {
-            altPermissions = FastList.newInstance();
-        }
-        for (Element altPermElement : altPermElements) {
-            altPermissions.add(new PermissionInfo(altPermElement));
-        }
-        Element failMessage = UtilXml.firstChildElement(element, "fail-message");
-        Element failProperty = UtilXml.firstChildElement(element, "fail-property");
-        if (failMessage != null) {
-            this.message = failMessage.getAttribute("message");
-            this.isProperty = false;
-        } else if (failProperty != null) {
-            this.propertyResource = failProperty.getAttribute("resource");
-            this.message = failProperty.getAttribute("property");
-            this.isProperty = true;
-        }
-    }
-
-    public void addMessage(List<Object> messages, MethodContext methodContext) {
-        String message = methodContext.expandString(this.message);
-        String propertyResource = methodContext.expandString(this.propertyResource);
-        if (!isProperty && message != null) {
-            messages.add(message);
-            // if (Debug.infoOn()) Debug.logInfo("[SimpleMapOperation.addMessage] Adding message: " + message, module);
-        } else if (isProperty && propertyResource != null && message != null) {
-            // String propMsg = UtilProperties.getPropertyValue(UtilURL.fromResource(propertyResource, loader), message);
-            String propMsg = UtilProperties.getMessage(propertyResource, message, methodContext.getEnvMap(), methodContext.getLocale());
-            if (UtilValidate.isEmpty(propMsg)) {
-                messages.add("Simple Method Permission error occurred, but no message was found, sorry.");
-            } else {
-                messages.add(methodContext.expandString(propMsg));
+            List<PermissionInfo> permissionInfoList = new ArrayList<PermissionInfo>(altPermElements.size());
+            for (Element altPermElement : altPermElements) {
+                permissionInfoList.add(new PermissionInfo(altPermElement));
             }
-            // if (Debug.infoOn()) Debug.logInfo("[SimpleMapOperation.addMessage] Adding property message: " + propMsg, module);
+            altPermissionInfoList = Collections.unmodifiableList(permissionInfoList);
         } else {
-            messages.add("Simple Method Permission error occurred, but no message was found, sorry.");
-            // if (Debug.infoOn()) Debug.logInfo("[SimpleMapOperation.addMessage] ERROR: No message found", module);
+            altPermissionInfoList = null;
         }
+        messageElement = MessageElement.fromParentElement(element, simpleMethod);
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
         boolean hasPermission = false;
-        List<Object> messages = errorListAcsr.get(methodContext);
-        if (messages == null) {
-            messages = FastList.newInstance();
-            errorListAcsr.put(methodContext, messages);
-        }
-        // if no user is logged in, treat as if the user does not have permission: do not run subops
         GenericValue userLogin = methodContext.getUserLogin();
         if (userLogin != null) {
             Authorization authz = methodContext.getAuthz();
             Security security = methodContext.getSecurity();
-            if (this.permissionInfo.hasPermission(methodContext, userLogin, authz, security)) {
-                hasPermission = true;
-            }
-            // if failed, check alternate permissions
-            if (!hasPermission && altPermissions != null) {
-                for (PermissionInfo altPermInfo : altPermissions) {
+            hasPermission = this.primaryPermissionInfo.hasPermission(methodContext, userLogin, authz, security);
+            if (!hasPermission && altPermissionInfoList != null) {
+                for (PermissionInfo altPermInfo : altPermissionInfoList) {
                     if (altPermInfo.hasPermission(methodContext, userLogin, authz, security)) {
                         hasPermission = true;
                         break;
@@ -124,61 +90,67 @@ public class CheckPermission extends Met
                 }
             }
         }
-        if (!hasPermission && acceptUlPartyIdEnvNameAcsr != null) {
-            String acceptPartyId = acceptUlPartyIdEnvNameAcsr.get(methodContext);
-            if (UtilValidate.isEmpty(acceptPartyId)) {
-                // try the parameters Map
-                Map<String, Object> parameters = methodContext.getEnv("parameters");
-                if (parameters != null) {
-                    acceptPartyId = acceptUlPartyIdEnvNameAcsr.get(parameters, methodContext);
-                }
+        if (!hasPermission && messageElement != null) {
+            List<String> messages = errorListFma.get(methodContext.getEnvMap());
+            if (messages == null) {
+                messages = FastList.newInstance();
+                errorListFma.put(methodContext.getEnvMap(), messages);
             }
-            if (UtilValidate.isNotEmpty(acceptPartyId) && UtilValidate.isNotEmpty(userLogin.getString("partyId")) && acceptPartyId.equals(userLogin.getString("partyId"))) {
-                hasPermission = true;
-            }
-        }
-        if (!hasPermission) {
-            this.addMessage(messages, methodContext);
+            messages.add(messageElement.getMessage(methodContext));
         }
         return true;
     }
 
     @Override
-    public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
-    }
-
-    @Override
-    public String rawString() {
-        // TODO: add all attributes and other info
-        return "<check-permission/>";
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<check-permission ");
+        sb.append("permission=\"").append(this.primaryPermissionInfo.permissionFse).append("\" ");
+        if (!this.primaryPermissionInfo.actionFse.isEmpty()) {
+            sb.append("action=\"").append(this.primaryPermissionInfo.actionFse).append("\" ");
+        }
+        if (!"error_list".equals(this.errorListFma.getOriginalName())) {
+            sb.append("error-list-name=\"").append(this.errorListFma).append("\" ");
+        }
+        if (messageElement != null) {
+            sb.append(">").append(messageElement).append("</check-permission>");
+        } else {
+            sb.append("/>");
+        }
+        return sb.toString();
     }
 
+    /**
+     * A &lt;check-permission&gt; element factory. 
+     */
     public static final class CheckPermissionFactory implements Factory<CheckPermission> {
+        @Override
         public CheckPermission createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new CheckPermission(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "check-permission";
         }
     }
 
-    public static class PermissionInfo {
-        String action;
-        String permission;
-
-        public PermissionInfo(Element altPermissionElement) {
-            this.permission = altPermissionElement.getAttribute("permission");
-            this.action = altPermissionElement.getAttribute("action");
-        }
-
-        public boolean hasPermission(MethodContext methodContext, GenericValue userLogin, Authorization authz, Security security) {
-            String permission = methodContext.expandString(this.permission);
-            String action = methodContext.expandString(this.action);
-
-            if (UtilValidate.isNotEmpty(action)) {
+    private class PermissionInfo {
+        private final FlexibleStringExpander actionFse;
+        private final FlexibleStringExpander permissionFse;
+
+        private PermissionInfo(Element element) throws MiniLangException {
+            if (MiniLangValidate.validationOn()) {
+                MiniLangValidate.attributeNames(simpleMethod, element, "permission", "action");
+                MiniLangValidate.requiredAttributes(simpleMethod, element, "permission");
+            }
+            this.permissionFse = FlexibleStringExpander.getInstance(element.getAttribute("permission"));
+            this.actionFse = FlexibleStringExpander.getInstance(element.getAttribute("action"));
+        }
+
+        private boolean hasPermission(MethodContext methodContext, GenericValue userLogin, Authorization authz, Security security) {
+            String permission = permissionFse.expandString(methodContext.getEnvMap());
+            String action = actionFse.expandString(methodContext.getEnvMap());
+            if (!action.isEmpty()) {
                 // run hasEntityPermission
                 return security.hasEntityPermission(permission, action, userLogin);
             } else {

Modified: ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/IfInstanceOf.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/IfInstanceOf.java?rev=1359626&r1=1359625&r2=1359626&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/IfInstanceOf.java (original)
+++ ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/IfInstanceOf.java Tue Jul 10 12:05:55 2012
@@ -20,61 +20,70 @@ package org.ofbiz.minilang.method.ifops;
 
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
-import javolution.util.FastList;
-
-import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.ObjectType;
 import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
 import org.ofbiz.minilang.MiniLangException;
+import org.ofbiz.minilang.MiniLangRuntimeException;
+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;
 
-public class IfInstanceOf extends MethodOperation {
-
-    public static final String module = IfInstanceOf.class.getName();
-
-    protected String className = null;
-    protected List<MethodOperation> elseSubOps = null;
-    protected ContextAccessor<Object> fieldAcsr = null;
-    protected ContextAccessor<Map<String, ? extends Object>> mapAcsr = null;
-    protected List<MethodOperation> subOps;
+/**
+ * Implements the &lt;if-instance-of&gt; element.
+ * 
+ * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Cifinstanceof%3E}}">Mini-language Reference</a>
+ */
+public final class IfInstanceOf extends MethodOperation {
+
+    private final String className;
+    private final Class<?> compareClass;
+    private final List<MethodOperation> elseSubOps;
+    private final FlexibleMapAccessor<Object> fieldFma;
+    private final List<MethodOperation> subOps;
 
     public IfInstanceOf(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        // the schema for this element now just has the "field" attribute, though the old "field-name" and "map-name" pair is still supported
-        this.fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field"), element.getAttribute("field-name"));
-        this.mapAcsr = new ContextAccessor<Map<String, ? extends Object>>(element.getAttribute("map-name"));
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "field", "class");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "field", "class");
+            MiniLangValidate.constantAttributes(simpleMethod, element, "class");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "field");
+        }
+        this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
         this.className = element.getAttribute("class");
+        Class<?> compareClass = null;
+        if (!className.isEmpty()) {
+            try {
+                compareClass = ObjectType.loadClass(className);
+            } catch (ClassNotFoundException e) {
+                MiniLangValidate.handleError("Invalid class name " + className, simpleMethod, element);
+            }
+        }
+        this.compareClass = compareClass;
         this.subOps = Collections.unmodifiableList(SimpleMethod.readOperations(element, simpleMethod));
         Element elseElement = UtilXml.firstChildElement(element, "else");
         if (elseElement != null) {
             this.elseSubOps = Collections.unmodifiableList(SimpleMethod.readOperations(elseElement, simpleMethod));
+        } else {
+            this.elseSubOps = null;
         }
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        // only run subOps if element is instanceOf
+        if (this.compareClass == null) {
+            throw new MiniLangRuntimeException("Invalid class name " + className, this);
+        }
         boolean runSubOps = false;
-        Object fieldVal = null;
-        if (!mapAcsr.isEmpty()) {
-            Map<String, ? extends Object> fromMap = mapAcsr.get(methodContext);
-            if (fromMap == null) {
-                if (Debug.infoOn())
-                    Debug.logInfo("Map not found with name " + mapAcsr + ", running operations", module);
-            } else {
-                fieldVal = fieldAcsr.get(fromMap, methodContext);
-            }
-        } else {
-            // no map name, try the env
-            fieldVal = fieldAcsr.get(methodContext);
+        Object fieldVal = fieldFma.get(methodContext.getEnvMap());
+        if (fieldVal != null) {
+            runSubOps = ObjectType.instanceOf(fieldVal.getClass(), compareClass);
         }
-        runSubOps = ObjectType.instanceOf(fieldVal, className);
         if (runSubOps) {
             return SimpleMethod.runSubOps(subOps, methodContext);
         } else {
@@ -87,30 +96,38 @@ public class IfInstanceOf extends Method
     }
 
     @Override
-    public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
-    }
-
-    public List<MethodOperation> getAllSubOps() {
-        List<MethodOperation> allSubOps = FastList.newInstance();
-        allSubOps.addAll(this.subOps);
-        if (this.elseSubOps != null)
-            allSubOps.addAll(this.elseSubOps);
-        return allSubOps;
+    public void gatherArtifactInfo(ArtifactInfoContext aic) {
+        for (MethodOperation method : this.subOps) {
+            method.gatherArtifactInfo(aic);
+        }
+        if (this.elseSubOps != null) {
+            for (MethodOperation method : this.elseSubOps) {
+                method.gatherArtifactInfo(aic);
+            }
+        }
     }
 
     @Override
-    public String rawString() {
-        // TODO: add all attributes and other info
-        return "<if-instance-of field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<if-instance-of ");
+        sb.append("field=\"").append(this.fieldFma).append("\" ");
+        if (compareClass != null) {
+            sb.append("class=\"").append(compareClass.getName()).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
+    /**
+     * A &lt;if-instance-of&gt; element factory. 
+     */
     public static final class IfInstanceOfFactory implements Factory<IfInstanceOf> {
+        @Override
         public IfInstanceOf createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new IfInstanceOf(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "if-instance-of";
         }

Modified: ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/IfNotEmpty.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/IfNotEmpty.java?rev=1359626&r1=1359625&r2=1359626&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/IfNotEmpty.java (original)
+++ ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/ifops/IfNotEmpty.java Tue Jul 10 12:05:55 2012
@@ -20,111 +20,83 @@ package org.ofbiz.minilang.method.ifops;
 
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
-import javolution.util.FastList;
-
-import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.ObjectType;
 import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
 import org.ofbiz.minilang.MiniLangException;
 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;
 
 /**
- * If the specified field is not empty process sub-operations
+ * Implements the &lt;if-not-empty&gt; element.
+ * 
+ * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Cifnotempty%3E}}">Mini-language Reference</a>
  */
-public class IfNotEmpty extends MethodOperation {
-
-    public static final String module = IfNotEmpty.class.getName();
+public final class IfNotEmpty extends MethodOperation {
 
-    protected List<MethodOperation> elseSubOps = null;
-    protected ContextAccessor<Object> fieldAcsr;
-    protected ContextAccessor<Map<String, ? extends Object>> mapAcsr;
-    protected List<MethodOperation> subOps;
+    private final List<MethodOperation> elseSubOps;
+    private final FlexibleMapAccessor<Object> fieldFma;
+    private final List<MethodOperation> subOps;
 
     public IfNotEmpty(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        // NOTE: this is still supported, but is deprecated
-        this.mapAcsr = new ContextAccessor<Map<String, ? extends Object>>(element.getAttribute("map-name"));
-        this.fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field"));
-        if (this.fieldAcsr.isEmpty()) {
-            // NOTE: this is still supported, but is deprecated
-            this.fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field-name"));
-        }
+        this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
         this.subOps = Collections.unmodifiableList(SimpleMethod.readOperations(element, simpleMethod));
         Element elseElement = UtilXml.firstChildElement(element, "else");
         if (elseElement != null) {
             this.elseSubOps = Collections.unmodifiableList(SimpleMethod.readOperations(elseElement, simpleMethod));
+        } else {
+            this.elseSubOps = null;
         }
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        // if conditions fails, always return true; if a sub-op returns false
-        // return false and stop, otherwise return true
-        // return true;
-        Object fieldVal = null;
-        if (!mapAcsr.isEmpty()) {
-            Map<String, ? extends Object> fromMap = mapAcsr.get(methodContext);
-            if (fromMap == null) {
-                if (Debug.verboseOn())
-                    Debug.logVerbose("Map not found with name " + mapAcsr + ", not running operations", module);
-            } else {
-                fieldVal = fieldAcsr.get(fromMap, methodContext);
-            }
-        } else {
-            // no map name, try the env
-            fieldVal = fieldAcsr.get(methodContext);
-        }
-        if (fieldVal == null) {
-            if (Debug.verboseOn())
-                Debug.logVerbose("Field value not found with name " + fieldAcsr + " in Map with name " + mapAcsr + ", not running operations", module);
-        }
-        // only run subOps if element is not empty/null
-        boolean runSubOps = !ObjectType.isEmpty(fieldVal);
-        if (runSubOps) {
-            // if (Debug.verboseOn()) Debug.logVerbose("IfNotEmpty: Running if operations mapAcsr=" + mapAcsr + " fieldAcsr=" + fieldAcsr, module);
+        Object fieldVal = fieldFma.get(methodContext.getEnvMap());
+        if (!ObjectType.isEmpty(fieldVal)) {
             return SimpleMethod.runSubOps(subOps, methodContext);
         } else {
             if (elseSubOps != null) {
-                // if (Debug.verboseOn()) Debug.logVerbose("IfNotEmpty: Running else operations mapAcsr=" + mapAcsr + " fieldAcsr=" + fieldAcsr, module);
                 return SimpleMethod.runSubOps(elseSubOps, methodContext);
             } else {
-                // if (Debug.verboseOn()) Debug.logVerbose("IfNotEmpty: Not Running any operations mapAcsr=" + mapAcsr + " fieldAcsr=" + fieldAcsr, module);
                 return true;
             }
         }
     }
 
     @Override
-    public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
-    }
-
-    public List<MethodOperation> getAllSubOps() {
-        List<MethodOperation> allSubOps = FastList.newInstance();
-        allSubOps.addAll(this.subOps);
-        if (this.elseSubOps != null)
-            allSubOps.addAll(this.elseSubOps);
-        return allSubOps;
+    public void gatherArtifactInfo(ArtifactInfoContext aic) {
+        for (MethodOperation method : this.subOps) {
+            method.gatherArtifactInfo(aic);
+        }
+        if (this.elseSubOps != null) {
+            for (MethodOperation method : this.elseSubOps) {
+                method.gatherArtifactInfo(aic);
+            }
+        }
     }
 
     @Override
-    public String rawString() {
-        // TODO: add all attributes and other info
-        return "<if-not-empty field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<if-not-empty ");
+        sb.append("field=\"").append(this.fieldFma).append("\"/>");
+        return sb.toString();
     }
 
+    /**
+     * A &lt;if-not-empty&gt; element factory. 
+     */
     public static final class IfNotEmptyFactory implements Factory<IfNotEmpty> {
+        @Override
         public IfNotEmpty createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new IfNotEmpty(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "if-not-empty";
         }

Modified: ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Calculate.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Calculate.java?rev=1359626&r1=1359625&r2=1359626&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Calculate.java (original)
+++ ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Calculate.java Tue Jul 10 12:05:55 2012
@@ -22,25 +22,26 @@ import java.math.BigDecimal;
 import java.text.DecimalFormat;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 
-import javolution.util.FastMap;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.ObjectType;
-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.MiniLangElement;
 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.w3c.dom.Element;
 
 /**
- * Calculates a result based on nested calcops.
+ * Implements the &lt;calculate&gt; element.
+ * 
+ * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Ccalculate%3E}}">Mini-language Reference</a>
  */
-public class Calculate extends MethodOperation {
+public final class Calculate extends MethodOperation {
 
     public static final String module = Calculate.class.getName();
 
@@ -50,36 +51,56 @@ public class Calculate extends MethodOpe
     public static final int TYPE_INTEGER = 4;
     public static final int TYPE_STRING = 5;
     public static final int TYPE_BIG_DECIMAL = 6;
-    public static final BigDecimal ZERO = BigDecimal.ZERO;
 
-    Calculate.SubCalc calcops[];
-    String decimalFormatString;
-    String decimalScaleString;
-    ContextAccessor<Object> fieldAcsr;
-    ContextAccessor<Map<String, Object>> mapAcsr;
-    String roundingModeString;
-    String typeString;
+    private final Calculate.SubCalc calcops[];
+    private final FlexibleStringExpander decimalFormatFse;
+    private final FlexibleStringExpander decimalScaleFse;
+    private final FlexibleMapAccessor<Object> fieldFma;
+    private final FlexibleStringExpander roundingModeFse;
+    private final int type;
+    private final String typeString;
 
     public Calculate(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        // the schema for this element now just has the "field" attribute, though the old "field-name" and "map-name" pair is still supported
-        this.fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field"), element.getAttribute("field-name"));
-        this.mapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("map-name"));
-        decimalScaleString = element.getAttribute("decimal-scale");
-        decimalFormatString = element.getAttribute("decimal-format");
-        typeString = element.getAttribute("type");
-        roundingModeString = element.getAttribute("rounding-mode");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.handleError("<calculate> element is deprecated (use <set>)", simpleMethod, element);
+            MiniLangValidate.attributeNames(simpleMethod, element, "field", "decimal-scale", "decimal-format", "rounding-mode", "type");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "field");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "field");
+            MiniLangValidate.childElements(simpleMethod, element, "calcop", "number");
+        }
+        this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
+        this.decimalFormatFse = FlexibleStringExpander.getInstance(element.getAttribute("decimal-format"));
+        this.decimalScaleFse = FlexibleStringExpander.getInstance(element.getAttribute("decimal-scale"));
+        this.roundingModeFse = FlexibleStringExpander.getInstance(element.getAttribute("rounding-mode"));
+        this.typeString = element.getAttribute("type");
+        int type = Calculate.TYPE_BIG_DECIMAL;
+        if ("Double".equals(typeString)) {
+            type = Calculate.TYPE_DOUBLE;
+        } else if ("Float".equals(typeString)) {
+            type = Calculate.TYPE_FLOAT;
+        } else if ("Long".equals(typeString)) {
+            type = Calculate.TYPE_LONG;
+        } else if ("Integer".equals(typeString)) {
+            type = Calculate.TYPE_INTEGER;
+        } else if ("String".equals(typeString)) {
+            type = Calculate.TYPE_STRING;
+        } else if ("BigDecimal".equals(typeString)) {
+            type = Calculate.TYPE_BIG_DECIMAL;
+        }
+        this.type = type;
         List<? extends Element> calcopElements = UtilXml.childElementList(element);
         calcops = new Calculate.SubCalc[calcopElements.size()];
         int i = 0;
         for (Element calcopElement : calcopElements) {
             String nodeName = calcopElement.getNodeName();
             if ("calcop".equals(nodeName)) {
-                calcops[i] = new Calculate.CalcOp(calcopElement);
+                calcops[i] = new CalcOp(calcopElement, simpleMethod);
             } else if ("number".equals(nodeName)) {
-                calcops[i] = new Calculate.NumberOp(calcopElement);
+                calcops[i] = new NumberOp(calcopElement, simpleMethod);
             } else {
-                Debug.logError("Error: calculate operation with type " + nodeName, module);
+                MiniLangValidate.handleError("Invalid calculate sub-element.", simpleMethod, calcopElement);
+                calcops[i] = new InvalidOp(calcopElement, simpleMethod);
             }
             i++;
         }
@@ -87,25 +108,8 @@ public class Calculate extends MethodOpe
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        String typeString = methodContext.expandString(this.typeString);
-        int type;
-        if ("Double".equals(typeString)) {
-            type = Calculate.TYPE_DOUBLE;
-        } else if ("Float".equals(typeString)) {
-            type = Calculate.TYPE_FLOAT;
-        } else if ("Long".equals(typeString)) {
-            type = Calculate.TYPE_LONG;
-        } else if ("Integer".equals(typeString)) {
-            type = Calculate.TYPE_INTEGER;
-        } else if ("String".equals(typeString)) {
-            type = Calculate.TYPE_STRING;
-        } else if ("BigDecimal".equals(typeString)) {
-            type = Calculate.TYPE_BIG_DECIMAL;
-        } else {
-            type = Calculate.TYPE_BIG_DECIMAL;
-        }
-        String roundingModeString = methodContext.expandString(this.roundingModeString);
-        int roundingMode;
+        String roundingModeString = roundingModeFse.expandString(methodContext.getEnvMap());
+        int roundingMode = BigDecimal.ROUND_HALF_EVEN;
         if ("Ceiling".equals(roundingModeString)) {
             roundingMode = BigDecimal.ROUND_CEILING;
         } else if ("Floor".equals(roundingModeString)) {
@@ -118,37 +122,19 @@ public class Calculate extends MethodOpe
             roundingMode = BigDecimal.ROUND_HALF_UP;
         } else if ("HalfDown".equals(roundingModeString)) {
             roundingMode = BigDecimal.ROUND_HALF_DOWN;
-        } else if ("HalfEven".equals(roundingModeString)) {
-            roundingMode = BigDecimal.ROUND_HALF_EVEN;
         } else if ("Unnecessary".equals(roundingModeString)) {
             roundingMode = BigDecimal.ROUND_UNNECESSARY;
-        } else {
-            // default to HalfEven, reduce cumulative errors
-            roundingMode = BigDecimal.ROUND_HALF_EVEN;
         }
-        String decimalScaleString = methodContext.expandString(this.decimalScaleString);
+        String decimalScaleString = decimalScaleFse.expandString(methodContext.getEnvMap());
         int decimalScale = 2;
-        if (UtilValidate.isNotEmpty(decimalScaleString)) {
+        if (!decimalScaleString.isEmpty()) {
             decimalScale = Integer.valueOf(decimalScaleString).intValue();
         }
-        String decimalFormatString = methodContext.expandString(this.decimalFormatString);
-        DecimalFormat df = null;
-        if (UtilValidate.isNotEmpty(decimalFormatString)) {
-            df = new DecimalFormat(decimalFormatString);
-        }
-        BigDecimal resultValue = ZERO;
-        resultValue = resultValue.setScale(decimalScale, roundingMode);
+        BigDecimal resultValue = BigDecimal.ZERO.setScale(decimalScale, roundingMode);
         for (Calculate.SubCalc calcop : calcops) {
             resultValue = resultValue.add(calcop.calcValue(methodContext, decimalScale, roundingMode));
-            // Debug.logInfo("main total so far: " + resultValue, module);
         }
         resultValue = resultValue.setScale(decimalScale, roundingMode);
-        /*
-         * the old thing that did conversion to string and back, may want to use somewhere sometime...: for now just doing the setScale above (before and after calc ops) try { resultValue = new
-         * BigDecimal(df.format(resultValue)); } catch (ParseException e) { String errorMessage = "Unable to format [" + formatString + "] result [" + resultValue + "]"; Debug.logError(e,
-         * errorMessage, module); if (methodContext.getMethodType() == MethodContext.EVENT) { methodContext.putEnv(simpleMethod.getEventErrorMessageName(), errorMessage); } else if
-         * (methodContext.getMethodType() == MethodContext.SERVICE) { methodContext.putEnv(simpleMethod.getServiceErrorMessageName(), errorMessage); } return false; }
-         */
         Object resultObj = null;
         switch (type) {
             case TYPE_DOUBLE:
@@ -167,7 +153,12 @@ public class Calculate extends MethodOpe
                 break;
             case TYPE_STRING:
                 // run the decimal-formatting
-                if (df != null && resultValue.compareTo(ZERO) > 0) {
+                String decimalFormatString = decimalFormatFse.expandString(methodContext.getEnvMap());
+                DecimalFormat df = null;
+                if (!decimalFormatString.isEmpty()) {
+                    df = new DecimalFormat(decimalFormatString);
+                }
+                if (df != null && resultValue.compareTo(BigDecimal.ZERO) != 0) {
                     resultObj = df.format(resultValue);
                 } else {
                     resultObj = resultValue.toString();
@@ -177,124 +168,112 @@ public class Calculate extends MethodOpe
                 resultObj = resultValue;
                 break;
         }
-
-        if (!mapAcsr.isEmpty()) {
-            Map<String, Object> toMap = mapAcsr.get(methodContext);
-            if (toMap == null) {
-                if (Debug.verboseOn())
-                    Debug.logVerbose("Map not found with name " + mapAcsr + ", creating new map", module);
-                toMap = FastMap.newInstance();
-                mapAcsr.put(methodContext, toMap);
-            }
-            fieldAcsr.put(toMap, resultObj, methodContext);
-        } else {
-            fieldAcsr.put(methodContext, resultObj);
-        }
-
+        fieldFma.put(methodContext.getEnvMap(), resultObj);
         return true;
     }
 
     @Override
-    public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<set ");
+        sb.append("field=\"").append(this.fieldFma).append("\" ");
+        if (!this.roundingModeFse.isEmpty()) {
+            sb.append("rounding-mode=\"").append(this.roundingModeFse).append("\" ");
+        }
+        if (!this.decimalScaleFse.isEmpty()) {
+            sb.append("decimal-scale=\"").append(this.decimalScaleFse).append("\" ");
+        }
+        if (!this.decimalFormatFse.isEmpty()) {
+            sb.append("decimal-format=\"").append(this.decimalFormatFse).append("\" ");
+        }
+        if (!typeString.isEmpty()) {
+            sb.append("type=\"").append(this.typeString).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
-    @Override
-    public String rawString() {
-        // TODO: add all attributes and other info
-        return "<calculate field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+    /**
+     * Interface for &lt;calculate&gt; sub-element implementations.
+     */
+    public interface SubCalc {
+        BigDecimal calcValue(MethodContext methodContext, int scale, int roundingMode) throws MiniLangException;
     }
 
-    protected static class CalcOp implements SubCalc {
-        public static final int OPERATOR_ADD = 1;
-        public static final int OPERATOR_DIVIDE = 4;
-        public static final int OPERATOR_MULTIPLY = 3;
-        public static final int OPERATOR_NEGATIVE = 5;
-        public static final int OPERATOR_SUBTRACT = 2;
-
-        Calculate.SubCalc calcops[];
-        ContextAccessor<Object> fieldAcsr;
-        ContextAccessor<Map<String, ? extends Object>> mapAcsr;
-        String operatorStr;
-
-        public CalcOp(Element element) {
-            // the schema for this element now just has the "field" attribute, though the old "field-name" and "map-name" pair is still supported
-            this.fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field"), element.getAttribute("field-name"));
-            this.mapAcsr = new ContextAccessor<Map<String, ? extends Object>>(element.getAttribute("map-name"));
-            operatorStr = element.getAttribute("operator");
+    /**
+     * Implements the &lt;calcop&gt; element.
+     * 
+     * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Ccalcop%3E}}">Mini-language Reference</a>
+     */
+    public final class CalcOp extends MiniLangElement implements SubCalc {
+        private static final int OPERATOR_ADD = 1;
+        private static final int OPERATOR_DIVIDE = 4;
+        private static final int OPERATOR_MULTIPLY = 3;
+        private static final int OPERATOR_NEGATIVE = 5;
+        private static final int OPERATOR_SUBTRACT = 2;
+
+        private final Calculate.SubCalc calcops[];
+        private final FlexibleMapAccessor<Object> fieldFma;
+        private final int operator;
+
+        private CalcOp(Element element, SimpleMethod simpleMethod) throws MiniLangException {
+            super(element, simpleMethod);
+            if (MiniLangValidate.validationOn()) {
+                MiniLangValidate.attributeNames(simpleMethod, element, "field", "operator");
+                MiniLangValidate.requiredAttributes(simpleMethod, element, "operator");
+                MiniLangValidate.expressionAttributes(simpleMethod, element, "field");
+                MiniLangValidate.childElements(simpleMethod, element, "calcop", "number");
+            }
+            this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
+            String operatorStr = element.getAttribute("operator");
+            int operator = CalcOp.OPERATOR_ADD;
+            if ("subtract".equals(operatorStr)) {
+                operator = CalcOp.OPERATOR_SUBTRACT;
+            } else if ("multiply".equals(operatorStr)) {
+                operator = CalcOp.OPERATOR_MULTIPLY;
+            } else if ("divide".equals(operatorStr)) {
+                operator = CalcOp.OPERATOR_DIVIDE;
+            } else if ("negative".equals(operatorStr)) {
+                operator = CalcOp.OPERATOR_NEGATIVE;
+            }
+            this.operator = operator;
             List<? extends Element> calcopElements = UtilXml.childElementList(element);
             calcops = new Calculate.SubCalc[calcopElements.size()];
             int i = 0;
-
             for (Element calcopElement : calcopElements) {
-                String nodeName = calcopElement.getNodeName();
                 if ("calcop".equals(calcopElement.getNodeName())) {
-                    calcops[i] = new Calculate.CalcOp(calcopElement);
+                    calcops[i] = new Calculate.CalcOp(calcopElement, simpleMethod);
                 } else if ("number".equals(calcopElement.getNodeName())) {
-                    calcops[i] = new Calculate.NumberOp(calcopElement);
+                    calcops[i] = new Calculate.NumberOp(calcopElement, simpleMethod);
                 } else {
-                    Debug.logError("Error: calculate operation unknown with type " + nodeName, module);
+                    MiniLangValidate.handleError("Invalid calculate sub-element.", simpleMethod, calcopElement);
+                    calcops[i] = new InvalidOp(calcopElement, simpleMethod);
                 }
                 i++;
             }
         }
 
-        public BigDecimal calcValue(MethodContext methodContext, int scale, int roundingMode) {
-            String operatorStr = methodContext.expandString(this.operatorStr);
-            int operator = CalcOp.OPERATOR_ADD;
-            if ("get".equals(operatorStr)) {
-                operator = CalcOp.OPERATOR_ADD;
-            } else if ("add".equals(operatorStr)) {
-                operator = CalcOp.OPERATOR_ADD;
-            } else if ("subtract".equals(operatorStr)) {
-                operator = CalcOp.OPERATOR_SUBTRACT;
-            } else if ("multiply".equals(operatorStr)) {
-                operator = CalcOp.OPERATOR_MULTIPLY;
-            } else if ("divide".equals(operatorStr)) {
-                operator = CalcOp.OPERATOR_DIVIDE;
-            } else if ("negative".equals(operatorStr)) {
-                operator = CalcOp.OPERATOR_NEGATIVE;
-            }
-            BigDecimal resultValue = ZERO;
-            resultValue = resultValue.setScale(scale, roundingMode);
+        @Override
+        public BigDecimal calcValue(MethodContext methodContext, int scale, int roundingMode) throws MiniLangException {
+            BigDecimal resultValue = BigDecimal.ZERO.setScale(scale, roundingMode);
             boolean isFirst = true;
-            // if a fieldAcsr was specified, get the field from the map or result and use it as the initial value
-            if (!fieldAcsr.isEmpty()) {
-                Object fieldObj = null;
-                if (!mapAcsr.isEmpty()) {
-                    Map<String, ? extends Object> fromMap = mapAcsr.get(methodContext);
-                    if (fromMap == null) {
-                        if (Debug.verboseOn())
-                            Debug.logVerbose("Map not found with name " + mapAcsr + ", creating new map", module);
-                        fromMap = FastMap.newInstance();
-                        mapAcsr.put(methodContext, fromMap);
-                    }
-                    fieldObj = fieldAcsr.get(fromMap, methodContext);
-                } else {
-                    fieldObj = fieldAcsr.get(methodContext);
-                }
-                if (fieldObj != null) {
-                    if (fieldObj instanceof Double) {
-                        resultValue = new BigDecimal(((Double) fieldObj).doubleValue());
-                    } else if (fieldObj instanceof Long) {
-                        resultValue = BigDecimal.valueOf(((Long) fieldObj).longValue());
-                    } else if (fieldObj instanceof Float) {
-                        resultValue = new BigDecimal(((Float) fieldObj).floatValue());
-                    } else if (fieldObj instanceof Integer) {
-                        resultValue = BigDecimal.valueOf(((Integer) fieldObj).longValue());
-                    } else if (fieldObj instanceof String) {
-                        resultValue = new BigDecimal((String) fieldObj);
-                    } else if (fieldObj instanceof BigDecimal) {
-                        resultValue = (BigDecimal) fieldObj;
-                    }
-                    if (operator == OPERATOR_NEGATIVE)
-                        resultValue = resultValue.negate();
-                    isFirst = false;
-                } else {
-                    if (Debug.infoOn())
-                        Debug.logInfo("Field not found with field-name " + fieldAcsr + ", and map-name " + mapAcsr + "using a default of 0", module);
+            Object fieldObj = fieldFma.get(methodContext.getEnvMap());
+            if (fieldObj != null) {
+                if (fieldObj instanceof Double) {
+                    resultValue = new BigDecimal(((Double) fieldObj).doubleValue());
+                } else if (fieldObj instanceof Long) {
+                    resultValue = BigDecimal.valueOf(((Long) fieldObj).longValue());
+                } else if (fieldObj instanceof Float) {
+                    resultValue = new BigDecimal(((Float) fieldObj).floatValue());
+                } else if (fieldObj instanceof Integer) {
+                    resultValue = BigDecimal.valueOf(((Integer) fieldObj).longValue());
+                } else if (fieldObj instanceof String) {
+                    resultValue = new BigDecimal((String) fieldObj);
+                } else if (fieldObj instanceof BigDecimal) {
+                    resultValue = (BigDecimal) fieldObj;
                 }
+                if (operator == OPERATOR_NEGATIVE)
+                    resultValue = resultValue.negate();
+                isFirst = false;
             }
             for (SubCalc calcop : calcops) {
                 if (isFirst) {
@@ -324,42 +303,64 @@ public class Calculate extends MethodOpe
         }
     }
 
-    public static final class CalculateFactory implements Factory<Calculate> {
-        public Calculate createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
-            return new Calculate(element, simpleMethod);
-        }
-
-        public String getName() {
-            return "calculate";
-        }
-    }
-
-    protected static class NumberOp implements SubCalc {
-        String valueStr;
-
-        public NumberOp(Element element) {
-            valueStr = element.getAttribute("value");
+    /**
+     * Implements the &lt;number&gt; element.
+     * 
+     * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Cnumber%3E}}">Mini-language Reference</a>
+     */
+    public final class NumberOp extends MiniLangElement implements SubCalc {
+
+        private final FlexibleStringExpander valueFse;
+
+        private NumberOp(Element element, SimpleMethod simpleMethod) throws MiniLangException {
+            super(element, simpleMethod);
+            if (MiniLangValidate.validationOn()) {
+                MiniLangValidate.attributeNames(simpleMethod, element, "value");
+                MiniLangValidate.requiredAttributes(simpleMethod, element, "value");
+                MiniLangValidate.noChildElements(simpleMethod, element);
+            }
+            valueFse = FlexibleStringExpander.getInstance(element.getAttribute("value"));
         }
 
-        public BigDecimal calcValue(MethodContext methodContext, int scale, int roundingMode) {
-            String valueStr = methodContext.expandString(this.valueStr);
+        @Override
+        public BigDecimal calcValue(MethodContext methodContext, int scale, int roundingMode) throws MiniLangException {
+            String valueStr = valueFse.expandString(methodContext.getEnvMap());
             Locale locale = methodContext.getLocale();
             if (locale == null)
                 locale = Locale.getDefault();
-            BigDecimal value;
             try {
-                BigDecimal parseVal = (BigDecimal) ObjectType.simpleTypeConvert(valueStr, "BigDecimal", null, null, locale, true);
-                value = parseVal.setScale(scale, roundingMode);
+                BigDecimal parsedVal = (BigDecimal) MiniLangUtil.convertType(valueStr, java.math.BigDecimal.class, locale, null, null);
+                return parsedVal.setScale(scale, roundingMode);
             } catch (Exception e) {
-                Debug.logError(e, "Could not parse the number string: " + valueStr, module);
-                throw new IllegalArgumentException("Could not parse the number string: " + valueStr);
+                throw new MiniLangRuntimeException("Exception thrown while parsing value attribute: " + e.getMessage(), this);
             }
-            return value;
         }
+    }
+
+    private final class InvalidOp extends MiniLangElement implements SubCalc {
 
+        private InvalidOp(Element element, SimpleMethod simpleMethod) throws MiniLangException {
+            super(element, simpleMethod);
+        }
+
+        @Override
+        public BigDecimal calcValue(MethodContext methodContext, int scale, int roundingMode) throws MiniLangException {
+            throw new MiniLangRuntimeException("Invalid calculate sub-element.", this);
+        }
     }
 
-    protected static interface SubCalc {
-        public BigDecimal calcValue(MethodContext methodContext, int scale, int roundingMode);
+    /**
+     * A factory for the &lt;calculate&gt; element.
+     */
+    public static final class CalculateFactory implements Factory<Calculate> {
+        @Override
+        public Calculate createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
+            return new Calculate(element, simpleMethod);
+        }
+
+        @Override
+        public String getName() {
+            return "calculate";
+        }
     }
 }

Modified: ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Log.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Log.java?rev=1359626&r1=1359625&r2=1359626&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Log.java (original)
+++ ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Log.java Tue Jul 10 12:05:55 2012
@@ -28,16 +28,17 @@ import org.ofbiz.minilang.method.MethodO
 import org.w3c.dom.Element;
 
 /**
- * Logs a message.
+ * Implements the &lt;log&gt; element.
+ * 
+ * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Clog%3E}}">Mini-language Reference</a>
  */
 public final class Log extends MethodOperation {
 
     public static final String module = Log.class.getName();
-    private static final String[] LEVEL_ARRAY = {"always", "verbose", "timing", "info", "important", "warning", "error", "fatal", "notify"};
+    public static final String[] LEVEL_ARRAY = {"always", "verbose", "timing", "info", "important", "warning", "error", "fatal", "notify"};
 
     private final int level;
     private final FlexibleStringExpander messageFse;
-    private final Object startLine;
 
     public Log(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
@@ -60,7 +61,6 @@ public final class Log extends MethodOpe
         } else {
             this.level = levelInt.intValue();
         }
-        this.startLine = element.getUserData("startLine");
     }
 
     @Override
@@ -76,10 +76,8 @@ public final class Log extends MethodOpe
             buf.append(methodLocation);
             buf.append("#");
             buf.append(this.simpleMethod.getMethodName());
-            if (this.startLine != null) {
-                buf.append(" line ");
-                buf.append(this.startLine);
-            }
+            buf.append(" line ");
+            buf.append(getLineNumber());
             buf.append("] ");
             buf.append(message);
             Debug.log(this.level, null, buf.toString(), module);
@@ -88,16 +86,6 @@ public final class Log extends MethodOpe
     }
 
     @Override
-    public String expandedString(MethodContext methodContext) {
-        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
-    }
-
-    @Override
-    public String rawString() {
-        return toString();
-    }
-
-    @Override
     public String toString() {
         StringBuilder sb = new StringBuilder("<log ");
         sb.append("level=\"").append(LEVEL_ARRAY[this.level]).append("\" ");
@@ -106,11 +94,16 @@ public final class Log extends MethodOpe
         return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;log&gt; element.
+     */
     public static final class LogFactory implements Factory<Log> {
+        @Override
         public Log createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new Log(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "log";
         }

Modified: ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/PropertyToField.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/PropertyToField.java?rev=1359626&r1=1359625&r2=1359626&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/PropertyToField.java (original)
+++ ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/PropertyToField.java Tue Jul 10 12:05:55 2012
@@ -20,103 +20,121 @@ package org.ofbiz.minilang.method.othero
 
 import java.text.MessageFormat;
 import java.util.List;
-import java.util.Map;
 
-import javolution.util.FastMap;
-
-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.util.EntityUtilProperties;
 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.w3c.dom.Element;
 
 /**
- * Copies an properties file property value to a field
+ * Implements the &lt;property-to-field&gt; element.
+ * 
+ * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Cpropertytofield%3E}}">Mini-language Reference</a>
  */
-public class PropertyToField extends MethodOperation {
+public final class PropertyToField extends MethodOperation {
 
-    public static final String module = PropertyToField.class.getName();
+    // This method is needed only during the v1 to v2 transition
+    private static boolean autoCorrect(Element element) {
+        // Correct deprecated arg-list-name attribute
+        String listAttr = element.getAttribute("arg-list-name");
+        if (listAttr.length() > 0) {
+            element.setAttribute("arg-list", listAttr);
+            element.removeAttribute("arg-list-name");
+            return true;
+        }
+        return false;
+    }
 
-    ContextAccessor<List<? extends Object>> argListAcsr;
-    String defaultVal;
-    ContextAccessor<Object> fieldAcsr;
-    ContextAccessor<Map<String, Object>> mapAcsr;
-    boolean noLocale;
-    String property;
-    String resource;
+    private final FlexibleMapAccessor<List<? extends Object>> argListFma;
+    private final FlexibleStringExpander defaultFse;
+    private final FlexibleMapAccessor<Object> fieldFma;
+    private final boolean noLocale;
+    private final FlexibleStringExpander propertyFse;
+    private final FlexibleStringExpander resourceFse;
 
     public PropertyToField(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        resource = element.getAttribute("resource");
-        property = element.getAttribute("property");
-        // the schema for this element now just has the "field" attribute, though the old "field-name" and "map-name" pair is still supported
-        this.fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field"), element.getAttribute("field-name"));
-        this.mapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("map-name"));
-        defaultVal = element.getAttribute("default");
-        // defaults to false, ie anything but true is false
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.deprecatedAttribute(simpleMethod, element, "arg-list-name", "replace with \"arg-list\"");
+            MiniLangValidate.attributeNames(simpleMethod, element, "field", "resource", "property", "arg-list", "default", "no-locale");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "field", "resource", "property");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "field", "arg-list");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        boolean elementModified = autoCorrect(element);
+        if (elementModified && MiniLangUtil.autoCorrectOn()) {
+            MiniLangUtil.flagDocumentAsCorrected(element);
+        }
+        fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
+        resourceFse = FlexibleStringExpander.getInstance(element.getAttribute("resource"));
+        propertyFse = FlexibleStringExpander.getInstance(element.getAttribute("property"));
+        argListFma = FlexibleMapAccessor.getInstance(element.getAttribute("arg-list"));
+        defaultFse = FlexibleStringExpander.getInstance(element.getAttribute("default"));
         noLocale = "true".equals(element.getAttribute("no-locale"));
-        argListAcsr = new ContextAccessor<List<? extends Object>>(element.getAttribute("arg-list-name"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        String resource = methodContext.expandString(this.resource);
-        String property = methodContext.expandString(this.property);
+        String resource = resourceFse.expandString(methodContext.getEnvMap());
+        String property = propertyFse.expandString(methodContext.getEnvMap());
         String value = null;
         if (noLocale) {
             value = EntityUtilProperties.getPropertyValue(resource, property, methodContext.getDelegator());
         } else {
             value = EntityUtilProperties.getMessage(resource, property, methodContext.getLocale(), methodContext.getDelegator());
         }
-        if (UtilValidate.isEmpty(value)) {
-            value = defaultVal;
-        }
-        // note that expanding the value string here will handle defaultValue and the string from
-        // the properties file; if we decide later that we don't want the string from the properties
-        // file to be expanded we should just expand the defaultValue at the beginning of this method.
-        value = methodContext.expandString(value);
-        if (!argListAcsr.isEmpty()) {
-            List<? extends Object> argList = argListAcsr.get(methodContext);
-            if (UtilValidate.isNotEmpty(argList)) {
+        value = FlexibleStringExpander.expandString(value, methodContext.getEnvMap());
+        if (value.isEmpty()) {
+            value = defaultFse.expandString(methodContext.getEnvMap());
+        }
+        List<? extends Object> argList = argListFma.get(methodContext.getEnvMap());
+        if (argList != null) {
+            try {
                 value = MessageFormat.format(value, argList.toArray());
+            } catch (IllegalArgumentException e) {
+                throw new MiniLangRuntimeException("Exception thrown while formatting the property value: " + e.getMessage(), this);
             }
         }
-        if (!mapAcsr.isEmpty()) {
-            Map<String, Object> toMap = mapAcsr.get(methodContext);
-            if (toMap == null) {
-                if (Debug.infoOn())
-                    Debug.logInfo("Map not found with name " + mapAcsr + ", creating new map", module);
-                toMap = FastMap.newInstance();
-                mapAcsr.put(methodContext, toMap);
-            }
-            fieldAcsr.put(toMap, value, methodContext);
-        } else {
-            fieldAcsr.put(methodContext, value);
-        }
+        fieldFma.put(methodContext.getEnvMap(), value);
         return true;
     }
 
     @Override
-    public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
-    }
-
-    @Override
-    public String rawString() {
-        // TODO: add all attributes and other info
-        return "<property-to-field field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<property-to-field ");
+        sb.append("field=\"").append(this.fieldFma).append("\" ");
+        sb.append("resource=\"").append(this.resourceFse).append("\" ");
+        sb.append("property=\"").append(this.propertyFse).append("\" ");
+        if (!this.argListFma.isEmpty()) {
+            sb.append("arg-list=\"").append(this.argListFma).append("\" ");
+        }
+        if (!this.defaultFse.isEmpty()) {
+            sb.append("default=\"").append(this.defaultFse).append("\" ");
+        }
+        if (noLocale) {
+            sb.append("no-locale=\"true\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;property-to-field&gt; element.
+     */
     public static final class PropertyToFieldFactory implements Factory<PropertyToField> {
+        @Override
         public PropertyToField createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new PropertyToField(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "property-to-field";
         }

Copied: ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Trace.java (from r1337137, ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/otherops/Trace.java)
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Trace.java?p2=ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Trace.java&p1=ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/otherops/Trace.java&r1=1337137&r2=1359626&rev=1359626&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/otherops/Trace.java (original)
+++ ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/otherops/Trace.java Tue Jul 10 12:05:55 2012
@@ -22,7 +22,6 @@ import java.util.Collections;
 import java.util.List;
 
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.minilang.MiniLangException;
 import org.ofbiz.minilang.MiniLangValidate;
 import org.ofbiz.minilang.SimpleMethod;
@@ -31,7 +30,9 @@ import org.ofbiz.minilang.method.MethodO
 import org.w3c.dom.Element;
 
 /**
- * Enables trace log messages in sub-elements.
+ * Implements the &lt;trace&gt; element.
+ * 
+ * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Ctrace%3E}}">Mini-language Reference</a>
  */
 public final class Trace extends MethodOperation {
 
@@ -70,27 +71,22 @@ public final class Trace extends MethodO
     }
 
     @Override
-    public String expandedString(MethodContext methodContext) {
-        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
-    }
-
-    @Override
-    public String rawString() {
-        return toString();
-    }
-
-    @Override
     public String toString() {
         StringBuilder sb = new StringBuilder("<trace ");
         sb.append("level=\"").append(Log.LEVEL_ARRAY[this.level]).append("\" >");
         return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;trace&gt; element.
+     */
     public static final class TraceFactory implements Factory<Trace> {
+        @Override
         public Trace createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new Trace(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "trace";
         }

Modified: ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java?rev=1359626&r1=1359625&r2=1359626&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java (original)
+++ ofbiz/branches/release12.04/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java Tue Jul 10 12:05:55 2012
@@ -19,7 +19,6 @@
 package org.ofbiz.minilang.method.serviceops;
 
 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.SimpleMethod;
@@ -28,7 +27,9 @@ import org.ofbiz.minilang.method.MethodO
 import org.w3c.dom.Element;
 
 /**
- * Copies a field to a service OUT attribute.
+ * Implements the &lt;field-to-request&gt; element.
+ * 
+ * @see <a href="https://cwiki.apache.org/OFBADMIN/mini-language-reference.html#Mini-languageReference-{{%3Cfieldtoresult%3E}}">Mini-language Reference</a>
  */
 public final class FieldToResult extends MethodOperation {
 
@@ -58,22 +59,18 @@ public final class FieldToResult extends
     public boolean exec(MethodContext methodContext) throws MiniLangException {
         Object fieldVal = this.fieldFma.get(methodContext.getEnvMap());
         if (fieldVal != null) {
-            this.resultFma.put(methodContext.getResults(), fieldVal);
+            if (this.resultFma.containsNestedExpression()) {
+                String expression = (String) this.resultFma.get(methodContext.getEnvMap());
+                FlexibleMapAccessor<Object> resultFma = FlexibleMapAccessor.getInstance(expression);
+                resultFma.put(methodContext.getResults(), fieldVal);
+            } else {
+                this.resultFma.put(methodContext.getResults(), fieldVal);
+            }
         }
         return true;
     }
 
     @Override
-    public String expandedString(MethodContext methodContext) {
-        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
-    }
-
-    @Override
-    public String rawString() {
-        return toString();
-    }
-
-    @Override
     public String toString() {
         StringBuilder sb = new StringBuilder("<field-to-result ");
         if (!this.fieldFma.isEmpty()) {
@@ -86,11 +83,16 @@ public final class FieldToResult extends
         return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;field-to-request&gt; element.
+     */
     public static final class FieldToResultFactory implements Factory<FieldToResult> {
+        @Override
         public FieldToResult createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new FieldToResult(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "field-to-result";
         }

Modified: ofbiz/branches/release12.04/framework/minilang/testdef/MinilangTests.xml
URL: http://svn.apache.org/viewvc/ofbiz/branches/release12.04/framework/minilang/testdef/MinilangTests.xml?rev=1359626&r1=1359625&r2=1359626&view=diff
==============================================================================
--- ofbiz/branches/release12.04/framework/minilang/testdef/MinilangTests.xml (original)
+++ ofbiz/branches/release12.04/framework/minilang/testdef/MinilangTests.xml Tue Jul 10 12:05:55 2012
@@ -26,4 +26,8 @@
         <junit-test-suite class-name="org.ofbiz.minilang.method.ifops.test.IfRegexpTest"/>
     </test-case>
 
+    <test-case case-name="MiniLangUnitTests">
+        <junit-test-suite class-name="org.ofbiz.minilang.test.MiniLangTests"/>
+    </test-case>
+
 </test-suite>

Propchange: ofbiz/branches/release12.04/framework/webapp/
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Tue Jul 10 12:05:55 2012
@@ -0,0 +1,6 @@
+/ofbiz/branches/addbirt/framework/webapp:831210-885099,885686-886087
+/ofbiz/branches/dojo1.4/framework/webapp:951708-952957
+/ofbiz/branches/jackrabbit20100709/framework/webapp:962442-1231517
+/ofbiz/branches/jquery/framework/webapp:952958-1044489
+/ofbiz/branches/multitenant20100310/framework/webapp:921280-927264
+/ofbiz/trunk/framework/webapp:1332097,1333885,1334201,1334336,1334427,1334483,1335047,1335343,1335347,1335351,1335946,1336921,1337046,1337057-1337059,1337202,1337502,1337524,1337644,1337789,1337800,1338065,1338101,1338224,1338570,1338591,1338700,1338831,1338845,1338974,1339081,1339122,1340273,1340352,1340357,1340400,1340405,1340415,1340657,1340661,1340774,1340821,1340826,1340943,1341314,1341399,1342875,1342893,1342980,1343088,1345473,1345484,1345532,1345547,1345553,1347762,1351778,1351999,1355660,1355801,1355859,1355975,1359599-1359600