Author: adrianc
Date: Thu May 3 14:59:56 2012 New Revision: 1333491 URL: http://svn.apache.org/viewvc?rev=1333491&view=rev Log: Overhauled Mini-language <call-class-method> <call-object-method> <field> and <string> elements. Modified: ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangUtil.java ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/FieldObject.java ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodObject.java ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/StringObject.java ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallBsh.java ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallClassMethod.java ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallObjectMethod.java ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CreateObject.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=1333491&r1=1333490&r2=1333491&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original) +++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Thu May 3 14:59:56 2012 @@ -117,45 +117,44 @@ under the License. <xs:element name="field"> <xs:annotation> <xs:documentation> - Used to specify a field to be passed as an argument to the method call. - The field can be in a map in the environment or if no map-name is specified - then the field will come directly from the environment. - - With the "." Syntax, the map-name is typically no longer necessary because - you can do map-name.field-name in the field-name attribute, but those are still there for legacy purposes. + Specifies an environment field to be passed as an argument to a method call. </xs:documentation> </xs:annotation> <xs:complexType> - <xs:attributeGroup ref="attlist.field"/> + <xs:attribute type="xs:string" name="field" use="required"> + <xs:annotation> + <xs:documentation> + The name of the environment field to use. + <br/><br/> + Required. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="type"> + <xs:annotation> + <xs:documentation> + The Java class of the argument. Defaults to java.lang.String. + If this is a method call or object creation and the type in the method signature being called is for a parent class or interface, + then it should be the type in that parent class or interface and not the type of the object being + passed in. + <br/><br/> + Optional. Attribute type: constant. + </xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> - <xs:attributeGroup name="attlist.field"> - <xs:attribute type="xs:string" name="field" use="required"> - <xs:annotation><xs:documentation>Name of the field to put value in.</xs:documentation></xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="type"> - <xs:annotation> - <xs:documentation> - Type of the value put in the field. - If this is a method call or object creation and the type in the method signature being called is for a parent class or interface, - then it should be the type in that parent class or interface and not the type of the object being passed in. - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:attributeGroup> <xs:element name="string"> <xs:annotation> <xs:documentation> - String of type java.lang.String. Inserts the value of the inline string where specified. + Specifies a java.lang.String to be passed as an argument to a method call. + The String can be contained in the value attribute or in the element body. </xs:documentation> </xs:annotation> - <xs:complexType mixed="true"> - <xs:attributeGroup ref="attlist.string"/> + <xs:complexType> + <xs:attribute type="xs:string" name="value" /> </xs:complexType> </xs:element> - <xs:attributeGroup name="attlist.string"> - <xs:attribute type="xs:string" name="value"/> - </xs:attributeGroup> <xs:element name="simple-methods"> <xs:annotation> <xs:documentation> @@ -164,13 +163,7 @@ under the License. </xs:annotation> <xs:complexType> <xs:sequence> - <xs:element maxOccurs="unbounded" ref="simple-method"> - <xs:annotation> - <xs:documentation> - Opening tag of a simple-method definition. - </xs:documentation> - </xs:annotation> - </xs:element> + <xs:element maxOccurs="unbounded" ref="simple-method"/> </xs:sequence> </xs:complexType> </xs:element> @@ -885,10 +878,10 @@ under the License. <xs:element name="call-bsh" substitutionGroup="CallOperations"> <xs:annotation> <xs:documentation> - Executes a BSH script. The script can be contained in a Java resource, or a short - script can be included in the element body. + Executes a BSH script. Deprecated - replace with <script>. <br/><br/> - Deprecated - replace with <script>. + The script can be contained in a Java resource, or a short + script can be included in the element body. </xs:documentation> </xs:annotation> <xs:complexType mixed="true"> @@ -967,110 +960,78 @@ under the License. <xs:element name="call-object-method" substitutionGroup="CallOperations"> <xs:annotation> <xs:documentation> - Calls a method on an existing object that exists in a field in the environment or in a map in the environment. - + Calls a method on an existing Java object. Deprecated - replace with <script>. + <br/><br/> The string and field sub-elements are passed to the method as arguments in the order they are specified. - If the sub-elements do not match the method arguments an error will be returned. - - The return value will be put in the named field if an value is returned and - if a field and optionally a map name are specified. + If the method returns a value, the value will be put in the named field. </xs:documentation> </xs:annotation> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> - <xs:element ref="string"> - <xs:annotation> - <xs:documentation> - Used to specify an inline String argument to the method call. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element ref="field"/> + <xs:element ref="string" /> + <xs:element ref="field" /> </xs:choice> - <xs:attributeGroup ref="attlist.call-object-method"/> + <xs:attribute type="xs:string" name="obj-field" use="required"> + <xs:annotation> + <xs:documentation> + The name of the field the object is in that has the method to be called. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="method-name" use="required"> + <xs:annotation> + <xs:documentation> + The name of the method to call on the given object. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="ret-field"> + <xs:annotation> + <xs:documentation> + The name of the field to put the result in. + If not specified any return value will be ignored. + </xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> - <xs:attributeGroup name="attlist.call-object-method"> - <xs:attribute type="xs:string" name="obj-field" use="required"> - <xs:annotation> - <xs:documentation> - The name of the field the object is in that has the method to be called. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="method-name" use="required"> - <xs:annotation> - <xs:documentation> - The name of the method to call on the given object. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="ret-field"> - <xs:annotation> - <xs:documentation> - The name of the field to put the result in. - If not specified any return value will be ignored. - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:attributeGroup> <xs:element name="call-class-method" substitutionGroup="CallOperations"> <xs:annotation> <xs:documentation> - Calls a static method on a class. - + Calls a static method on a Java class. Deprecated - replace with <script>. + <br/><br/> The string and field sub-elements are passed to the method as arguments in the order they are specified. - If the sub-elements do not match the method arguments an error will be returned. - - The return value will be put in the named field if an value is returned and if a - field and optionally a map name are specified. + If the method returns a value, the value will be put in the named field. </xs:documentation> </xs:annotation> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> - <xs:element ref="string"> - <xs:annotation> - <xs:documentation> - Used to specify an inline String argument to the method call. - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element ref="field"> - <xs:annotation> - <xs:documentation> - Used to specify a field to be passed as an argument to the constructor method. - The field can be in a map in the environment or if no map-name is specified then - the field will come directly from the environment. - </xs:documentation> - </xs:annotation> - </xs:element> + <xs:element ref="string"/> + <xs:element ref="field"/> </xs:choice> - <xs:attributeGroup ref="attlist.call-class-method"/> + <xs:attribute type="xs:string" name="class-name" use="required"> + <xs:annotation> + <xs:documentation> + The name of the class to call the static method on. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="method-name" use="required"> + <xs:annotation> + <xs:documentation> + The name of the static method to call on the given class. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="ret-field"> + <xs:annotation> + <xs:documentation> + The name of the field to put the result in. If not specified any return value will be ignored. + </xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> - <xs:attributeGroup name="attlist.call-class-method"> - <xs:attribute type="xs:string" name="class-name" use="required"> - <xs:annotation> - <xs:documentation> - The name of the class to call the static method on. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="method-name" use="required"> - <xs:annotation> - <xs:documentation> - The name of the static method to call on the given class. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="ret-field"> - <xs:annotation> - <xs:documentation> - The name of the field to put the result in. If not specified any return value will be ignored. - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:attributeGroup> <xs:element name="create-object" substitutionGroup="CallOperations"> <xs:annotation> <xs:documentation> Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangUtil.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangUtil.java?rev=1333491&r1=1333490&r2=1333491&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangUtil.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangUtil.java Thu May 3 14:59:56 2012 @@ -21,9 +21,11 @@ package org.ofbiz.minilang; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Method; import java.net.URL; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import javax.xml.transform.Transformer; @@ -35,7 +37,11 @@ import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.ScriptUtil; import org.ofbiz.base.util.UtilProperties; import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.collections.FlexibleMapAccessor; import org.ofbiz.base.util.string.FlexibleStringExpander; +import org.ofbiz.minilang.method.MethodContext; +import org.ofbiz.minilang.method.MethodObject; +import org.ofbiz.minilang.method.MethodOperation; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; @@ -72,6 +78,36 @@ public final class MiniLangUtil { return "true".equals(UtilProperties.getPropertyValue("minilang.properties", "autocorrect")); } + public static void callMethod(MethodOperation operation, MethodContext methodContext, List<MethodObject<?>> parameters, Class<?> methodClass, Object methodObject, String methodName, FlexibleMapAccessor<Object> retFieldFma) throws MiniLangRuntimeException { + Object[] args = null; + Class<?>[] parameterTypes = null; + if (parameters != null) { + args = new Object[parameters.size()]; + parameterTypes = new Class<?>[parameters.size()]; + int i = 0; + for (MethodObject<?> methodObjectDef : parameters) { + args[i] = methodObjectDef.getObject(methodContext); + Class<?> typeClass = null; + try { + typeClass = methodObjectDef.getTypeClass(methodContext); + } catch (ClassNotFoundException e) { + throw new MiniLangRuntimeException(e, operation); + } + parameterTypes[i] = typeClass; + i++; + } + } + try { + Method method = methodClass.getMethod(methodName, parameterTypes); + Object retValue = method.invoke(methodObject, args); + if (!retFieldFma.isEmpty()) { + retFieldFma.put(methodContext.getEnvMap(), retValue); + } + } catch (Exception e) { + throw new MiniLangRuntimeException(e, operation); + } + } + public static void flagDocumentAsCorrected(Element element) { Document doc = element.getOwnerDocument(); if (doc != null) { Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/FieldObject.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/FieldObject.java?rev=1333491&r1=1333490&r2=1333491&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/FieldObject.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/FieldObject.java Thu May 3 14:59:56 2012 @@ -18,72 +18,44 @@ *******************************************************************************/ package org.ofbiz.minilang.method; -import java.util.Map; - -import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.ObjectType; import org.ofbiz.base.util.UtilGenerics; -import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.collections.FlexibleMapAccessor; import org.ofbiz.minilang.SimpleMethod; import org.w3c.dom.Element; /** - * A type of MethodObject that represents an Object value in a certain location + * Specifies an environment field to be passed as an argument to a method call. */ -public class FieldObject<T> extends MethodObject<T> { - - public static final String module = FieldObject.class.getName(); +public final class FieldObject<T> extends MethodObject<T> { - ContextAccessor<T> fieldAcsr; - ContextAccessor<Map<String, ? extends Object>> mapAcsr; - String type; + private final FlexibleMapAccessor<Object> fieldFma; + private final String type; public FieldObject(Element element, SimpleMethod simpleMethod) { super(element, simpleMethod); - // the schema for this element now just has the "field" attribute, though the old "field-name" and "map-name" pair is still supported - fieldAcsr = new ContextAccessor<T>(element.getAttribute("field"), element.getAttribute("field-name")); - mapAcsr = new ContextAccessor<Map<String, ? extends Object>>(element.getAttribute("map-name")); - type = element.getAttribute("type"); - if (UtilValidate.isEmpty(type)) { - type = "String"; + this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field")); + String typeAttribute = element.getAttribute("type"); + if (typeAttribute.isEmpty()) { + this.type = "java.lang.String"; + } else { + this.type = typeAttribute; } } + @SuppressWarnings("unchecked") @Override public T getObject(MethodContext methodContext) { - T fieldVal = null; - if (!mapAcsr.isEmpty()) { - Map<String, ? extends Object> fromMap = mapAcsr.get(methodContext); - if (fromMap == null) { - Debug.logWarning("Map not found with name " + mapAcsr + ", not getting Object value, returning null.", module); - return null; - } - fieldVal = fieldAcsr.get(fromMap, methodContext); - } else { - // no map name, try the env - fieldVal = fieldAcsr.get(methodContext); - } - if (fieldVal == null) { - if (Debug.infoOn()) - Debug.logInfo("Field value not found with name " + fieldAcsr + " in Map with name " + mapAcsr + ", not getting Object value, returning null.", module); - return null; - } - return fieldVal; + return (T) this.fieldFma.get(methodContext.getEnvMap()); } @Override - public Class<T> getTypeClass(ClassLoader loader) { - try { - return UtilGenerics.cast(ObjectType.loadClass(type, loader)); - } catch (ClassNotFoundException e) { - Debug.logError(e, "Could not find class for type: " + type, module); - return null; - } + public Class<T> getTypeClass(MethodContext methodContext) throws ClassNotFoundException { + return UtilGenerics.cast(ObjectType.loadClass(this.type, methodContext.getLoader())); } - /** Get the name for the type of the object */ @Override public String getTypeName() { - return type; + return this.type; } } Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodObject.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodObject.java?rev=1333491&r1=1333490&r2=1333491&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodObject.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodObject.java Thu May 3 14:59:56 2012 @@ -18,25 +18,24 @@ *******************************************************************************/ package org.ofbiz.minilang.method; +import org.ofbiz.minilang.MiniLangElement; import org.ofbiz.minilang.SimpleMethod; import org.w3c.dom.Element; /** * A single Object value to be used as a parameter or whatever */ -public abstract class MethodObject<T> { - - protected SimpleMethod simpleMethod; +public abstract class MethodObject<T> extends MiniLangElement { public MethodObject(Element element, SimpleMethod simpleMethod) { - this.simpleMethod = simpleMethod; + super(element, simpleMethod); } /** Get the Object value */ public abstract T getObject(MethodContext methodContext); /** Get the Class for the type of the object */ - public abstract Class<T> getTypeClass(ClassLoader loader); + public abstract Class<T> getTypeClass(MethodContext methodContext) throws ClassNotFoundException; /** Get the name for the type of the object */ public abstract String getTypeName(); Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/StringObject.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/StringObject.java?rev=1333491&r1=1333490&r2=1333491&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/StringObject.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/StringObject.java Thu May 3 14:59:56 2012 @@ -18,44 +18,34 @@ *******************************************************************************/ package org.ofbiz.minilang.method; -import org.ofbiz.base.util.UtilValidate; import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.string.FlexibleStringExpander; import org.ofbiz.minilang.SimpleMethod; import org.w3c.dom.Element; /** - * A type of MethodObject that represents a String constant value to be used as an Object + * Specifies a <code>java.lang.String</code> to be passed as an argument to a method call. */ -public class StringObject extends MethodObject<String> { +public final class StringObject extends MethodObject<String> { - String cdataValue; - String value; + private final FlexibleStringExpander cdataValueFse; + private final FlexibleStringExpander valueFse; public StringObject(Element element, SimpleMethod simpleMethod) { super(element, simpleMethod); - value = element.getAttribute("value"); - cdataValue = UtilXml.elementValue(element); + this.cdataValueFse = FlexibleStringExpander.getInstance(UtilXml.elementValue(element)); + this.valueFse = FlexibleStringExpander.getInstance(element.getAttribute("value")); } @Override public String getObject(MethodContext methodContext) { - String value = methodContext.expandString(this.value); - String cdataValue = methodContext.expandString(this.cdataValue); - boolean valueExists = UtilValidate.isNotEmpty(value); - boolean cdataValueExists = UtilValidate.isNotEmpty(cdataValue); - if (valueExists && cdataValueExists) { - return value + cdataValue; - } else { - if (valueExists) { - return value; - } else { - return cdataValue; - } - } + String value = this.valueFse.expandString(methodContext.getEnvMap()); + String cdataValue = this.cdataValueFse.expandString(methodContext.getEnvMap()); + return value.concat(cdataValue); } @Override - public Class<String> getTypeClass(ClassLoader loader) { + public Class<String> getTypeClass(MethodContext methodContext) throws ClassNotFoundException { return java.lang.String.class; } Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallBsh.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallBsh.java?rev=1333491&r1=1333490&r2=1333491&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallBsh.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallBsh.java Thu May 3 14:59:56 2012 @@ -131,7 +131,7 @@ public final class CallBsh extends Metho methodContext.putAllEnv(UtilGenerics.<String, Object> checkMap(inlineResult)); } } catch (EvalError e) { - Debug.logError(e, "BeanShell execution caused an error", module); + Debug.logWarning(e, "BeanShell execution caused an error", module); addErrorMessage(methodContext, "BeanShell execution caused an error: " + e.getMessage()); } // always return true, error messages just go on the error list Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallClassMethod.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallClassMethod.java?rev=1333491&r1=1333490&r2=1333491&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallClassMethod.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallClassMethod.java Thu May 3 14:59:56 2012 @@ -19,17 +19,18 @@ package org.ofbiz.minilang.method.callops; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Map; -import javolution.util.FastList; - -import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.ObjectType; 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.MiniLangUtil; +import org.ofbiz.minilang.MiniLangValidate; import org.ofbiz.minilang.SimpleMethod; -import org.ofbiz.minilang.method.ContextAccessor; import org.ofbiz.minilang.method.FieldObject; import org.ofbiz.minilang.method.MethodContext; import org.ofbiz.minilang.method.MethodObject; @@ -38,74 +39,84 @@ import org.ofbiz.minilang.method.StringO import org.w3c.dom.Element; /** - * Calls a Java class method using the given fields as parameters + * Calls a static method on a Java class. */ -public class CallClassMethod extends MethodOperation { +public final class CallClassMethod extends MethodOperation { public static final String module = CallClassMethod.class.getName(); - String className; - String methodName; - /** A list of MethodObject objects to use as the method call parameters */ - List<MethodObject<?>> parameters; - ContextAccessor<Object> retFieldAcsr; - ContextAccessor<Map<String, Object>> retMapAcsr; + private final String className; + private final Class<?> methodClass; + private final String methodName; + private final List<MethodObject<?>> parameters; + private final FlexibleMapAccessor<Object> retFieldFma; public CallClassMethod(Element element, SimpleMethod simpleMethod) throws MiniLangException { super(element, simpleMethod); - className = element.getAttribute("class-name"); - methodName = element.getAttribute("method-name"); - // the schema for this element now just has the "ret-field" attribute, though the - // old "ret-field-name" and "ret-map-name" pair is still supported - retFieldAcsr = new ContextAccessor<Object>(element.getAttribute("ret-field"), element.getAttribute("ret-field-name")); - retMapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("ret-map-name")); + if (MiniLangValidate.validationOn()) { + MiniLangValidate.handleError("<call-class-method> element is deprecated (use <script>)", simpleMethod, element); + MiniLangValidate.attributeNames(simpleMethod, element, "class-name", "method-name", "ret-field"); + MiniLangValidate.constantAttributes(simpleMethod, element, "class-name", "method-name"); + MiniLangValidate.requiredAttributes(simpleMethod, element, "class-name", "method-name"); + MiniLangValidate.childElements(simpleMethod, element, "string", "field"); + } + this.className = element.getAttribute("class-name"); + Class<?> methodClass = null; + try { + methodClass = ObjectType.loadClass(this.className); + } catch (ClassNotFoundException e) { + MiniLangValidate.handleError("Class not found with name " + this.className, simpleMethod, element); + } + this.methodClass = methodClass; + this.methodName = element.getAttribute("method-name"); + this.retFieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("ret-field")); List<? extends Element> parameterElements = UtilXml.childElementList(element); if (parameterElements.size() > 0) { - parameters = FastList.newInstance(); + ArrayList<MethodObject<?>> parameterList = new ArrayList<MethodObject<?>>(parameterElements.size()); for (Element parameterElement : parameterElements) { - MethodObject<?> methodObject = null; if ("string".equals(parameterElement.getNodeName())) { - methodObject = new StringObject(parameterElement, simpleMethod); + parameterList.add(new StringObject(parameterElement, simpleMethod)); } else if ("field".equals(parameterElement.getNodeName())) { - methodObject = new FieldObject<Object>(parameterElement, simpleMethod); - } else { - // whoops, invalid tag here, print warning - Debug.logWarning("Found an unsupported tag under the call-object-method tag: " + parameterElement.getNodeName() + "; ignoring", module); - } - if (methodObject != null) { - parameters.add(methodObject); + parameterList.add(new FieldObject<Object>(parameterElement, simpleMethod)); } } + parameterList.trimToSize(); + this.parameters = Collections.unmodifiableList(parameterList); + } else { + this.parameters = null; } } @Override public boolean exec(MethodContext methodContext) throws MiniLangException { - String className = methodContext.expandString(this.className); - String methodName = methodContext.expandString(this.methodName); - Class<?> methodClass = null; - try { - methodClass = ObjectType.loadClass(className, methodContext.getLoader()); - } catch (ClassNotFoundException e) { - Debug.logError(e, "Class to create not found with name " + className + " in create-object operation", module); - - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [Class to create not found with name " + className + ": " + e.toString() + "]"; - methodContext.setErrorReturn(errMsg, simpleMethod); - return false; - } - return CallObjectMethod.callMethod(simpleMethod, methodContext, parameters, methodClass, null, methodName, retFieldAcsr, retMapAcsr); + MiniLangUtil.callMethod(this, methodContext, parameters, methodClass, null, methodName, retFieldFma); + return true; } @Override public String expandedString(MethodContext methodContext) { - // TODO: something more than a stub/dummy - return this.rawString(); + return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap()); } @Override public String rawString() { - // TODO: something more than the empty tag - return "<call-class-method/>"; + return toString(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("<call-class-method "); + if (!this.className.isEmpty()) { + sb.append("class-name=\"").append(this.className).append("\" "); + } + if (!this.methodName.isEmpty()) { + sb.append("method-name=\"").append(this.methodName).append("\" "); + } + if (!this.retFieldFma.isEmpty()) { + sb.append("ret-field=\"").append(this.retFieldFma).append("\" "); + } + sb.append("/>"); + return sb.toString(); } public static final class CallClassMethodFactory implements Factory<CallClassMethod> { Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallObjectMethod.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallObjectMethod.java?rev=1333491&r1=1333490&r2=1333491&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallObjectMethod.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CallObjectMethod.java Thu May 3 14:59:56 2012 @@ -18,19 +18,18 @@ *******************************************************************************/ package org.ofbiz.minilang.method.callops; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Map; -import javolution.util.FastList; -import javolution.util.FastMap; - -import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.collections.FlexibleMapAccessor; +import org.ofbiz.base.util.string.FlexibleStringExpander; import org.ofbiz.minilang.MiniLangException; +import org.ofbiz.minilang.MiniLangRuntimeException; +import org.ofbiz.minilang.MiniLangUtil; +import org.ofbiz.minilang.MiniLangValidate; import org.ofbiz.minilang.SimpleMethod; -import org.ofbiz.minilang.method.ContextAccessor; import org.ofbiz.minilang.method.FieldObject; import org.ofbiz.minilang.method.MethodContext; import org.ofbiz.minilang.method.MethodObject; @@ -41,155 +40,78 @@ import org.w3c.dom.Element; /** * Calls a Java object method using the given fields as parameters */ -public class CallObjectMethod extends MethodOperation { +public final class CallObjectMethod extends MethodOperation { public static final String module = CallClassMethod.class.getName(); - public static boolean callMethod(SimpleMethod simpleMethod, MethodContext methodContext, List<MethodObject<?>> parameters, Class<?> methodClass, Object methodObject, String methodName, ContextAccessor<Object> retFieldAcsr, ContextAccessor<Map<String, Object>> retMapAcsr) { - Object[] args = null; - Class<?>[] parameterTypes = null; - if (parameters != null) { - args = new Object[parameters.size()]; - parameterTypes = new Class<?>[parameters.size()]; - int i = 0; - for (MethodObject<?> methodObjectDef : parameters) { - args[i] = methodObjectDef.getObject(methodContext); - Class<?> typeClass = methodObjectDef.getTypeClass(methodContext.getLoader()); - if (typeClass == null) { - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [Parameter type not found with name " + methodObjectDef.getTypeName() + "]"; - Debug.logError(errMsg, module); - methodContext.setErrorReturn(errMsg, simpleMethod); - return false; - } - parameterTypes[i] = typeClass; - i++; - } - } - try { - Method method = methodClass.getMethod(methodName, parameterTypes); - try { - Object retValue = method.invoke(methodObject, args); - // if retFieldAcsr is empty, ignore return value - if (!retFieldAcsr.isEmpty()) { - if (!retMapAcsr.isEmpty()) { - Map<String, Object> retMap = retMapAcsr.get(methodContext); - if (retMap == null) { - retMap = FastMap.newInstance(); - retMapAcsr.put(methodContext, retMap); - } - retFieldAcsr.put(retMap, retValue, methodContext); - } else { - // no map name, use the env - retFieldAcsr.put(methodContext, retValue); - } - } - } catch (IllegalAccessException e) { - Debug.logError(e, "Could not access method in call method operation", module); - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [Could not access method to execute named " + methodName + ": " + e.toString() + "]"; - methodContext.setErrorReturn(errMsg, simpleMethod); - return false; - } catch (IllegalArgumentException e) { - Debug.logError(e, "Illegal argument calling method in call method operation", module); - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [Illegal argument calling method to execute named " + methodName + ": " + e.toString() + "]"; - methodContext.setErrorReturn(errMsg, simpleMethod); - return false; - } catch (InvocationTargetException e) { - Debug.logError(e.getTargetException(), "Method in call method operation threw an exception", module); - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [Method to execute named " + methodName + " threw an exception: " + e.getTargetException() + "]"; - methodContext.setErrorReturn(errMsg, simpleMethod); - return false; - } - } catch (NoSuchMethodException e) { - Debug.logError(e, "Could not find method to execute in simple-method call method operation", module); - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [Could not find method to execute named " + methodName + ": " + e.toString() + "]"; - methodContext.setErrorReturn(errMsg, simpleMethod); - return false; - } catch (SecurityException e) { - Debug.logError(e, "Security exception finding method to execute in simple-method call method operation", module); - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [Security exception finding method to execute named " + methodName + ": " + e.toString() + "]"; - methodContext.setErrorReturn(errMsg, simpleMethod); - return false; - } - return true; - } - - String methodName; - ContextAccessor<Object> objFieldAcsr; - ContextAccessor<Map<String, ? extends Object>> objMapAcsr; - /** A list of MethodObject objects to use as the method call parameters */ - List<MethodObject<?>> parameters; - ContextAccessor<Object> retFieldAcsr; - ContextAccessor<Map<String, Object>> retMapAcsr; + private final String methodName; + private final FlexibleMapAccessor<Object> objFieldFma; + private final List<MethodObject<?>> parameters; + private final FlexibleMapAccessor<Object> retFieldFma; public CallObjectMethod(Element element, SimpleMethod simpleMethod) throws MiniLangException { super(element, simpleMethod); - // the schema for this element now just has the "obj-field" attribute, though the - // old "obj-field-name" and "obj-map-name" pair is still supported - objFieldAcsr = new ContextAccessor<Object>(element.getAttribute("obj-field"), element.getAttribute("obj-field-name")); - objMapAcsr = new ContextAccessor<Map<String, ? extends Object>>(element.getAttribute("obj-map-name")); - methodName = element.getAttribute("method-name"); - // the schema for this element now just has the "ret-field" attribute, though the - // old "ret-field-name" and "ret-map-name" pair is still supported - retFieldAcsr = new ContextAccessor<Object>(element.getAttribute("ret-field"), element.getAttribute("ret-field-name")); - retMapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("ret-map-name")); + if (MiniLangValidate.validationOn()) { + MiniLangValidate.handleError("<call-object-method> element is deprecated (use <script>)", simpleMethod, element); + MiniLangValidate.attributeNames(simpleMethod, element, "obj-field", "method-name", "ret-field"); + MiniLangValidate.constantAttributes(simpleMethod, element, "method-name"); + MiniLangValidate.requiredAttributes(simpleMethod, element, "obj-field", "method-name"); + MiniLangValidate.childElements(simpleMethod, element, "string", "field"); + } + this.methodName = element.getAttribute("method-name"); + this.objFieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("obj-field")); + this.retFieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("ret-field")); List<? extends Element> parameterElements = UtilXml.childElementList(element); if (parameterElements.size() > 0) { - parameters = FastList.newInstance(); + ArrayList<MethodObject<?>> parameterList = new ArrayList<MethodObject<?>>(parameterElements.size()); for (Element parameterElement : parameterElements) { - MethodObject<?> methodObject = null; if ("string".equals(parameterElement.getNodeName())) { - methodObject = new StringObject(parameterElement, simpleMethod); + parameterList.add(new StringObject(parameterElement, simpleMethod)); } else if ("field".equals(parameterElement.getNodeName())) { - methodObject = new FieldObject<Object>(parameterElement, simpleMethod); - } else { - // whoops, invalid tag here, print warning - Debug.logWarning("Found an unsupported tag under the call-object-method tag: " + parameterElement.getNodeName() + "; ignoring", module); - } - if (methodObject != null) { - parameters.add(methodObject); + parameterList.add(new FieldObject<Object>(parameterElement, simpleMethod)); } } + parameterList.trimToSize(); + this.parameters = Collections.unmodifiableList(parameterList); + } else { + this.parameters = null; } } @Override public boolean exec(MethodContext methodContext) throws MiniLangException { - String methodName = methodContext.expandString(this.methodName); - Object methodObject = null; - if (!objMapAcsr.isEmpty()) { - Map<String, ? extends Object> fromMap = objMapAcsr.get(methodContext); - if (fromMap == null) { - Debug.logWarning("Map not found with name " + objMapAcsr + ", which should contain the object to execute a method on; not executing method, rerturning error.", module); - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [Map not found with name " + objMapAcsr + ", which should contain the object to execute a method on]"; - methodContext.setErrorReturn(errMsg, simpleMethod); - return false; - } - methodObject = objFieldAcsr.get(fromMap, methodContext); - } else { - // no map name, try the env - methodObject = objFieldAcsr.get(methodContext); - } + Object methodObject = this.objFieldFma.get(methodContext.getEnvMap()); if (methodObject == null) { - if (Debug.infoOn()) - Debug.logInfo("Object not found to execute method on with name " + objFieldAcsr + " in Map with name " + objMapAcsr + ", not executing method, rerturning error.", module); - String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [Object not found to execute method on with name " + objFieldAcsr + " in Map with name " + objMapAcsr + "]"; - methodContext.setErrorReturn(errMsg, simpleMethod); - return false; + throw new MiniLangRuntimeException("Object not found: " + this.objFieldFma, this); } - Class<?> methodClass = methodObject.getClass(); - return CallObjectMethod.callMethod(simpleMethod, methodContext, parameters, methodClass, methodObject, methodName, retFieldAcsr, retMapAcsr); + MiniLangUtil.callMethod(this, methodContext, parameters, methodObject.getClass(), methodObject, methodName, retFieldFma); + return true; } @Override public String expandedString(MethodContext methodContext) { - // TODO: something more than a stub/dummy - return this.rawString(); + return FlexibleStringExpander.expandString(toString(), methodContext.getEnvMap()); } @Override public String rawString() { - // TODO: something more than the empty tag - return "<call-object-method/>"; + return toString(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("<call-class-method "); + if (!this.objFieldFma.isEmpty()) { + sb.append("obj-field=\"").append(this.objFieldFma).append("\" "); + } + if (!this.methodName.isEmpty()) { + sb.append("method-name=\"").append(this.methodName).append("\" "); + } + if (!this.retFieldFma.isEmpty()) { + sb.append("ret-field=\"").append(this.retFieldFma).append("\" "); + } + sb.append("/>"); + return sb.toString(); } public static final class CallObjectMethodFactory implements Factory<CallObjectMethod> { Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CreateObject.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CreateObject.java?rev=1333491&r1=1333490&r2=1333491&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CreateObject.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/callops/CreateObject.java Thu May 3 14:59:56 2012 @@ -99,8 +99,10 @@ public class CreateObject extends Method int i = 0; for (MethodObject<?> methodObjectDef : parameters) { args[i] = methodObjectDef.getObject(methodContext); - Class<?> typeClass = methodObjectDef.getTypeClass(methodContext.getLoader()); - if (typeClass == null) { + Class<?> typeClass = null; + try { + typeClass = methodObjectDef.getTypeClass(methodContext); + } catch (ClassNotFoundException e) { String errMsg = "ERROR: Could not complete the " + simpleMethod.getShortDescription() + " process [Parameter type not found with name " + methodObjectDef.getTypeName() + "]"; Debug.logError(errMsg, module); methodContext.setErrorReturn(errMsg, simpleMethod); |
Free forum by Nabble | Edit this page |