Author: adrianc
Date: Wed May 16 13:09:30 2012
New Revision: 1339149
URL: http://svn.apache.org/viewvc?rev=1339149&view=rev
Log:
Overhauled Mini-language <call-service-asynch> and <call-map-processor>
elements.
Modified:
ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.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=1339149&r1=1339148&r2=1339149&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original)
+++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Wed May 16
13:09:30 2012
@@ -466,71 +466,70 @@ under the License.
<xs:documentation>
The call-map-processor tag invokes a simple map processor from
an existing map, creating a new map or adding to an existing one
if the named out-map already exists. Resulting messages are
added to the named list, and a new list is created if a list with
- the given name does not yet exist. Note that all lists and
maps exist in the same context and must have unique names.
-
+ the given name does not yet exist. All lists and maps exist in
the same context and must have unique names.
+ <br/><br/>
An inline simple-map-processor can be used by putting a
simple-map-processor tag under the call-map-processor tag.
-
If both an external and an inline map-processor are specified,
the external
one will be called first, allowing the inline one to override
its behavior.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
- <xs:element minOccurs="0" ref="simple-map-processor">
- <xs:annotation>
- <xs:documentation>
- Uses the same definition as the
simple-map-processor in the context of a simple-map-processors XML file.
- Allows for an inlined simple-map-processor.
- </xs:documentation>
- </xs:annotation>
- </xs:element>
+ <xs:element minOccurs="0" ref="simple-map-processor" />
</xs:sequence>
- <xs:attributeGroup ref="attlist.call-map-processor"/>
+ <xs:attribute type="xs:string" name="processor-name">
+ <xs:annotation>
+ <xs:documentation>
+ The name of the external map processor to execute in
the specified xml-resource.
+ This is only required if an external map processor is
desired.
+ <br/><br/>
+ Optional. 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 map processor to execute.
+ This is only required if an external map processor is
desired.
+ <br/><br/>
+ Optional. Attribute type: constant.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="in-map-name" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The name of a map in the method environment to use as
the input map.
+ <br/><br/>
+ Required. Attribute type: expression.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="out-map-name" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The name of a map in the method environment to use as
the output map.
+ Will be created if it does not exist already.
+ If already exists will be added to in place.
+ <br/><br/>
+ Required. Attribute type: expression.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="error-list-name">
+ <xs:annotation>
+ <xs:documentation>
+ The name of a list in the method environment that the
error messages will be added to.
+ Will be created if it does not exist.
+ Defaults to "error_list".
+ <br/><br/>
+ Optional. Attribute type: constant.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
</xs:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.call-map-processor">
- <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 map processor to execute.
- This is only required if an external map processor is
desired.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="processor-name">
- <xs:annotation>
- <xs:documentation>
- The name of the external map processor to execute in the
specified xml-resource.
- This is only required if an external map processor is
desired.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="in-map-name" use="required">
- <xs:annotation>
- <xs:documentation>
- The name of a map in the method environment to use as the
input map.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="out-map-name" use="required">
- <xs:annotation>
- <xs:documentation>
- The name of a map in the method environment to use as the
output map.
- Will be created if it does not exist already.
- If already exists will be added to in place.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="error-list-name"
default="error_list">
- <xs:annotation>
- <xs:documentation>
- The name of a list in the method environment that the
error messages will be added to.
- Will be created if it does not exist.
- Defaults to "error_list".
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
<xs:element name="set-service-fields" substitutionGroup="CallOperations">
<xs:annotation>
<xs:documentation>
@@ -911,38 +910,47 @@ under the License.
</xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:attributeGroup ref="attlist.call-service-asynch"/>
+ <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: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
call-service-asynch 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:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.call-service-asynch">
- <xs:attribute type="xs:string" name="service-name" use="required">
- <xs:annotation>
- <xs:documentation>
- Name of the service called asynchronously.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="in-map-name">
- <xs:annotation>
- <xs:documentation>
- The name of a map in the method environment to use as the
input map.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="include-user-login" default="true">
- <xs:annotation>
- <xs:documentation>
- 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:attributeGroup>
<xs:element name="script" substitutionGroup="CallOperations">
<xs:annotation>
<xs:documentation>
Modified:
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java?rev=1339149&r1=1339148&r2=1339149&view=diff
==============================================================================
---
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java
(original)
+++
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallServiceAsynch.java
Wed May 16 13:09:30 2012
@@ -24,10 +24,12 @@ import java.util.Map;
import javolution.util.FastMap;
import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+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.ContextAccessor;
import org.ofbiz.minilang.method.MethodContext;
import org.ofbiz.minilang.method.MethodOperation;
import org.ofbiz.service.GenericServiceException;
@@ -36,80 +38,100 @@ import org.w3c.dom.Element;
/**
* Calls a service using the given parameters
*/
-public class CallServiceAsynch extends MethodOperation {
+public final class CallServiceAsynch extends MethodOperation {
public static final String module = CallServiceAsynch.class.getName();
- protected String includeUserLoginStr;
- protected ContextAccessor<Map<String, Object>> inMapAcsr;
- protected String serviceName;
+ private final boolean includeUserLogin;
+ private final FlexibleMapAccessor<Map<String, Object>> inMapFma;
+ private final FlexibleStringExpander serviceNameFse;
public CallServiceAsynch(Element element, SimpleMethod simpleMethod)
throws MiniLangException {
super(element, simpleMethod);
- serviceName = element.getAttribute("service-name");
- inMapAcsr = new ContextAccessor<Map<String,
Object>>(element.getAttribute("in-map-name"));
- includeUserLoginStr = element.getAttribute("include-user-login");
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.attributeNames(simpleMethod, element,
"serviceName", "in-map-name", "include-user-login");
+ MiniLangValidate.constantAttributes(simpleMethod, element,
"include-user-login");
+ MiniLangValidate.expressionAttributes(simpleMethod, element,
"service-name", "in-map-name");
+ MiniLangValidate.requiredAttributes(simpleMethod, element,
"service-name");
+ MiniLangValidate.noChildElements(simpleMethod, element);
+ }
+ serviceNameFse =
FlexibleStringExpander.getInstance(element.getAttribute("service-name"));
+ inMapFma =
FlexibleMapAccessor.getInstance(element.getAttribute("in-map-name"));
+ includeUserLogin =
!"false".equals(element.getAttribute("include-user-login"));
}
@Override
public boolean exec(MethodContext methodContext) throws MiniLangException {
- String serviceName = methodContext.expandString(this.serviceName);
- boolean includeUserLogin =
!"false".equals(methodContext.expandString(includeUserLoginStr));
- Map<String, Object> inMap = null;
- if (inMapAcsr.isEmpty()) {
+ if (methodContext.isTraceOn()) {
+ outputTraceMessage(methodContext, "Begin call-service-asynch.");
+ }
+ String serviceName =
serviceNameFse.expandString(methodContext.getEnvMap());
+ Map<String, Object> inMap = inMapFma.get(methodContext.getEnvMap());
+ if (inMap == null) {
inMap = FastMap.newInstance();
- } else {
- inMap = inMapAcsr.get(methodContext);
- if (inMap == null) {
- inMap = FastMap.newInstance();
- inMapAcsr.put(methodContext, inMap);
- }
}
- // add UserLogin to context if expected
if (includeUserLogin) {
GenericValue userLogin = methodContext.getUserLogin();
-
if (userLogin != null && inMap.get("userLogin") == null) {
inMap.put("userLogin", userLogin);
}
}
- // always add Locale to context unless null
Locale locale = methodContext.getLocale();
if (locale != null) {
inMap.put("locale", locale);
}
- // invoke the service
try {
+ if (methodContext.isTraceOn()) {
+ outputTraceMessage(methodContext, "Invoking service \"" +
serviceName + "\", IN attributes:", inMap.toString());
+ }
methodContext.getDispatcher().runAsync(serviceName, inMap);
} catch (GenericServiceException e) {
+ if (methodContext.isTraceOn()) {
+ outputTraceMessage(methodContext, "Service engine threw an
exception: " + e.getMessage() + ", halting script execution. End
call-service-asynch.");
+ }
Debug.logError(e, module);
String errMsg = "ERROR: Could not complete the " +
simpleMethod.getShortDescription() + " process [problem invoking the " +
serviceName + " service: " + e.getMessage() + "]";
if (methodContext.getMethodType() == MethodContext.EVENT) {
methodContext.putEnv(simpleMethod.getEventErrorMessageName(),
errMsg);
methodContext.putEnv(simpleMethod.getEventResponseCodeName(),
simpleMethod.getDefaultErrorCode());
- } else if (methodContext.getMethodType() == MethodContext.SERVICE)
{
+ } else {
methodContext.putEnv(simpleMethod.getServiceErrorMessageName(), errMsg);
methodContext.putEnv(simpleMethod.getServiceResponseMessageName(),
simpleMethod.getDefaultErrorCode());
}
return false;
}
+ if (methodContext.isTraceOn()) {
+ outputTraceMessage(methodContext, "End call-service-asynch.");
+ }
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 getServiceName() {
- return this.serviceName;
+ return this.serviceNameFse.getOriginal();
}
@Override
public String rawString() {
- // TODO: something more than the empty tag
- return "<call-service-asynch/>";
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("<call-service-asynch ");
+ sb.append("service-name=\"").append(this.serviceNameFse).append("\" ");
+ if (!this.inMapFma.isEmpty()) {
+ sb.append("in-map-name=\"").append(this.inMapFma).append("\" ");
+ }
+ if (!this.includeUserLogin) {
+ sb.append("include-user-login=\"false\" ");
+ }
+ sb.append("/>");
+ return sb.toString();
}
public static final class CallServiceAsynchFactory implements
Factory<CallServiceAsynch> {
Modified:
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.java?rev=1339149&r1=1339148&r2=1339149&view=diff
==============================================================================
---
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.java
(original)
+++
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallSimpleMapProcessor.java
Wed May 16 13:09:30 2012
@@ -24,11 +24,13 @@ import java.util.Map;
import javolution.util.FastList;
import javolution.util.FastMap;
-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.MiniLangValidate;
+import org.ofbiz.minilang.SimpleMapProcessor;
import org.ofbiz.minilang.SimpleMethod;
-import org.ofbiz.minilang.method.ContextAccessor;
import org.ofbiz.minilang.method.MethodContext;
import org.ofbiz.minilang.method.MethodOperation;
import org.ofbiz.minilang.operation.MapProcessor;
@@ -39,54 +41,60 @@ import org.w3c.dom.Element;
*/
public class CallSimpleMapProcessor extends MethodOperation {
- ContextAccessor<List<Object>> errorListAcsr;
- MapProcessor inlineMapProcessor = null;
- ContextAccessor<Map<String, Object>> inMapAcsr;
- ContextAccessor<Map<String, Object>> outMapAcsr;
- String processorName;
- String xmlResource;
+ private final FlexibleMapAccessor<List<Object>> errorListFma;
+ private final MapProcessor inlineMapProcessor;
+ private final FlexibleMapAccessor<Map<String, Object>> inMapFma;
+ private final FlexibleMapAccessor<Map<String, Object>> outMapFma;
+ private final String processorName;
+ private final String xmlResource;
public CallSimpleMapProcessor(Element element, SimpleMethod simpleMethod)
throws MiniLangException {
super(element, simpleMethod);
- xmlResource = element.getAttribute("xml-resource");
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.attributeNames(simpleMethod, element,
"processor-name", "xml-resource", "in-map-name", "out-map-name",
"error-list-name");
+ MiniLangValidate.constantAttributes(simpleMethod, element,
"processor-name", "xml-resource", "error-list-name");
+ MiniLangValidate.expressionAttributes(simpleMethod, element,
"in-map-name", "out-map-name");
+ MiniLangValidate.requiredAttributes(simpleMethod, element,
"in-map-name", "out-map-name");
+ MiniLangValidate.childElements(simpleMethod, element,
"simple-map-processor");
+ }
processorName = element.getAttribute("processor-name");
- inMapAcsr = new ContextAccessor<Map<String,
Object>>(element.getAttribute("in-map-name"));
- outMapAcsr = new ContextAccessor<Map<String,
Object>>(element.getAttribute("out-map-name"));
- errorListAcsr = new
ContextAccessor<List<Object>>(element.getAttribute("error-list-name"),
"error_list");
+ xmlResource = element.getAttribute("xml-resource");
+ errorListFma =
FlexibleMapAccessor.getInstance(MiniLangValidate.checkAttribute(element.getAttribute("error-list-name"),
"error_list"));
+ inMapFma =
FlexibleMapAccessor.getInstance(element.getAttribute("in-map-name"));
+ outMapFma =
FlexibleMapAccessor.getInstance(element.getAttribute("out-map-name"));
Element simpleMapProcessorElement = UtilXml.firstChildElement(element,
"simple-map-processor");
if (simpleMapProcessorElement != null) {
inlineMapProcessor = new MapProcessor(simpleMapProcessorElement);
+ } else {
+ inlineMapProcessor = null;
}
}
@Override
public boolean exec(MethodContext methodContext) throws MiniLangException {
- List<Object> messages = errorListAcsr.get(methodContext);
+ List<Object> messages = errorListFma.get(methodContext.getEnvMap());
if (messages == null) {
messages = FastList.newInstance();
- errorListAcsr.put(methodContext, messages);
+ errorListFma.put(methodContext.getEnvMap(), messages);
}
- Map<String, Object> inMap = inMapAcsr.get(methodContext);
+ Map<String, Object> inMap = inMapFma.get(methodContext.getEnvMap());
if (inMap == null) {
inMap = FastMap.newInstance();
- inMapAcsr.put(methodContext, inMap);
}
- Map<String, Object> outMap = outMapAcsr.get(methodContext);
+ Map<String, Object> outMap = outMapFma.get(methodContext.getEnvMap());
if (outMap == null) {
outMap = FastMap.newInstance();
- outMapAcsr.put(methodContext, outMap);
+ outMapFma.put(methodContext.getEnvMap(), outMap);
}
// run external map processor first
- if (UtilValidate.isNotEmpty(this.xmlResource) &&
UtilValidate.isNotEmpty(this.processorName)) {
- String xmlResource = methodContext.expandString(this.xmlResource);
- String processorName =
methodContext.expandString(this.processorName);
+ if (!this.xmlResource.isEmpty() && !this.processorName.isEmpty()) {
try {
-
org.ofbiz.minilang.SimpleMapProcessor.runSimpleMapProcessor(xmlResource,
processorName, inMap, outMap, messages, methodContext.getLocale(),
methodContext.getLoader());
+ SimpleMapProcessor.runSimpleMapProcessor(xmlResource,
processorName, inMap, outMap, messages, methodContext.getLocale(),
methodContext.getLoader());
} catch (MiniLangException e) {
messages.add("Error running SimpleMapProcessor in XML file \""
+ xmlResource + "\": " + e.toString());
}
}
- // run inlined map processor last so it can override the external map
processor
+ // run inline map processor last so it can override the external map
processor
if (inlineMapProcessor != null) {
inlineMapProcessor.exec(inMap, outMap, messages,
methodContext.getLocale(), methodContext.getLoader());
}
@@ -95,14 +103,34 @@ public class CallSimpleMapProcessor exte
@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: something more than the empty tag
- return "<call-simple-map-processor/>";
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("<call-map-processor ");
+ if (!this.processorName.isEmpty()) {
+
sb.append("processor-name=\"").append(this.processorName).append("\" ");
+ }
+ if (!this.xmlResource.isEmpty()) {
+ sb.append("xml-resource=\"").append(this.xmlResource).append("\"
");
+ }
+ if (!this.inMapFma.isEmpty()) {
+ sb.append("in-map-name=\"").append(this.inMapFma).append("\" ");
+ }
+ if (!this.outMapFma.isEmpty()) {
+ sb.append("out-map-name=\"").append(this.outMapFma).append("\" ");
+ }
+ if (!"error_list".equals(errorListFma.toString())) {
+ sb.append("error-list-name=\"").append(errorListFma).append("\" ");
+ }
+ sb.append("/>");
+ return sb.toString();
}
public static final class CallSimpleMapProcessorFactory implements
Factory<CallSimpleMapProcessor> {