|
Author: adrianc
Date: Thu Jun 14 17:00:53 2012 New Revision: 1350337 URL: http://svn.apache.org/viewvc?rev=1350337&view=rev Log: Overhauled Mini-language <property-to-field> element. The overhaul includes: removing unnecessary object creation, make the class thread-safe, add syntax validation, and misc code cleanups. Modified: ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/otherops/PropertyToField.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=1350337&r1=1350336&r2=1350337&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original) +++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Thu Jun 14 17:00:53 2012 @@ -4207,58 +4207,71 @@ under the License. <xs:element name="property-to-field" substitutionGroup="OtherOperations"> <xs:annotation> <xs:documentation> - The property-to-field tag puts the inlined string value in the specified field. + Assigns a property value to a field. </xs:documentation> </xs:annotation> <xs:complexType> - <xs:attributeGroup ref="attlist.property-to-field"/> + <xs:attribute ref="field" /> + <xs:attribute type="xs:string" name="resource" use="required"> + <xs:annotation> + <xs:documentation> + The name of a properties resource. Can be a file on the classpath or + a resource defined in the SystemProperty entity. + <br/><br/> + Required. Attribute types: constant, ${expression}. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="property" use="required"> + <xs:annotation> + <xs:documentation> + The property whose value will be put in the field. + <br/><br/> + Required. Attribute types: constant, ${expression}. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="default"> + <xs:annotation> + <xs:documentation> + The default value to use if the specified property value is null or empty. + <br/><br/> + Optional. Attribute types: constant, ${expression}. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="booleanConst" name="no-locale"> + <xs:annotation> + <xs:documentation> + Suppress property value localization. The user's/system locale will be ignored + when retriving the property value. + Defaults to "false". + <br/><br/> + Optional. Attribute type: constant. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="arg-list"> + <xs:annotation> + <xs:documentation> + An argument list to be used with a formatting string. + The argument list is applied to the property value. + Does nothing if the argument list is not found. + See the java.text.MessageFormat class for more information. + <br/><br/> + Optional. Attribute type: expression. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" name="arg-list-name"> + <xs:annotation> + <xs:documentation> + Deprecated - use the arg-list attribute. + </xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> - <xs:attributeGroup name="attlist.property-to-field"> - <xs:attribute type="xs:string" name="resource" use="required"> - <xs:annotation> - <xs:documentation> - Name of a properties file on the classpath. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="property" use="required"> - <xs:annotation> - <xs:documentation> - The property whose value will be put in the field. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="field" use="required"> - <xs:annotation> - <xs:documentation> - The name (key) of the map field to use. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute type="xs:string" name="default"> - <xs:annotation> - <xs:documentation> - The default value to use if the specified property is empty. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute name="no-locale" default="false"> - <xs:annotation> - <xs:documentation> - If sets to true don't use the default locale variable. - 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="arg-list-name"/> - </xs:attributeGroup> <xs:element name="set-current-user-login" substitutionGroup="OtherOperations"> <xs:annotation> <xs:documentation> @@ -4299,6 +4312,8 @@ under the License. <xs:documentation> Rounding mode for BigDecimal calculation, primarily for divide operation. Defaults to "HalfEven". + <br/><br/> + Optional. Attribute types: constant, ${expression}. </xs:documentation> </xs:annotation> <xs:simpleType> @@ -4373,6 +4388,8 @@ under the License. <xs:annotation> <xs:documentation> Initial scale to use for the internal BigDecimal. Defaults to "2". + <br/><br/> + Optional. Attribute types: constant, ${expression}. </xs:documentation> </xs:annotation> </xs:attribute> @@ -4380,6 +4397,8 @@ under the License. <xs:annotation> <xs:documentation> Decimal format to use for conversion to string. + <br/><br/> + Optional. Attribute types: constant, ${expression}. </xs:documentation> </xs:annotation> </xs:attribute> @@ -4387,6 +4406,8 @@ under the License. <xs:annotation> <xs:documentation> Data type of the calculation result. Defaults to "BigDecimal". + <br/><br/> + Optional. Attribute types: constant, ${expression}. </xs:documentation> </xs:annotation> <xs:simpleType> @@ -4432,7 +4453,7 @@ under the License. <xs:enumeration value="negative"> <xs:annotation> <xs:documentation> - Negates the value + Negates the value. </xs:documentation> </xs:annotation> </xs:enumeration> @@ -4460,6 +4481,8 @@ under the License. <xs:annotation> <xs:documentation> Literal or flexible string. + <br/><br/> + Required. Attribute types: constant, ${expression}. </xs:documentation> </xs:annotation> </xs:attribute> Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/otherops/PropertyToField.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/otherops/PropertyToField.java?rev=1350337&r1=1350336&r2=1350337&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/otherops/PropertyToField.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/otherops/PropertyToField.java Thu Jun 14 17:00:53 2012 @@ -20,103 +20,129 @@ package org.ofbiz.minilang.method.othero import java.text.MessageFormat; import java.util.List; -import java.util.Map; -import javolution.util.FastMap; - -import org.ofbiz.base.util.Debug; -import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.collections.FlexibleMapAccessor; +import org.ofbiz.base.util.string.FlexibleStringExpander; import org.ofbiz.entity.util.EntityUtilProperties; 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.MethodContext; import org.ofbiz.minilang.method.MethodOperation; import org.w3c.dom.Element; /** - * Copies an properties file property value to a field + * Implements the <property-to-field> element. */ -public class PropertyToField extends MethodOperation { +public final class PropertyToField extends MethodOperation { - public static final String module = PropertyToField.class.getName(); + // This method is needed only during the v1 to v2 transition + private static boolean autoCorrect(Element element) { + // Correct deprecated arg-list-name attribute + String listAttr = element.getAttribute("arg-list-name"); + if (listAttr.length() > 0) { + element.setAttribute("arg-list", listAttr); + element.removeAttribute("arg-list-name"); + return true; + } + return false; + } - ContextAccessor<List<? extends Object>> argListAcsr; - String defaultVal; - ContextAccessor<Object> fieldAcsr; - ContextAccessor<Map<String, Object>> mapAcsr; - boolean noLocale; - String property; - String resource; + private final FlexibleMapAccessor<List<? extends Object>> argListFma; + private final FlexibleStringExpander defaultFse; + private final FlexibleMapAccessor<Object> fieldFma; + private final boolean noLocale; + private final FlexibleStringExpander propertyFse; + private final FlexibleStringExpander resourceFse; public PropertyToField(Element element, SimpleMethod simpleMethod) throws MiniLangException { super(element, simpleMethod); - resource = element.getAttribute("resource"); - property = element.getAttribute("property"); - // the schema for this element now just has the "field" attribute, though the old "field-name" and "map-name" pair is still supported - this.fieldAcsr = new ContextAccessor<Object>(element.getAttribute("field"), element.getAttribute("field-name")); - this.mapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("map-name")); - defaultVal = element.getAttribute("default"); - // defaults to false, ie anything but true is false + if (MiniLangValidate.validationOn()) { + MiniLangValidate.deprecatedAttribute(simpleMethod, element, "arg-list-name", "replace with \"arg-list\""); + MiniLangValidate.attributeNames(simpleMethod, element, "field", "resource", "property", "arg-list", "default", "no-locale"); + MiniLangValidate.requiredAttributes(simpleMethod, element, "field", "resource", "property"); + MiniLangValidate.expressionAttributes(simpleMethod, element, "field", "arg-list"); + MiniLangValidate.noChildElements(simpleMethod, element); + } + boolean elementModified = autoCorrect(element); + if (elementModified && MiniLangUtil.autoCorrectOn()) { + MiniLangUtil.flagDocumentAsCorrected(element); + } + fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field")); + resourceFse = FlexibleStringExpander.getInstance(element.getAttribute("resource")); + propertyFse = FlexibleStringExpander.getInstance(element.getAttribute("property")); + argListFma = FlexibleMapAccessor.getInstance(element.getAttribute("arg-list")); + defaultFse = FlexibleStringExpander.getInstance(element.getAttribute("default")); noLocale = "true".equals(element.getAttribute("no-locale")); - argListAcsr = new ContextAccessor<List<? extends Object>>(element.getAttribute("arg-list-name")); } @Override public boolean exec(MethodContext methodContext) throws MiniLangException { - String resource = methodContext.expandString(this.resource); - String property = methodContext.expandString(this.property); + String resource = resourceFse.expandString(methodContext.getEnvMap()); + String property = propertyFse.expandString(methodContext.getEnvMap()); String value = null; if (noLocale) { value = EntityUtilProperties.getPropertyValue(resource, property, methodContext.getDelegator()); } else { value = EntityUtilProperties.getMessage(resource, property, methodContext.getLocale(), methodContext.getDelegator()); } - if (UtilValidate.isEmpty(value)) { - value = defaultVal; - } - // note that expanding the value string here will handle defaultValue and the string from - // the properties file; if we decide later that we don't want the string from the properties - // file to be expanded we should just expand the defaultValue at the beginning of this method. - value = methodContext.expandString(value); - if (!argListAcsr.isEmpty()) { - List<? extends Object> argList = argListAcsr.get(methodContext); - if (UtilValidate.isNotEmpty(argList)) { + value = FlexibleStringExpander.expandString(value, methodContext.getEnvMap()); + if (value.isEmpty()) { + value = defaultFse.expandString(methodContext.getEnvMap()); + } + List<? extends Object> argList = argListFma.get(methodContext.getEnvMap()); + if (argList != null) { + try { value = MessageFormat.format(value, argList.toArray()); + } catch (IllegalArgumentException e) { + throw new MiniLangRuntimeException("Exception thrown while formatting the property value: " + e.getMessage(), this); } } - if (!mapAcsr.isEmpty()) { - Map<String, Object> toMap = mapAcsr.get(methodContext); - if (toMap == null) { - if (Debug.infoOn()) - Debug.logInfo("Map not found with name " + mapAcsr + ", creating new map", module); - toMap = FastMap.newInstance(); - mapAcsr.put(methodContext, toMap); - } - fieldAcsr.put(toMap, value, methodContext); - } else { - fieldAcsr.put(methodContext, value); - } + fieldFma.put(methodContext.getEnvMap(), value); 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: add all attributes and other info - return "<property-to-field field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>"; + return toString(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("<property-to-field "); + sb.append("field=\"").append(this.fieldFma).append("\" "); + sb.append("resource=\"").append(this.resourceFse).append("\" "); + sb.append("property=\"").append(this.propertyFse).append("\" "); + if (!this.argListFma.isEmpty()) { + sb.append("arg-list=\"").append(this.argListFma).append("\" "); + } + if (!this.defaultFse.isEmpty()) { + sb.append("default=\"").append(this.defaultFse).append("\" "); + } + if (noLocale) { + sb.append("no-locale=\"true\" "); + } + sb.append("/>"); + return sb.toString(); } + /** + * A factory for the <property-to-field> element. + */ public static final class PropertyToFieldFactory implements Factory<PropertyToField> { + @Override public PropertyToField createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException { return new PropertyToField(element, simpleMethod); } + @Override public String getName() { return "property-to-field"; } |
| Free forum by Nabble | Edit this page |
