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/04/27 00:40:23 UTC
svn commit: r1331137 - in /ofbiz/trunk/framework/minilang:
dtd/simple-methods-v2.xsd
src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java
src/org/ofbiz/minilang/method/envops/Now.java
src/org/ofbiz/minilang/method/serviceops/FieldToResult.java
Author: adrianc
Date: Thu Apr 26 22:40:22 2012
New Revision: 1331137
URL: http://svn.apache.org/viewvc?rev=1331137&view=rev
Log:
Added new attribute "memory-model" to the Mini-language <call-simple-method> element. Code cleanup and validation in FieldToResult.java. Improved validation in Now.java.
Modified:
ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.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=1331137&r1=1331136&r2=1331137&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original)
+++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Thu Apr 26 22:40:22 2012
@@ -918,33 +918,64 @@ under the License.
<xs:element name="call-simple-method" substitutionGroup="CallOperations">
<xs:annotation>
<xs:documentation>
- The call-simple-method tag calls another simple-method in the same context as the current one.
- In other words the called simple-method will have the same environment as the calling simple-method,
- including all environment fields, and either the event or service objects that the calling simple-method was called with.
+ Calls another simple-method in the same context as the current one.
+ The called simple-method will have the same environment as the calling simple-method,
+ including all environment fields, and either the event or service objects
+ that the calling simple-method was called
+ with.
</xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:attributeGroup ref="attlist.call-simple-method"/>
+ <xs:sequence>
+ <xs:element ref="result-to-field" minOccurs="0" maxOccurs="unbounded">
+ <xs:annotation>
+ <xs:documentation>
+ Used when memory-model="function". Copies the called method fields
+ to the calling method fields.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="method-name" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The name of the simple-method to execute in the specified xml-resource,
+ or in the current XML file if no xml-resource is specified.
+ <br/><br/>
+ Required. Attribute type: constant.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="xml-resource">
+ <xs:annotation>
+ <xs:documentation>
+ The full path and filename on the classpath of the XML file which contains an external simple-method to execute.
+ This is only required if a simple-method in a different file is desired.
+ <br/><br/>
+ Optional. Attribute type: constant.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="memory-model">
+ <xs:annotation>
+ <xs:documentation>
+ The memory model to use. In an "inline" memory model, fields declared or modified in the called method
+ will be reflected back to the calling method - as if the called method was inline. In a "function" memory
+ model, fields declared or modified in the called method are local to the called method - they are not
+ reflected back to the calling method.
+ <br/><br/>
+ Optional. Attribute type: constant.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="inline" />
+ <xs:enumeration value="function" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
</xs:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.call-simple-method">
- <xs:attribute type="xs:string" name="xml-resource">
- <xs:annotation>
- <xs:documentation>
- The full path and filename on the classpath of the XML file which contains an external simple-method to execute.
- This is only required if a simple-method in a different file is desired.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="method-name" use="required">
- <xs:annotation>
- <xs:documentation>
- The name of the simple-method to execute in the specified xml-resource,
- or in the current XML file if no xml-resource is specified.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
<!-- Operations to call Java methods and create Java objects -->
<xs:element name="call-object-method" substitutionGroup="CallOperations">
<xs:annotation>
@@ -1265,26 +1296,43 @@ under the License.
<xs:annotation><xs:documentation>The name of the session attribute to use. Defaults to the value of field attribute</xs:documentation></xs:annotation>
</xs:attribute>
</xs:attributeGroup>
- <!-- Service specific operations -->
- <xs:element name="field-to-result" substitutionGroup="ServiceOperations">
+ <xs:element name="field-to-result" substitutionGroup="EnvOperations">
<xs:annotation>
<xs:documentation>
- The field-to-result tag copies a field from a map to the specified service result field.
- The tag is only used when the simple-method is called as a service, it is ignored otherwise.
+ Copies a field to a service OUT attribute.
</xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:attributeGroup ref="attlist.field-to-result"/>
+ <xs:attribute name="field" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The name of the field to copy from. The source of the assignment.
+ <br/><br/>
+ Required. Attribute type: expression.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="result-name">
+ <xs:annotation>
+ <xs:documentation>
+ The name of the result field to set. The target of the assignment.
+ <br/><br/>
+ Optional. Attribute type: expression.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
</xs:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.field-to-result">
- <xs:attribute type="xs:string" name="field" use="required">
- <xs:annotation><xs:documentation>The name (key) of the map field to use.</xs:documentation></xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="result-name">
- <xs:annotation><xs:documentation>The name of the result Map name/key to use. Defaults to the value of field attribute.</xs:documentation></xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
<!-- Environment specific operations -->
<xs:element name="map-to-map" substitutionGroup="EnvOperations">
<xs:annotation>
@@ -4436,6 +4484,8 @@ under the License.
<xs:annotation>
<xs:documentation>
The field data type. Defaults to java.sql.Timestamp.
+ <br/><br/>
+ Optional. Attribute type: constant.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java?rev=1331137&r1=1331136&r2=1331137&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java Thu Apr 26 22:40:22 2012
@@ -18,117 +18,151 @@
*******************************************************************************/
package org.ofbiz.minilang.method.callops;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
+import javolution.util.FastMap;
+
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+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.ValidationException;
import org.ofbiz.minilang.method.MethodContext;
import org.ofbiz.minilang.method.MethodOperation;
import org.w3c.dom.Element;
/**
- * An operation that calls a simple method in the same, or from another, file
+ * Invokes a Mini-language simple method.
*/
-public class CallSimpleMethod extends MethodOperation {
+public final class CallSimpleMethod extends MethodOperation {
public static final String module = CallSimpleMethod.class.getName();
- String methodName;
- String xmlResource;
+ private final String methodName;
+ private final String xmlResource;
+ private final String memoryModel;
+ private final List<ResultToField> resultToFieldList;
public CallSimpleMethod(Element element, SimpleMethod simpleMethod) throws MiniLangException {
super(element, simpleMethod);
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.attributeNames(simpleMethod, element, "method-name", "xml-resource", "memory-model");
+ MiniLangValidate.requiredAttributes(simpleMethod, element, "method-name");
+ MiniLangValidate.constantAttributes(simpleMethod, element, "method-name", "xml-resource", "memory-model");
+ MiniLangValidate.childElements(simpleMethod, element, "result-to-field");
+ }
this.methodName = element.getAttribute("method-name");
this.xmlResource = element.getAttribute("xml-resource");
+ this.memoryModel = element.getAttribute("memory-model");
+ List<? extends Element> resultToFieldElements = UtilXml.childElementList(element, "result-to-field");
+ if (UtilValidate.isNotEmpty(resultToFieldElements)) {
+ if (!"function".equals(this.memoryModel)) {
+ MiniLangValidate.handleError("Inline memory model cannot include <result-to-field> elements.", simpleMethod, element);
+ }
+ List<ResultToField> resultToFieldList = new ArrayList<ResultToField>(resultToFieldElements.size());
+ for (Element resultToFieldElement : resultToFieldElements) {
+ resultToFieldList.add(new ResultToField(resultToFieldElement, simpleMethod));
+ }
+ this.resultToFieldList = resultToFieldList;
+ } else {
+ this.resultToFieldList = null;
+ }
}
@Override
public boolean exec(MethodContext methodContext) throws MiniLangException {
- if (UtilValidate.isNotEmpty(this.methodName)) {
- String methodName = methodContext.expandString(this.methodName);
- String xmlResource = methodContext.expandString(this.xmlResource);
- SimpleMethod simpleMethodToCall = null;
- try {
- simpleMethodToCall = getSimpleMethodToCall(methodContext.getLoader());
- } catch (MiniLangException e) {
- String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [error getting methods from resource: " + e.getMessage() + "]";
- Debug.logError(e, errMsg, module);
- methodContext.setErrorReturn(errMsg, simpleMethod);
- return false;
+ if (UtilValidate.isEmpty(this.methodName)) {
+ throw new MiniLangRuntimeException("method-name attribute is empty", this);
+ }
+ SimpleMethod simpleMethodToCall = null;
+ if (UtilValidate.isEmpty(this.xmlResource)) {
+ simpleMethodToCall = this.simpleMethod.getSimpleMethodInSameFile(methodName);
+ } else {
+ Map<String, SimpleMethod> simpleMethods = SimpleMethod.getSimpleMethods(this.xmlResource, methodContext.getLoader());
+ simpleMethodToCall = simpleMethods.get(this.methodName);
+ }
+ if (simpleMethodToCall == null) {
+ throw new MiniLangRuntimeException("Could not find <simple-method name=\"" + this.methodName + "\"> in XML document " + this.xmlResource, this);
+ }
+ MethodContext localContext = methodContext;
+ if ("function".equals(this.memoryModel)) {
+ Map<String, Object> localEnv = FastMap.newInstance();
+ localEnv.putAll(methodContext.getEnvMap());
+ localEnv.remove(this.simpleMethod.getEventResponseCodeName());
+ localEnv.remove(this.simpleMethod.getServiceResponseMessageName());
+ localContext = new MethodContext(localEnv, methodContext.getLoader(), methodContext.getMethodType());
+ }
+ String returnVal = simpleMethodToCall.exec(localContext);
+ if (Debug.verboseOn())
+ Debug.logVerbose("Called simple-method named [" + this.methodName + "] in resource [" + this.xmlResource + "], returnVal is [" + returnVal + "]", module);
+ if (simpleMethodToCall.getDefaultErrorCode().equals(returnVal)) {
+ if (methodContext.getMethodType() == MethodContext.EVENT) {
+ methodContext.putEnv(simpleMethod.getEventResponseCodeName(), simpleMethod.getDefaultErrorCode());
+ } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
+ methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), simpleMethod.getDefaultErrorCode());
}
- if (simpleMethodToCall == null) {
- String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process, could not find SimpleMethod " + methodName + " in XML document in resource: " + xmlResource;
- methodContext.setErrorReturn(errMsg, simpleMethod);
+ return false;
+ }
+ if (methodContext.getMethodType() == MethodContext.EVENT) {
+ // FIXME: This doesn't make sense. We are comparing the called method's response code with this method's
+ // response code. Since response codes are configurable per method, this code will fail.
+ String responseCode = (String) localContext.getEnv(this.simpleMethod.getEventResponseCodeName());
+ if (this.simpleMethod.getDefaultErrorCode().equals(responseCode)) {
+ Debug.logWarning("Got error [" + responseCode + "] calling inline simple-method named [" + this.methodName + "] in resource [" + this.xmlResource + "], message is " + methodContext.getEnv(this.simpleMethod.getEventErrorMessageName()), module);
return false;
}
- String returnVal = simpleMethodToCall.exec(methodContext);
- if (Debug.verboseOn())
- Debug.logVerbose("Called inline simple-method named [" + methodName + "] in resource [" + xmlResource + "], returnVal is [" + returnVal + "]", module);
- if (returnVal != null && returnVal.equals(simpleMethodToCall.getDefaultErrorCode())) {
- // in this case just set the error code just in case it hasn't already
- // been set, the error messages will already be in place...
- if (methodContext.getMethodType() == MethodContext.EVENT) {
- methodContext.putEnv(simpleMethod.getEventResponseCodeName(), simpleMethod.getDefaultErrorCode());
- } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
- methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), simpleMethod.getDefaultErrorCode());
- }
+ } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
+ // FIXME: This doesn't make sense. We are comparing the called method's response message with this method's
+ // response message. Since response messages are configurable per method, this code will fail.
+ String responseMessage = (String) localContext.getEnv(this.simpleMethod.getServiceResponseMessageName());
+ if (this.simpleMethod.getDefaultErrorCode().equals(responseMessage)) {
+ Debug.logWarning("Got error [" + responseMessage + "] calling inline simple-method named [" + this.methodName + "] in resource [" + this.xmlResource + "], message is " + methodContext.getEnv(this.simpleMethod.getServiceErrorMessageName()) + ", and the error message list is: "
+ + methodContext.getEnv(this.simpleMethod.getServiceErrorMessageListName()), module);
return false;
}
- // if the response code/message is error, if so show the error and return
- // false
- if (methodContext.getMethodType() == MethodContext.EVENT) {
- String responseCode = (String) methodContext.getEnv(simpleMethod.getEventResponseCodeName());
- if (responseCode != null && responseCode.equals(simpleMethod.getDefaultErrorCode())) {
- Debug.logWarning("Got error [" + responseCode + "] calling inline simple-method named [" + methodName + "] in resource [" + xmlResource + "], message is " + methodContext.getEnv(simpleMethod.getEventErrorMessageName()), module);
- return false;
- }
- } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
- String resonseMessage = (String) methodContext.getEnv(simpleMethod.getServiceResponseMessageName());
- if (resonseMessage != null && resonseMessage.equals(simpleMethod.getDefaultErrorCode())) {
- Debug.logWarning("Got error [" + resonseMessage + "] calling inline simple-method named [" + methodName + "] in resource [" + xmlResource + "], message is " + methodContext.getEnv(simpleMethod.getServiceErrorMessageName()) + ", and the error message list is: "
- + methodContext.getEnv(simpleMethod.getServiceErrorMessageListName()), module);
- return false;
+ }
+ if ("function".equals(this.memoryModel) && this.resultToFieldList != null) {
+ Map<String, Object> results = localContext.getResults();
+ if (results != null) {
+ for (ResultToField resultToField : this.resultToFieldList) {
+ resultToField.exec(methodContext.getEnvMap(), results);
}
}
- } else {
- String errMsg = "ERROR in call-simple-method: methodName was missing; not running simpleMethod";
- Debug.logError(errMsg, module);
- methodContext.setErrorReturn(errMsg, simpleMethod);
- return false;
}
return true;
}
@Override
public String expandedString(MethodContext methodContext) {
- // TODO: something more than a stub/dummy
- return this.rawString();
+ return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
}
- public String getMethodName() {
- return this.methodName;
- }
-
- public SimpleMethod getSimpleMethodToCall(ClassLoader loader) throws MiniLangException {
- SimpleMethod simpleMethodToCall = null;
- if (UtilValidate.isEmpty(xmlResource)) {
- simpleMethodToCall = this.simpleMethod.getSimpleMethodInSameFile(methodName);
- } else {
- Map<String, SimpleMethod> simpleMethods = SimpleMethod.getSimpleMethods(xmlResource, loader);
- simpleMethodToCall = simpleMethods.get(methodName);
- }
- return simpleMethodToCall;
- }
-
- public String getXmlResource() {
- return this.xmlResource;
+ @Override
+ public String rawString() {
+ return toString();
}
@Override
- public String rawString() {
- return "<call-simple-method xml-resource=\"" + this.xmlResource + "\" method-name=\"" + this.methodName + "\" />";
+ public String toString() {
+ StringBuilder sb = new StringBuilder("<call-simple-method ");
+ if (this.methodName.length() > 0) {
+ sb.append("method-name=\"").append(this.methodName).append("\" ");
+ }
+ if (this.xmlResource.length() > 0) {
+ sb.append("xml-resource=\"").append(this.xmlResource).append("\" ");
+ }
+ if (this.memoryModel.length() > 0) {
+ sb.append("memory-model=\"").append(this.memoryModel).append("\" ");
+ }
+ sb.append("/>");
+ return sb.toString();
}
public static final class CallSimpleMethodFactory implements Factory<CallSimpleMethod> {
@@ -140,4 +174,33 @@ public class CallSimpleMethod extends Me
return "call-simple-method";
}
}
+
+ private final class ResultToField {
+
+ private final FlexibleMapAccessor<Object> fieldFma;
+ private final FlexibleMapAccessor<Object> resultNameFma;
+
+ private ResultToField(Element element, SimpleMethod simpleMethod) throws ValidationException {
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.attributeNames(simpleMethod, element, "result-name", "field");
+ MiniLangValidate.requiredAttributes(simpleMethod, element, "result-name");
+ MiniLangValidate.expressionAttributes(simpleMethod, element, "result-name", "field");
+ MiniLangValidate.noChildElements(simpleMethod, element);
+ }
+ this.resultNameFma = FlexibleMapAccessor.getInstance(element.getAttribute("result-name"));
+ String fieldAttribute = element.getAttribute("field");
+ if (fieldAttribute.length() == 0) {
+ this.fieldFma = this.resultNameFma;
+ } else {
+ this.fieldFma = FlexibleMapAccessor.getInstance(fieldAttribute);
+ }
+ }
+
+ private void exec(Map<String, Object> context, Map<String, Object> results) throws MiniLangException {
+ Object value = this.resultNameFma.get(results);
+ if (value != null) {
+ this.fieldFma.put(context, value);
+ }
+ }
+ }
}
Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java?rev=1331137&r1=1331136&r2=1331137&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java Thu Apr 26 22:40:22 2012
@@ -47,6 +47,8 @@ public final class Now extends MethodOpe
if (MiniLangValidate.validationOn()) {
MiniLangValidate.attributeNames(simpleMethod, element, "field", "type");
MiniLangValidate.requiredAttributes(simpleMethod, element, "field");
+ MiniLangValidate.expressionAttributes(simpleMethod, element, "field");
+ MiniLangValidate.constantAttributes(simpleMethod, element, "type");
MiniLangValidate.noChildElements(simpleMethod, element);
}
this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java?rev=1331137&r1=1331136&r2=1331137&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java Thu Apr 26 22:40:22 2012
@@ -18,70 +18,72 @@
*******************************************************************************/
package org.ofbiz.minilang.method.serviceops;
-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.MiniLangValidate;
import org.ofbiz.minilang.SimpleMethod;
-import org.ofbiz.minilang.method.ContextAccessor;
import org.ofbiz.minilang.method.MethodContext;
import org.ofbiz.minilang.method.MethodOperation;
import org.w3c.dom.Element;
/**
- * Copies a map field to a Service result entry
+ * Copies a field to a service OUT attribute.
*/
-public class FieldToResult extends MethodOperation {
+public final class FieldToResult extends MethodOperation {
public static final String module = FieldToResult.class.getName();
- ContextAccessor<Object> fieldAcsr;
- ContextAccessor<Map<String, ? extends Object>> mapAcsr;
- ContextAccessor<Object> resultAcsr;
+ private final FlexibleMapAccessor<Object> fieldFma;
+ private final FlexibleMapAccessor<Object> resultFma;
public FieldToResult(Element element, SimpleMethod simpleMethod) throws MiniLangException {
super(element, simpleMethod);
- // the schema for this element now just has the "field" attribute, though the old "field-name" and "map-name" pair is still supported
- mapAcsr = new ContextAccessor<Map<String, ? extends Object>>(element.getAttribute("map-name"));
- fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field"), element.getAttribute("field-name"));
- resultAcsr = new ContextAccessor<Object>(element.getAttribute("result-name"), fieldAcsr.toString());
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.attributeNames(simpleMethod, element, "field", "result-name");
+ MiniLangValidate.requiredAttributes(simpleMethod, element, "field");
+ MiniLangValidate.expressionAttributes(simpleMethod, element, "field", "result-name");
+ MiniLangValidate.noChildElements(simpleMethod, element);
+ }
+ this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
+ String resultNameAttribute = element.getAttribute("result-name");
+ if (resultNameAttribute.length() == 0) {
+ this.resultFma = this.fieldFma;
+ } else {
+ this.resultFma = FlexibleMapAccessor.getInstance(resultNameAttribute);
+ }
}
@Override
public boolean exec(MethodContext methodContext) throws MiniLangException {
- // only run this if it is in an SERVICE context
- if (methodContext.getMethodType() == MethodContext.SERVICE) {
- Object fieldVal = null;
- if (!mapAcsr.isEmpty()) {
- Map<String, ? extends Object> fromMap = mapAcsr.get(methodContext);
- if (fromMap == null) {
- Debug.logWarning("Map not found with name " + mapAcsr, module);
- return true;
- }
- fieldVal = fieldAcsr.get(fromMap, methodContext);
- } else {
- // no map name, try the env
- fieldVal = fieldAcsr.get(methodContext);
- }
- if (fieldVal == null) {
- Debug.logWarning("Field value not found with name " + fieldAcsr + " in Map with name " + mapAcsr, module);
- return true;
- }
- resultAcsr.put(methodContext.getResults(), fieldVal, methodContext);
+ Object fieldVal = this.fieldFma.get(methodContext.getEnvMap());
+ if (fieldVal != null) {
+ this.resultFma.put(methodContext.getResults(), fieldVal);
}
return true;
}
@Override
public String expandedString(MethodContext methodContext) {
- // TODO: something more than a stub/dummy
- return this.rawString();
+ return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
}
@Override
public String rawString() {
- // TODO: add all attributes and other info
- return "<field-to-result field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("<now ");
+ if (!this.fieldFma.isEmpty()) {
+ sb.append("field=\"").append(this.fieldFma).append("\" ");
+ }
+ if (!this.resultFma.isEmpty()) {
+ sb.append("result-name=\"").append(this.resultFma).append("\" ");
+ }
+ sb.append("/>");
+ return sb.toString();
}
public static final class FieldToResultFactory implements Factory<FieldToResult> {
Re: svn commit: r1331137 - in /ofbiz/trunk/framework/minilang: dtd/simple-methods-v2.xsd
src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java src/org/ofbiz/minilang/method/envops/Now.java
src/org/ofbiz/minilang/method/serviceops/FieldToResult.java
Posted by Adrian Crum <ad...@sandglass-software.com>.
Fixed rev 1331247.
-Adrian
On 4/27/2012 7:43 AM, Jacques Le Roux wrote:
> Hi Adrian,
>
> This is blocking trunk demo, please fix or revert
>
> Thanks
>
> Jacques
>
> From: <ad...@apache.org>
>> Author: adrianc
>> Date: Thu Apr 26 22:40:22 2012
>> New Revision: 1331137
>>
>> URL: http://svn.apache.org/viewvc?rev=1331137&view=rev
>> Log:
>> Added new attribute "memory-model" to the Mini-language
>> <call-simple-method> element. Code cleanup and validation in
>> FieldToResult.java. Improved validation in Now.java.
>>
>> Modified:
>> ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd
>>
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java
>>
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java
>>
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.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=1331137&r1=1331136&r2=1331137&view=diff
>> ==============================================================================
>>
>> --- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original)
>> +++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Thu Apr
>> 26 22:40:22 2012
>> @@ -918,33 +918,64 @@ under the License.
>> <xs:element name="call-simple-method"
>> substitutionGroup="CallOperations">
>> <xs:annotation>
>> <xs:documentation>
>> - The call-simple-method tag calls another
>> simple-method in the same context as the current one.
>> - In other words the called simple-method will have
>> the same environment as the calling simple-method,
>> - including all environment fields, and either the
>> event or service objects that the calling simple-method was called with.
>> + Calls another simple-method in the same context as
>> the current one.
>> + The called simple-method will have the same
>> environment as the calling simple-method,
>> + including all environment fields, and either the
>> event or service objects
>> + that the calling simple-method was called
>> + with.
>> </xs:documentation>
>> </xs:annotation>
>> <xs:complexType>
>> - <xs:attributeGroup ref="attlist.call-simple-method"/>
>> + <xs:sequence>
>> + <xs:element ref="result-to-field" minOccurs="0" maxOccurs="unbounded">
>> + <xs:annotation>
>> + <xs:documentation>
>> + Used when
>> memory-model="function". Copies the called method fields
>> + to the calling method fields.
>> + </xs:documentation>
>> + </xs:annotation>
>> + </xs:element>
>> + </xs:sequence>
>> + <xs:attribute type="xs:string" name="method-name" use="required">
>> + <xs:annotation>
>> + <xs:documentation>
>> + The name of the simple-method to execute in
>> the specified xml-resource,
>> + or in the current XML file if no
>> xml-resource is specified.
>> + <br/><br/>
>> + Required. Attribute type: constant.
>> + </xs:documentation>
>> + </xs:annotation>
>> + </xs:attribute>
>> + <xs:attribute type="xs:string" name="xml-resource">
>> + <xs:annotation>
>> + <xs:documentation>
>> + The full path and filename on the classpath
>> of the XML file which contains an external simple-method to execute.
>> + This is only required if a simple-method in
>> a different file is desired.
>> + <br/><br/>
>> + Optional. Attribute type: constant.
>> + </xs:documentation>
>> + </xs:annotation>
>> + </xs:attribute>
>> + <xs:attribute name="memory-model">
>> + <xs:annotation>
>> + <xs:documentation>
>> + The memory model to use. In an
>> "inline" memory model, fields declared or modified in the
>> called method
>> + will be reflected back to the calling method
>> - as if the called method was inline. In a "function" memory
>> + model, fields declared or modified in the
>> called method are local to the called method - they are not
>> + reflected back to the calling method.
>> + <br/><br/>
>> + Optional. Attribute type: constant.
>> + </xs:documentation>
>> + </xs:annotation>
>> + <xs:simpleType>
>> + <xs:restriction base="xs:token">
>> + <xs:enumeration value="inline" />
>> + <xs:enumeration value="function" />
>> + </xs:restriction>
>> + </xs:simpleType>
>> + </xs:attribute>
>> </xs:complexType>
>> </xs:element>
>> - <xs:attributeGroup name="attlist.call-simple-method">
>> - <xs:attribute type="xs:string" name="xml-resource">
>> - <xs:annotation>
>> - <xs:documentation>
>> - The full path and filename on the classpath of
>> the XML file which contains an external simple-method to execute.
>> - This is only required if a simple-method in a
>> different file is desired.
>> - </xs:documentation>
>> - </xs:annotation>
>> - </xs:attribute>
>> - <xs:attribute type="xs:string" name="method-name" use="required">
>> - <xs:annotation>
>> - <xs:documentation>
>> - The name of the simple-method to execute in the
>> specified xml-resource,
>> - or in the current XML file if no xml-resource is
>> specified.
>> - </xs:documentation>
>> - </xs:annotation>
>> - </xs:attribute>
>> - </xs:attributeGroup>
>> <!-- Operations to call Java methods and create Java objects -->
>> <xs:element name="call-object-method"
>> substitutionGroup="CallOperations">
>> <xs:annotation>
>> @@ -1265,26 +1296,43 @@ under the License.
>> <xs:annotation><xs:documentation>The name of the session attribute to
>> use. Defaults to the value of field
>> attribute</xs:documentation></xs:annotation>
>> </xs:attribute>
>> </xs:attributeGroup>
>> - <!-- Service specific operations -->
>> - <xs:element name="field-to-result"
>> substitutionGroup="ServiceOperations">
>> + <xs:element name="field-to-result" substitutionGroup="EnvOperations">
>> <xs:annotation>
>> <xs:documentation>
>> - The field-to-result tag copies a field from a map to
>> the specified service result field.
>> - The tag is only used when the simple-method is
>> called as a service, it is ignored otherwise.
>> + Copies a field to a service OUT attribute.
>> </xs:documentation>
>> </xs:annotation>
>> <xs:complexType>
>> - <xs:attributeGroup ref="attlist.field-to-result"/>
>> + <xs:attribute name="field" use="required">
>> + <xs:annotation>
>> + <xs:documentation>
>> + The name of the field to copy from. The
>> source of the assignment.
>> + <br/><br/>
>> + Required. Attribute type: expression.
>> + </xs:documentation>
>> + </xs:annotation>
>> + <xs:simpleType>
>> + <xs:restriction base="xs:string">
>> + <xs:minLength value="1" />
>> + </xs:restriction>
>> + </xs:simpleType>
>> + </xs:attribute>
>> + <xs:attribute name="result-name">
>> + <xs:annotation>
>> + <xs:documentation>
>> + The name of the result field to set. The
>> target of the assignment.
>> + <br/><br/>
>> + Optional. Attribute type: expression.
>> + </xs:documentation>
>> + </xs:annotation>
>> + <xs:simpleType>
>> + <xs:restriction base="xs:string">
>> + <xs:minLength value="1" />
>> + </xs:restriction>
>> + </xs:simpleType>
>> + </xs:attribute>
>> </xs:complexType>
>> </xs:element>
>> - <xs:attributeGroup name="attlist.field-to-result">
>> - <xs:attribute type="xs:string" name="field" use="required">
>> - <xs:annotation><xs:documentation>The name (key) of the map field to
>> use.</xs:documentation></xs:annotation>
>> - </xs:attribute>
>> - <xs:attribute type="xs:string" name="result-name">
>> - <xs:annotation><xs:documentation>The name of the result Map
>> name/key to use. Defaults to the value of field
>> attribute.</xs:documentation></xs:annotation>
>> - </xs:attribute>
>> - </xs:attributeGroup>
>> <!-- Environment specific operations -->
>> <xs:element name="map-to-map" substitutionGroup="EnvOperations">
>> <xs:annotation>
>> @@ -4436,6 +4484,8 @@ under the License.
>> <xs:annotation>
>> <xs:documentation>
>> The field data type. Defaults to
>> java.sql.Timestamp.
>> + <br/><br/>
>> + Optional. Attribute type: constant.
>> </xs:documentation>
>> </xs:annotation>
>> <xs:simpleType>
>>
>> Modified:
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java?rev=1331137&r1=1331136&r2=1331137&view=diff
>> ==============================================================================
>>
>> ---
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java
>> (original)
>> +++
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java
>> Thu Apr 26 22:40:22 2012
>> @@ -18,117 +18,151 @@
>> *******************************************************************************/
>>
>> package org.ofbiz.minilang.method.callops;
>>
>> +import java.util.ArrayList;
>> +import java.util.List;
>> import java.util.Map;
>>
>> +import javolution.util.FastMap;
>> +
>> import org.ofbiz.base.util.Debug;
>> import org.ofbiz.base.util.UtilValidate;
>> +import org.ofbiz.base.util.UtilXml;
>> +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.ValidationException;
>> import org.ofbiz.minilang.method.MethodContext;
>> import org.ofbiz.minilang.method.MethodOperation;
>> import org.w3c.dom.Element;
>>
>> /**
>> - * An operation that calls a simple method in the same, or from
>> another, file
>> + * Invokes a Mini-language simple method.
>> */
>> -public class CallSimpleMethod extends MethodOperation {
>> +public final class CallSimpleMethod extends MethodOperation {
>>
>> public static final String module =
>> CallSimpleMethod.class.getName();
>>
>> - String methodName;
>> - String xmlResource;
>> + private final String methodName;
>> + private final String xmlResource;
>> + private final String memoryModel;
>> + private final List<ResultToField> resultToFieldList;
>>
>> public CallSimpleMethod(Element element, SimpleMethod
>> simpleMethod) throws MiniLangException {
>> super(element, simpleMethod);
>> + if (MiniLangValidate.validationOn()) {
>> + MiniLangValidate.attributeNames(simpleMethod, element,
>> "method-name", "xml-resource", "memory-model");
>> + MiniLangValidate.requiredAttributes(simpleMethod,
>> element, "method-name");
>> + MiniLangValidate.constantAttributes(simpleMethod,
>> element, "method-name", "xml-resource", "memory-model");
>> + MiniLangValidate.childElements(simpleMethod, element,
>> "result-to-field");
>> + }
>> this.methodName = element.getAttribute("method-name");
>> this.xmlResource = element.getAttribute("xml-resource");
>> + this.memoryModel = element.getAttribute("memory-model");
>> + List<? extends Element> resultToFieldElements =
>> UtilXml.childElementList(element, "result-to-field");
>> + if (UtilValidate.isNotEmpty(resultToFieldElements)) {
>> + if (!"function".equals(this.memoryModel)) {
>> + MiniLangValidate.handleError("Inline memory model
>> cannot include <result-to-field> elements.", simpleMethod, element);
>> + }
>> + List<ResultToField> resultToFieldList = new
>> ArrayList<ResultToField>(resultToFieldElements.size());
>> + for (Element resultToFieldElement :
>> resultToFieldElements) {
>> + resultToFieldList.add(new
>> ResultToField(resultToFieldElement, simpleMethod));
>> + }
>> + this.resultToFieldList = resultToFieldList;
>> + } else {
>> + this.resultToFieldList = null;
>> + }
>> }
>>
>> @Override
>> public boolean exec(MethodContext methodContext) throws
>> MiniLangException {
>> - if (UtilValidate.isNotEmpty(this.methodName)) {
>> - String methodName =
>> methodContext.expandString(this.methodName);
>> - String xmlResource =
>> methodContext.expandString(this.xmlResource);
>> - SimpleMethod simpleMethodToCall = null;
>> - try {
>> - simpleMethodToCall =
>> getSimpleMethodToCall(methodContext.getLoader());
>> - } catch (MiniLangException e) {
>> - String errMsg = "ERROR: Could not complete the " +
>> simpleMethod.getShortDescription() + " process [error getting methods
>> from resource: " + e.getMessage() + "]";
>> - Debug.logError(e, errMsg, module);
>> - methodContext.setErrorReturn(errMsg, simpleMethod);
>> - return false;
>> + if (UtilValidate.isEmpty(this.methodName)) {
>> + throw new MiniLangRuntimeException("method-name
>> attribute is empty", this);
>> + }
>> + SimpleMethod simpleMethodToCall = null;
>> + if (UtilValidate.isEmpty(this.xmlResource)) {
>> + simpleMethodToCall =
>> this.simpleMethod.getSimpleMethodInSameFile(methodName);
>> + } else {
>> + Map<String, SimpleMethod> simpleMethods =
>> SimpleMethod.getSimpleMethods(this.xmlResource,
>> methodContext.getLoader());
>> + simpleMethodToCall = simpleMethods.get(this.methodName);
>> + }
>> + if (simpleMethodToCall == null) {
>> + throw new MiniLangRuntimeException("Could not find
>> <simple-method name=\"" + this.methodName + "\"> in XML document " +
>> this.xmlResource, this);
>> + }
>> + MethodContext localContext = methodContext;
>> + if ("function".equals(this.memoryModel)) {
>> + Map<String, Object> localEnv = FastMap.newInstance();
>> + localEnv.putAll(methodContext.getEnvMap());
>> +
>> localEnv.remove(this.simpleMethod.getEventResponseCodeName());
>> +
>> localEnv.remove(this.simpleMethod.getServiceResponseMessageName());
>> + localContext = new MethodContext(localEnv,
>> methodContext.getLoader(), methodContext.getMethodType());
>> + }
>> + String returnVal = simpleMethodToCall.exec(localContext);
>> + if (Debug.verboseOn())
>> + Debug.logVerbose("Called simple-method named [" +
>> this.methodName + "] in resource [" + this.xmlResource + "],
>> returnVal is [" + returnVal + "]", module);
>> + if
>> (simpleMethodToCall.getDefaultErrorCode().equals(returnVal)) {
>> + if (methodContext.getMethodType() == MethodContext.EVENT) {
>> +
>> methodContext.putEnv(simpleMethod.getEventResponseCodeName(),
>> simpleMethod.getDefaultErrorCode());
>> + } else if (methodContext.getMethodType() ==
>> MethodContext.SERVICE) {
>> +
>> methodContext.putEnv(simpleMethod.getServiceResponseMessageName(),
>> simpleMethod.getDefaultErrorCode());
>> }
>> - if (simpleMethodToCall == null) {
>> - String errMsg = "ERROR: Could not complete the " +
>> simpleMethod.getShortDescription() + " process, could not find
>> SimpleMethod " + methodName + " in XML document in resource: " +
>> xmlResource;
>> - methodContext.setErrorReturn(errMsg, simpleMethod);
>> + return false;
>> + }
>> + if (methodContext.getMethodType() == MethodContext.EVENT) {
>> + // FIXME: This doesn't make sense. We are comparing the
>> called method's response code with this method's
>> + // response code. Since response codes are configurable
>> per method, this code will fail.
>> + String responseCode = (String)
>> localContext.getEnv(this.simpleMethod.getEventResponseCodeName());
>> + if
>> (this.simpleMethod.getDefaultErrorCode().equals(responseCode)) {
>> + Debug.logWarning("Got error [" + responseCode + "]
>> calling inline simple-method named [" + this.methodName + "] in
>> resource [" + this.xmlResource + "], message is " +
>> methodContext.getEnv(this.simpleMethod.getEventErrorMessageName()),
>> module);
>> return false;
>> }
>> - String returnVal = simpleMethodToCall.exec(methodContext);
>> - if (Debug.verboseOn())
>> - Debug.logVerbose("Called inline simple-method named
>> [" + methodName + "] in resource [" + xmlResource + "], returnVal is
>> [" + returnVal + "]", module);
>> - if (returnVal != null &&
>> returnVal.equals(simpleMethodToCall.getDefaultErrorCode())) {
>> - // in this case just set the error code just in case
>> it hasn't already
>> - // been set, the error messages will already be in
>> place...
>> - if (methodContext.getMethodType() ==
>> MethodContext.EVENT) {
>> -
>> methodContext.putEnv(simpleMethod.getEventResponseCodeName(),
>> simpleMethod.getDefaultErrorCode());
>> - } else if (methodContext.getMethodType() ==
>> MethodContext.SERVICE) {
>> -
>> methodContext.putEnv(simpleMethod.getServiceResponseMessageName(),
>> simpleMethod.getDefaultErrorCode());
>> - }
>> + } else if (methodContext.getMethodType() ==
>> MethodContext.SERVICE) {
>> + // FIXME: This doesn't make sense. We are comparing the
>> called method's response message with this method's
>> + // response message. Since response messages are
>> configurable per method, this code will fail.
>> + String responseMessage = (String)
>> localContext.getEnv(this.simpleMethod.getServiceResponseMessageName());
>> + if
>> (this.simpleMethod.getDefaultErrorCode().equals(responseMessage)) {
>> + Debug.logWarning("Got error [" + responseMessage +
>> "] calling inline simple-method named [" + this.methodName + "] in
>> resource [" + this.xmlResource + "], message is " +
>> methodContext.getEnv(this.simpleMethod.getServiceErrorMessageName())
>> + ", and the error message list is: "
>> + +
>> methodContext.getEnv(this.simpleMethod.getServiceErrorMessageListName()),
>> module);
>> return false;
>> }
>> - // if the response code/message is error, if so show the
>> error and return
>> - // false
>> - if (methodContext.getMethodType() == MethodContext.EVENT) {
>> - String responseCode = (String)
>> methodContext.getEnv(simpleMethod.getEventResponseCodeName());
>> - if (responseCode != null &&
>> responseCode.equals(simpleMethod.getDefaultErrorCode())) {
>> - Debug.logWarning("Got error [" + responseCode +
>> "] calling inline simple-method named [" + methodName + "] in
>> resource [" + xmlResource + "], message is " +
>> methodContext.getEnv(simpleMethod.getEventErrorMessageName()), module);
>> - return false;
>> - }
>> - } else if (methodContext.getMethodType() ==
>> MethodContext.SERVICE) {
>> - String resonseMessage = (String)
>> methodContext.getEnv(simpleMethod.getServiceResponseMessageName());
>> - if (resonseMessage != null &&
>> resonseMessage.equals(simpleMethod.getDefaultErrorCode())) {
>> - Debug.logWarning("Got error [" + resonseMessage
>> + "] calling inline simple-method named [" + methodName + "] in
>> resource [" + xmlResource + "], message is " +
>> methodContext.getEnv(simpleMethod.getServiceErrorMessageName()) + ",
>> and the error message list is: "
>> - +
>> methodContext.getEnv(simpleMethod.getServiceErrorMessageListName()),
>> module);
>> - return false;
>> + }
>> + if ("function".equals(this.memoryModel) &&
>> this.resultToFieldList != null) {
>> + Map<String, Object> results = localContext.getResults();
>> + if (results != null) {
>> + for (ResultToField resultToField :
>> this.resultToFieldList) {
>> + resultToField.exec(methodContext.getEnvMap(),
>> results);
>> }
>> }
>> - } else {
>> - String errMsg = "ERROR in call-simple-method: methodName
>> was missing; not running simpleMethod";
>> - Debug.logError(errMsg, module);
>> - methodContext.setErrorReturn(errMsg, simpleMethod);
>> - return false;
>> }
>> return true;
>> }
>>
>> @Override
>> public String expandedString(MethodContext methodContext) {
>> - // TODO: something more than a stub/dummy
>> - return this.rawString();
>> + return FlexibleStringExpander.expandString(toString(),
>> methodContext.getEnvMap());
>> }
>>
>> - public String getMethodName() {
>> - return this.methodName;
>> - }
>> -
>> - public SimpleMethod getSimpleMethodToCall(ClassLoader loader)
>> throws MiniLangException {
>> - SimpleMethod simpleMethodToCall = null;
>> - if (UtilValidate.isEmpty(xmlResource)) {
>> - simpleMethodToCall =
>> this.simpleMethod.getSimpleMethodInSameFile(methodName);
>> - } else {
>> - Map<String, SimpleMethod> simpleMethods =
>> SimpleMethod.getSimpleMethods(xmlResource, loader);
>> - simpleMethodToCall = simpleMethods.get(methodName);
>> - }
>> - return simpleMethodToCall;
>> - }
>> -
>> - public String getXmlResource() {
>> - return this.xmlResource;
>> + @Override
>> + public String rawString() {
>> + return toString();
>> }
>>
>> @Override
>> - public String rawString() {
>> - return "<call-simple-method xml-resource=\"" +
>> this.xmlResource + "\" method-name=\"" + this.methodName + "\" />";
>> + public String toString() {
>> + StringBuilder sb = new StringBuilder("<call-simple-method ");
>> + if (this.methodName.length() > 0) {
>> +
>> sb.append("method-name=\"").append(this.methodName).append("\" ");
>> + }
>> + if (this.xmlResource.length() > 0) {
>> +
>> sb.append("xml-resource=\"").append(this.xmlResource).append("\" ");
>> + }
>> + if (this.memoryModel.length() > 0) {
>> +
>> sb.append("memory-model=\"").append(this.memoryModel).append("\" ");
>> + }
>> + sb.append("/>");
>> + return sb.toString();
>> }
>>
>> public static final class CallSimpleMethodFactory implements
>> Factory<CallSimpleMethod> {
>> @@ -140,4 +174,33 @@ public class CallSimpleMethod extends Me
>> return "call-simple-method";
>> }
>> }
>> +
>> + private final class ResultToField {
>> +
>> + private final FlexibleMapAccessor<Object> fieldFma;
>> + private final FlexibleMapAccessor<Object> resultNameFma;
>> +
>> + private ResultToField(Element element, SimpleMethod
>> simpleMethod) throws ValidationException {
>> + if (MiniLangValidate.validationOn()) {
>> + MiniLangValidate.attributeNames(simpleMethod,
>> element, "result-name", "field");
>> + MiniLangValidate.requiredAttributes(simpleMethod,
>> element, "result-name");
>> + MiniLangValidate.expressionAttributes(simpleMethod,
>> element, "result-name", "field");
>> + MiniLangValidate.noChildElements(simpleMethod,
>> element);
>> + }
>> + this.resultNameFma =
>> FlexibleMapAccessor.getInstance(element.getAttribute("result-name"));
>> + String fieldAttribute = element.getAttribute("field");
>> + if (fieldAttribute.length() == 0) {
>> + this.fieldFma = this.resultNameFma;
>> + } else {
>> + this.fieldFma =
>> FlexibleMapAccessor.getInstance(fieldAttribute);
>> + }
>> + }
>> +
>> + private void exec(Map<String, Object> context, Map<String,
>> Object> results) throws MiniLangException {
>> + Object value = this.resultNameFma.get(results);
>> + if (value != null) {
>> + this.fieldFma.put(context, value);
>> + }
>> + }
>> + }
>> }
>>
>> Modified:
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java?rev=1331137&r1=1331136&r2=1331137&view=diff
>> ==============================================================================
>>
>> ---
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java
>> (original)
>> +++
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java
>> Thu Apr 26 22:40:22 2012
>> @@ -47,6 +47,8 @@ public final class Now extends MethodOpe
>> if (MiniLangValidate.validationOn()) {
>> MiniLangValidate.attributeNames(simpleMethod, element,
>> "field", "type");
>> MiniLangValidate.requiredAttributes(simpleMethod,
>> element, "field");
>> + MiniLangValidate.expressionAttributes(simpleMethod,
>> element, "field");
>> + MiniLangValidate.constantAttributes(simpleMethod,
>> element, "type");
>> MiniLangValidate.noChildElements(simpleMethod, element);
>> }
>> this.fieldFma =
>> FlexibleMapAccessor.getInstance(element.getAttribute("field"));
>>
>> Modified:
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java?rev=1331137&r1=1331136&r2=1331137&view=diff
>> ==============================================================================
>>
>> ---
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java
>> (original)
>> +++
>> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java
>> Thu Apr 26 22:40:22 2012
>> @@ -18,70 +18,72 @@
>> *******************************************************************************/
>>
>> package org.ofbiz.minilang.method.serviceops;
>>
>> -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.MiniLangValidate;
>> import org.ofbiz.minilang.SimpleMethod;
>> -import org.ofbiz.minilang.method.ContextAccessor;
>> import org.ofbiz.minilang.method.MethodContext;
>> import org.ofbiz.minilang.method.MethodOperation;
>> import org.w3c.dom.Element;
>>
>> /**
>> - * Copies a map field to a Service result entry
>> + * Copies a field to a service OUT attribute.
>> */
>> -public class FieldToResult extends MethodOperation {
>> +public final class FieldToResult extends MethodOperation {
>>
>> public static final String module = FieldToResult.class.getName();
>>
>> - ContextAccessor<Object> fieldAcsr;
>> - ContextAccessor<Map<String, ? extends Object>> mapAcsr;
>> - ContextAccessor<Object> resultAcsr;
>> + private final FlexibleMapAccessor<Object> fieldFma;
>> + private final FlexibleMapAccessor<Object> resultFma;
>>
>> public FieldToResult(Element element, SimpleMethod simpleMethod)
>> throws MiniLangException {
>> super(element, simpleMethod);
>> - // the schema for this element now just has the "field"
>> attribute, though the old "field-name" and "map-name" pair is still
>> supported
>> - mapAcsr = new ContextAccessor<Map<String, ? extends
>> Object>>(element.getAttribute("map-name"));
>> - fieldAcsr = new
>> ContextAccessor<Object>(element.getAttribute("field"),
>> element.getAttribute("field-name"));
>> - resultAcsr = new
>> ContextAccessor<Object>(element.getAttribute("result-name"),
>> fieldAcsr.toString());
>> + if (MiniLangValidate.validationOn()) {
>> + MiniLangValidate.attributeNames(simpleMethod, element,
>> "field", "result-name");
>> + MiniLangValidate.requiredAttributes(simpleMethod,
>> element, "field");
>> + MiniLangValidate.expressionAttributes(simpleMethod,
>> element, "field", "result-name");
>> + MiniLangValidate.noChildElements(simpleMethod, element);
>> + }
>> + this.fieldFma =
>> FlexibleMapAccessor.getInstance(element.getAttribute("field"));
>> + String resultNameAttribute =
>> element.getAttribute("result-name");
>> + if (resultNameAttribute.length() == 0) {
>> + this.resultFma = this.fieldFma;
>> + } else {
>> + this.resultFma =
>> FlexibleMapAccessor.getInstance(resultNameAttribute);
>> + }
>> }
>>
>> @Override
>> public boolean exec(MethodContext methodContext) throws
>> MiniLangException {
>> - // only run this if it is in an SERVICE context
>> - if (methodContext.getMethodType() == MethodContext.SERVICE) {
>> - Object fieldVal = null;
>> - if (!mapAcsr.isEmpty()) {
>> - Map<String, ? extends Object> fromMap =
>> mapAcsr.get(methodContext);
>> - if (fromMap == null) {
>> - Debug.logWarning("Map not found with name " +
>> mapAcsr, module);
>> - return true;
>> - }
>> - fieldVal = fieldAcsr.get(fromMap, methodContext);
>> - } else {
>> - // no map name, try the env
>> - fieldVal = fieldAcsr.get(methodContext);
>> - }
>> - if (fieldVal == null) {
>> - Debug.logWarning("Field value not found with name "
>> + fieldAcsr + " in Map with name " + mapAcsr, module);
>> - return true;
>> - }
>> - resultAcsr.put(methodContext.getResults(), fieldVal,
>> methodContext);
>> + Object fieldVal = this.fieldFma.get(methodContext.getEnvMap());
>> + if (fieldVal != null) {
>> + this.resultFma.put(methodContext.getResults(), fieldVal);
>> }
>> return true;
>> }
>>
>> @Override
>> public String expandedString(MethodContext methodContext) {
>> - // TODO: something more than a stub/dummy
>> - return this.rawString();
>> + return FlexibleStringExpander.expandString(toString(),
>> methodContext.getEnvMap());
>> }
>>
>> @Override
>> public String rawString() {
>> - // TODO: add all attributes and other info
>> - return "<field-to-result field-name=\"" + this.fieldAcsr +
>> "\" map-name=\"" + this.mapAcsr + "\"/>";
>> + return toString();
>> + }
>> +
>> + @Override
>> + public String toString() {
>> + StringBuilder sb = new StringBuilder("<now ");
>> + if (!this.fieldFma.isEmpty()) {
>> + sb.append("field=\"").append(this.fieldFma).append("\" ");
>> + }
>> + if (!this.resultFma.isEmpty()) {
>> +
>> sb.append("result-name=\"").append(this.resultFma).append("\" ");
>> + }
>> + sb.append("/>");
>> + return sb.toString();
>> }
>>
>> public static final class FieldToResultFactory implements
>> Factory<FieldToResult> {
>>
>>
Re: svn commit: r1331137 - in /ofbiz/trunk/framework/minilang: dtd/simple-methods-v2.xsd src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java src/org/ofbiz/minilang/method/envops/Now.java src/org/ofbiz/minilang/method/serviceops/FieldToResult.java
Posted by Jacques Le Roux <ja...@les7arts.com>.
Hi Adrian,
This is blocking trunk demo, please fix or revert
Thanks
Jacques
From: <ad...@apache.org>
> Author: adrianc
> Date: Thu Apr 26 22:40:22 2012
> New Revision: 1331137
>
> URL: http://svn.apache.org/viewvc?rev=1331137&view=rev
> Log:
> Added new attribute "memory-model" to the Mini-language <call-simple-method> element. Code cleanup and validation in
> FieldToResult.java. Improved validation in Now.java.
>
> Modified:
> ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd
> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java
> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java
> ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.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=1331137&r1=1331136&r2=1331137&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original)
> +++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Thu Apr 26 22:40:22 2012
> @@ -918,33 +918,64 @@ under the License.
> <xs:element name="call-simple-method" substitutionGroup="CallOperations">
> <xs:annotation>
> <xs:documentation>
> - The call-simple-method tag calls another simple-method in the same context as the current one.
> - In other words the called simple-method will have the same environment as the calling simple-method,
> - including all environment fields, and either the event or service objects that the calling simple-method was
> called with.
> + Calls another simple-method in the same context as the current one.
> + The called simple-method will have the same environment as the calling simple-method,
> + including all environment fields, and either the event or service objects
> + that the calling simple-method was called
> + with.
> </xs:documentation>
> </xs:annotation>
> <xs:complexType>
> - <xs:attributeGroup ref="attlist.call-simple-method"/>
> + <xs:sequence>
> + <xs:element ref="result-to-field" minOccurs="0" maxOccurs="unbounded">
> + <xs:annotation>
> + <xs:documentation>
> + Used when memory-model="function". Copies the called method fields
> + to the calling method fields.
> + </xs:documentation>
> + </xs:annotation>
> + </xs:element>
> + </xs:sequence>
> + <xs:attribute type="xs:string" name="method-name" use="required">
> + <xs:annotation>
> + <xs:documentation>
> + The name of the simple-method to execute in the specified xml-resource,
> + or in the current XML file if no xml-resource is specified.
> + <br/><br/>
> + Required. Attribute type: constant.
> + </xs:documentation>
> + </xs:annotation>
> + </xs:attribute>
> + <xs:attribute type="xs:string" name="xml-resource">
> + <xs:annotation>
> + <xs:documentation>
> + The full path and filename on the classpath of the XML file which contains an external simple-method to
> execute.
> + This is only required if a simple-method in a different file is desired.
> + <br/><br/>
> + Optional. Attribute type: constant.
> + </xs:documentation>
> + </xs:annotation>
> + </xs:attribute>
> + <xs:attribute name="memory-model">
> + <xs:annotation>
> + <xs:documentation>
> + The memory model to use. In an "inline" memory model, fields declared or modified in the called
> method
> + will be reflected back to the calling method - as if the called method was inline. In a
> "function" memory
> + model, fields declared or modified in the called method are local to the called method - they are not
> + reflected back to the calling method.
> + <br/><br/>
> + Optional. Attribute type: constant.
> + </xs:documentation>
> + </xs:annotation>
> + <xs:simpleType>
> + <xs:restriction base="xs:token">
> + <xs:enumeration value="inline" />
> + <xs:enumeration value="function" />
> + </xs:restriction>
> + </xs:simpleType>
> + </xs:attribute>
> </xs:complexType>
> </xs:element>
> - <xs:attributeGroup name="attlist.call-simple-method">
> - <xs:attribute type="xs:string" name="xml-resource">
> - <xs:annotation>
> - <xs:documentation>
> - The full path and filename on the classpath of the XML file which contains an external simple-method to
> execute.
> - This is only required if a simple-method in a different file is desired.
> - </xs:documentation>
> - </xs:annotation>
> - </xs:attribute>
> - <xs:attribute type="xs:string" name="method-name" use="required">
> - <xs:annotation>
> - <xs:documentation>
> - The name of the simple-method to execute in the specified xml-resource,
> - or in the current XML file if no xml-resource is specified.
> - </xs:documentation>
> - </xs:annotation>
> - </xs:attribute>
> - </xs:attributeGroup>
> <!-- Operations to call Java methods and create Java objects -->
> <xs:element name="call-object-method" substitutionGroup="CallOperations">
> <xs:annotation>
> @@ -1265,26 +1296,43 @@ under the License.
> <xs:annotation><xs:documentation>The name of the session attribute to use. Defaults to the value of field
> attribute</xs:documentation></xs:annotation>
> </xs:attribute>
> </xs:attributeGroup>
> - <!-- Service specific operations -->
> - <xs:element name="field-to-result" substitutionGroup="ServiceOperations">
> + <xs:element name="field-to-result" substitutionGroup="EnvOperations">
> <xs:annotation>
> <xs:documentation>
> - The field-to-result tag copies a field from a map to the specified service result field.
> - The tag is only used when the simple-method is called as a service, it is ignored otherwise.
> + Copies a field to a service OUT attribute.
> </xs:documentation>
> </xs:annotation>
> <xs:complexType>
> - <xs:attributeGroup ref="attlist.field-to-result"/>
> + <xs:attribute name="field" use="required">
> + <xs:annotation>
> + <xs:documentation>
> + The name of the field to copy from. The source of the assignment.
> + <br/><br/>
> + Required. Attribute type: expression.
> + </xs:documentation>
> + </xs:annotation>
> + <xs:simpleType>
> + <xs:restriction base="xs:string">
> + <xs:minLength value="1" />
> + </xs:restriction>
> + </xs:simpleType>
> + </xs:attribute>
> + <xs:attribute name="result-name">
> + <xs:annotation>
> + <xs:documentation>
> + The name of the result field to set. The target of the assignment.
> + <br/><br/>
> + Optional. Attribute type: expression.
> + </xs:documentation>
> + </xs:annotation>
> + <xs:simpleType>
> + <xs:restriction base="xs:string">
> + <xs:minLength value="1" />
> + </xs:restriction>
> + </xs:simpleType>
> + </xs:attribute>
> </xs:complexType>
> </xs:element>
> - <xs:attributeGroup name="attlist.field-to-result">
> - <xs:attribute type="xs:string" name="field" use="required">
> - <xs:annotation><xs:documentation>The name (key) of the map field to use.</xs:documentation></xs:annotation>
> - </xs:attribute>
> - <xs:attribute type="xs:string" name="result-name">
> - <xs:annotation><xs:documentation>The name of the result Map name/key to use. Defaults to the value of field
> attribute.</xs:documentation></xs:annotation>
> - </xs:attribute>
> - </xs:attributeGroup>
> <!-- Environment specific operations -->
> <xs:element name="map-to-map" substitutionGroup="EnvOperations">
> <xs:annotation>
> @@ -4436,6 +4484,8 @@ under the License.
> <xs:annotation>
> <xs:documentation>
> The field data type. Defaults to java.sql.Timestamp.
> + <br/><br/>
> + Optional. Attribute type: constant.
> </xs:documentation>
> </xs:annotation>
> <xs:simpleType>
>
> Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java?rev=1331137&r1=1331136&r2=1331137&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java (original)
> +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java Thu Apr 26 22:40:22 2012
> @@ -18,117 +18,151 @@
> *******************************************************************************/
> package org.ofbiz.minilang.method.callops;
>
> +import java.util.ArrayList;
> +import java.util.List;
> import java.util.Map;
>
> +import javolution.util.FastMap;
> +
> import org.ofbiz.base.util.Debug;
> import org.ofbiz.base.util.UtilValidate;
> +import org.ofbiz.base.util.UtilXml;
> +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.ValidationException;
> import org.ofbiz.minilang.method.MethodContext;
> import org.ofbiz.minilang.method.MethodOperation;
> import org.w3c.dom.Element;
>
> /**
> - * An operation that calls a simple method in the same, or from another, file
> + * Invokes a Mini-language simple method.
> */
> -public class CallSimpleMethod extends MethodOperation {
> +public final class CallSimpleMethod extends MethodOperation {
>
> public static final String module = CallSimpleMethod.class.getName();
>
> - String methodName;
> - String xmlResource;
> + private final String methodName;
> + private final String xmlResource;
> + private final String memoryModel;
> + private final List<ResultToField> resultToFieldList;
>
> public CallSimpleMethod(Element element, SimpleMethod simpleMethod) throws MiniLangException {
> super(element, simpleMethod);
> + if (MiniLangValidate.validationOn()) {
> + MiniLangValidate.attributeNames(simpleMethod, element, "method-name", "xml-resource", "memory-model");
> + MiniLangValidate.requiredAttributes(simpleMethod, element, "method-name");
> + MiniLangValidate.constantAttributes(simpleMethod, element, "method-name", "xml-resource", "memory-model");
> + MiniLangValidate.childElements(simpleMethod, element, "result-to-field");
> + }
> this.methodName = element.getAttribute("method-name");
> this.xmlResource = element.getAttribute("xml-resource");
> + this.memoryModel = element.getAttribute("memory-model");
> + List<? extends Element> resultToFieldElements = UtilXml.childElementList(element, "result-to-field");
> + if (UtilValidate.isNotEmpty(resultToFieldElements)) {
> + if (!"function".equals(this.memoryModel)) {
> + MiniLangValidate.handleError("Inline memory model cannot include <result-to-field> elements.", simpleMethod,
> element);
> + }
> + List<ResultToField> resultToFieldList = new ArrayList<ResultToField>(resultToFieldElements.size());
> + for (Element resultToFieldElement : resultToFieldElements) {
> + resultToFieldList.add(new ResultToField(resultToFieldElement, simpleMethod));
> + }
> + this.resultToFieldList = resultToFieldList;
> + } else {
> + this.resultToFieldList = null;
> + }
> }
>
> @Override
> public boolean exec(MethodContext methodContext) throws MiniLangException {
> - if (UtilValidate.isNotEmpty(this.methodName)) {
> - String methodName = methodContext.expandString(this.methodName);
> - String xmlResource = methodContext.expandString(this.xmlResource);
> - SimpleMethod simpleMethodToCall = null;
> - try {
> - simpleMethodToCall = getSimpleMethodToCall(methodContext.getLoader());
> - } catch (MiniLangException e) {
> - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [error getting
> methods from resource: " + e.getMessage() + "]";
> - Debug.logError(e, errMsg, module);
> - methodContext.setErrorReturn(errMsg, simpleMethod);
> - return false;
> + if (UtilValidate.isEmpty(this.methodName)) {
> + throw new MiniLangRuntimeException("method-name attribute is empty", this);
> + }
> + SimpleMethod simpleMethodToCall = null;
> + if (UtilValidate.isEmpty(this.xmlResource)) {
> + simpleMethodToCall = this.simpleMethod.getSimpleMethodInSameFile(methodName);
> + } else {
> + Map<String, SimpleMethod> simpleMethods = SimpleMethod.getSimpleMethods(this.xmlResource, methodContext.getLoader());
> + simpleMethodToCall = simpleMethods.get(this.methodName);
> + }
> + if (simpleMethodToCall == null) {
> + throw new MiniLangRuntimeException("Could not find <simple-method name=\"" + this.methodName + "\"> in XML document "
> + this.xmlResource, this);
> + }
> + MethodContext localContext = methodContext;
> + if ("function".equals(this.memoryModel)) {
> + Map<String, Object> localEnv = FastMap.newInstance();
> + localEnv.putAll(methodContext.getEnvMap());
> + localEnv.remove(this.simpleMethod.getEventResponseCodeName());
> + localEnv.remove(this.simpleMethod.getServiceResponseMessageName());
> + localContext = new MethodContext(localEnv, methodContext.getLoader(), methodContext.getMethodType());
> + }
> + String returnVal = simpleMethodToCall.exec(localContext);
> + if (Debug.verboseOn())
> + Debug.logVerbose("Called simple-method named [" + this.methodName + "] in resource [" + this.xmlResource + "],
> returnVal is [" + returnVal + "]", module);
> + if (simpleMethodToCall.getDefaultErrorCode().equals(returnVal)) {
> + if (methodContext.getMethodType() == MethodContext.EVENT) {
> + methodContext.putEnv(simpleMethod.getEventResponseCodeName(), simpleMethod.getDefaultErrorCode());
> + } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
> + methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), simpleMethod.getDefaultErrorCode());
> }
> - if (simpleMethodToCall == null) {
> - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process, could not find
> SimpleMethod " + methodName + " in XML document in resource: " + xmlResource;
> - methodContext.setErrorReturn(errMsg, simpleMethod);
> + return false;
> + }
> + if (methodContext.getMethodType() == MethodContext.EVENT) {
> + // FIXME: This doesn't make sense. We are comparing the called method's response code with this method's
> + // response code. Since response codes are configurable per method, this code will fail.
> + String responseCode = (String) localContext.getEnv(this.simpleMethod.getEventResponseCodeName());
> + if (this.simpleMethod.getDefaultErrorCode().equals(responseCode)) {
> + Debug.logWarning("Got error [" + responseCode + "] calling inline simple-method named [" + this.methodName + "]
> in resource [" + this.xmlResource + "], message is " + methodContext.getEnv(this.simpleMethod.getEventErrorMessageName()),
> module);
> return false;
> }
> - String returnVal = simpleMethodToCall.exec(methodContext);
> - if (Debug.verboseOn())
> - Debug.logVerbose("Called inline simple-method named [" + methodName + "] in resource [" + xmlResource + "],
> returnVal is [" + returnVal + "]", module);
> - if (returnVal != null && returnVal.equals(simpleMethodToCall.getDefaultErrorCode())) {
> - // in this case just set the error code just in case it hasn't already
> - // been set, the error messages will already be in place...
> - if (methodContext.getMethodType() == MethodContext.EVENT) {
> - methodContext.putEnv(simpleMethod.getEventResponseCodeName(), simpleMethod.getDefaultErrorCode());
> - } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
> - methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), simpleMethod.getDefaultErrorCode());
> - }
> + } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
> + // FIXME: This doesn't make sense. We are comparing the called method's response message with this method's
> + // response message. Since response messages are configurable per method, this code will fail.
> + String responseMessage = (String) localContext.getEnv(this.simpleMethod.getServiceResponseMessageName());
> + if (this.simpleMethod.getDefaultErrorCode().equals(responseMessage)) {
> + Debug.logWarning("Got error [" + responseMessage + "] calling inline simple-method named [" + this.methodName +
> "] in resource [" + this.xmlResource + "], message is " + methodContext.getEnv(this.simpleMethod.getServiceErrorMessageName()) +
> ", and the error message list is: "
> + + methodContext.getEnv(this.simpleMethod.getServiceErrorMessageListName()), module);
> return false;
> }
> - // if the response code/message is error, if so show the error and return
> - // false
> - if (methodContext.getMethodType() == MethodContext.EVENT) {
> - String responseCode = (String) methodContext.getEnv(simpleMethod.getEventResponseCodeName());
> - if (responseCode != null && responseCode.equals(simpleMethod.getDefaultErrorCode())) {
> - Debug.logWarning("Got error [" + responseCode + "] calling inline simple-method named [" + methodName + "] in
> resource [" + xmlResource + "], message is " + methodContext.getEnv(simpleMethod.getEventErrorMessageName()), module);
> - return false;
> - }
> - } else if (methodContext.getMethodType() == MethodContext.SERVICE) {
> - String resonseMessage = (String) methodContext.getEnv(simpleMethod.getServiceResponseMessageName());
> - if (resonseMessage != null && resonseMessage.equals(simpleMethod.getDefaultErrorCode())) {
> - Debug.logWarning("Got error [" + resonseMessage + "] calling inline simple-method named [" + methodName + "]
> in resource [" + xmlResource + "], message is " + methodContext.getEnv(simpleMethod.getServiceErrorMessageName()) + ", and the
> error message list is: "
> - + methodContext.getEnv(simpleMethod.getServiceErrorMessageListName()), module);
> - return false;
> + }
> + if ("function".equals(this.memoryModel) && this.resultToFieldList != null) {
> + Map<String, Object> results = localContext.getResults();
> + if (results != null) {
> + for (ResultToField resultToField : this.resultToFieldList) {
> + resultToField.exec(methodContext.getEnvMap(), results);
> }
> }
> - } else {
> - String errMsg = "ERROR in call-simple-method: methodName was missing; not running simpleMethod";
> - Debug.logError(errMsg, module);
> - methodContext.setErrorReturn(errMsg, simpleMethod);
> - return false;
> }
> return true;
> }
>
> @Override
> public String expandedString(MethodContext methodContext) {
> - // TODO: something more than a stub/dummy
> - return this.rawString();
> + return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
> }
>
> - public String getMethodName() {
> - return this.methodName;
> - }
> -
> - public SimpleMethod getSimpleMethodToCall(ClassLoader loader) throws MiniLangException {
> - SimpleMethod simpleMethodToCall = null;
> - if (UtilValidate.isEmpty(xmlResource)) {
> - simpleMethodToCall = this.simpleMethod.getSimpleMethodInSameFile(methodName);
> - } else {
> - Map<String, SimpleMethod> simpleMethods = SimpleMethod.getSimpleMethods(xmlResource, loader);
> - simpleMethodToCall = simpleMethods.get(methodName);
> - }
> - return simpleMethodToCall;
> - }
> -
> - public String getXmlResource() {
> - return this.xmlResource;
> + @Override
> + public String rawString() {
> + return toString();
> }
>
> @Override
> - public String rawString() {
> - return "<call-simple-method xml-resource=\"" + this.xmlResource + "\" method-name=\"" + this.methodName + "\" />";
> + public String toString() {
> + StringBuilder sb = new StringBuilder("<call-simple-method ");
> + if (this.methodName.length() > 0) {
> + sb.append("method-name=\"").append(this.methodName).append("\" ");
> + }
> + if (this.xmlResource.length() > 0) {
> + sb.append("xml-resource=\"").append(this.xmlResource).append("\" ");
> + }
> + if (this.memoryModel.length() > 0) {
> + sb.append("memory-model=\"").append(this.memoryModel).append("\" ");
> + }
> + sb.append("/>");
> + return sb.toString();
> }
>
> public static final class CallSimpleMethodFactory implements Factory<CallSimpleMethod> {
> @@ -140,4 +174,33 @@ public class CallSimpleMethod extends Me
> return "call-simple-method";
> }
> }
> +
> + private final class ResultToField {
> +
> + private final FlexibleMapAccessor<Object> fieldFma;
> + private final FlexibleMapAccessor<Object> resultNameFma;
> +
> + private ResultToField(Element element, SimpleMethod simpleMethod) throws ValidationException {
> + if (MiniLangValidate.validationOn()) {
> + MiniLangValidate.attributeNames(simpleMethod, element, "result-name", "field");
> + MiniLangValidate.requiredAttributes(simpleMethod, element, "result-name");
> + MiniLangValidate.expressionAttributes(simpleMethod, element, "result-name", "field");
> + MiniLangValidate.noChildElements(simpleMethod, element);
> + }
> + this.resultNameFma = FlexibleMapAccessor.getInstance(element.getAttribute("result-name"));
> + String fieldAttribute = element.getAttribute("field");
> + if (fieldAttribute.length() == 0) {
> + this.fieldFma = this.resultNameFma;
> + } else {
> + this.fieldFma = FlexibleMapAccessor.getInstance(fieldAttribute);
> + }
> + }
> +
> + private void exec(Map<String, Object> context, Map<String, Object> results) throws MiniLangException {
> + Object value = this.resultNameFma.get(results);
> + if (value != null) {
> + this.fieldFma.put(context, value);
> + }
> + }
> + }
> }
>
> Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java?rev=1331137&r1=1331136&r2=1331137&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java (original)
> +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/Now.java Thu Apr 26 22:40:22 2012
> @@ -47,6 +47,8 @@ public final class Now extends MethodOpe
> if (MiniLangValidate.validationOn()) {
> MiniLangValidate.attributeNames(simpleMethod, element, "field", "type");
> MiniLangValidate.requiredAttributes(simpleMethod, element, "field");
> + MiniLangValidate.expressionAttributes(simpleMethod, element, "field");
> + MiniLangValidate.constantAttributes(simpleMethod, element, "type");
> MiniLangValidate.noChildElements(simpleMethod, element);
> }
> this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
>
> Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java?rev=1331137&r1=1331136&r2=1331137&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java (original)
> +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/serviceops/FieldToResult.java Thu Apr 26 22:40:22 2012
> @@ -18,70 +18,72 @@
> *******************************************************************************/
> package org.ofbiz.minilang.method.serviceops;
>
> -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.MiniLangValidate;
> import org.ofbiz.minilang.SimpleMethod;
> -import org.ofbiz.minilang.method.ContextAccessor;
> import org.ofbiz.minilang.method.MethodContext;
> import org.ofbiz.minilang.method.MethodOperation;
> import org.w3c.dom.Element;
>
> /**
> - * Copies a map field to a Service result entry
> + * Copies a field to a service OUT attribute.
> */
> -public class FieldToResult extends MethodOperation {
> +public final class FieldToResult extends MethodOperation {
>
> public static final String module = FieldToResult.class.getName();
>
> - ContextAccessor<Object> fieldAcsr;
> - ContextAccessor<Map<String, ? extends Object>> mapAcsr;
> - ContextAccessor<Object> resultAcsr;
> + private final FlexibleMapAccessor<Object> fieldFma;
> + private final FlexibleMapAccessor<Object> resultFma;
>
> public FieldToResult(Element element, SimpleMethod simpleMethod) throws MiniLangException {
> super(element, simpleMethod);
> - // the schema for this element now just has the "field" attribute, though the old "field-name" and "map-name" pair is
> still supported
> - mapAcsr = new ContextAccessor<Map<String, ? extends Object>>(element.getAttribute("map-name"));
> - fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field"), element.getAttribute("field-name"));
> - resultAcsr = new ContextAccessor<Object>(element.getAttribute("result-name"), fieldAcsr.toString());
> + if (MiniLangValidate.validationOn()) {
> + MiniLangValidate.attributeNames(simpleMethod, element, "field", "result-name");
> + MiniLangValidate.requiredAttributes(simpleMethod, element, "field");
> + MiniLangValidate.expressionAttributes(simpleMethod, element, "field", "result-name");
> + MiniLangValidate.noChildElements(simpleMethod, element);
> + }
> + this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
> + String resultNameAttribute = element.getAttribute("result-name");
> + if (resultNameAttribute.length() == 0) {
> + this.resultFma = this.fieldFma;
> + } else {
> + this.resultFma = FlexibleMapAccessor.getInstance(resultNameAttribute);
> + }
> }
>
> @Override
> public boolean exec(MethodContext methodContext) throws MiniLangException {
> - // only run this if it is in an SERVICE context
> - if (methodContext.getMethodType() == MethodContext.SERVICE) {
> - Object fieldVal = null;
> - if (!mapAcsr.isEmpty()) {
> - Map<String, ? extends Object> fromMap = mapAcsr.get(methodContext);
> - if (fromMap == null) {
> - Debug.logWarning("Map not found with name " + mapAcsr, module);
> - return true;
> - }
> - fieldVal = fieldAcsr.get(fromMap, methodContext);
> - } else {
> - // no map name, try the env
> - fieldVal = fieldAcsr.get(methodContext);
> - }
> - if (fieldVal == null) {
> - Debug.logWarning("Field value not found with name " + fieldAcsr + " in Map with name " + mapAcsr, module);
> - return true;
> - }
> - resultAcsr.put(methodContext.getResults(), fieldVal, methodContext);
> + Object fieldVal = this.fieldFma.get(methodContext.getEnvMap());
> + if (fieldVal != null) {
> + this.resultFma.put(methodContext.getResults(), fieldVal);
> }
> return true;
> }
>
> @Override
> public String expandedString(MethodContext methodContext) {
> - // TODO: something more than a stub/dummy
> - return this.rawString();
> + return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap());
> }
>
> @Override
> public String rawString() {
> - // TODO: add all attributes and other info
> - return "<field-to-result field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
> + return toString();
> + }
> +
> + @Override
> + public String toString() {
> + StringBuilder sb = new StringBuilder("<now ");
> + if (!this.fieldFma.isEmpty()) {
> + sb.append("field=\"").append(this.fieldFma).append("\" ");
> + }
> + if (!this.resultFma.isEmpty()) {
> + sb.append("result-name=\"").append(this.resultFma).append("\" ");
> + }
> + sb.append("/>");
> + return sb.toString();
> }
>
> public static final class FieldToResultFactory implements Factory<FieldToResult> {
>
>
Re: Fwd: svn commit: r1331137 - in /ofbiz/trunk/framework/minilang:
dtd/simple-methods-v2.xsd src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java
src/org/ofbiz/minilang/method/envops/Now.java src/org/ofbiz/minilang/method/serviceops/FieldToResult.java
Posted by Adrian Crum <ad...@sandglass-software.com>.
Done, rev 1331259.
-Adrian
On 4/27/2012 6:06 AM, Jacopo Cappellato wrote:
> Hi Adrian,
>
> I am wondering if, instead of "memory-model", the name "scope" (or similar) would be a better fit.
>
> Jacopo
>
>
> Begin forwarded message:
>
>> Added new attribute "memory-model" to the Mini-language<call-simple-method> element.
Fwd: svn commit: r1331137 - in /ofbiz/trunk/framework/minilang: dtd/simple-methods-v2.xsd src/org/ofbiz/minilang/method/callops/CallSimpleMethod.java src/org/ofbiz/minilang/method/envops/Now.java src/org/ofbiz/minilang/method/serviceops/FieldToResult.java
Posted by Jacopo Cappellato <ja...@hotwaxmedia.com>.
Hi Adrian,
I am wondering if, instead of "memory-model", the name "scope" (or similar) would be a better fit.
Jacopo
Begin forwarded message:
> Added new attribute "memory-model" to the Mini-language <call-simple-method> element.