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));
}
}