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/10 18:21:42 UTC

svn commit: r1348620 - in /ofbiz/trunk/framework/minilang: dtd/ src/org/ofbiz/minilang/method/entityops/

Author: adrianc
Date: Sun Jun 10 16:21:41 2012
New Revision: 1348620

URL: http://svn.apache.org/viewvc?rev=1348620&view=rev
Log:
Overhauled Mini-language <set-current-user-login>, <set-nonpk-fields>, <set-pk-fields>, <store-list>, <store-value>, <transaction-begin>, <transaction-commit>, <transaction-rollback> 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/entityops/RemoveValue.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetCurrentUserLogin.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetNonpkFields.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetPkFields.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreList.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreValue.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionBegin.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionCommit.java
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionRollback.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=1348620&r1=1348619&r2=1348620&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original)
+++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Sun Jun 10 16:21:41 2012
@@ -57,6 +57,19 @@ under the License.
         </xs:choice>
     </xs:group>
 
+    <xs:simpleType name="booleanConst">
+        <xs:restriction base="xs:token">
+            <xs:enumeration value="true" />
+            <xs:enumeration value="false" />
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="booleanExpr">
+        <xs:restriction base="xs:token">
+            <xs:pattern value="\$\{[a-zA-Z_]{1}[a-zA-Z0-9_\-.]+\}|true|false" />
+        </xs:restriction>
+    </xs:simpleType>
+
     <xs:attribute name="field">
         <xs:annotation>
             <xs:documentation>
@@ -66,8 +79,7 @@ under the License.
             </xs:documentation>
         </xs:annotation>
         <xs:simpleType>
-            <xs:restriction base="xs:string">
-                <xs:whiteSpace value="collapse" />
+            <xs:restriction base="xs:token">
                 <xs:minLength value="1" />
             </xs:restriction>
         </xs:simpleType>
@@ -342,12 +354,13 @@ under the License.
                 &lt;br/&gt;&lt;br/&gt;
                 A simple method can be called in either an event context from the Control
                 Servlet (or another event) or in a service context through the Service
-                Engine, or any other component that has access to a service dispatcher.
+                Engine, or any other component that has access to a service
+                dispatcher.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
             <xs:group minOccurs="0" maxOccurs="unbounded" ref="AllOperations" />
-            <xs:attribute type="xs:string" name="method-name" use="required">
+            <xs:attribute name="method-name" use="required">
                 <xs:annotation>
                     <xs:documentation>
                         A name (preferably a legal Java identifier) for this method.
@@ -356,6 +369,11 @@ under the License.
                         Required. Attribute type: constant.
                     </xs:documentation>
                 </xs:annotation>
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:pattern value="[a-zA-Z_]{1}[a-zA-Z0-9_\-.]+" />
+                    </xs:restriction>
+                </xs:simpleType>
             </xs:attribute>
             <xs:attribute type="xs:string" name="short-description">
                 <xs:annotation>
@@ -366,7 +384,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="login-required">
+            <xs:attribute name="login-required" type="booleanConst">
                 <xs:annotation>
                     <xs:documentation>
                         Require a user login to run this method. Defaults to "true".
@@ -374,14 +392,8 @@ under the License.
                         Optional. Attribute type: constant.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
-            <xs:attribute name="use-transaction">
+            <xs:attribute name="use-transaction" type="booleanConst">
                 <xs:annotation>
                     <xs:documentation>
                         Create a transaction if none exists for this thread. Defaults to "true".
@@ -389,12 +401,6 @@ under the License.
                         Optional. Attribute type: constant.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
             <xs:attribute type="xs:string" name="default-error-code">
                 <xs:annotation>
@@ -678,7 +684,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="include-user-login">
+            <xs:attribute name="include-user-login" type="booleanConst">
                 <xs:annotation>
                     <xs:documentation>
                         Include the current UserLogin GenericValue in the called service IN attributes.
@@ -687,16 +693,8 @@ under the License.
                         Optional. Attribute type: constant.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:annotation>
-                    </xs:annotation>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
-            <xs:attribute name="break-on-error">
+            <xs:attribute name="break-on-error" type="booleanConst">
                 <xs:annotation>
                     <xs:documentation>
                         Halt script execution if the called service returns an error.
@@ -705,12 +703,6 @@ under the License.
                         Optional. Attribute type: constant.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
             <xs:attribute type="xs:string" name="error-code">
                 <xs:annotation>
@@ -732,7 +724,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="require-new-transaction">
+            <xs:attribute name="require-new-transaction" type="booleanConst">
                 <xs:annotation>
                     <xs:documentation>
                         Require a new transaction for the called service.
@@ -741,12 +733,6 @@ under the License.
                         Optional. Attribute type: constant.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
             <xs:attribute type="xs:string" name="transaction-timeout">
                 <xs:annotation>
@@ -997,7 +983,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="include-user-login">
+            <xs:attribute name="include-user-login" type="booleanConst">
                 <xs:annotation>
                     <xs:documentation>
                         Include the current UserLogin GenericValue in the called service IN attributes.
@@ -1006,14 +992,6 @@ under the License.
                         Optional. Attribute type: constant.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:annotation>
-                    </xs:annotation>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
         </xs:complexType>
     </xs:element>
@@ -1815,72 +1793,53 @@ under the License.
         These operations are used to interact with a data source through the entity
         engine and facilitate related operations.
     -->
+    <xs:attribute type="xs:string" name="began-transaction-name">
+        <xs:annotation>
+            <xs:documentation>
+                The name of the field that contains a Boolean value specifying whether or not a transaction was begun in the current transaction demarcation.
+                Defaults to "beganTransaction".
+                &lt;br/&gt;&lt;br/&gt;
+                Optional. Attribute type: expression.
+            </xs:documentation>
+        </xs:annotation>
+    </xs:attribute>
     <xs:element name="transaction-begin" substitutionGroup="EntityTxOperations">
         <xs:annotation>
             <xs:documentation>
-                The transaction-begin tag will begin a transaction if one is not already in place.
-                If a transaction is begun the environment field named as the began-transaction-name will be set to true, otherwise it will be set to false.
-
-                Note that unless the simple-method is flagged to not use a transaction all simple-methods will be inside a transaction.
-                The same is true for service calls through the Service Engine.
+                Begins a transaction if one is not already in place.
+                &lt;br/&gt;&lt;br/&gt;
+                Note that all simple-methods are executed inside a transaction unless
+                the simple-method is flagged to not use a transaction.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.transaction-begin"/>
+            <xs:attribute ref="began-transaction-name" />
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.transaction-begin">
-        <xs:attribute type="xs:string" name="began-transaction-name" default="beganTransaction">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the method environment field that contains a Boolean specifying whether or not a transaction was begun in the current transaction demarcation.
-                    Defaults to "beganTransaction".
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="transaction-commit" substitutionGroup="EntityTxOperations">
         <xs:annotation>
             <xs:documentation>
-                The transaction-commit tag will commit a transaction if a transaction was begun in the current demarcation context as represented by the environment field named as the began-transaction-name.
-                If the Boolean in that field is false no commit will be done.
+                Commits a transaction that was begun with the transaction-begin element.
+                Does nothing if no transaction was begun.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.transaction-commit"/>
+            <xs:attribute ref="began-transaction-name" />
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.transaction-commit">
-        <xs:attribute type="xs:string" name="began-transaction-name" default="beganTransaction">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the method environment field that contains a Boolean specifying whether or not a transaction was begun in the current transaction demarcation.
-                    Defaults to "beganTransaction".
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="transaction-rollback" substitutionGroup="EntityTxOperations">
         <xs:annotation>
             <xs:documentation>
-                The transaction-rollback tag will rollback a transaction if a transaction was begun in the current demarcation context as represented by the environment field named as the began-transaction-name.
-                If the Boolean in that field is false a set rollback only will operation will be done instead of rollback which will force the transaction to rollback regardless of which method or object is responsible for beginning and ending the transaction.
+                Rolls back a transaction that was begun with the transaction-begin element.
+                If no transaction was begun with the transaction-begin element, a "set rollback only"
+                operation will be performed - which will force the transaction to rollback regardless
+                of which method or object is responsible for beginning and ending the transaction.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.transaction-rollback"/>
+            <xs:attribute ref="began-transaction-name" />
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.transaction-rollback">
-        <xs:attribute type="xs:string" name="began-transaction-name" default="beganTransaction">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the method environment field that contains a Boolean specifying whether or not a transaction was begun in the current transaction demarcation.
-                    Defaults to "beganTransaction".
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="sequenced-id" substitutionGroup="EntityMiscOperations">
         <xs:annotation>
             <xs:documentation>
@@ -1910,7 +1869,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="get-long-only">
+            <xs:attribute name="get-long-only" type="booleanConst">
                 <xs:annotation>
                     <xs:documentation>
                         Preserve the sequence type - a numeric long. If set to "false" the sequence
@@ -1919,12 +1878,6 @@ under the License.
                         Optional. Attribute type: constant.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="false" />
-                        <xs:enumeration value="true" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
         </xs:complexType>
     </xs:element>
@@ -2161,7 +2114,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="use-iterator">
+            <xs:attribute name="use-iterator" type="booleanExpr">
                 <xs:annotation>
                     <xs:documentation>
                         Specifies whether or not to use the EntityListIterator when doing the query.
@@ -2173,12 +2126,6 @@ under the License.
                         Optional. Attribute type: constant, ${expression}.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="false" />
-                        <xs:enumeration value="true" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
             <xs:attribute type="xs:string" name="delegator-name">
                 <xs:annotation>
@@ -2246,7 +2193,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="auto-field-map">
+            <xs:attribute name="auto-field-map" type="booleanExpr">
                 <xs:annotation>
                     <xs:documentation>
                         When "true", the operation looks for all primary key field names in the current context as well as in the parameters map.
@@ -2255,12 +2202,6 @@ under the License.
                         Optional. Attribute type: constant, ${expression}.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
         </xs:complexType>
     </xs:element>
@@ -3051,7 +2992,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="do-cache-clear">
+            <xs:attribute name="do-cache-clear" type="booleanConst">
                 <xs:annotation>
                     <xs:documentation>
                         Clear the cache. Defaults to "true".
@@ -3059,14 +3000,8 @@ under the License.
                         Optional. Attribute type: constant.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
-            <xs:attribute name="or-store">
+            <xs:attribute name="or-store" type="booleanConst">
                 <xs:annotation>
                     <xs:documentation>
                         Store value if it already exists. Defaults to "false".
@@ -3074,48 +3009,37 @@ under the License.
                         Optional. Attribute type: constant.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
         </xs:complexType>
     </xs:element>
     <xs:element name="store-value" substitutionGroup="EntityValueOperations">
         <xs:annotation>
             <xs:documentation>
-                The store-value tag persists the specified GenericValue object by updating the instance of the entity in the datasource.
-                An error will result if an instance of the entity does not exist in the datasource with the same primary key.
+                Stores an entity value in the database. An error will be generated
+                if the entity value does not exist in the database.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.store-value"/>
+            <xs:attribute name="value-field" type="xs:string" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the field containing the entity value.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="do-cache-clear" type="booleanExpr">
+                <xs:annotation>
+                    <xs:documentation>
+                        Clear the cache. Defaults to "true".
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute type: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.store-value">
-        <xs:attribute type="xs:string" name="value-field" use="required">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the method environment field that contains the GenericValue object.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute name="do-cache-clear" default="true">
-            <xs:annotation>
-                <xs:documentation>
-                    Clear the cache, defaults to true
-                </xs:documentation>
-            </xs:annotation>
-            <xs:simpleType>
-                <xs:restriction base="xs:token">
-                    <xs:enumeration value="true"/>
-                    <xs:enumeration value="false"/>
-                </xs:restriction>
-            </xs:simpleType>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="refresh-value" substitutionGroup="EntityValueOperations">
         <xs:annotation>
             <xs:documentation>
@@ -3132,7 +3056,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="do-cache-clear">
+            <xs:attribute name="do-cache-clear" type="booleanExpr">
                 <xs:annotation>
                     <xs:documentation>
                         Clear the cache. Defaults to "true".
@@ -3140,12 +3064,6 @@ under the License.
                         Optional. Attribute type: constant, ${expression}.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
         </xs:complexType>
     </xs:element>
@@ -3165,7 +3083,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="do-cache-clear">
+            <xs:attribute name="do-cache-clear" type="booleanExpr">
                 <xs:annotation>
                     <xs:documentation>
                         Clear the cache. Defaults to "true".
@@ -3173,12 +3091,6 @@ under the License.
                         Optional. Attribute type: constant, ${expression}.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
         </xs:complexType>
     </xs:element>
@@ -3209,7 +3121,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="do-cache-clear">
+            <xs:attribute name="do-cache-clear" type="booleanExpr">
                 <xs:annotation>
                     <xs:documentation>
                         Clear the cache. Defaults to "true".
@@ -3217,12 +3129,6 @@ under the License.
                         Optional. Attribute type: constant, ${expression}.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
         </xs:complexType>
     </xs:element>
@@ -3254,7 +3160,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="do-cache-clear">
+            <xs:attribute name="do-cache-clear" type="booleanExpr">
                 <xs:annotation>
                     <xs:documentation>
                         Clear the cache. Defaults to "true".
@@ -3262,12 +3168,6 @@ under the License.
                         Optional. Attribute type: constant, ${expression}.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
         </xs:complexType>
     </xs:element>
@@ -3314,116 +3214,106 @@ under the License.
     <xs:element name="set-pk-fields" substitutionGroup="EntityValueOperations">
         <xs:annotation>
             <xs:documentation>
-                Looks for each PK field in the named map and if it exists there it will copy it into the named value object.
+                Copies PK fields from a map to an entity value.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.set-pk-fields"/>
+            <xs:attribute type="xs:string" name="value-field" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the field that contains the entity value.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="map" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the field that contains a map that is used to initialize the entity value pk fields.
+                        Map values whose key matches one of the entity value fields will be copied to the entity value.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="set-if-null" type="booleanExpr">
+                <xs:annotation>
+                    <xs:documentation>
+                        Set entity value fields that are null or empty.
+                        Defaults to "true".
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute type: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.set-pk-fields">
-        <xs:attribute type="xs:string" name="value-field" use="required">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the method environment field that contains the GenericValue object.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="map">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of a map in the method environment that will be used for the entity fields.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute name="set-if-null" default="true">
-            <xs:annotation>
-                <xs:documentation>
-                    Specifies whether or not to set fields that are null or empty.
-                    Defaults to true.
-                </xs:documentation>
-            </xs:annotation>
-            <xs:simpleType>
-                <xs:restriction base="xs:token">
-                    <xs:enumeration value="true"/>
-                    <xs:enumeration value="false"/>
-                </xs:restriction>
-            </xs:simpleType>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="set-nonpk-fields" substitutionGroup="EntityValueOperations">
         <xs:annotation>
             <xs:documentation>
-                Looks for each non-PK field in the named map and if it exists there it will copy it into the named value object.
+                Copies non-PK fields from a map to an entity value.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.set-nonpk-fields"/>
+            <xs:attribute type="xs:string" name="value-field" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the field that contains the entity value.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="map" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the field that contains a map that is used to initialize the entity value non-pk fields.
+                        Map values whose key matches one of the entity value fields will be copied to the entity value.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="set-if-null" type="booleanExpr">
+                <xs:annotation>
+                    <xs:documentation>
+                        Set entity value fields that are null or empty.
+                        Defaults to "true".
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute type: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.set-nonpk-fields">
-        <xs:attribute type="xs:string" name="value-field" use="required">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the method environment field that contains the GenericValue object.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute type="xs:string" name="map">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of a map in the method environment that will be used for the entity fields.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute name="set-if-null" default="true">
-            <xs:annotation>
-                <xs:documentation>
-                    Specifies whether or not to set fields that are null or empty.
-                    Defaults to true.
-                </xs:documentation>
-            </xs:annotation>
-            <xs:simpleType>
-                <xs:restriction base="xs:token">
-                    <xs:enumeration value="true"/>
-                    <xs:enumeration value="false"/>
-                </xs:restriction>
-            </xs:simpleType>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="store-list" substitutionGroup="EntityListOperations">
         <xs:annotation>
             <xs:documentation>
-                The store-list tag uses the delegator to store all entity values in the list.
-                This is different than storing a single value in that values in the list will be inserted if it does not exist or updated if it does exist.
+                Store all entity values in a list. Entity values that do not exist in the database will be added to the database.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.store-list"/>
+            <xs:attribute type="xs:string" name="list" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the field that contains the list of entity values.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="do-cache-clear" type="booleanExpr">
+                <xs:annotation>
+                    <xs:documentation>
+                        Clear the cache. Defaults to "true".
+                        &lt;br/&gt;&lt;br/&gt;
+                        Optional. Attribute type: constant, ${expression}.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.store-list">
-        <xs:attribute type="xs:string" name="list" use="required">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the method environment field that contains the list of GenericValue objects.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-        <xs:attribute name="do-cache-clear" default="true">
-            <xs:annotation>
-                <xs:documentation>
-                    Clear the cache, defaults to true
-                </xs:documentation>
-            </xs:annotation>
-            <xs:simpleType>
-                <xs:restriction base="xs:token">
-                    <xs:enumeration value="true"/>
-                    <xs:enumeration value="false"/>
-                </xs:restriction>
-            </xs:simpleType>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="remove-list" substitutionGroup="EntityListOperations">
         <xs:annotation>
             <xs:documentation>
@@ -3442,7 +3332,7 @@ under the License.
                     </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
-            <xs:attribute name="do-cache-clear">
+            <xs:attribute name="do-cache-clear" type="booleanExpr">
                 <xs:annotation>
                     <xs:documentation>
                         Clear the cache. Defaults to "true".
@@ -3450,12 +3340,6 @@ under the License.
                         Optional. Attribute type: constant, ${expression}.
                     </xs:documentation>
                 </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
             </xs:attribute>
         </xs:complexType>
     </xs:element>
@@ -4338,23 +4222,25 @@ under the License.
     <xs:element name="set-current-user-login" substitutionGroup="OtherOperations">
         <xs:annotation>
             <xs:documentation>
-                The set-current-user-login tag sets the UserLogin GenericValue object to be used for authentication for the rest of the method.
+                Sets the UserLogin entity value to be used for authentication for the rest of the method.
                 This is mostly used for calling services, etc.
+                &lt;br/&gt;&lt;br/&gt;
+                This element is deprecated. You can pass an alternate UserLogin
+                entity value to the called service's IN attributes.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.set-current-user-login"/>
+            <xs:attribute type="xs:string" name="value-field" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the field that contains the UserLogin entity value.
+                        &lt;br/&gt;&lt;br/&gt;
+                        Required. Attribute type: expression.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:attributeGroup name="attlist.set-current-user-login">
-        <xs:attribute type="xs:string" name="value-field" use="required">
-            <xs:annotation>
-                <xs:documentation>
-                    The name of the method environment field that contains the UserLogin GenericValue object.
-                </xs:documentation>
-            </xs:annotation>
-        </xs:attribute>
-    </xs:attributeGroup>
     <xs:element name="calculate" substitutionGroup="OtherOperations">
         <xs:annotation>
             <xs:documentation>

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveValue.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveValue.java?rev=1348620&r1=1348619&r2=1348620&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveValue.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveValue.java Sun Jun 10 16:21:41 2012
@@ -34,7 +34,7 @@ import org.w3c.dom.Element;
 /**
  * Implements the &lt;remove-value&gt; element.
  */
-public class RemoveValue extends MethodOperation {
+public final class RemoveValue extends MethodOperation {
 
     public static final String module = RemoveValue.class.getName();
 

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetCurrentUserLogin.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetCurrentUserLogin.java?rev=1348620&r1=1348619&r2=1348620&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetCurrentUserLogin.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetCurrentUserLogin.java Sun Jun 10 16:21:41 2012
@@ -18,35 +18,41 @@
  *******************************************************************************/
 package org.ofbiz.minilang.method.entityops;
 
-import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.minilang.MiniLangException;
+import org.ofbiz.minilang.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;
 
 /**
- * Uses the delegator to create the specified value object entity in the datasource
+ * Implements the &lt;set-current-user-login&gt; element.
  */
-public class SetCurrentUserLogin extends MethodOperation {
+public final class SetCurrentUserLogin extends MethodOperation {
 
-    public static final String module = SetCurrentUserLogin.class.getName();
-
-    ContextAccessor<GenericValue> valueAcsr;
+    private final FlexibleMapAccessor<GenericValue> valueFma;
 
     public SetCurrentUserLogin(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        valueAcsr = new ContextAccessor<GenericValue>(element.getAttribute("value-field"), element.getAttribute("value-name"));
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.handleError("Deprecated - use the called service's userLogin IN attribute", simpleMethod, element);
+            MiniLangValidate.attributeNames(simpleMethod, element, "value-field");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "value-field");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "value-field");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        valueFma = FlexibleMapAccessor.getInstance(element.getAttribute("value-field"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        GenericValue userLogin = valueAcsr.get(methodContext);
+        GenericValue userLogin = valueFma.get(methodContext.getEnvMap());
         if (userLogin == null) {
-            Debug.logWarning("In SetCurrentUserLogin a value was not found with the specified valueName: " + valueAcsr + ", not setting", module);
-            return true;
+            throw new MiniLangRuntimeException("Entity value not found with name: " + valueFma, this);
         }
         methodContext.setUserLogin(userLogin, this.simpleMethod.getUserLoginEnvName());
         return true;
@@ -54,21 +60,31 @@ public class SetCurrentUserLogin extends
 
     @Override
     public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
+        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
     }
 
     @Override
     public String rawString() {
-        // TODO: something more than the empty tag
-        return "<set-current-user-login/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<set-current-user-login ");
+        sb.append("value-field=\"").append(this.valueFma).append("\" />");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;set-current-user-login&gt; element.
+     */
     public static final class SetCurrentUserLoginFactory implements Factory<SetCurrentUserLogin> {
+        @Override
         public SetCurrentUserLogin createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new SetCurrentUserLogin(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "set-current-user-login";
         }

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetNonpkFields.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetNonpkFields.java?rev=1348620&r1=1348619&r2=1348620&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetNonpkFields.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetNonpkFields.java Sun Jun 10 16:21:41 2012
@@ -20,76 +20,86 @@ package org.ofbiz.minilang.method.entity
 
 import java.util.Map;
 
-import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.minilang.MiniLangException;
+import org.ofbiz.minilang.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;
 
 /**
- * Looks for each non-PK field in the named map and if it exists there it will copy it into the named value object.
+ * Implements the &lt;set-nonpk-fields&gt; element.
  */
-public class SetNonpkFields extends MethodOperation {
+public final class SetNonpkFields extends MethodOperation {
 
-    public static final String module = SetNonpkFields.class.getName();
-
-    ContextAccessor<Map<String, ? extends Object>> mapAcsr;
-    String setIfNullStr;
-    ContextAccessor<GenericValue> valueAcsr;
+    private final FlexibleMapAccessor<Map<String, ? extends Object>> mapFma;
+    private final FlexibleStringExpander setIfNullFse;
+    private final FlexibleMapAccessor<GenericValue> valueFma;
 
     public SetNonpkFields(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        valueAcsr = new ContextAccessor<GenericValue>(element.getAttribute("value-field"), element.getAttribute("value-name"));
-        mapAcsr = new ContextAccessor<Map<String, ? extends Object>>(element.getAttribute("map"), element.getAttribute("map-name"));
-        setIfNullStr = element.getAttribute("set-if-null");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "value-field", "set-if-null", "map");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "value-field", "map");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "value-field", "map");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        valueFma = FlexibleMapAccessor.getInstance(element.getAttribute("value-field"));
+        setIfNullFse = FlexibleStringExpander.getInstance(element.getAttribute("set-if-null"));
+        mapFma = FlexibleMapAccessor.getInstance(element.getAttribute("map"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        // if anything but false it will be true
-        boolean setIfNull = !"false".equals(methodContext.expandString(setIfNullStr));
-        GenericValue value = valueAcsr.get(methodContext);
+        GenericValue value = valueFma.get(methodContext.getEnvMap());
         if (value == null) {
-            String errMsg = "In set-nonpk-fields a value was not found with the specified valueAcsr: " + valueAcsr + ", not setting fields";
-            Debug.logWarning(errMsg, module);
-            if (methodContext.getMethodType() == MethodContext.EVENT) {
-                methodContext.putEnv(simpleMethod.getEventErrorMessageName(), errMsg);
-                methodContext.putEnv(simpleMethod.getEventResponseCodeName(), simpleMethod.getDefaultErrorCode());
-            } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
-                methodContext.putEnv(simpleMethod.getServiceErrorMessageName(), errMsg);
-                methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), simpleMethod.getDefaultErrorCode());
-            }
-            return false;
+            throw new MiniLangRuntimeException("Entity value not found with name: " + valueFma, this);
         }
-        Map<String, ? extends Object> theMap = mapAcsr.get(methodContext);
+        Map<String, ? extends Object> theMap = mapFma.get(methodContext.getEnvMap());
         if (theMap == null) {
-            Debug.logWarning("In set-nonpk-fields could not find map with name " + mapAcsr + ", not setting any fields", module);
-        } else {
-            value.setNonPKFields(theMap, setIfNull);
+            throw new MiniLangRuntimeException("Map not found with name: " + mapFma, this);
         }
+        boolean setIfNull = !"false".equals(setIfNullFse.expand(methodContext.getEnvMap()));
+        value.setNonPKFields(theMap, setIfNull);
         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: something more than the empty tag
-        return "<set-nonpk-fields/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<set-nonpk-fields ");
+        sb.append("value-field=\"").append(this.valueFma).append("\" ");
+        sb.append("map=\"").append(this.mapFma).append("\" ");
+        if (!setIfNullFse.isEmpty()) {
+            sb.append("set-if-null=\"").append(this.setIfNullFse).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;set-nonpk-fields&gt; element.
+     */
     public static final class SetNonpkFieldsFactory implements Factory<SetNonpkFields> {
+        @Override
         public SetNonpkFields createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new SetNonpkFields(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "set-nonpk-fields";
         }

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetPkFields.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetPkFields.java?rev=1348620&r1=1348619&r2=1348620&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetPkFields.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/SetPkFields.java Sun Jun 10 16:21:41 2012
@@ -20,77 +20,86 @@ package org.ofbiz.minilang.method.entity
 
 import java.util.Map;
 
-import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.minilang.MiniLangException;
+import org.ofbiz.minilang.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;
 
 /**
- * Looks for each PK field in the named map and if it exists there it will copy it into the named value object.
+ * Implements the &lt;set-pk-fields&gt; element.
  */
-public class SetPkFields extends MethodOperation {
+public final class SetPkFields extends MethodOperation {
 
-    public static final String module = SetPkFields.class.getName();
-
-    ContextAccessor<Map<String, ? extends Object>> mapAcsr;
-    String setIfNullStr;
-    ContextAccessor<GenericValue> valueAcsr;
+    private final FlexibleMapAccessor<Map<String, ? extends Object>> mapFma;
+    private final FlexibleStringExpander setIfNullFse;
+    private final FlexibleMapAccessor<GenericValue> valueFma;
 
     public SetPkFields(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        valueAcsr = new ContextAccessor<GenericValue>(element.getAttribute("value-field"), element.getAttribute("value-name"));
-        mapAcsr = new ContextAccessor<Map<String, ? extends Object>>(element.getAttribute("map"), element.getAttribute("map-name"));
-        setIfNullStr = element.getAttribute("set-if-null");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "value-field", "set-if-null", "map");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "value-field", "map");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "value-field", "map");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        valueFma = FlexibleMapAccessor.getInstance(element.getAttribute("value-field"));
+        setIfNullFse = FlexibleStringExpander.getInstance(element.getAttribute("set-if-null"));
+        mapFma = FlexibleMapAccessor.getInstance(element.getAttribute("map"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        // if anything but false it will be true
-        boolean setIfNull = !"false".equals(methodContext.expandString(setIfNullStr));
-        GenericValue value = valueAcsr.get(methodContext);
+        GenericValue value = valueFma.get(methodContext.getEnvMap());
         if (value == null) {
-            String errMsg = "In set-pk-fields a value was not found with the specified valueAcsr: " + valueAcsr + ", not setting fields";
-
-            Debug.logWarning(errMsg, module);
-            if (methodContext.getMethodType() == MethodContext.EVENT) {
-                methodContext.putEnv(simpleMethod.getEventErrorMessageName(), errMsg);
-                methodContext.putEnv(simpleMethod.getEventResponseCodeName(), simpleMethod.getDefaultErrorCode());
-            } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
-                methodContext.putEnv(simpleMethod.getServiceErrorMessageName(), errMsg);
-                methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), simpleMethod.getDefaultErrorCode());
-            }
-            return false;
+            throw new MiniLangRuntimeException("Entity value not found with name: " + valueFma, this);
         }
-        Map<String, ? extends Object> theMap = mapAcsr.get(methodContext);
+        Map<String, ? extends Object> theMap = mapFma.get(methodContext.getEnvMap());
         if (theMap == null) {
-            Debug.logWarning("In set-pk-fields could not find map with name " + mapAcsr + ", not setting any fields", module);
-        } else {
-            value.setPKFields(theMap, setIfNull);
+            throw new MiniLangRuntimeException("Map not found with name: " + mapFma, this);
         }
+        boolean setIfNull = !"false".equals(setIfNullFse.expand(methodContext.getEnvMap()));
+        value.setPKFields(theMap, setIfNull);
         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: something more than the empty tag
-        return "<set-pk-fields/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<set-pk-fields ");
+        sb.append("value-field=\"").append(this.valueFma).append("\" ");
+        sb.append("map=\"").append(this.mapFma).append("\" ");
+        if (!setIfNullFse.isEmpty()) {
+            sb.append("set-if-null=\"").append(this.setIfNullFse).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;set-pk-fields&gt; element.
+     */
     public static final class SetPkFieldsFactory implements Factory<SetPkFields> {
+        @Override
         public SetPkFields createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new SetPkFields(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "set-pk-fields";
         }

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreList.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreList.java?rev=1348620&r1=1348619&r2=1348620&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreList.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreList.java Sun Jun 10 16:21:41 2012
@@ -21,51 +21,53 @@ package org.ofbiz.minilang.method.entity
 import java.util.List;
 
 import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 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;
 
 /**
- * Uses the delegator to store the specified value object list in the datasource
+ * Implements the &lt;store-list&gt; element.
  */
-public class StoreList extends MethodOperation {
+public final class StoreList extends MethodOperation {
 
     public static final String module = StoreList.class.getName();
 
-    String doCacheClearStr;
-    ContextAccessor<List<GenericValue>> listAcsr;
+    private final FlexibleStringExpander doCacheClearFse;
+    private final FlexibleMapAccessor<List<GenericValue>> listFma;
 
     public StoreList(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        listAcsr = new ContextAccessor<List<GenericValue>>(element.getAttribute("list"), element.getAttribute("list-name"));
-        doCacheClearStr = element.getAttribute("do-cache-clear");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "list", "do-cache-clear");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "list");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "list");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        listFma = FlexibleMapAccessor.getInstance(element.getAttribute("list"));
+        doCacheClearFse = FlexibleStringExpander.getInstance(element.getAttribute("do-cache-clear"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        boolean doCacheClear = !"false".equals(methodContext.expandString(doCacheClearStr));
-        List<GenericValue> values = listAcsr.get(methodContext);
+        List<GenericValue> values = listFma.get(methodContext.getEnvMap());
         if (values == null) {
-            String errMsg = "In store-list a value list was not found with the specified listAcsr: " + listAcsr + ", not storing";
-            Debug.logInfo(errMsg, module);
+            throw new MiniLangRuntimeException("Entity value list not found with name: " + listFma, this);
         }
+        boolean doCacheClear = !"false".equals(doCacheClearFse.expandString(methodContext.getEnvMap()));
         try {
             methodContext.getDelegator().storeAll(values, doCacheClear);
         } catch (GenericEntityException e) {
-            Debug.logError(e, module);
-            String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [problem storing the " + listAcsr + " value list: " + e.getMessage() + "]";
-            if (methodContext.getMethodType() == MethodContext.EVENT) {
-                methodContext.putEnv(simpleMethod.getEventErrorMessageName(), errMsg);
-                methodContext.putEnv(simpleMethod.getEventResponseCodeName(), simpleMethod.getDefaultErrorCode());
-            } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
-                methodContext.putEnv(simpleMethod.getServiceErrorMessageName(), errMsg);
-                methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), simpleMethod.getDefaultErrorCode());
-            }
+            String errMsg = "Exception thrown while storing entities: " + e.getMessage();
+            Debug.logWarning(e, errMsg, module);
+            simpleMethod.addErrorMessage(methodContext, errMsg);
             return false;
         }
         return true;
@@ -73,21 +75,35 @@ public class StoreList extends MethodOpe
 
     @Override
     public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
+        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
     }
 
     @Override
     public String rawString() {
-        // TODO: something more than the empty tag
-        return "<store-list/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<store-list ");
+        sb.append("list=\"").append(this.listFma).append("\" ");
+        if (!doCacheClearFse.isEmpty()) {
+            sb.append("do-cache-clear=\"").append(this.doCacheClearFse).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;store-list&gt; element.
+     */
     public static final class StoreListFactory implements Factory<StoreList> {
+        @Override
         public StoreList createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new StoreList(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "store-list";
         }

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreValue.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreValue.java?rev=1348620&r1=1348619&r2=1348620&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreValue.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreValue.java Sun Jun 10 16:21:41 2012
@@ -19,55 +19,53 @@
 package org.ofbiz.minilang.method.entityops;
 
 import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 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;
 
 /**
- * Uses the delegator to store the specified value object entity in the datasource
+ * Implements the &lt;store-value&gt; element.
  */
-public class StoreValue extends MethodOperation {
+public final class StoreValue extends MethodOperation {
 
     public static final String module = StoreValue.class.getName();
 
-    String doCacheClearStr;
-    ContextAccessor<GenericValue> valueAcsr;
+    private final FlexibleStringExpander doCacheClearFse;
+    private final FlexibleMapAccessor<GenericValue> valueFma;
 
     public StoreValue(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        valueAcsr = new ContextAccessor<GenericValue>(element.getAttribute("value-field"), element.getAttribute("value-name"));
-        doCacheClearStr = element.getAttribute("do-cache-clear");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "value-field", "do-cache-clear");
+            MiniLangValidate.requiredAttributes(simpleMethod, element, "value-field");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "value-field");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        valueFma = FlexibleMapAccessor.getInstance(element.getAttribute("value-field"));
+        doCacheClearFse = FlexibleStringExpander.getInstance(element.getAttribute("do-cache-clear"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
-        boolean doCacheClear = !"false".equals(methodContext.expandString(doCacheClearStr));
-        GenericValue value = null;
-        try {
-            value = valueAcsr.get(methodContext);
-        } catch (ClassCastException e) {
-            String errMsg = "In store-value the value specified by valueAcsr [" + valueAcsr + "] was not an instance of GenericValue, not storing";
-            Debug.logError(errMsg, module);
-            methodContext.setErrorReturn(errMsg, simpleMethod);
-            return false;
-        }
+        GenericValue value = valueFma.get(methodContext.getEnvMap());
         if (value == null) {
-            String errMsg = "In store-value a value was not found with the specified valueAcsr: " + valueAcsr + ", not storing";
-            Debug.logWarning(errMsg, module);
-            methodContext.setErrorReturn(errMsg, simpleMethod);
-            return false;
+            throw new MiniLangRuntimeException("Entity value not found with name: " + valueFma, this);
         }
+        boolean doCacheClear = !"false".equals(doCacheClearFse.expandString(methodContext.getEnvMap()));
         try {
             methodContext.getDelegator().store(value, doCacheClear);
         } catch (GenericEntityException e) {
-            Debug.logError(e, module);
-            String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [problem storing the " + valueAcsr + " value: " + e.getMessage() + "]";
-            methodContext.setErrorReturn(errMsg, simpleMethod);
+            String errMsg = "Exception thrown while storing entity value: " + e.getMessage();
+            Debug.logWarning(e, errMsg, module);
+            simpleMethod.addErrorMessage(methodContext, errMsg);
             return false;
         }
         return true;
@@ -75,21 +73,35 @@ public class StoreValue extends MethodOp
 
     @Override
     public String expandedString(MethodContext methodContext) {
-        // TODO: something more than a stub/dummy
-        return this.rawString();
+        return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
     }
 
     @Override
     public String rawString() {
-        // TODO: something more than the empty tag
-        return "<store-value/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<store-value ");
+        sb.append("value-field=\"").append(this.valueFma).append("\" ");
+        if (!doCacheClearFse.isEmpty()) {
+            sb.append("do-cache-clear=\"").append(this.doCacheClearFse).append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;store-value&gt; element.
+     */
     public static final class StoreValueFactory implements Factory<StoreValue> {
+        @Override
         public StoreValue createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new StoreValue(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "store-value";
         }

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionBegin.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionBegin.java?rev=1348620&r1=1348619&r2=1348620&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionBegin.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionBegin.java Sun Jun 10 16:21:41 2012
@@ -19,27 +19,34 @@
 package org.ofbiz.minilang.method.entityops;
 
 import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.transaction.GenericTransactionException;
 import org.ofbiz.entity.transaction.TransactionUtil;
 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;
 
 /**
- * Begins a transaction if one is not already in place; if does begin one puts true in the began-transaction-name env variable, otherwise it returns false.
+ * Implements the &lt;transaction-begin&gt; element.
  */
-public class TransactionBegin extends MethodOperation {
+public final class TransactionBegin extends MethodOperation {
 
     public static final String module = TransactionBegin.class.getName();
 
-    ContextAccessor<Boolean> beganTransactionAcsr;
+    private final FlexibleMapAccessor<Boolean> beganTransactionFma;
 
     public TransactionBegin(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        beganTransactionAcsr = new ContextAccessor<Boolean>(element.getAttribute("began-transaction-name"), "beganTransaction");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "began-transaction-name");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "began-transaction-name");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        beganTransactionFma = FlexibleMapAccessor.getInstance(MiniLangValidate.checkAttribute(element.getAttribute("began-transaction-name"), "beganTransaction"));
     }
 
     @Override
@@ -48,32 +55,42 @@ public class TransactionBegin extends Me
         try {
             beganTransaction = TransactionUtil.begin();
         } catch (GenericTransactionException e) {
-            Debug.logError(e, "Could not begin transaction in simple-method, returning error.", module);
-            String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [error beginning a transaction: " + e.getMessage() + "]";
-            methodContext.setErrorReturn(errMsg, simpleMethod);
+            String errMsg = "Exception thrown while beginning transaction: " + e.getMessage();
+            Debug.logWarning(e, errMsg, module);
+            simpleMethod.addErrorMessage(methodContext, errMsg);
             return false;
         }
-        beganTransactionAcsr.put(methodContext, beganTransaction);
+        beganTransactionFma.put(methodContext.getEnvMap(), beganTransaction);
         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: something more than the empty tag
-        return "<transaction-begin/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<transaction-begin ");
+        sb.append("began-transaction-name=\"").append(this.beganTransactionFma).append("\" />");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;transaction-begin&gt; element.
+     */
     public static final class TransactionBeginFactory implements Factory<TransactionBegin> {
+        @Override
         public TransactionBegin createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new TransactionBegin(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "transaction-begin";
         }

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionCommit.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionCommit.java?rev=1348620&r1=1348619&r2=1348620&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionCommit.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionCommit.java Sun Jun 10 16:21:41 2012
@@ -19,65 +19,82 @@
 package org.ofbiz.minilang.method.entityops;
 
 import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.transaction.GenericTransactionException;
 import org.ofbiz.entity.transaction.TransactionUtil;
 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;
 
 /**
- * Commits a transaction if beganTransaction is true, otherwise does nothing.
+ * Implements the &lt;transaction-commit&gt; element.
  */
-public class TransactionCommit extends MethodOperation {
+public final class TransactionCommit extends MethodOperation {
 
     public static final String module = TransactionCommit.class.getName();
 
-    ContextAccessor<Boolean> beganTransactionAcsr;
+    private final FlexibleMapAccessor<Boolean> beganTransactionFma;
 
     public TransactionCommit(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        beganTransactionAcsr = new ContextAccessor<Boolean>(element.getAttribute("began-transaction-name"), "beganTransaction");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "began-transaction-name");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "began-transaction-name");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        beganTransactionFma = FlexibleMapAccessor.getInstance(MiniLangValidate.checkAttribute(element.getAttribute("began-transaction-name"), "beganTransaction"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
         boolean beganTransaction = false;
-        Boolean beganTransactionBoolean = beganTransactionAcsr.get(methodContext);
+        Boolean beganTransactionBoolean = beganTransactionFma.get(methodContext.getEnvMap());
         if (beganTransactionBoolean != null) {
             beganTransaction = beganTransactionBoolean.booleanValue();
         }
         try {
             TransactionUtil.commit(beganTransaction);
         } catch (GenericTransactionException e) {
-            Debug.logError(e, "Could not commit transaction in simple-method, returning error.", module);
-            String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [error committing a transaction: " + e.getMessage() + "]";
-            methodContext.setErrorReturn(errMsg, simpleMethod);
+            String errMsg = "Exception thrown while committing transaction: " + e.getMessage();
+            Debug.logWarning(e, errMsg, module);
+            simpleMethod.addErrorMessage(methodContext, errMsg);
             return false;
         }
-        beganTransactionAcsr.remove(methodContext);
+        beganTransactionFma.remove(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: something more than the empty tag
-        return "<transaction-commit/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<transaction-commit ");
+        sb.append("began-transaction-name=\"").append(this.beganTransactionFma).append("\" />");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;transaction-commit&gt; element.
+     */
     public static final class TransactionCommitFactory implements Factory<TransactionCommit> {
+        @Override
         public TransactionCommit createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new TransactionCommit(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "transaction-commit";
         }

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionRollback.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionRollback.java?rev=1348620&r1=1348619&r2=1348620&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionRollback.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/entityops/TransactionRollback.java Sun Jun 10 16:21:41 2012
@@ -19,65 +19,82 @@
 package org.ofbiz.minilang.method.entityops;
 
 import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.transaction.GenericTransactionException;
 import org.ofbiz.entity.transaction.TransactionUtil;
 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;
 
 /**
- * Rolls back a transaction if beganTransaction is true, otherwise tries to do a setRollbackOnly.
+ * Implements the &lt;transaction-rollback&gt; element.
  */
-public class TransactionRollback extends MethodOperation {
+public final class TransactionRollback extends MethodOperation {
 
     public static final String module = TransactionRollback.class.getName();
 
-    ContextAccessor<Boolean> beganTransactionAcsr;
+    private final FlexibleMapAccessor<Boolean> beganTransactionFma;
 
     public TransactionRollback(Element element, SimpleMethod simpleMethod) throws MiniLangException {
         super(element, simpleMethod);
-        beganTransactionAcsr = new ContextAccessor<Boolean>(element.getAttribute("began-transaction-name"), "beganTransaction");
+        if (MiniLangValidate.validationOn()) {
+            MiniLangValidate.attributeNames(simpleMethod, element, "began-transaction-name");
+            MiniLangValidate.expressionAttributes(simpleMethod, element, "began-transaction-name");
+            MiniLangValidate.noChildElements(simpleMethod, element);
+        }
+        beganTransactionFma = FlexibleMapAccessor.getInstance(MiniLangValidate.checkAttribute(element.getAttribute("began-transaction-name"), "beganTransaction"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
         boolean beganTransaction = false;
-        Boolean beganTransactionBoolean = beganTransactionAcsr.get(methodContext);
+        Boolean beganTransactionBoolean = beganTransactionFma.get(methodContext.getEnvMap());
         if (beganTransactionBoolean != null) {
             beganTransaction = beganTransactionBoolean.booleanValue();
         }
         try {
             TransactionUtil.rollback(beganTransaction, "Explicit rollback in simple-method [" + this.simpleMethod.getShortDescription() + "]", null);
         } catch (GenericTransactionException e) {
-            Debug.logError(e, "Could not rollback transaction in simple-method, returning error.", module);
-            String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [error rolling back a transaction: " + e.getMessage() + "]";
-            methodContext.setErrorReturn(errMsg, simpleMethod);
+            String errMsg = "Exception thrown while rolling back transaction: " + e.getMessage();
+            Debug.logWarning(e, errMsg, module);
+            simpleMethod.addErrorMessage(methodContext, errMsg);
             return false;
         }
-        beganTransactionAcsr.remove(methodContext);
+        beganTransactionFma.remove(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: something more than the empty tag
-        return "<transaction-rollback/>";
+        return toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("<transaction-rollback ");
+        sb.append("began-transaction-name=\"").append(this.beganTransactionFma).append("\" />");
+        return sb.toString();
     }
 
+    /**
+     * A factory for the &lt;transaction-rollback&gt; element.
+     */
     public static final class TransactionRollbackFactory implements Factory<TransactionRollback> {
+        @Override
         public TransactionRollback createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
             return new TransactionRollback(element, simpleMethod);
         }
 
+        @Override
         public String getName() {
             return "transaction-rollback";
         }