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> { |
Free forum by Nabble | Edit this page |