Administrator
|
Hi Adrian,
This is blocking trunk demo, please fix or revert Thanks Jacques From: <[hidden email]> > 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> { > > |
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: <[hidden email]> >> 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> { >> >> |
Free forum by Nabble | Edit this page |