You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2012/05/06 02:43:59 UTC
svn commit: r1334536 - in /ofbiz/trunk/framework/minilang:
dtd/simple-methods-v2.xsd
src/org/ofbiz/minilang/method/conditional/While.java
src/org/ofbiz/minilang/method/envops/IterateMap.java
src/org/ofbiz/minilang/method/envops/Loop.java
Author: adrianc
Date: Sun May 6 00:43:58 2012
New Revision: 1334536
URL: http://svn.apache.org/viewvc?rev=1334536&view=rev
Log:
Overhauled Mini-language <iterate-map>, <loop>, and <while> elements.
Modified:
ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/conditional/While.java
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/IterateMap.java
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Loop.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=1334536&r1=1334535&r2=1334536&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original)
+++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Sun May 6 00:43:58 2012
@@ -3415,19 +3415,19 @@ under the License.
</xs:annotation>
<xs:complexType>
<xs:group minOccurs="0" maxOccurs="unbounded" ref="AllOperations" />
- <xs:attribute type="xs:string" name="entry" use="required">
+ <xs:attribute type="xs:string" name="list" use="required">
<xs:annotation>
<xs:documentation>
- The name of the environment field that will contain each entry in the list.
+ The name of the environment field that contains the list to iterate over.
<br/><br/>
Required. Attribute type: expression.
</xs:documentation>
</xs:annotation>
</xs:attribute>
- <xs:attribute type="xs:string" name="list" use="required">
+ <xs:attribute type="xs:string" name="entry" use="required">
<xs:annotation>
<xs:documentation>
- The name of the environment field that contains the list to iterate over.
+ The name of the environment field that will contain each entry in the list.
<br/><br/>
Required. Attribute type: expression.
</xs:documentation>
@@ -3438,77 +3438,84 @@ under the License.
<xs:element name="iterate-map" substitutionGroup="ControlOperations">
<xs:annotation>
<xs:documentation>
- The operations contained by the iterate-map tag will be executed for each of the entries in the map.
- It will run all of the operations underneath the iterate-map-element for each of the entries in the given map,
- setting the key for that entry and the key name variable, and the value for that entry and the value variable.
-
- This tag can contain any of the simple-method operations, including the conditional/if operations.
-
- Any simple-method operation can be nested under the iterate-map tag.
+ The operations contained in the iterate-map element will be executed for each of the entries in the list,
+ and will make the current entry key/value pair available in the environment by the names specified.
</xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:group minOccurs="0" maxOccurs="unbounded" ref="AllOperations"/>
- <xs:attributeGroup ref="attlist.iterate-map"/>
+ <xs:group minOccurs="0" maxOccurs="unbounded" ref="AllOperations" />
+ <xs:attribute type="xs:string" name="map" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The name of the environment field that contains the map to iterate over.
+ <br/><br/>
+ Required. Attribute type: expression.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="key" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The name of the environment field that will contain the map entry key.
+ <br/><br/>
+ Required. Attribute type: expression.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="value" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The name of the environment field that will contain the map entry value.
+ <br/><br/>
+ Required. Attribute type: expression.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
</xs:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.iterate-map">
- <xs:attribute type="xs:string" name="key" use="required">
- <xs:annotation>
- <xs:documentation>
- Name of the variable to put the key.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="value" use="required">
- <xs:annotation>
- <xs:documentation>
- Name of the variable to put the value in.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="map" use="required">
- <xs:annotation>
- <xs:documentation>
- Name of the map to use.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
<xs:element name="loop" substitutionGroup="ControlOperations">
<xs:annotation>
<xs:documentation>
- Loop, rather than iterating over some sort of a structure,
- will simply loop a certain number of times. The
- number of times to loop is specified in the count attribute,
- and it will put the current count in the field attribute,
- or in the variable named by the field attribute. So if you
- want to loop ten times you say count=ten, and
- field=count for example. First time through count will
- be zero; last time through count will be nine.
+ The operations contained in the loop element will be executed repeatedly until the specified count is reached.
+ The current count value is available in the environment by the name specified.
</xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:group minOccurs="0" maxOccurs="unbounded" ref="AllOperations"/>
- <xs:attributeGroup ref="attlist.loop"/>
+ <xs:group minOccurs="0" maxOccurs="unbounded" ref="AllOperations" />
+ <xs:attribute type="xs:string" name="count" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The number of times to loop.
+ <br/><br/>
+ Required. Attribute types: constant, expression.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="field">
+ <xs:annotation>
+ <xs:documentation>
+ The name of the environment field that will contain the current count.
+ <br/><br/>
+ Optional. Attribute type: expression.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="while" substitutionGroup="ControlOperations">
+ <xs:annotation>
+ <xs:documentation>
+ The operations contained in the while element will be executed as long as its condition element
+ evaluates to true.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="condition" />
+ <xs:element ref="then" />
+ </xs:sequence>
</xs:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.loop">
- <xs:attribute type="xs:string" name="count" use="required">
- <xs:annotation>
- <xs:documentation>
- Number of times to loop.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="field" use="optional">
- <xs:annotation>
- <xs:documentation>
- Current count is put in the field attribute.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
<xs:element name="check-errors" substitutionGroup="ControlOperations">
<xs:annotation>
<xs:documentation>
@@ -3682,34 +3689,6 @@ under the License.
</xs:sequence>
</xs:complexType>
</xs:element>
- <xs:element name="while" substitutionGroup="IfOtherOperations">
- <xs:annotation>
- <xs:documentation>
- While loop operation, uses the same condition element as the if operation.
- </xs:documentation>
- </xs:annotation>
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="condition">
- <xs:annotation>
- <xs:documentation>
- A simple element with no attributes that contains the condition that will be evaluated to determine which sub-operations to execute.
- To combine the other if operations documented below the and, or, xor, and notelements can be used.
- The and, or, and xor elements can contain as many general if operations and modifier/combination elements (ie and, or, xor, and not).
- </xs:documentation>
- </xs:annotation>
- </xs:element>
- <xs:element ref="then">
- <xs:annotation>
- <xs:documentation>
- The then element is used to contain operations that will run if the condition evaluate to true.
- A then tag must be included, but can be empty.
- </xs:documentation>
- </xs:annotation>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
<xs:element name="condition">
<xs:annotation>
<xs:documentation>
Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/conditional/While.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/conditional/While.java?rev=1334536&r1=1334535&r2=1334536&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/conditional/While.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/conditional/While.java Sun May 6 00:43:58 2012
@@ -23,6 +23,7 @@ import java.util.List;
import org.ofbiz.base.util.UtilXml;
import org.ofbiz.minilang.MiniLangException;
+import org.ofbiz.minilang.MiniLangValidate;
import org.ofbiz.minilang.SimpleMethod;
import org.ofbiz.minilang.method.MethodContext;
import org.ofbiz.minilang.method.MethodOperation;
@@ -33,13 +34,17 @@ import org.w3c.dom.Element;
/**
* Continually processes sub-ops while the condition remains true
*/
-public class While extends MethodOperation {
+public final class While extends MethodOperation {
- Conditional condition;
- List<MethodOperation> thenSubOps;
+ private final Conditional condition;
+ private final List<MethodOperation> thenSubOps;
public While(Element element, SimpleMethod simpleMethod) throws MiniLangException {
super(element, simpleMethod);
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.childElements(simpleMethod, element, "condition", "then");
+ MiniLangValidate.requiredChildElements(simpleMethod, element, "condition", "then");
+ }
Element conditionElement = UtilXml.firstChildElement(element, "condition");
Element conditionChildElement = UtilXml.firstChildElement(conditionElement);
this.condition = ConditionalFactory.makeConditional(conditionChildElement, simpleMethod);
@@ -49,9 +54,6 @@ public class While extends MethodOperati
@Override
public boolean exec(MethodContext methodContext) throws MiniLangException {
- // if conditions fails, always return true;
- // if a sub-op returns false return false and stop, otherwise drop though loop and
- // return true
while (condition.checkCondition(methodContext)) {
try {
for (MethodOperation methodOperation : thenSubOps) {
Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/IterateMap.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/IterateMap.java?rev=1334536&r1=1334535&r2=1334536&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/IterateMap.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/IterateMap.java Sun May 6 00:43:58 2012
@@ -23,9 +23,12 @@ import java.util.List;
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.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.ofbiz.minilang.method.envops.Break.BreakElementException;
@@ -35,51 +38,57 @@ import org.w3c.dom.Element;
/**
* Process sub-operations for each entry in the map
*/
-public class IterateMap extends MethodOperation {
+public final class IterateMap extends MethodOperation {
public static final String module = IterateMap.class.getName();
- ContextAccessor<Object> keyAcsr;
- ContextAccessor<Map<? extends Object, ? extends Object>> mapAcsr;
- List<MethodOperation> subOps;
- ContextAccessor<Object> valueAcsr;
+ private final FlexibleMapAccessor<Object> keyFma;
+ private final FlexibleMapAccessor<Map<? extends Object, ? extends Object>> mapFma;
+ private final List<MethodOperation> subOps;
+ private final FlexibleMapAccessor<Object> valueFma;
public IterateMap(Element element, SimpleMethod simpleMethod) throws MiniLangException {
super(element, simpleMethod);
- this.keyAcsr = new ContextAccessor<Object>(element.getAttribute("key"), element.getAttribute("key-name"));
- this.valueAcsr = new ContextAccessor<Object>(element.getAttribute("value"), element.getAttribute("value-name"));
- this.mapAcsr = new ContextAccessor<Map<? extends Object, ? extends Object>>(element.getAttribute("map"), element.getAttribute("map-name"));
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.attributeNames(simpleMethod, element, "key", "map", "value");
+ MiniLangValidate.requiredAttributes(simpleMethod, element, "key", "map", "value");
+ MiniLangValidate.expressionAttributes(simpleMethod, element, "key", "map", "value");
+ }
+ this.keyFma = FlexibleMapAccessor.getInstance(element.getAttribute("key"));
+ this.mapFma = FlexibleMapAccessor.getInstance(element.getAttribute("map"));
+ this.valueFma = FlexibleMapAccessor.getInstance(element.getAttribute("value"));
this.subOps = Collections.unmodifiableList(SimpleMethod.readOperations(element, simpleMethod));
}
@Override
public boolean exec(MethodContext methodContext) throws MiniLangException {
- if (mapAcsr.isEmpty()) {
- Debug.logWarning("No map-name specified in iterate tag, doing nothing: " + rawString(), module);
- return true;
+ if (mapFma.isEmpty()) {
+ throw new MiniLangRuntimeException("No map specified.", this);
}
- Object oldKey = keyAcsr.get(methodContext);
- Object oldValue = valueAcsr.get(methodContext);
+ Object oldKey = keyFma.get(methodContext.getEnvMap());
+ Object oldValue = valueFma.get(methodContext.getEnvMap());
if (oldKey != null) {
- Debug.logWarning("In iterate-map the key had a non-null value before entering the loop for the operation: " + this.rawString(), module);
+ if (Debug.verboseOn())
+ Debug.logVerbose("In iterate-map the key had a non-null value before entering the loop for the operation: " + this, module);
}
if (oldValue != null) {
- Debug.logWarning("In iterate-map the value had a non-null value before entering the loop for the operation: " + this.rawString(), module);
+ if (Debug.verboseOn())
+ Debug.logVerbose("In iterate-map the value had a non-null value before entering the loop for the operation: " + this, module);
}
- Map<? extends Object, ? extends Object> theMap = mapAcsr.get(methodContext);
+ Map<? extends Object, ? extends Object> theMap = mapFma.get(methodContext.getEnvMap());
if (theMap == null) {
- if (Debug.infoOn())
- Debug.logInfo("Map not found with name " + mapAcsr + ", doing nothing: " + rawString(), module);
+ if (Debug.verboseOn())
+ Debug.logVerbose("Map not found with name " + mapFma + ", doing nothing: " + this, module);
return true;
}
if (theMap.size() == 0) {
if (Debug.verboseOn())
- Debug.logVerbose("Map with name " + mapAcsr + " has zero entries, doing nothing: " + rawString(), module);
+ Debug.logVerbose("Map with name " + mapFma + " has zero entries, doing nothing: " + this, module);
return true;
}
for (Map.Entry<? extends Object, ? extends Object> theEntry : theMap.entrySet()) {
- keyAcsr.put(methodContext, theEntry.getKey());
- valueAcsr.put(methodContext, theEntry.getValue());
+ keyFma.put(methodContext.getEnvMap(), theEntry.getKey());
+ valueFma.put(methodContext.getEnvMap(), theEntry.getValue());
try {
for (MethodOperation methodOperation : subOps) {
if (!methodOperation.exec(methodContext)) {
@@ -101,8 +110,7 @@ public class IterateMap extends MethodOp
@Override
public String expandedString(MethodContext methodContext) {
- // TODO: something more than a stub/dummy
- return this.rawString();
+ return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
}
public List<MethodOperation> getSubOps() {
@@ -111,7 +119,23 @@ public class IterateMap extends MethodOp
@Override
public String rawString() {
- return "<iterate-map map-name=\"" + this.mapAcsr + "\" key=\"" + this.keyAcsr + "\" value=\"" + this.valueAcsr + "\"/>";
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("<iterate-map ");
+ if (!this.mapFma.isEmpty()) {
+ sb.append("map=\"").append(this.mapFma).append("\" ");
+ }
+ if (!this.keyFma.isEmpty()) {
+ sb.append("key=\"").append(this.keyFma).append("\" ");
+ }
+ if (!this.valueFma.isEmpty()) {
+ sb.append("value=\"").append(this.valueFma).append("\" ");
+ }
+ sb.append("/>");
+ return sb.toString();
}
public static final class IterateMapFactory implements Factory<IterateMap> {
Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Loop.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Loop.java?rev=1334536&r1=1334535&r2=1334536&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Loop.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Loop.java Sun May 6 00:43:58 2012
@@ -21,10 +21,12 @@ package org.ofbiz.minilang.method.envops
import java.util.Collections;
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.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.ofbiz.minilang.method.envops.Break.BreakElementException;
@@ -34,40 +36,40 @@ import org.w3c.dom.Element;
/**
* Loop
*/
-public class Loop extends MethodOperation {
+public final class Loop extends MethodOperation {
public static final String module = Loop.class.getName();
- protected String countStr;
- protected ContextAccessor<Integer> fieldAcsr;
- protected List<MethodOperation> subOps;
+ private final FlexibleStringExpander countFse;
+ private final FlexibleMapAccessor<Integer> fieldFma;
+ private final List<MethodOperation> subOps;
public Loop(Element element, SimpleMethod simpleMethod) throws MiniLangException {
super(element, simpleMethod);
- this.fieldAcsr = new ContextAccessor<Integer>(element.getAttribute("field"));
- this.countStr = element.getAttribute("count");
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.attributeNames(simpleMethod, element, "count", "field");
+ MiniLangValidate.requiredAttributes(simpleMethod, element, "count");
+ MiniLangValidate.expressionAttributes(simpleMethod, element, "count", "field");
+ }
+ this.countFse = FlexibleStringExpander.getInstance(element.getAttribute("count"));
+ this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
this.subOps = Collections.unmodifiableList(SimpleMethod.readOperations(element, simpleMethod));
}
@Override
public boolean exec(MethodContext methodContext) throws MiniLangException {
- String countStrExp = methodContext.expandString(this.countStr);
+ String countStr = this.countFse.expandString(methodContext.getEnvMap());
int count = 0;
try {
- Double ctDbl = Double.valueOf(countStrExp);
- if (ctDbl != null) {
- count = ctDbl.intValue();
- }
+ count = Double.valueOf(countStr).intValue();
} catch (NumberFormatException e) {
- Debug.logError(e, module);
- return false;
+ throw new MiniLangRuntimeException("Error while converting \"" + countStr + "\" to a number: " + e.getMessage(), this);
}
if (count < 0) {
- Debug.logWarning("Unable to execute loop operation because the count variable is negative: " + rawString(), module);
- return false;
+ throw new MiniLangRuntimeException("Unable to execute loop operation because the count is negative: " + countStr, this);
}
for (int i = 0; i < count; i++) {
- fieldAcsr.put(methodContext, i);
+ this.fieldFma.put(methodContext.getEnvMap(), i);
try {
for (MethodOperation methodOperation : subOps) {
if (!methodOperation.exec(methodContext)) {
@@ -89,7 +91,7 @@ public class Loop extends MethodOperatio
@Override
public String expandedString(MethodContext methodContext) {
- return this.rawString();
+ return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
}
public List<MethodOperation> getSubOps() {
@@ -98,7 +100,20 @@ public class Loop extends MethodOperatio
@Override
public String rawString() {
- return "<loop field=\"" + this.fieldAcsr + "\" count=\"" + this.countStr + "\"/>";
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("<loop ");
+ if (!this.countFse.isEmpty()) {
+ sb.append("count=\"").append(this.countFse).append("\" ");
+ }
+ if (!this.fieldFma.isEmpty()) {
+ sb.append("field=\"").append(this.fieldFma).append("\" ");
+ }
+ sb.append("/>");
+ return sb.toString();
}
public static final class LoopFactory implements Factory<Loop> {