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/06/13 15:01:19 UTC

svn commit: r1349819 - in /ofbiz/trunk/framework/minilang: dtd/ src/org/ofbiz/minilang/method/eventops/

Author: adrianc
Date: Wed Jun 13 13:01:18 2012
New Revision: 1349819

URL: http://svn.apache.org/viewvc?rev=1349819&view=rev
Log:
Overhauled Mini-language <field-to-request>, <field-to-session>, <request-parameters-to-list>, <request-to-field>, <session-to-field>, <webapp-property-to-field> elements.

The overhaul includes: removing unnecessary object creation, make the class thread-safe, add syntax validation, and misc code cleanups.

Modified:
    ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/FieldToRequest.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/FieldToSession.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/RequestParametersToList.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/RequestToField.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/SessionToField.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/WebappPropertyToField.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=1349819&r1=1349818&r2=1349819&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original)
+++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Wed Jun 13 13:01:18 2012
@@ -1215,166 +1215,194 @@ under the License.
     <xs:element name="field-to-request" substitutionGroup="EventOperations">
         <xs:annotation>
             <xs:documentation>
-                The field-to-request tag copies a field from a map to the specified servlet request attribute.
-                The tag is only used when the simple-method is called as an event, it is ignored otherwise.
+                Copies a field to the specified servlet request attribute.
+                Does nothing if the specified field does not exist.
+                Valid only when the simple-method is called as an event, it is ignored otherwise.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.field-to-request"/>
+            <xs:attribute type="xs:string" name="field" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the field to copy.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="request-name">
+                <xs:annotation>
+                    <xs:documentation>
+                        The servlet request attribute name. Defaults to the value of field attribute.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute types: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.field-to-request">
-        <xs:attribute type="xs:string" name="field" use="required">
-            <xs:annotation><xs:documentation>The context name of the field to use.</xs:documentation></xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="request-name">
-            <xs:annotation><xs:documentation>The name of the request attribute to use. Defaults to the value of field attribute.</xs:documentation></xs:annotation>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="field-to-session" substitutionGroup="EventOperations">
         <xs:annotation>
             <xs:documentation>
-                The field-to-session tag copies a field from a map to the specified servlet session attribute.
-                The tag is only used when the simple-method is called as an event, it is ignored otherwise.
+                Copies a field to the specified servlet session attribute.
+                Does nothing if the specified field does not exist.
+                Valid only when the simple-method is called as an event, it is ignored otherwise.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.field-to-session"/>
+            <xs:attribute type="xs:string" name="field" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the field to copy.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="session-name">
+                <xs:annotation>
+                    <xs:documentation>
+                        The servlet session attribute name. Defaults to the value of field attribute.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute types: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.field-to-session">
-        <xs:attribute type="xs:string" name="field" use="required">
-            <xs:annotation><xs:documentation>The context name of the field to use.</xs:documentation></xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="session-name">
-            <xs:annotation><xs:documentation>The name of the session attribute to use. Defaults to the value of field attribute.</xs:documentation></xs:annotation>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="request-to-field" substitutionGroup="EventOperations">
         <xs:annotation>
             <xs:documentation>
-                The request-to-field tag copies an attribute from the servlet request to a field of a map in the method environment.
-                The tag is only used when the simple-method is called as an event, it is ignored otherwise (except the default value, if specified).
+                Copies a servlet request attribute to a field.
+                Valid only when the simple-method is called as an event, it is ignored otherwise.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.request-to-field"/>
+            <xs:attribute ref="field" />
+            <xs:attribute type="xs:string" name="request-name">
+                <xs:annotation>
+                    <xs:documentation>
+                        The servlet request attribute name. Defaults to the value of field attribute.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute types: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="default">
+                <xs:annotation>
+                    <xs:documentation>
+                        A default value to use if the request attribute does not exist.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute types: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.request-to-field">
-        <xs:attribute type="xs:string" name="field" use="required">
-            <xs:annotation><xs:documentation>The context name of the field to use.</xs:documentation></xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="default">
-            <xs:annotation>
-                <xs:documentation>
-                    A default value to use if the request attribute is null or is a String and is empty.
-                    This will also be used when NOT running as an event.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="request-name">
-            <xs:annotation><xs:documentation>The name of the request attribute to use. Defaults to the value of the field attribute.</xs:documentation></xs:annotation>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="request-parameters-to-list" substitutionGroup="EventOperations">
         <xs:annotation>
             <xs:documentation>
-                The request-parameters-to-list tag appends a request parameter values from the servlet request to the specified list.
-                The tag is only used when the simple-method is called as an event, it is ignored otherwise.
+                Appends a servlet request parameter list to a list. If the target list does not exist, one will be created.
+                Valid only when the simple-method is called as an event, it is ignored otherwise.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.request-parameters-to-list"/>
+            <xs:attribute type="xs:string" name="request-name" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The servlet request parameter name.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute types: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="list">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the field containing the list. Defaults to the request-name attribute value.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="list-name">
+                <xs:annotation>
+                    <xs:documentation>
+                        Deprecated - use the list attribute.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.request-parameters-to-list">
-        <xs:attribute type="xs:string" name="request-name" use="required">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the request parameter values to use.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="list-name">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the list in the method environment that the request parameter values will be appended to.
-                    (default: request-name)
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="session-to-field" substitutionGroup="EventOperations">
         <xs:annotation>
             <xs:documentation>
-                The session-to-field tag copies an attribute from the servlet session to a field of a map in the method environment.
-                The tag is only used when the simple-method is called as an event, it is ignored otherwise (except the default value, if specified).
+                Copies a servlet request attribute to a field.
+                Valid only when the simple-method is called as an event, it is ignored otherwise.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.session-to-field"/>
+            <xs:attribute ref="field" />
+            <xs:attribute type="xs:string" name="session-name">
+                <xs:annotation>
+                    <xs:documentation>
+                        The servlet session attribute name. Defaults to the value of field attribute.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute types: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="default">
+                <xs:annotation>
+                    <xs:documentation>
+                        A default value to use if the request attribute does not exist.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute types: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.session-to-field">
-        <xs:attribute type="xs:string" name="field" use="required">
-            <xs:annotation><xs:documentation>The name (key) of the map field to use.</xs:documentation></xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="default">
-            <xs:annotation>
-                <xs:documentation>
-                    A default value to use if the session attribute is null or is a String and is empty.
-                    This will also be used when NOT running as an event.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="session-name">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the session attribute to use. Defaults to the value of field attribute.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="webapp-property-to-field" substitutionGroup="EventOperations">
         <xs:annotation>
             <xs:documentation>
                 The webapp-property-to-field tag copies a property value from a properties file in a ServletContext resource to a field.
-                The tag is only used when the simple-method is called as an event, it is ignored otherwise (except the default value, if specified).
+                Valid only when the simple-method is called as an event, it is ignored otherwise.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.webapp-property-to-field"/>
+            <xs:attribute ref="field" />
+            <xs:attribute type="xs:string" name="resource" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The resource location of the properties file inside the webapp,
+                        and relative to the root of the webapp (can be inside a war file).
+                        An example of this is "/WEB-INF/myprops.properties".
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute types: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="property" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The property whose value will be put in the field.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute types: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="default">
+                <xs:annotation>
+                    <xs:documentation>
+                        A default value to use if the property value is null or empty.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute types: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.webapp-property-to-field">
-        <xs:attribute type="xs:string" name="resource" use="required">
-            <xs:annotation>
-                <xs:documentation>
-                    The resource location of the properties file inside the webapp,
-                    and relative to the root of the webapp (can be inside a war file).
-                    An example of this is "/WEB-INF/myprops.properties".
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="property" use="required">
-            <xs:annotation><xs:documentation>The property whose value will be put in the field.</xs:documentation></xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="default">
-            <xs:annotation>
-                <xs:documentation>
-                    A default value to use if the property value is null or empty.
-                    This will also be used when NOT running as an event.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="field" use="required">
-            <xs:annotation><xs:documentation>The name (key) of the field to use.</xs:documentation></xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="session-name">
-            <xs:annotation><xs:documentation>The name of the session attribute to use. Defaults to the value of field attribute</xs:documentation></xs:annotation>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="field-to-result" substitutionGroup="EnvOperations">
         <xs:annotation>
             <xs:documentation>

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/FieldToRequest.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/FieldToRequest.java?rev=1349819&r1=1349818&r2=1349819&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/FieldToRequest.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/FieldToRequest.java Wed Jun 13 13:01:18 2012
@@ -18,79 +18,85 @@
  *******************************************************************************/
 package org.ofbiz.minilang.method.eventops;
 
-import java.util.Map;
-
-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 map field to a Servlet request attribute
+ * Implements the &lt;field-to-request&gt; element.
  */
-public class FieldToRequest extends MethodOperation {
-
-    public static final String module = FieldToRequest.class.getName();
+public final class FieldToRequest extends MethodOperation {
 
-    ContextAccessor<Object> fieldAcsr;
-    ContextAccessor<Map<String, ? extends Object>> mapAcsr;
-    FlexibleServletAccessor<Object> requestAcsr;
+    private final FlexibleMapAccessor<Object> fieldFma;
+    private final FlexibleStringExpander attributeNameFse;
 
     public FieldToRequest(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, ? extends Object>>(element.getAttribute("map-name"));
-        fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field"), element.getAttribute("field-name"));
-        requestAcsr = new FlexibleServletAccessor<Object>(element.getAttribute("request-name"), fieldAcsr.toString());
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "field", "request-name");
+            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("request-name");
+        if (!attributeName.isEmpty()) {
+            this.attributeNameFse = FlexibleStringExpander.getInstance(attributeName);
+        } else {
+            this.attributeNameFse = FlexibleStringExpander.getInstance(this.fieldFma.toString());
+        }
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        // only run this if it is in an EVENT context
         if (methodContext.getMethodType() == MethodContext.EVENT) {
-            Object fieldVal = null;
-            if (!mapAcsr.isEmpty()) {
-                Map<String, ? extends Object> fromMap = mapAcsr.get(methodContext);
-                if (fromMap == null) {
-                    Debug.logWarning("Map not found with name " + mapAcsr, module);
-                    return true;
+            Object fieldVal = fieldFma.get(methodContext.getEnvMap());
+            if (fieldVal != null) {
+                String attributeName = attributeNameFse.expandString(methodContext.getEnvMap());
+                if (!attributeName.isEmpty()) {
+                    methodContext.getRequest().setAttribute(attributeName, fieldVal);
                 }
-                fieldVal = fieldAcsr.get(fromMap, methodContext);
-            } else {
-                // no map name, try the env
-                fieldVal = fieldAcsr.get(methodContext);
-            }
-
-            if (fieldVal == null) {
-                Debug.logWarning("Field value not found with name " + fieldAcsr + " in Map with name " + mapAcsr, module);
-                return true;
             }
-            requestAcsr.put(methodContext.getRequest(), fieldVal, methodContext.getEnvMap());
         }
         return true;
     }
 
     @Override
     public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
+        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
     }
 
     @Override
     public String rawString() {
-        // TODO: add all attributes and other info
-        return "<field-to-request field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<field-to-request ");
+        sb.append("field=\"").append(this.fieldFma).append("\" ");
+        if (!this.attributeNameFse.isEmpty()) {
+            sb.append("request-name=\"").append(this.attributeNameFse).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;field-to-request&gt; element.
+     */
     public static final class FieldToRequestFactory implements Factory<FieldToRequest> {
+        @Override
         public FieldToRequest createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new FieldToRequest(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "field-to-request";
         }

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/FieldToSession.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/FieldToSession.java?rev=1349819&r1=1349818&r2=1349819&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/FieldToSession.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/FieldToSession.java Wed Jun 13 13:01:18 2012
@@ -18,79 +18,85 @@
  *******************************************************************************/
 package org.ofbiz.minilang.method.eventops;
 
-import java.util.Map;
-
-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 map field to a Servlet session attribute
+ * Implements the &lt;field-to-session&gt; element.
  */
-public class FieldToSession extends MethodOperation {
-
-    public static final String module = FieldToSession.class.getName();
+public final class FieldToSession extends MethodOperation {
 
-    ContextAccessor<Object> fieldAcsr;
-    ContextAccessor<Map<String, ? extends Object>> mapAcsr;
-    FlexibleServletAccessor<Object> sessionAcsr;
+    private final FlexibleMapAccessor<Object> fieldFma;
+    private final FlexibleStringExpander attributeNameFse;
 
     public FieldToSession(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, ? extends 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());
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "field", "session-name");
+            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());
+        }
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        // only run this if it is in an EVENT context
         if (methodContext.getMethodType() == MethodContext.EVENT) {
-            Object fieldVal = null;
-            if (!mapAcsr.isEmpty()) {
-                Map<String, ? extends Object> fromMap = mapAcsr.get(methodContext);
-                if (fromMap == null) {
-                    Debug.logWarning("Map not found with name " + mapAcsr, module);
-                    return true;
+            Object fieldVal = fieldFma.get(methodContext.getEnvMap());
+            if (fieldVal != null) {
+                String attributeName = attributeNameFse.expandString(methodContext.getEnvMap());
+                if (!attributeName.isEmpty()) {
+                    methodContext.getRequest().getSession().setAttribute(attributeName, fieldVal);
                 }
-                fieldVal = fieldAcsr.get(fromMap, methodContext);
-            } else {
-                // no map name, try the env
-                fieldVal = fieldAcsr.get(methodContext);
-            }
-
-            if (fieldVal == null) {
-                Debug.logWarning("Field value not found with name " + fieldAcsr + " in Map with name " + mapAcsr, module);
-                return true;
             }
-            sessionAcsr.put(methodContext.getRequest().getSession(), fieldVal, methodContext.getEnvMap());
         }
         return true;
     }
 
     @Override
     public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
+        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
     }
 
     @Override
     public String rawString() {
-        // TODO: add all attributes and other info
-        return "<field-to-session field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<field-to-session ");
+        sb.append("field=\"").append(this.fieldFma).append("\" ");
+        if (!this.attributeNameFse.isEmpty()) {
+            sb.append("session-name=\"").append(this.attributeNameFse).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;field-to-session&gt; element.
+     */
     public static final class FieldToSessionFactory implements Factory<FieldToSession> {
+        @Override
         public FieldToSession createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new FieldToSession(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "field-to-session";
         }

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/RequestParametersToList.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/RequestParametersToList.java?rev=1349819&r1=1349818&r2=1349819&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/RequestParametersToList.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/RequestParametersToList.java Wed Jun 13 13:01:18 2012
@@ -22,74 +22,108 @@ import java.util.List;
 
 import javolution.util.FastList;
 
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.minilang.MiniLangException;
+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 a Servlet request parameter values to a list
+ * Implements the &lt;request-parameters-to-list&gt; element.
  */
-public class RequestParametersToList extends MethodOperation {
+public final class RequestParametersToList extends MethodOperation {
 
-    public static final String module = RequestParametersToList.class.getName();
+    // This method is needed only during the v1 to v2 transition
+    private static boolean autoCorrect(Element element) {
+        // Correct deprecated list-name attribute
+        String listAttr = element.getAttribute("list-name");
+        if (listAttr.length() > 0) {
+            element.setAttribute("list", listAttr);
+            element.removeAttribute("list-name");
+            return true;
+        }
+        return false;
+    }
 
-    ContextAccessor<List<String>> listAcsr;
-    String requestName;
+    private final FlexibleMapAccessor<List<String>> listFma;
+    private final FlexibleStringExpander attributeNameFse;
 
     public RequestParametersToList(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        requestName = element.getAttribute("request-name");
-        listAcsr = new ContextAccessor<List<String>>(element.getAttribute("list-name"), requestName);
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.deprecatedAttribute(simpleMethod, element, "list-name", "replace with \"list\"");
+            MiniLangValidate.attributeNames(simpleMethod, element, "list", "request-name");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "request-name");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "list");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        boolean elementModified = autoCorrect(element);
+        if (elementModified && MiniLangUtil.autoCorrectOn()) {
+            MiniLangUtil.flagDocumentAsCorrected(element);
+        }
+        this.attributeNameFse = FlexibleStringExpander.getInstance(element.getAttribute("request-name"));
+        String attributeName = element.getAttribute("list");
+        if (!attributeName.isEmpty()) {
+            this.listFma = FlexibleMapAccessor.getInstance(attributeName);
+        } else {
+            this.listFma = FlexibleMapAccessor.getInstance(attributeNameFse.toString());
+        }
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        List<String> listVal = null;
-        // only run this if it is in an EVENT context
         if (methodContext.getMethodType() == MethodContext.EVENT) {
-            String[] parameterValues = methodContext.getRequest().getParameterValues(requestName);
-            if (parameterValues == null) {
-                Debug.logWarning("Request parameter values not found with name " + requestName, module);
-            } else {
-                listVal = UtilMisc.toListArray(parameterValues);
+            String attributeName = attributeNameFse.expandString(methodContext.getEnvMap());
+            String[] parameterValues = methodContext.getRequest().getParameterValues(attributeName);
+            if (parameterValues != null) {
+                List<String> valueList = listFma.get(methodContext.getEnvMap());
+                if (valueList == null) {
+                    valueList = FastList.newInstance();
+                    listFma.put(methodContext.getEnvMap(), valueList);
+                }
+                for (int i = 0; i < parameterValues.length; i++) {
+                    valueList.add(parameterValues[i]);
+                }
             }
         }
-        // if listVal is null, use a empty list;
-        if (listVal == null) {
-            listVal = FastList.newInstance();
-        }
-        List<String> toList = listAcsr.get(methodContext);
-        if (toList == null) {
-            if (Debug.verboseOn())
-                Debug.logVerbose("List not found with name " + listAcsr + ", creating new list", module);
-            toList = FastList.newInstance();
-            listAcsr.put(methodContext, toList);
-        }
-        toList.addAll(listVal);
         return true;
     }
 
     @Override
     public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
+        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
     }
 
     @Override
     public String rawString() {
-        return "<request-parameters-to-list request-name=\"" + this.requestName + "\" list-name=\"" + this.listAcsr + "\"/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<request-parameters-to-list ");
+        sb.append("request-name=\"").append(this.attributeNameFse).append("\" ");
+        if (!this.listFma.isEmpty()) {
+            sb.append("list=\"").append(this.listFma).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;request-parameters-to-list&gt; element.
+     */
     public static final class RequestParametersToListFactory implements Factory<RequestParametersToList> {
+        @Override
         public RequestParametersToList createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new RequestParametersToList(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "request-parameters-to-list";
         }

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/RequestToField.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/RequestToField.java?rev=1349819&r1=1349818&r2=1349819&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/RequestToField.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/RequestToField.java Wed Jun 13 13:01:18 2012
@@ -18,92 +18,89 @@
  *******************************************************************************/
 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 request attribute to a map field
+ * Implements the &lt;request-to-field&gt; element.
  */
-public class RequestToField extends MethodOperation {
-
-    public static final String module = RequestToField.class.getName();
+public final class RequestToField extends MethodOperation {
 
-    String defaultVal;
-    ContextAccessor<Object> fieldAcsr;
-    ContextAccessor<Map<String, Object>> mapAcsr;
-    FlexibleServletAccessor<Object> requestAcsr;
+    private final FlexibleStringExpander defaultFse;
+    private final FlexibleMapAccessor<Object> fieldFma;
+    private final FlexibleStringExpander attributeNameFse;
 
     public RequestToField(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"));
-        requestAcsr = new FlexibleServletAccessor<Object>(element.getAttribute("request-name"), fieldAcsr.toString());
-        defaultVal = element.getAttribute("default");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "field", "request-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("request-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 = requestAcsr.get(methodContext.getRequest(), methodContext.getEnvMap());
-            if (fieldVal == null) {
-                Debug.logWarning("Request attribute value not found with name " + requestAcsr, 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().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();
+        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
     }
 
     @Override
     public String rawString() {
-        // TODO: add all attributes and other info
-        return "<request-to-field request-name=\"" + this.requestAcsr + "\" field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<request-to-field ");
+        sb.append("field=\"").append(this.fieldFma).append("\" ");
+        if (!this.attributeNameFse.isEmpty()) {
+            sb.append("request-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;request-to-field&gt; element.
+     */
     public static final class RequestToFieldFactory implements Factory<RequestToField> {
+        @Override
         public RequestToField createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new RequestToField(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "request-to-field";
         }

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/SessionToField.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/SessionToField.java?rev=1349819&r1=1349818&r2=1349819&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/SessionToField.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/SessionToField.java Wed Jun 13 13:01:18 2012
@@ -18,91 +18,89 @@
  *******************************************************************************/
 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 &lt;session-to-field&gt; element.
  */
 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();
+        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
     }
 
     @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 + "\"/>";
+        return toString();
+    }
+
+    @Override
+    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/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/WebappPropertyToField.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/WebappPropertyToField.java?rev=1349819&r1=1349818&r2=1349819&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/WebappPropertyToField.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/eventops/WebappPropertyToField.java Wed Jun 13 13:01:18 2012
@@ -19,103 +19,101 @@
 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.
  */
-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();
+        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
     }
 
     @Override
     public String rawString() {
-        // TODO: add all attributes and other info
-        return "<webapp-property-to-field field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+        return toString();
+    }
+
+    @Override
+    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";
         }