Author: adrianc
Date: Wed May 16 09:20:03 2012 New Revision: 1339079 URL: http://svn.apache.org/viewvc?rev=1339079&view=rev Log: Overhauled Mini-language <call-service> element, final pass. Modified: ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallService.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=1339079&r1=1339078&r2=1339079&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original) +++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Wed May 16 09:20:03 2012 @@ -323,7 +323,7 @@ under the License. <xs:attribute type="xs:string" name="default-error-code"> <xs:annotation> <xs:documentation> - The default error return code. Defauts to "error". + The default error return code. Defaults to "error". <br/><br/> Optional. Attribute type: constant. </xs:documentation> @@ -332,7 +332,7 @@ under the License. <xs:attribute type="xs:string" name="default-success-code"> <xs:annotation> <xs:documentation> - The default success return code. Defauts to "success". + The default success return code. Defaults to "success". <br/><br/> Optional. Attribute type: constant. </xs:documentation> @@ -572,128 +572,129 @@ under the License. <xs:element name="call-service" substitutionGroup="CallOperations"> <xs:annotation> <xs:documentation> - The call-service tag invokes a service through the Service Engine. - If the specified error code is returned from the service, - the event is aborted and the transaction in the current thread is rolled back. - Otherwise, the remaining operations are invoked. - - The result-to-request and result-to-session elements will be IGNORED when - called in a service context. So, they are ONLY used when called in an event context. + Invokes a service through the Service Engine. </xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> - <xs:element minOccurs="0" ref="error-prefix"/> - <xs:element minOccurs="0" ref="error-suffix"/> - <xs:element minOccurs="0" ref="success-prefix"/> - <xs:element minOccurs="0" ref="success-suffix"/> - <xs:element minOccurs="0" ref="message-prefix"/> - <xs:element minOccurs="0" ref="message-suffix"/> - <xs:element minOccurs="0" ref="default-message"/> + <xs:element minOccurs="0" ref="error-prefix" /> + <xs:element minOccurs="0" ref="error-suffix" /> + <xs:element minOccurs="0" ref="success-prefix" /> + <xs:element minOccurs="0" ref="success-suffix" /> + <xs:element minOccurs="0" ref="message-prefix" /> + <xs:element minOccurs="0" ref="message-suffix" /> + <xs:element minOccurs="0" ref="default-message" /> <xs:choice minOccurs="0" maxOccurs="unbounded"> - <xs:element ref="results-to-map"/> - <xs:element ref="result-to-field"/> - <xs:element ref="result-to-request"/> - <xs:element ref="result-to-session"/> - <xs:element ref="result-to-result"/> + <xs:element ref="results-to-map" /> + <xs:element ref="result-to-field" /> + <xs:element ref="result-to-request" /> + <xs:element ref="result-to-session" /> + <xs:element ref="result-to-result" /> </xs:choice> </xs:sequence> - <xs:attributeGroup ref="attlist.call-service"/> - </xs:complexType> - </xs:element> - <xs:attributeGroup name="attlist.call-service"> - <xs:attribute type="xs:string" name="service-name" use="required"> - <xs:annotation> - <xs:documentation> - Name of the service to call. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="in-map-name"> - <xs:annotation> - <xs:documentation> - Optional name of a map in the method environment to use as the input map. - If you're not going to pass any parameters to the service than you can just - leave off the in-map name, although typically in a service tag you will see - a service-name and the in-map-name passed in. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute name="include-user-login"> - <xs:annotation> - <xs:documentation> - Include-user-login by default will include the user login - so if there is a user login for the current simple-method - it will pass that in to the service. If you don't want it to - pass that in you can just set this to false. - Defaults to "true". - </xs:documentation> - </xs:annotation> - <xs:simpleType> + <xs:attribute type="xs:string" name="service-name" use="required"> <xs:annotation> + <xs:documentation> + Name of the service to call. + <br/><br/> + Required. Attribute type: constant, expression. + </xs:documentation> </xs:annotation> - <xs:restriction base="xs:token"> - <xs:enumeration value="true"/> - <xs:enumeration value="false"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute name="break-on-error"> - <xs:annotation> - <xs:documentation> - If there's an error in the service by default - it will stop the current simple-method and return an - error message that came from the service it called. If - you don't want it to when there's an error you can just - set that to false. - Defaults to "true". - </xs:documentation> - </xs:annotation> - <xs:simpleType> - <xs:restriction base="xs:token"> - <xs:enumeration value="true"/> - <xs:enumeration value="false"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute type="xs:string" name="error-code"> - <xs:annotation> - <xs:documentation> - Defaults to "error". - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="success-code"> - <xs:annotation> - <xs:documentation> - Defaults to "success". - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute name="require-new-transaction"> - <xs:annotation> - <xs:documentation> - Defines if the simple-method requires a new transaction or not. - Defaults to "false". - </xs:documentation> - </xs:annotation> - <xs:simpleType> - <xs:restriction base="xs:token"> - <xs:enumeration value="true"/> - <xs:enumeration value="false"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute type="xs:string" name="transaction-timeout"> - <xs:annotation> - <xs:documentation> - Defines the timeout for the transaction, in seconds. - Defaults to the value set in the service definition which in turn defaults to the setting - in the TransactionFactory being used (typically 60 seconds). - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:attributeGroup> + </xs:attribute> + <xs:attribute type="xs:string" name="in-map-name"> + <xs:annotation> + <xs:documentation> + A map in the method environment to use as the input map. + If you're not going to pass any parameters to the service than you can just + omit the in-map attribute, although typically in a service element you will see + the in-map-name attribute included. + <br/><br/> + Optional. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="include-user-login"> + <xs:annotation> + <xs:documentation> + Include the current UserLogin GenericValue in the called service IN attributes. + Defaults to "true". + <br/><br/> + Optional. Attribute type: constant. + </xs:documentation> + </xs:annotation> + <xs:simpleType> + <xs:annotation> + </xs:annotation> + <xs:restriction base="xs:token"> + <xs:enumeration value="true" /> + <xs:enumeration value="false" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name="break-on-error"> + <xs:annotation> + <xs:documentation> + Halt script execution if the called service returns an error. + Defaults to "true". + <br/><br/> + Optional. Attribute type: constant. + </xs:documentation> + </xs:annotation> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="true" /> + <xs:enumeration value="false" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute type="xs:string" name="error-code"> + <xs:annotation> + <xs:documentation> + The error code returned by the called service. The error code is copied to the script result. + Defaults to the enclosing simple-method "default-error-code" attribute value. + <br/><br/> + Optional. Attribute type: constant. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="success-code"> + <xs:annotation> + <xs:documentation> + The success code returned by the called service. The success code is copied to the script result. + Defaults to the enclosing simple-method "default-success-code" attribute value. + <br/><br/> + Optional. Attribute type: constant. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="require-new-transaction"> + <xs:annotation> + <xs:documentation> + Require a new transaction for the called service. + Defaults to "false". + <br/><br/> + Optional. Attribute type: constant. + </xs:documentation> + </xs:annotation> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="true" /> + <xs:enumeration value="false" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute type="xs:string" name="transaction-timeout"> + <xs:annotation> + <xs:documentation> + The timeout for the new transaction, in seconds. + Defaults to the value set in the service definition. + <br/><br/> + Optional. Attribute type: constant. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> <xs:element name="error-prefix"> <xs:annotation> <xs:documentation> @@ -768,132 +769,134 @@ under the License. <xs:element name="results-to-map"> <xs:annotation> <xs:documentation> - results-to-map will take all of the results of the service, - the outgoing maps from the service and put them in a map of the given map-name. + Copies the called service result Map to the specified field. </xs:documentation> </xs:annotation> <xs:complexType> - <xs:attributeGroup ref="attlist.results-to-map"/> + <xs:attribute type="xs:string" name="map-name" use="required"> + <xs:annotation> + <xs:documentation> + Name of the target field. + <br/><br/> + Required. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> - <xs:attributeGroup name="attlist.results-to-map"> - <xs:attribute type="xs:string" name="map-name" use="required"> - <xs:annotation> - <xs:documentation> - Name of a map where results will be put in. - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:attributeGroup> <xs:element name="result-to-field"> <xs:annotation> <xs:documentation> - Specify the name of the field in the result and then the name of the field in the context you want to put it in, - and optionally the name in the map. - - There's a field-map there. If you don't specify a field-name then the result-name will be used for the field-name, - that's the name of the variable that will be created in the current context for the value of that result. + Copies the called service OUT attribute to the specified field. </xs:documentation> </xs:annotation> <xs:complexType> - <xs:attributeGroup ref="attlist.result-to-field"/> + <xs:attribute type="xs:string" name="result-name" use="required"> + <xs:annotation> + <xs:documentation> + Name of the called service OUT attribute. + <br/><br/> + Required. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="field"> + <xs:annotation> + <xs:documentation> + Name of target field. Defaults to the "result-name" attribute value. + <br/><br/> + Optional. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> - <xs:attributeGroup name="attlist.result-to-field"> - <xs:attribute type="xs:string" name="result-name" use="required"> - <xs:annotation> - <xs:documentation> - Name of the result. May be used for the field-name. If you don't specify a field-name, - this will be name of the variable that will be created in the current context for the value of that result. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="field"> - <xs:annotation><xs:documentation>Optional name of target field. If empty will default to result-name.</xs:documentation></xs:annotation> - </xs:attribute> - </xs:attributeGroup> <xs:element name="result-to-request"> <xs:annotation> <xs:documentation> - result-to-request is event specific. - It takes the result with the given name and puts it in a request attribute with the given name here. - Again the request-name is optional. - If you leave it off then it will put it in an attribute with the name of the result-name. + Copies the called service OUT attribute to the specified request attribute. + Valid only when the script is run in an event. </xs:documentation> </xs:annotation> <xs:complexType> - <xs:attributeGroup ref="attlist.result-to-request"/> + <xs:attribute type="xs:string" name="result-name" use="required"> + <xs:annotation> + <xs:documentation> + Name of the called service OUT attribute. + <br/><br/> + Required. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="request-name"> + <xs:annotation> + <xs:documentation> + Name of the target request attribute. Defaults to the "result-name" attribute value. + <br/><br/> + Optional. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> - <xs:attributeGroup name="attlist.result-to-request"> - <xs:attribute type="xs:string" name="result-name" use="required"> - <xs:annotation> - <xs:documentation> - Name of the result. May be used for the request attribute name. If you don't specify a request-name , - that's the name of the request attribute that will be created for the value of that result. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="request-name"> - <xs:annotation> - <xs:documentation> - Optionnal request name. - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:attributeGroup> <xs:element name="result-to-session"> <xs:annotation> <xs:documentation> - Specify the name of the session attribute that you want it to put the value in. - If you don't specify one it will use the result-name. + Copies the called service OUT attribute to the specified session attribute. + Valid only when the script is run in an event. </xs:documentation> </xs:annotation> <xs:complexType> - <xs:attributeGroup ref="attlist.result-to-session"/> + <xs:attribute type="xs:string" name="result-name" use="required"> + <xs:annotation> + <xs:documentation> + Name of the called service OUT attribute. + <br/><br/> + Required. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="session-name"> + <xs:annotation> + <xs:documentation> + Name of the target session attribute. Defaults to the "result-name" attribute value. + <br/><br/> + Optional. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> - <xs:attributeGroup name="attlist.result-to-session"> - <xs:attribute type="xs:string" name="result-name" use="required"> - <xs:annotation> - <xs:documentation> - Name of the result. May be used for the session attribute name. If you don't specify a session-name, - that's the name of the session attribute that will be created for the value of that result. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="session-name"> - <xs:annotation> - <xs:documentation> - Optional session name. - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:attributeGroup> <xs:element name="result-to-result"> <xs:annotation> <xs:documentation> Copies service OUT attributes from a called service to the calling service's OUT attributes. - Only valid when the script is run in a service. + This element can also be used to copy the called service OUT attributes to the return result of + a simple-method called as a function. <br/><br/> Note that the attribute names are somewhat confusing: - result-name is the name of the OUT attribute of the called service, and - service-result-name is the name of the OUT attribute of the calling service. - In other words, copy the OUT attribute FROM result-name TO service-result-name. + "result-name" is the name of the OUT attribute of the called service, and + "service-result-name" is the name of the OUT attribute of the calling service. + In other words, copy the OUT attribute FROM "result-name" TO "service-result-name". </xs:documentation> </xs:annotation> <xs:complexType> <xs:attribute type="xs:string" name="result-name" use="required"> <xs:annotation> <xs:documentation> - Name of the field in the result of this service call that the value comes FROM. + Name of the called service OUT attribute. + <br/><br/> + Required. Attribute type: expression. </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute type="xs:string" name="service-result-name"> <xs:annotation> <xs:documentation> - Name of the field in the result of this simple-method called as a service where the value goes TO. + Name of the calling service OUT attribute (or function return result). + Defaults to the "result-name" attribute value. + <br/><br/> + Optional. Attribute type: expression. </xs:documentation> </xs:annotation> </xs:attribute> Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallService.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallService.java?rev=1339079&r1=1339078&r2=1339079&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallService.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallService.java Wed May 16 09:20:03 2012 @@ -34,8 +34,10 @@ import org.ofbiz.base.util.UtilValidate; import org.ofbiz.base.util.UtilXml; import org.ofbiz.base.util.collections.FlexibleMapAccessor; import org.ofbiz.base.util.collections.FlexibleServletAccessor; +import org.ofbiz.base.util.string.FlexibleStringExpander; import org.ofbiz.entity.GenericValue; import org.ofbiz.minilang.MiniLangException; +import org.ofbiz.minilang.MiniLangValidate; import org.ofbiz.minilang.SimpleMethod; import org.ofbiz.minilang.method.MethodContext; import org.ofbiz.minilang.method.MethodOperation; @@ -75,6 +77,12 @@ public final class CallService extends M public CallService(Element element, SimpleMethod simpleMethod) throws MiniLangException { super(element, simpleMethod); + if (MiniLangValidate.validationOn()) { + MiniLangValidate.attributeNames(simpleMethod, element, "serviceName", "in-map-name", "include-user-login", "break-on-error", "error-code", "require-new-transaction", "transaction-timeout", "success-code"); + MiniLangValidate.constantAttributes(simpleMethod, element, "include-user-login", "break-on-error", "error-code", "require-new-transaction", "transaction-timeout", "success-code"); + MiniLangValidate.expressionAttributes(simpleMethod, element, "service-name", "in-map-name"); + MiniLangValidate.childElements(simpleMethod, element, "error-prefix", "error-suffix", "success-prefix", "success-suffix", "message-prefix", "message-suffix", "default-message", "results-to-map", "result-to-field", "result-to-request", "result-to-session", "result-to-result"); + } serviceName = element.getAttribute("service-name"); inMapFma = FlexibleMapAccessor.getInstance(element.getAttribute("in-map-name")); includeUserLogin = !"false".equals(element.getAttribute("include-user-login")); @@ -87,7 +95,7 @@ public final class CallService extends M try { timeout = Integer.parseInt(timeoutStr); } catch (NumberFormatException e) { - Debug.logWarning(e, "Setting timeout to 0 (default)", module); + MiniLangValidate.handleError("Exception thrown while parsing transaction-timeout attribute: " + e.getMessage(), simpleMethod, element); timeout = 0; } } @@ -154,6 +162,9 @@ public final class CallService extends M @Override public boolean exec(MethodContext methodContext) throws MiniLangException { + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "Begin call-service."); + } String serviceName = methodContext.expandString(this.serviceName); String errorCode = this.errorCode; if (errorCode.isEmpty()) { @@ -172,7 +183,7 @@ public final class CallService extends M methodContext.removeEnv(simpleMethod.getEventErrorMessageName()); methodContext.removeEnv(simpleMethod.getEventEventMessageName()); methodContext.removeEnv(simpleMethod.getEventResponseCodeName()); - } else if (methodContext.getMethodType() == MethodContext.SERVICE) { + } else { methodContext.removeEnv(simpleMethod.getServiceErrorMessageName()); methodContext.removeEnv(simpleMethod.getServiceSuccessMessageName()); methodContext.removeEnv(simpleMethod.getServiceResponseMessageName()); @@ -197,45 +208,72 @@ public final class CallService extends M if (this.transactionTimeout >= 0) { timeout = this.transactionTimeout; } + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "Invoking service \"" + serviceName + "\", require-new-transaction = " + requireNewTransaction + ", transaction-timeout = " + timeout + ", IN attributes:", inMap.toString()); + } result = methodContext.getDispatcher().runSync(serviceName, inMap, timeout, requireNewTransaction); } catch (GenericServiceException e) { + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "Service engine threw an exception: " + e.getMessage()); + } String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [problem invoking the [" + serviceName + "] service with the map named [" + inMapFma + "] containing [" + inMap + "]: " + e.getMessage() + "]"; Debug.logError(e, errMsg, module); if (breakOnError) { if (methodContext.getMethodType() == MethodContext.EVENT) { methodContext.putEnv(simpleMethod.getEventErrorMessageName(), errMsg); methodContext.putEnv(simpleMethod.getEventResponseCodeName(), errorCode); - } else if (methodContext.getMethodType() == MethodContext.SERVICE) { + } else { methodContext.putEnv(simpleMethod.getServiceErrorMessageName(), errMsg); methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), errorCode); } + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "break-on-error set to \"true\", halting script execution. End call-service."); + } return false; } else { + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "End call-service."); + } return true; } } if (resultsToMapList != null) { + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "Processing " + resultsToMapList.size() + " <results-to-map> elements."); + } for (String mapName : resultsToMapList) { methodContext.putEnv(mapName, UtilMisc.makeMapWritable(result)); } } if (resultToFieldList != null) { + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "Processing " + resultToFieldList.size() + " <result-to-field> elements."); + } for (ResultToField rtfDef : resultToFieldList) { rtfDef.exec(methodContext, result); } } if (resultToResultList != null) { + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "Processing " + resultToResultList.size() + " <result-to-result> elements."); + } for (ResultToResult rtrDef : resultToResultList) { rtrDef.exec(methodContext, result); } } if (methodContext.getMethodType() == MethodContext.EVENT) { if (resultToRequestList != null) { + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "Processing " + resultToRequestList.size() + " <result-to-request> elements."); + } for (ResultToRequest rtrDef : resultToRequestList) { rtrDef.exec(methodContext, result); } } if (resultToSessionList != null) { + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "Processing " + resultToSessionList.size() + " <result-to-session> elements."); + } for (ResultToSession rtsDef : resultToSessionList) { rtsDef.exec(methodContext, result); } @@ -268,7 +306,7 @@ public final class CallService extends M } methodContext.putEnv(simpleMethod.getEventErrorMessageListName(), errorMessageList); } - } else if (methodContext.getMethodType() == MethodContext.SERVICE) { + } else { ServiceUtil.addErrors(UtilMisc.<String, String> getListFromMap(methodContext.getEnvMap(), this.simpleMethod.getServiceErrorMessageListName()), UtilMisc.<String, String, Object> getMapFromMap(methodContext.getEnvMap(), this.simpleMethod.getServiceErrorMessageMapName()), result); Debug.logError(new Exception(errorMessage), module); } @@ -277,7 +315,7 @@ public final class CallService extends M if (UtilValidate.isNotEmpty(successMessage)) { if (methodContext.getMethodType() == MethodContext.EVENT) { methodContext.putEnv(simpleMethod.getEventEventMessageName(), successMessage); - } else if (methodContext.getMethodType() == MethodContext.SERVICE) { + } else { methodContext.putEnv(simpleMethod.getServiceSuccessMessageName(), successMessage); } } @@ -285,28 +323,38 @@ public final class CallService extends M if (UtilValidate.isEmpty(errorMessage) && UtilValidate.isEmpty(errorMessageList) && UtilValidate.isEmpty(successMessage) && UtilValidate.isNotEmpty(defaultMessageStr)) { if (methodContext.getMethodType() == MethodContext.EVENT) { methodContext.putEnv(simpleMethod.getEventEventMessageName(), defaultMessageStr); - } else if (methodContext.getMethodType() == MethodContext.SERVICE) { + } else { methodContext.putEnv(simpleMethod.getServiceSuccessMessageName(), defaultMessageStr); } } - // handle the result String responseCode = result.containsKey(ModelService.RESPONSE_MESSAGE) ? (String) result.get(ModelService.RESPONSE_MESSAGE) : successCode; if (errorCode.equals(responseCode)) { + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "Service returned an error."); + } if (breakOnError) { if (methodContext.getMethodType() == MethodContext.EVENT) { methodContext.putEnv(simpleMethod.getEventResponseCodeName(), responseCode); - } else if (methodContext.getMethodType() == MethodContext.SERVICE) { + } else { methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), responseCode); } + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "break-on-error set to \"true\", halting script execution. End call-service."); + } return false; } else { - // avoid responseCode here since we are ignoring the error + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "End call-service."); + } return true; } } else { + if (methodContext.isTraceOn()) { + outputTraceMessage(methodContext, "Service ran successfully. End call-service."); + } if (methodContext.getMethodType() == MethodContext.EVENT) { methodContext.putEnv(simpleMethod.getEventResponseCodeName(), responseCode); - } else if (methodContext.getMethodType() == MethodContext.SERVICE) { + } else { methodContext.putEnv(simpleMethod.getServiceResponseMessageName(), responseCode); } return true; @@ -315,8 +363,7 @@ public final class CallService extends M @Override public String expandedString(MethodContext methodContext) { - // TODO: something more than a stub/dummy - return this.rawString(); + return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap()); } public String getServiceName() { @@ -325,8 +372,18 @@ public final class CallService extends M @Override public String rawString() { - // TODO: something more than the empty tag - return "<call-service/>"; + return toString(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("<call-service "); + sb.append("service-name=\"").append(this.serviceName).append("\" "); + if (!this.inMapFma.isEmpty()) { + sb.append("in-map-name=\"").append(this.inMapFma).append("\" "); + } + sb.append("/>"); + return sb.toString(); } public static final class CallServiceFactory implements Factory<CallService> { @@ -341,19 +398,20 @@ public final class CallService extends M private final class ResultToField { private final FlexibleMapAccessor<Object> fieldFma; - private final String resultName; + private final FlexibleMapAccessor<Object> resultFma; private ResultToField(Element element) { - resultName = element.getAttribute("result-name"); + resultFma = FlexibleMapAccessor.getInstance(element.getAttribute("result-name")); String fieldAttribute = element.getAttribute("field"); if (fieldAttribute.isEmpty()) { - fieldAttribute = resultName; + fieldFma = resultFma; + } else { + fieldFma = FlexibleMapAccessor.getInstance(fieldAttribute); } - fieldFma = FlexibleMapAccessor.getInstance(fieldAttribute); } private void exec(MethodContext methodContext, Map<String, Object> resultMap) { - fieldFma.put(methodContext.getEnvMap(), resultMap.get(resultName)); + fieldFma.put(methodContext.getEnvMap(), resultFma.get(resultMap)); } } |
Free forum by Nabble | Edit this page |