You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2012/06/13 08:04:49 UTC
svn commit: r1349646 [1/2] - in /ofbiz/trunk/framework/minilang: dtd/
src/META-INF/services/ src/org/ofbiz/minilang/method/envops/
Author: adrianc
Date: Wed Jun 13 06:04:49 2012
New Revision: 1349646
URL: http://svn.apache.org/viewvc?rev=1349646&view=rev
Log:
Overhauled Mini-language <order-map-list>, <set-calendar>, <string-append>, <string-to-list>, <to-string> elements. Added a format attribute to the <set> element - to be used for type conversions. Also removed deprecated StringToField class.
The overhaul includes: removing unnecessary object creation, make the class thread-safe, add syntax validation, and misc code cleanups.
Removed:
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/StringToField.java
Modified:
ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd
ofbiz/trunk/framework/minilang/src/META-INF/services/org.ofbiz.minilang.method.MethodOperation$Factory
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/OrderMapList.java
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetCalendar.java
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetOperation.java
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/StringAppend.java
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/StringToList.java
ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/ToString.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=1349646&r1=1349645&r2=1349646&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd (original)
+++ ofbiz/trunk/framework/minilang/dtd/simple-methods-v2.xsd Wed Jun 13 06:04:49 2012
@@ -1418,7 +1418,7 @@ under the License.
<xs:documentation>
Copies a map to another map. Does nothing if the source map does not exist.
If a target map is not specified, the source map is copied to the current
- envirnment (memory space).
+ environment (memory space).
</xs:documentation>
</xs:annotation>
<xs:complexType>
@@ -1501,18 +1501,27 @@ under the License.
</xs:complexType>
</xs:element>
<xs:element name="order-map-list" substitutionGroup="EnvOperations">
- <xs:annotation><xs:documentation>Sort a List containing Maps: order by fields names given in order-by sub-element.</xs:documentation>
+ <xs:annotation>
+ <xs:documentation>
+ Sorts a list of maps. Maps are sorted by the keys specified in the order-by sub-elements.
+ Does nothing if the list is not found.
+ </xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:sequence><xs:element maxOccurs="unbounded" ref="order-by"/></xs:sequence>
- <xs:attributeGroup ref="attlist.order-map-list"/>
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" ref="order-by" />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="list" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ Name of the field containing the list to be sorted.
+ <br/><br/>
+ Required. Attribute type: expression.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
</xs:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.order-map-list">
- <xs:attribute type="xs:string" name="list" use="required">
- <xs:annotation><xs:documentation>Name of the list to be sorted.</xs:documentation></xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
<xs:element name="set" substitutionGroup="EnvOperations">
<xs:annotation>
<xs:documentation>
@@ -1544,7 +1553,7 @@ under the License.
<xs:documentation>
A constant value, or a constant that includes an expression. The source of the assignment.
<br/><br/>
- Required if the from-field attribute is empty. Attribute type: constant+expr.
+ Required if the from attribute is empty. Attribute type: constant+expr.
Defaults to java.lang.String data type.
</xs:documentation>
</xs:annotation>
@@ -1559,7 +1568,7 @@ under the License.
<xs:attribute type="xs:string" name="default">
<xs:annotation>
<xs:documentation>
- A default value that is used when the from-field attribute evaluates to null or empty.
+ A default value that is used when the from attribute evaluates to null or empty.
<br/><br/>
Optional. Attribute types: constant, ${expression}.
</xs:documentation>
@@ -1574,10 +1583,19 @@ under the License.
</xs:documentation>
</xs:annotation>
</xs:attribute>
+ <xs:attribute type="xs:string" name="format">
+ <xs:annotation>
+ <xs:documentation>
+ Format to be used for object type conversion. Used when the type attribute is not empty.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
<xs:attribute name="set-if-null" type="booleanConst">
<xs:annotation>
<xs:documentation>
- Controls if the target field can be set to null when the from-field attribute evaluates to null.
+ Controls if the target field can be set to null when the from attribute evaluates to null.
Defaults to "false".
<br/><br/>
Optional. Attribute type: constant.
@@ -1599,158 +1617,150 @@ under the License.
<xs:element name="string-append" substitutionGroup="EnvOperations">
<xs:annotation>
<xs:documentation>
- NOTE: the prefix and suffix will only be used IFF the current string and the string to be appended are both not empty.
-
- So if the field does not exist then it will create a new field with this string value.
- If it does exist then it will append this string value to the end.
+ Performs string concatenation and formatting. The operation starts by applying
+ an argument list (if found) to the string attribute value, the result is
+ prepended by the prefix attribute value, and the suffix attribute value is
+ appended to the result. If the string specified in the field attribute exists,
+ the final result is appended to it, else the field is set to the final result.
</xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:attributeGroup ref="attlist.string-append"/>
+ <xs:attribute type="xs:string" name="field" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The target of the string concatention.
+ <br/><br/>
+ Required. Attribute type: expression.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="string" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The string to append to the field named in the field attribute.
+ This can be a formatting string that is used with the argument list
+ specified in the arg-list attribute.
+ <br/><br/>
+ Required. Attribute types: constant, ${expression}.
+ </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 string attribute 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="prefix">
+ <xs:annotation>
+ <xs:documentation>
+ A string that will be prepended to the string attribute value.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="suffix">
+ <xs:annotation>
+ <xs:documentation>
+ A string that will be appended to the string attribute value.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
</xs:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.string-append">
- <xs:attribute type="xs:string" name="field" use="required">
- <xs:annotation>
- <xs:documentation>
- The field that you want string-append to operate on.
- This is the target field where the value will be put, and this is the string to append to that field.
-
- So if the field does not exist then it will create a new field with this string value.
- If it does exist then it will append this string value to the end.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="string" use="required">
- <xs:annotation>
- <xs:documentation>
- The string to append to the field named in field-name.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="arg-list">
- <xs:annotation>
- <xs:documentation>
- arg-list-name is used to insert values from a list into
- the string using the object in the standard Java library
- that does this sort of string expression with a { } brackets
- and a number, no dollar sign.
-
- This pattern of the arg-list-name with the prefix and
- suffix is something form the early days which is still
- supported, but the best thing to do here is just use the
- flexible string expander which is far more flexible and
- powerful. So you can have the prefix variables to expand
- and everything all mixed into one string.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="prefix">
- <xs:annotation>
- <xs:documentation>
- Used in conjunction with arg-list-name.
- String that will be prepended to the string,
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="suffix">
- <xs:annotation>
- <xs:documentation>
- Used in conjunction with arg-list-name.
- String that will be appended to the string,
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
<xs:element name="string-to-list" substitutionGroup="EnvOperations">
<xs:annotation>
<xs:documentation>
- Take a string literally that can also have a flexible string expander and such in it,
- and it will add it to a list.
-
- Note that you can have an arg-listname for using the standard
- Java style argument list where you have in the source
- string numbers inside of { } brackets that represent the
- number the index in the argument list to insert at that point.
+ Adds a string to a list of strings. Deprecated - use the set element.
</xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:attributeGroup ref="attlist.string-to-list"/>
+ <xs:attribute type="xs:string" name="string" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The string to add to the list specified in the list attribute.
+ <br/><br/>
+ Required. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="list" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ List to add the string to. If the list does not exist, one will be created.
+ <br/><br/>
+ Required. Attribute type: expression.
+ </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 string attribute 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="message-field">
+ <xs:annotation>
+ <xs:documentation>
+ To insert a message above a field (used in conjunction with @fieldErrors FTL macro)
+ <br/><br/>
+ Optional. Attribute type: constant.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
</xs:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.string-to-list">
- <xs:attribute type="xs:string" name="string" use="required">
- <xs:annotation>
- <xs:documentation>
- String to add to the list named in list-name.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="list" use="required">
- <xs:annotation>
- <xs:documentation>
- List to add string to.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="arg-list">
- <xs:annotation>
- <xs:documentation>
- arg-list-name is used to insert values from a list into
- the string using the object in the standard Java library
- that does this sort of string expresison with a { } brackets
- and a number, no dollar sign.
-
- This pattern of the arg-list-name with the prefix and
- suffix is something form the early days which is still
- supported, but the best thing to do here is just use the
- flexible string expander which is far more flexible and
- powerful. So you can have the prefix variables to expand
- and everything all mixed into one string.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="message-field">
- <xs:annotation>
- <xs:documentation>
- To insert a message above a field (used in conjunction with @fieldErrors FTL macro)
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
<xs:element name="to-string" substitutionGroup="EnvOperations">
<xs:annotation>
<xs:documentation>
- The to-string tag converts the Object in the specified field to a String, putting the string in the same field.
+ Converts an object to a string. Deprecated - use the set element.
</xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:attributeGroup ref="attlist.to-string"/>
+ <xs:attribute type="xs:string" name="field" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The name of the field containing the object to convert.
+ <br/><br/>
+ Required. Attribute type: expression.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="format">
+ <xs:annotation>
+ <xs:documentation>
+ Format to use for the conversion.
+ <br/><br/>
+ Optional. Attribute type: constant.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="numeric-padding">
+ <xs:annotation>
+ <xs:documentation>
+ Left-pad the string with the specified number of zeroes.
+ <br/><br/>
+ Optional. Attribute type: constant.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
</xs:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.to-string">
- <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="format">
- <xs:annotation>
- <xs:documentation>
- Format based on the type of the object (date,number, etc.).
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="numeric-padding">
- <xs:annotation>
- <xs:documentation>
- Padding to use if a numeric object is used.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
<xs:element name="clear-field" substitutionGroup="EnvOperations">
<xs:annotation>
<xs:documentation>
@@ -4381,193 +4391,204 @@ under the License.
</xs:annotation>
</xs:attribute>
</xs:attributeGroup>
- <xs:element name="set-calendar" substitutionGroup="OtherOperations">
+ <xs:element name="set-calendar" substitutionGroup="EnvOperations">
<xs:annotation>
<xs:documentation>
- The set-calendar tag allows to set a date "field" from another "from-field" date field type
- or directly from a value using at least one adjuster to modify the from-field date.
- The type of fields or value is Timestamp.
-
- Again you can use the flexible string expander here, the ${} syntax and such. It can also do a type conversion,
- so going from whatever type the source data is in, which would be a string value or whatever the variable
- type is for a from field, it can convert that to any ofthese types before setting it in the target field.
-
- You can also specify a default value in the case that the value evaluates to an empty string or the from-field is
- null or empty. Then the default-value will be used.
-
- Adjuster years, months, days, hours, minutes, seconds and millis use integers optionally precedeed by + or -
- Period-align-start and period-align-end allows to align on end or start of a period.
-
- You may specify a locale or a time-zone else the respective default request value is used.
+ Adjusts a Timestamp by a specified time duration.
</xs:documentation>
</xs:annotation>
<xs:complexType>
- <xs:attributeGroup ref="attlist.set-calendar"/>
+ <xs:attribute ref="field" />
+ <xs:attribute type="xs:string" name="from-field">
+ <xs:annotation>
+ <xs:documentation>
+ Deprecated - use the from attribute.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="from">
+ <xs:annotation>
+ <xs:documentation>
+ An expression or script that returns an object or null. The source of the assignment.
+ <br/><br/>
+ A script must be prefixed with the script language followed by a colon (":").
+ <br/><br/>
+ Required if the value attribute is empty. Attribute types: expression, script.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="value">
+ <xs:annotation>
+ <xs:documentation>
+ A constant value, or a constant that includes an expression. The source of the assignment.
+ <br/><br/>
+ Required if the from attribute is empty. Attribute type: constant+expr.
+ Defaults to java.lang.String data type.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="default-value">
+ <xs:annotation>
+ <xs:documentation>
+ Deprecated - use the default attribute.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="default">
+ <xs:annotation>
+ <xs:documentation>
+ A default value that is used when the from attribute evaluates to null or empty.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="set-if-null" type="booleanConst">
+ <xs:annotation>
+ <xs:documentation>
+ Controls if the target field can be set to null when the from attribute evaluates to null.
+ Defaults to "false".
+ <br/><br/>
+ Optional. Attribute type: constant.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="set-if-empty" type="booleanConst">
+ <xs:annotation>
+ <xs:documentation>
+ Controls if the target field can be set to an empty value. The meaning of "empty" depends on the Java data type.
+ Defaults to "true".
+ <br/><br/>
+ Optional. Attribute type: constant.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="years">
+ <xs:annotation>
+ <xs:documentation>
+ Add (optionally using +) or subtract (using -) a number of year(s).
+ If an expression is used, it should evaluate to an integer.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="months">
+ <xs:annotation>
+ <xs:documentation>
+ Add (optionally using +) or subtract (using -) a number of month(s).
+ If an expression is used, it should evaluate to an integer.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="days">
+ <xs:annotation>
+ <xs:documentation>
+ Add (optionally using +) or subtract (using -) a number of days(s).
+ If an expression is used, it should evaluate to an integer.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="hours">
+ <xs:annotation>
+ <xs:documentation>
+ Add (optionally using +) or subtract (using -) a number of hour(s).
+ If an expression is used, it should evaluate to an integer.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="minutes">
+ <xs:annotation>
+ <xs:documentation>
+ Add (optionally using +) or subtract (using -) a number of minute(s).
+ If an expression is used, it should evaluate to an integer.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="seconds">
+ <xs:annotation>
+ <xs:documentation>
+ Add (optionally using +) or subtract (using -) a number of second(s).
+ If an expression is used, it should evaluate to an integer.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="millis">
+ <xs:annotation>
+ <xs:documentation>
+ Add (optionally using +) or subtract (using -) a number of milli-second(s).
+ If an expression is used, it should evaluate to an integer.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="period-align-start">
+ <xs:annotation>
+ <xs:documentation>
+ Align the adjusted date to the start of a period.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="year" />
+ <xs:enumeration value="month" />
+ <xs:enumeration value="week" />
+ <xs:enumeration value="day" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="period-align-end">
+ <xs:annotation>
+ <xs:documentation>
+ Align the adjusted date to the end of a period.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="year" />
+ <xs:enumeration value="month" />
+ <xs:enumeration value="week" />
+ <xs:enumeration value="day" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="locale">
+ <xs:annotation>
+ <xs:documentation>
+ A locale value (eg: en). The locale selects the calendar to be used for the adjustment.
+ Defaults to the environment locale.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="time-zone">
+ <xs:annotation>
+ <xs:documentation>
+ A time zone value (eg: GMT).
+ Defaults to the environment time zone.
+ <br/><br/>
+ Optional. Attribute types: constant, ${expression}.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
</xs:complexType>
</xs:element>
- <xs:attributeGroup name="attlist.set-calendar">
- <xs:attribute type="xs:string" name="field" use="required">
- <xs:annotation>
- <xs:documentation>
- Name of the field to copy value to.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="from-field">
- <xs:annotation>
- <xs:documentation>
- Name of the field to copy value from.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="value">
- <xs:annotation>
- <xs:documentation>
- Simple value to copy in field.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="default-value">
- <xs:annotation>
- <xs:documentation>
- Default value to copy in field if value evaluates to an empty string or the from-field is null or empty.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="set-if-null" default="false">
- <xs:annotation>
- <xs:documentation>
- Specifies whether or not to set fields that are null or empty.
- Defaults to true.
- </xs:documentation>
- </xs:annotation>
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="true"/>
- <xs:enumeration value="false"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- <xs:attribute name="set-if-empty" default="true">
- <xs:annotation>
- <xs:documentation>
- If the source value, either from a value or from a field, is empty, and
- empty-string an empty list or a null value.
- In this case it's set to true.
-
- If you don't want to set, if you want it to
- leave the target field alone when the source is empty,
- then you need to set this 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="years">
- <xs:annotation>
- <xs:documentation>
- Add (optionally using +) or subtract (using -) a number of year(s).
- If an expression is used, it should evaluate to an integer.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="months">
- <xs:annotation>
- <xs:documentation>
- Add (optionally using +) or subtract (using -) a number of month(s).
- If an expression is used, it should evaluate to an integer.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="days">
- <xs:annotation>
- <xs:documentation>
- Add (optionally using +) or subtract (using -) a number of days(s).
- If an expression is used, it should evaluate to an integer.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="hours">
- <xs:annotation>
- <xs:documentation>
- Add (optionally using +) or subtract (using -) a number of hour(s).
- If an expression is used, it should evaluate to an integer.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="minutes">
- <xs:annotation>
- <xs:documentation>
- Add (optionally using +) or subtract (using -) a number of minute(s).
- If an expression is used, it should evaluate to an integer.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="seconds">
- <xs:annotation>
- <xs:documentation>
- Add (optionally using +) or subtract (using -) a number of second(s).
- If an expression is used, it should evaluate to an integer.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="millis">
- <xs:annotation>
- <xs:documentation>
- Add (optionally using +) or subtract (using -) a number of milli-second(s).
- If an expression is used, it should evaluate to an integer.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute name="period-align-start">
- <xs:annotation>
- <xs:documentation>
- Align the returned date to the start of the chosen adjustment between year, month, week or day.
- </xs:documentation>
- </xs:annotation>
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="year"/>
- <xs:enumeration value="month"/>
- <xs:enumeration value="week"/>
- <xs:enumeration value="day"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- <xs:attribute name="period-align-end">
- <xs:annotation>
- <xs:documentation>
- Align the returned date to the end of the chosen adjustment between year, month, week or day.
- </xs:documentation>
- </xs:annotation>
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="year"/>
- <xs:enumeration value="month"/>
- <xs:enumeration value="week"/>
- <xs:enumeration value="day"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- <xs:attribute type="xs:string" name="locale">
- <xs:annotation>
- <xs:documentation>
- A locale value (eg: en)
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="time-zone">
- <xs:annotation>
- <xs:documentation>
- a time zone value (eg: GMT)
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- </xs:attributeGroup>
<!--
======================================================
========== The Simple Map Processor Section ==========
Modified: ofbiz/trunk/framework/minilang/src/META-INF/services/org.ofbiz.minilang.method.MethodOperation$Factory
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/META-INF/services/org.ofbiz.minilang.method.MethodOperation%24Factory?rev=1349646&r1=1349645&r2=1349646&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/META-INF/services/org.ofbiz.minilang.method.MethodOperation$Factory (original)
+++ ofbiz/trunk/framework/minilang/src/META-INF/services/org.ofbiz.minilang.method.MethodOperation$Factory Wed Jun 13 06:04:49 2012
@@ -86,7 +86,6 @@ org.ofbiz.minilang.method.envops.OrderMa
org.ofbiz.minilang.method.envops.SetCalendar$SetCalendarFactory
org.ofbiz.minilang.method.envops.SetOperation$SetOperationFactory
org.ofbiz.minilang.method.envops.StringAppend$StringAppendFactory
-org.ofbiz.minilang.method.envops.StringToField$StringToFieldFactory
org.ofbiz.minilang.method.envops.StringToList$StringToListFactory
org.ofbiz.minilang.method.envops.ToString$ToStringFactory
org.ofbiz.minilang.method.envops.While$WhileFactory
Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/OrderMapList.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/OrderMapList.java?rev=1349646&r1=1349645&r2=1349646&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/OrderMapList.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/OrderMapList.java Wed Jun 13 06:04:49 2012
@@ -18,73 +18,93 @@
*******************************************************************************/
package org.ofbiz.minilang.method.envops;
+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.UtilValidate;
import org.ofbiz.base.util.UtilXml;
import org.ofbiz.base.util.collections.FlexibleMapAccessor;
import org.ofbiz.base.util.collections.MapComparator;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
import org.ofbiz.minilang.MiniLangException;
+import org.ofbiz.minilang.MiniLangRuntimeException;
+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 environment field to a list
+ * Implements the <order-map-list> element.
*/
-public class OrderMapList extends MethodOperation {
-
- public static final String module = FieldToList.class.getName();
+public final class OrderMapList extends MethodOperation {
- protected ContextAccessor<List<Map<Object, Object>>> listAcsr;
- protected MapComparator mc;
- protected List<FlexibleMapAccessor<String>> orderByAcsrList = FastList.newInstance();
+ private final FlexibleMapAccessor<List<Map<Object, Object>>> listFma;
+ private final MapComparator mc;
public OrderMapList(Element element, SimpleMethod simpleMethod) throws MiniLangException {
super(element, simpleMethod);
- listAcsr = new ContextAccessor<List<Map<Object, Object>>>(element.getAttribute("list"), element.getAttribute("list-name"));
- for (Element orderByElement : UtilXml.childElementList(element, "order-by")) {
- FlexibleMapAccessor<String> fma = FlexibleMapAccessor.getInstance(UtilValidate.isNotEmpty(orderByElement.getAttribute("field")) ? orderByElement.getAttribute("field") : orderByElement.getAttribute("field-name"));
- this.orderByAcsrList.add(fma);
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.attributeNames(simpleMethod, element, "list");
+ MiniLangValidate.requiredAttributes(simpleMethod, element, "list");
+ MiniLangValidate.expressionAttributes(simpleMethod, element, "list");
+ MiniLangValidate.childElements(simpleMethod, element, "order-by");
+ MiniLangValidate.requiredChildElements(simpleMethod, element, "order-by");
+ }
+ listFma = FlexibleMapAccessor.getInstance(element.getAttribute("list"));
+ List<? extends Element> orderByElements = UtilXml.childElementList(element, "order-by");
+ if (orderByElements.size() > 0) {
+ ArrayList<FlexibleMapAccessor<String>> orderByList = new ArrayList<FlexibleMapAccessor<String>>(orderByElements.size());
+ for (Element orderByElement : orderByElements) {
+ FlexibleMapAccessor<String> fma = FlexibleMapAccessor.getInstance(orderByElement.getAttribute("field"));
+ orderByList.add(fma);
+ }
+ mc = new MapComparator(orderByList);
+ } else {
+ mc = null;
}
- this.mc = new MapComparator(this.orderByAcsrList);
}
@Override
public boolean exec(MethodContext methodContext) throws MiniLangException {
- List<Map<Object, Object>> orderList = listAcsr.get(methodContext);
- if (orderList == null) {
- if (Debug.infoOn())
- Debug.logInfo("List not found with name " + listAcsr + ", not ordering/sorting list.", module);
- return true;
+ if (mc == null) {
+ throw new MiniLangRuntimeException("order-by sub-elements not found.", this);
+ }
+ List<Map<Object, Object>> orderList = listFma.get(methodContext.getEnvMap());
+ if (orderList != null) {
+ Collections.sort(orderList, mc);
}
- Collections.sort(orderList, mc);
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() {
- return "<order-map-list list-name=\"" + this.listAcsr + "\"/>";
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("<order-map-list ");
+ sb.append("list=\"").append(this.listFma).append("\" />");
+ return sb.toString();
}
+ /**
+ * A factory for the <order-map-list> element.
+ */
public static final class OrderMapListFactory implements Factory<OrderMapList> {
+ @Override
public OrderMapList createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
return new OrderMapList(element, simpleMethod);
}
+ @Override
public String getName() {
return "order-map-list";
}
Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetCalendar.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetCalendar.java?rev=1349646&r1=1349645&r2=1349646&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetCalendar.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetCalendar.java Wed Jun 13 06:04:49 2012
@@ -24,12 +24,16 @@ import java.util.TimeZone;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.ObjectType;
+import org.ofbiz.base.util.Scriptlet;
+import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.UtilDateTime;
+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.MethodContext;
import org.ofbiz.minilang.method.MethodOperation;
import org.w3c.dom.Element;
@@ -37,90 +41,144 @@ import org.w3c.dom.Element;
import com.ibm.icu.util.Calendar;
/**
- * Adjust a Timestamp by a specified time.
+ * Implements the <set-calendar> element.
*/
-public class SetCalendar extends MethodOperation {
+public final class SetCalendar extends MethodOperation {
public static final String module = SetCalendar.class.getName();
- protected FlexibleStringExpander daysExdr;
- protected FlexibleStringExpander defaultExdr;
- protected ContextAccessor<Timestamp> field;
- protected ContextAccessor<Object> fromField;
- protected FlexibleStringExpander hoursExdr;
- protected FlexibleStringExpander localeExdr;
- protected FlexibleStringExpander millisExdr;
- protected FlexibleStringExpander minutesExdr;
- protected FlexibleStringExpander monthsExdr;
- protected FlexibleStringExpander periodAlignEnd;
- protected FlexibleStringExpander periodAlignStart;
- protected FlexibleStringExpander secondsExdr;
- protected boolean setIfEmpty; // default to true
- protected boolean setIfNull; // default to false
- protected FlexibleStringExpander timeZoneExdr;
- protected FlexibleStringExpander valueExdr;
- protected FlexibleStringExpander yearsExdr;
+ // This method is needed only during the v1 to v2 transition
+ private static boolean autoCorrect(Element element) {
+ boolean elementModified = false;
+ // Correct deprecated default-value attribute
+ String defaultAttr = element.getAttribute("default-value");
+ if (defaultAttr.length() > 0) {
+ element.setAttribute("default", defaultAttr);
+ element.removeAttribute("default-value");
+ elementModified = true;
+ }
+ // Correct deprecated from-field attribute
+ String fromAttr = element.getAttribute("from-field");
+ if (fromAttr.length() > 0) {
+ element.setAttribute("from", fromAttr);
+ element.removeAttribute("from-field");
+ elementModified = true;
+ }
+ // Correct value attribute expression that belongs in from attribute
+ String valueAttr = element.getAttribute("value").trim();
+ if (valueAttr.startsWith("${") && valueAttr.endsWith("}")) {
+ valueAttr = valueAttr.substring(2, valueAttr.length() - 1);
+ if (!valueAttr.contains("${")) {
+ element.setAttribute("from", valueAttr);
+ element.removeAttribute("value");
+ elementModified = true;
+ }
+ }
+ return elementModified;
+ }
+
+ private final FlexibleStringExpander daysFse;
+ private final FlexibleStringExpander defaultFse;
+ private final FlexibleMapAccessor<Object> fieldFma;
+ private final FlexibleMapAccessor<Object> fromFma;
+ private final FlexibleStringExpander hoursFse;
+ private final FlexibleStringExpander localeFse;
+ private final FlexibleStringExpander millisFse;
+ private final FlexibleStringExpander minutesFse;
+ private final FlexibleStringExpander monthsFse;
+ private final FlexibleStringExpander periodAlignEnd;
+ private final FlexibleStringExpander periodAlignStart;
+ private final FlexibleStringExpander secondsFse;
+ private final boolean setIfEmpty;
+ private final boolean setIfNull;
+ private final Scriptlet scriptlet;
+ private final FlexibleStringExpander timeZoneFse;
+ private final FlexibleStringExpander valueFse;
+ private final FlexibleStringExpander yearsFse;
public SetCalendar(Element element, SimpleMethod simpleMethod) throws MiniLangException {
super(element, simpleMethod);
- this.field = new ContextAccessor<Timestamp>(element.getAttribute("field"));
- this.fromField = new ContextAccessor<Object>(element.getAttribute("from-field"));
- this.valueExdr = FlexibleStringExpander.getInstance(element.getAttribute("value"));
- this.defaultExdr = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
- this.yearsExdr = FlexibleStringExpander.getInstance(element.getAttribute("years"));
- this.monthsExdr = FlexibleStringExpander.getInstance(element.getAttribute("months"));
- this.daysExdr = FlexibleStringExpander.getInstance(element.getAttribute("days"));
- this.hoursExdr = FlexibleStringExpander.getInstance(element.getAttribute("hours"));
- this.minutesExdr = FlexibleStringExpander.getInstance(element.getAttribute("minutes"));
- this.secondsExdr = FlexibleStringExpander.getInstance(element.getAttribute("seconds"));
- this.millisExdr = FlexibleStringExpander.getInstance(element.getAttribute("millis"));
- this.periodAlignStart = FlexibleStringExpander.getInstance(element.getAttribute("period-align-start"));
- this.periodAlignEnd = FlexibleStringExpander.getInstance(element.getAttribute("period-align-end"));
- this.localeExdr = FlexibleStringExpander.getInstance(element.getAttribute("locale"));
- this.timeZoneExdr = FlexibleStringExpander.getInstance(element.getAttribute("time-zone"));
- // default to false, anything but true is false
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.deprecatedAttribute(simpleMethod, element, "from-field", "replace with \"from\"");
+ MiniLangValidate.deprecatedAttribute(simpleMethod, element, "default-value", "replace with \"default\"");
+ MiniLangValidate.attributeNames(simpleMethod, element, "field", "from-field", "from", "value", "default-value", "default", "set-if-null", "set-if-empty",
+ "years", "months", "days", "hours", "minutes", "seconds", "millis", "period-align-start", "period-align-end", "locale", "time-zone");
+ MiniLangValidate.requiredAttributes(simpleMethod, element, "field");
+ MiniLangValidate.requireAnyAttribute(simpleMethod, element, "from", "value");
+ MiniLangValidate.constantPlusExpressionAttributes(simpleMethod, element, "value");
+ MiniLangValidate.constantAttributes(simpleMethod, element, "set-if-null", "set-if-empty");
+ MiniLangValidate.expressionAttributes(simpleMethod, element, "field", "from", "from-field");
+ MiniLangValidate.noChildElements(simpleMethod, element);
+ }
+ boolean elementModified = autoCorrect(element);
+ if (elementModified && MiniLangUtil.autoCorrectOn()) {
+ MiniLangUtil.flagDocumentAsCorrected(element);
+ }
+ this.fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
+ String fromAttribute = element.getAttribute("from");
+ if (MiniLangUtil.containsScript(fromAttribute)) {
+ this.scriptlet = new Scriptlet(StringUtil.convertOperatorSubstitutions(fromAttribute));
+ this.fromFma = FlexibleMapAccessor.getInstance(null);
+ } else {
+ this.scriptlet = null;
+ this.fromFma = FlexibleMapAccessor.getInstance(fromAttribute);
+ }
+ this.valueFse = FlexibleStringExpander.getInstance(element.getAttribute("value"));
+ if (!fromAttribute.isEmpty() && !this.valueFse.isEmpty()) {
+ throw new IllegalArgumentException("Cannot include both a from attribute and a value attribute in a <set-calendar> element.");
+ }
+ this.defaultFse = FlexibleStringExpander.getInstance(element.getAttribute("default"));
this.setIfNull = "true".equals(element.getAttribute("set-if-null"));
- // default to true, anything but false is true
this.setIfEmpty = !"false".equals(element.getAttribute("set-if-empty"));
- if (!this.fromField.isEmpty() && !this.valueExdr.isEmpty()) {
- throw new IllegalArgumentException("Cannot specify a from-field [" + element.getAttribute("from-field") + "] and a value [" + element.getAttribute("value") + "] on the set-calendar action in a screen widget");
- }
+ this.yearsFse = FlexibleStringExpander.getInstance(element.getAttribute("years"));
+ this.monthsFse = FlexibleStringExpander.getInstance(element.getAttribute("months"));
+ this.daysFse = FlexibleStringExpander.getInstance(element.getAttribute("days"));
+ this.hoursFse = FlexibleStringExpander.getInstance(element.getAttribute("hours"));
+ this.minutesFse = FlexibleStringExpander.getInstance(element.getAttribute("minutes"));
+ this.secondsFse = FlexibleStringExpander.getInstance(element.getAttribute("seconds"));
+ this.millisFse = FlexibleStringExpander.getInstance(element.getAttribute("millis"));
+ this.periodAlignStart = FlexibleStringExpander.getInstance(element.getAttribute("period-align-start"));
+ this.periodAlignEnd = FlexibleStringExpander.getInstance(element.getAttribute("period-align-end"));
+ this.localeFse = FlexibleStringExpander.getInstance(element.getAttribute("locale"));
+ this.timeZoneFse = FlexibleStringExpander.getInstance(element.getAttribute("time-zone"));
}
@Override
public boolean exec(MethodContext methodContext) throws MiniLangException {
Object newValue = null;
- if (!this.fromField.isEmpty()) {
- newValue = this.fromField.get(methodContext);
- if (Debug.verboseOn())
- Debug.logVerbose("In screen getting value for field from [" + this.fromField.toString() + "]: " + newValue, module);
- } else if (!this.valueExdr.isEmpty()) {
- newValue = methodContext.expandString(this.valueExdr);
- }
- // If newValue is still empty, use the default value
- if (ObjectType.isEmpty(newValue) && !this.defaultExdr.isEmpty()) {
- newValue = methodContext.expandString(this.defaultExdr);
+ if (this.scriptlet != null) {
+ try {
+ newValue = this.scriptlet.executeScript(methodContext.getEnvMap());
+ } catch (Exception exc) {
+ Debug.logWarning(exc, "Error evaluating scriptlet [" + this.scriptlet + "]: " + exc, module);
+ }
+ } else if (!this.fromFma.isEmpty()) {
+ newValue = this.fromFma.get(methodContext.getEnvMap());
+ } else if (!this.valueFse.isEmpty()) {
+ newValue = this.valueFse.expand(methodContext.getEnvMap());
+ }
+ if (ObjectType.isEmpty(newValue) && !this.defaultFse.isEmpty()) {
+ newValue = this.defaultFse.expand(methodContext.getEnvMap());
}
if (!setIfNull && newValue == null) {
- if (Debug.verboseOn())
- Debug.logVerbose("Field value not found (null) with name [" + fromField + "] and value [" + valueExdr + "], and there was not default value, not setting field", module);
return true;
}
if (!setIfEmpty && ObjectType.isEmpty(newValue)) {
- if (Debug.verboseOn())
- Debug.logVerbose("Field value not found (empty) with name [" + fromField + "] and value [" + valueExdr + "], and there was not default value, not setting field", module);
return true;
}
- // Convert attributes to the corresponding data types
Locale locale = null;
TimeZone timeZone = null;
Timestamp fromStamp = null;
+ int years = 0;
+ int months = 0;
+ int days = 0;
+ int hours = 0;
+ int minutes = 0;
+ int seconds = 0;
+ int millis = 0;
try {
- if (!this.localeExdr.isEmpty()) {
- locale = (Locale) ObjectType.simpleTypeConvert(methodContext.expandString(this.localeExdr), "Locale", null, null);
- }
- if (!this.timeZoneExdr.isEmpty()) {
- timeZone = (TimeZone) ObjectType.simpleTypeConvert(methodContext.expandString(this.timeZoneExdr), "TimeZone", null, null);
+ if (!this.localeFse.isEmpty()) {
+ locale = (Locale) ObjectType.simpleTypeConvert(this.localeFse.expand(methodContext.getEnvMap()), "Locale", null, null);
}
if (locale == null) {
locale = methodContext.getLocale();
@@ -128,6 +186,9 @@ public class SetCalendar extends MethodO
if (locale == null) {
locale = Locale.getDefault();
}
+ if (!this.timeZoneFse.isEmpty()) {
+ timeZone = (TimeZone) ObjectType.simpleTypeConvert(this.timeZoneFse.expand(methodContext.getEnvMap()), "TimeZone", null, null);
+ }
if (timeZone == null) {
timeZone = methodContext.getTimeZone();
}
@@ -135,21 +196,30 @@ public class SetCalendar extends MethodO
timeZone = TimeZone.getDefault();
}
fromStamp = (Timestamp) MiniLangUtil.convertType(newValue, java.sql.Timestamp.class, locale, timeZone, UtilDateTime.DATE_TIME_FORMAT);
+ if (!this.yearsFse.isEmpty()) {
+ years= Integer.parseInt(this.yearsFse.expandString(methodContext.getEnvMap()));
+ }
+ if (!this.monthsFse.isEmpty()) {
+ months = Integer.parseInt(this.monthsFse.expandString(methodContext.getEnvMap()));
+ }
+ if (!this.daysFse.isEmpty()) {
+ days = Integer.parseInt(this.daysFse.expandString(methodContext.getEnvMap()));
+ }
+ if (!this.hoursFse.isEmpty()) {
+ hours = Integer.parseInt(this.hoursFse.expandString(methodContext.getEnvMap()));
+ }
+ if (!this.minutesFse.isEmpty()) {
+ minutes = Integer.parseInt(this.minutesFse.expandString(methodContext.getEnvMap()));
+ }
+ if (!this.secondsFse.isEmpty()) {
+ seconds = Integer.parseInt(this.secondsFse.expandString(methodContext.getEnvMap()));
+ }
+ if (!this.millisFse.isEmpty()) {
+ millis = Integer.parseInt(this.millisFse.expandString(methodContext.getEnvMap()));
+ }
} catch (Exception e) {
- // Catching all exceptions - even potential ClassCastException
- if (Debug.verboseOn())
- Debug.logVerbose("Error converting attributes to objects: " + e.getMessage(), module);
- return true;
+ throw new MiniLangRuntimeException("Exception thrown while parsing attributes: " + e.getMessage(), this);
}
- // Convert Strings to ints
- int years = this.yearsExdr.isEmpty() ? 0 : Integer.parseInt(methodContext.expandString(this.yearsExdr));
- int months = this.monthsExdr.isEmpty() ? 0 : Integer.parseInt(methodContext.expandString(this.monthsExdr));
- int days = this.daysExdr.isEmpty() ? 0 : Integer.parseInt(methodContext.expandString(this.daysExdr));
- int hours = this.hoursExdr.isEmpty() ? 0 : Integer.parseInt(methodContext.expandString(this.hoursExdr));
- int minutes = this.minutesExdr.isEmpty() ? 0 : Integer.parseInt(methodContext.expandString(this.minutesExdr));
- int seconds = this.secondsExdr.isEmpty() ? 0 : Integer.parseInt(methodContext.expandString(this.secondsExdr));
- int millis = this.millisExdr.isEmpty() ? 0 : Integer.parseInt(methodContext.expandString(this.millisExdr));
- // Adjust calendar
Calendar cal = UtilDateTime.toCalendar(fromStamp, timeZone, locale);
cal.add(Calendar.MILLISECOND, millis);
cal.add(Calendar.SECOND, seconds);
@@ -159,9 +229,8 @@ public class SetCalendar extends MethodO
cal.add(Calendar.MONTH, months);
cal.add(Calendar.YEAR, years);
Timestamp toStamp = new Timestamp(cal.getTimeInMillis());
- // Align period start/end
if (!periodAlignStart.isEmpty()) {
- String period = methodContext.expandString(periodAlignStart);
+ String period = periodAlignStart.expandString(methodContext.getEnvMap());
if ("day".equals(period)) {
toStamp = UtilDateTime.getDayStart(toStamp, 0, timeZone, locale);
} else if ("week".equals(period)) {
@@ -170,9 +239,11 @@ public class SetCalendar extends MethodO
toStamp = UtilDateTime.getMonthStart(toStamp, 0, timeZone, locale);
} else if ("year".equals(period)) {
toStamp = UtilDateTime.getYearStart(toStamp, 0, timeZone, locale);
+ } else {
+ throw new MiniLangRuntimeException("Invalid period-align-start attribute value: " + period, this);
}
} else if (!periodAlignEnd.isEmpty()) {
- String period = methodContext.expandString(periodAlignEnd);
+ String period = periodAlignEnd.expandString(methodContext.getEnvMap());
if ("day".equals(period)) {
toStamp = UtilDateTime.getDayEnd(toStamp, timeZone, locale);
} else if ("week".equals(period)) {
@@ -181,31 +252,93 @@ public class SetCalendar extends MethodO
toStamp = UtilDateTime.getMonthEnd(toStamp, timeZone, locale);
} else if ("year".equals(period)) {
toStamp = UtilDateTime.getYearEnd(toStamp, timeZone, locale);
+ } else {
+ throw new MiniLangRuntimeException("Invalid period-align-end attribute value: " + period, this);
}
}
- if (Debug.verboseOn())
- Debug.logVerbose("In screen setting calendar [" + this.field.toString(), module);
- this.field.put(methodContext, toStamp);
+ this.fieldFma.put(methodContext.getEnvMap(), toStamp);
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() {
- return "<set-calendar field=\"" + this.field + (this.valueExdr.isEmpty() ? "" : "\" value=\"" + this.valueExdr.getOriginal()) + (this.fromField.isEmpty() ? "" : "\" from-field=\"" + this.fromField) + (this.defaultExdr.isEmpty() ? "" : "\" default-value=\"" + this.defaultExdr.getOriginal())
- + "\"/>";
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("<set-calendar ");
+ sb.append("field=\"").append(this.fieldFma).append("\" ");
+ if (!this.fromFma.isEmpty()) {
+ sb.append("from=\"").append(this.fromFma).append("\" ");
+ }
+ if (this.scriptlet != null) {
+ sb.append("from=\"").append(this.scriptlet).append("\" ");
+ }
+ if (!this.valueFse.isEmpty()) {
+ sb.append("value=\"").append(this.valueFse).append("\" ");
+ }
+ if (!this.defaultFse.isEmpty()) {
+ sb.append("default=\"").append(this.defaultFse).append("\" ");
+ }
+ if (!this.yearsFse.isEmpty()) {
+ sb.append("years=\"").append(this.yearsFse).append("\" ");
+ }
+ if (!this.monthsFse.isEmpty()) {
+ sb.append("months=\"").append(this.monthsFse).append("\" ");
+ }
+ if (!this.daysFse.isEmpty()) {
+ sb.append("days=\"").append(this.daysFse).append("\" ");
+ }
+ if (!this.hoursFse.isEmpty()) {
+ sb.append("hours=\"").append(this.hoursFse).append("\" ");
+ }
+ if (!this.minutesFse.isEmpty()) {
+ sb.append("minutes=\"").append(this.minutesFse).append("\" ");
+ }
+ if (!this.secondsFse.isEmpty()) {
+ sb.append("seconds=\"").append(this.secondsFse).append("\" ");
+ }
+ if (!this.millisFse.isEmpty()) {
+ sb.append("millis=\"").append(this.millisFse).append("\" ");
+ }
+ if (!this.periodAlignStart.isEmpty()) {
+ sb.append("period-align-start=\"").append(this.localeFse).append("\" ");
+ }
+ if (!this.periodAlignEnd.isEmpty()) {
+ sb.append("period-align-end=\"").append(this.localeFse).append("\" ");
+ }
+ if (!this.localeFse.isEmpty()) {
+ sb.append("locale=\"").append(this.localeFse).append("\" ");
+ }
+ if (!this.timeZoneFse.isEmpty()) {
+ sb.append("time-zone=\"").append(this.timeZoneFse).append("\" ");
+ }
+ if (this.setIfNull) {
+ sb.append("set-if-null=\"true\" ");
+ }
+ if (!this.setIfEmpty) {
+ sb.append("set-if-empty=\"false\" ");
+ }
+ sb.append("/>");
+ return sb.toString();
}
+ /**
+ * A factory for the <set-calendar> element.
+ */
public static final class SetCalendarFactory implements Factory<SetCalendar> {
+ @Override
public SetCalendar createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
return new SetCalendar(element, simpleMethod);
}
+ @Override
public String getName() {
return "set-calendar";
}
Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetOperation.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetOperation.java?rev=1349646&r1=1349645&r2=1349646&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetOperation.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetOperation.java Wed Jun 13 06:04:49 2012
@@ -36,7 +36,7 @@ import org.ofbiz.minilang.method.MethodO
import org.w3c.dom.Element;
/**
- * Assigns a field from an expression or script, or from a constant value. Also supports a default value and type conversion.
+ * Implements the <set> element.
*/
public final class SetOperation extends MethodOperation {
@@ -73,6 +73,7 @@ public final class SetOperation extends
}
private final FlexibleStringExpander defaultFse;
+ private final FlexibleStringExpander formatFse;
private final FlexibleMapAccessor<Object> fieldFma;
private final FlexibleMapAccessor<Object> fromFma;
private final Scriptlet scriptlet;
@@ -85,11 +86,9 @@ public final class SetOperation extends
public SetOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
super(element, simpleMethod);
if (MiniLangValidate.validationOn()) {
- /*
MiniLangValidate.deprecatedAttribute(simpleMethod, element, "from-field", "replace with \"from\"");
MiniLangValidate.deprecatedAttribute(simpleMethod, element, "default-value", "replace with \"default\"");
- */
- MiniLangValidate.attributeNames(simpleMethod, element, "field", "from-field", "from", "value", "default-value", "default", "type", "set-if-null", "set-if-empty");
+ MiniLangValidate.attributeNames(simpleMethod, element, "field", "from-field", "from", "value", "default-value", "default", "format", "type", "set-if-null", "set-if-empty");
MiniLangValidate.requiredAttributes(simpleMethod, element, "field");
MiniLangValidate.requireAnyAttribute(simpleMethod, element, "from-field", "from", "value");
MiniLangValidate.constantPlusExpressionAttributes(simpleMethod, element, "value");
@@ -112,6 +111,7 @@ public final class SetOperation extends
}
this.valueFse = FlexibleStringExpander.getInstance(element.getAttribute("value"));
this.defaultFse = FlexibleStringExpander.getInstance(element.getAttribute("default"));
+ this.formatFse = FlexibleStringExpander.getInstance(element.getAttribute("format"));
this.type = element.getAttribute("type");
Class<?> targetClass = null;
if (!this.type.isEmpty()) {
@@ -124,7 +124,7 @@ public final class SetOperation extends
this.targetClass = targetClass;
this.setIfNull = "true".equals(element.getAttribute("set-if-null")); // default to false, anything but true is false
this.setIfEmpty = !"false".equals(element.getAttribute("set-if-empty")); // default to true, anything but false is true
- if (!this.fromFma.isEmpty() && !this.valueFse.isEmpty()) {
+ if (!fromAttribute.isEmpty() && !this.valueFse.isEmpty()) {
throw new IllegalArgumentException("Cannot include both a from attribute and a value attribute in a <set> element.");
}
}
@@ -166,13 +166,17 @@ public final class SetOperation extends
newValue = FastList.newInstance();
} else {
try {
+ String format = null;
+ if (!this.formatFse.isEmpty()) {
+ format = this.formatFse.expandString(methodContext.getEnvMap());
+ }
Class<?> targetClass = this.targetClass;
if (targetClass == null) {
targetClass = MiniLangUtil.getObjectClassForConversion(newValue);
}
- newValue = MiniLangUtil.convertType(newValue, targetClass, methodContext.getLocale(), methodContext.getTimeZone(), null);
+ newValue = MiniLangUtil.convertType(newValue, targetClass, methodContext.getLocale(), methodContext.getTimeZone(), format);
} catch (Exception e) {
- String errMsg = "Could not convert field value for the field: [" + this.fieldFma.toString() + "] to the [" + this.type + "] type for the value [" + newValue + "]: " + e.toString();
+ String errMsg = "Could not convert field value for the field: [" + this.fieldFma.toString() + "] to the [" + this.type + "] type for the value [" + newValue + "]: " + e.getMessage();
Debug.logWarning(e, errMsg, module);
this.simpleMethod.addErrorMessage(methodContext, errMsg);
return false;
@@ -180,7 +184,7 @@ public final class SetOperation extends
}
}
if (Debug.verboseOn())
- Debug.logVerbose("In screen setting field [" + this.fieldFma.toString() + "] to value: " + newValue, module);
+ Debug.logVerbose("Setting field [" + this.fieldFma.toString() + "] to value: " + newValue, module);
this.fieldFma.put(methodContext.getEnvMap(), newValue);
return true;
}
@@ -216,15 +220,26 @@ public final class SetOperation extends
if (this.type.length() > 0) {
sb.append("type=\"").append(this.type).append("\" ");
}
+ if (this.setIfNull) {
+ sb.append("set-if-null=\"true\" ");
+ }
+ if (!this.setIfEmpty) {
+ sb.append("set-if-empty=\"false\" ");
+ }
sb.append("/>");
return sb.toString();
}
+ /**
+ * A factory for the <set> element.
+ */
public static final class SetOperationFactory implements Factory<SetOperation> {
+ @Override
public SetOperation createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
return new SetOperation(element, simpleMethod);
}
+ @Override
public String getName() {
return "set";
}
Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/StringAppend.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/StringAppend.java?rev=1349646&r1=1349645&r2=1349646&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/StringAppend.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/StringAppend.java Wed Jun 13 06:04:49 2012
@@ -20,110 +20,106 @@ package org.ofbiz.minilang.method.envops
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.minilang.MiniLangException;
+import org.ofbiz.minilang.MiniLangRuntimeException;
+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;
/**
- * Appends the specified String to a field
+ * Implements the <string-append> element.
*/
-public class StringAppend extends MethodOperation {
-
- public static final String module = StringAppend.class.getName();
+public final class StringAppend extends MethodOperation {
- ContextAccessor<List<? extends Object>> argListAcsr;
- ContextAccessor<String> fieldAcsr;
- ContextAccessor<Map<String, Object>> mapAcsr;
- String prefix;
- String string;
- String suffix;
+ private final FlexibleMapAccessor<List<? extends Object>> argListFma;
+ private final FlexibleMapAccessor<String> fieldFma;
+ private final FlexibleStringExpander prefixFse;
+ private final FlexibleStringExpander stringFse;
+ private final FlexibleStringExpander suffixFse;
public StringAppend(Element element, SimpleMethod simpleMethod) throws MiniLangException {
super(element, simpleMethod);
- string = element.getAttribute("string");
- prefix = element.getAttribute("prefix");
- suffix = element.getAttribute("suffix");
- // 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<String>(element.getAttribute("field"), element.getAttribute("field-name"));
- mapAcsr = new ContextAccessor<Map<String, Object>>(element.getAttribute("map-name"));
- argListAcsr = new ContextAccessor<List<? extends Object>>(element.getAttribute("arg-list"), element.getAttribute("arg-list-name"));
- }
-
- public String appendString(String oldValue, MethodContext methodContext) {
- String value = methodContext.expandString(string);
- String prefixValue = methodContext.expandString(prefix);
- String suffixValue = methodContext.expandString(suffix);
- if (!argListAcsr.isEmpty()) {
- List<? extends Object> argList = argListAcsr.get(methodContext);
- if (UtilValidate.isNotEmpty(argList)) {
- value = MessageFormat.format(value, argList.toArray());
- }
- }
- StringBuilder newValue = new StringBuilder();
- if (UtilValidate.isNotEmpty(value)) {
- if (UtilValidate.isEmpty(oldValue)) {
- newValue.append(value);
- } else {
- newValue.append(oldValue);
- if (prefixValue != null)
- newValue.append(prefixValue);
- newValue.append(value);
- if (suffixValue != null)
- newValue.append(suffixValue);
- }
- } else {
- if (UtilValidate.isEmpty(oldValue)) {
- newValue.append(oldValue);
- }
+ if (MiniLangValidate.validationOn()) {
+ MiniLangValidate.attributeNames(simpleMethod, element, "field", "arg-list", "prefix", "string", "suffix");
+ MiniLangValidate.requiredAttributes(simpleMethod, element, "field", "string");
+ MiniLangValidate.expressionAttributes(simpleMethod, element, "field", "arg-list");
+ MiniLangValidate.noChildElements(simpleMethod, element);
}
- return newValue.toString();
+ argListFma = FlexibleMapAccessor.getInstance(element.getAttribute("arg-list"));
+ fieldFma = FlexibleMapAccessor.getInstance(element.getAttribute("field"));
+ prefixFse = FlexibleStringExpander.getInstance(element.getAttribute("prefix"));
+ stringFse = FlexibleStringExpander.getInstance(element.getAttribute("string"));
+ suffixFse = FlexibleStringExpander.getInstance(element.getAttribute("suffix"));
}
@Override
public boolean exec(MethodContext methodContext) throws MiniLangException {
- if (!mapAcsr.isEmpty()) {
- Map<String, Object> toMap = mapAcsr.get(methodContext);
- if (toMap == null) {
- if (Debug.verboseOn())
- Debug.logVerbose("Map not found with name " + mapAcsr + ", creating new map", module);
- toMap = FastMap.newInstance();
- mapAcsr.put(methodContext, toMap);
+ String value = stringFse.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 string attribute: " + e.getMessage(), this);
}
- String oldValue = fieldAcsr.get(toMap, methodContext);
- fieldAcsr.put(toMap, this.appendString(oldValue, methodContext), methodContext);
- } else {
- String oldValue = fieldAcsr.get(methodContext);
- fieldAcsr.put(methodContext, this.appendString(oldValue, methodContext));
+ }
+ if (!value.isEmpty()) {
+ String prefixValue = prefixFse.expandString(methodContext.getEnvMap());
+ String suffixValue = suffixFse.expandString(methodContext.getEnvMap());
+ StringBuilder newValue = new StringBuilder();
+ String oldValue = fieldFma.get(methodContext.getEnvMap());
+ if (oldValue != null) {
+ newValue.append(oldValue);
+ }
+ newValue.append(prefixValue).append(value).append(suffixValue);
+ fieldFma.put(methodContext.getEnvMap(), newValue.toString());
}
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 "<string-append string=\"" + this.string + "\" prefix=\"" + this.prefix + "\" suffix=\"" + this.suffix + "\" field-name=\"" + this.fieldAcsr + "\" map-name=\"" + this.mapAcsr + "\"/>";
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("<string-append ");
+ sb.append("field=\"").append(this.fieldFma).append("\" ");
+ sb.append("string=\"").append(this.stringFse).append("\" ");
+ if (!this.argListFma.isEmpty()) {
+ sb.append("arg-list=\"").append(this.argListFma).append("\" ");
+ }
+ if (!this.prefixFse.isEmpty()) {
+ sb.append("prefix=\"").append(this.prefixFse).append("\" ");
+ }
+ if (!this.suffixFse.isEmpty()) {
+ sb.append("suffix=\"").append(this.suffixFse).append("\" ");
+ }
+ sb.append("/>");
+ return sb.toString();
}
+ /**
+ * A factory for the <string-append> element.
+ */
public static final class StringAppendFactory implements Factory<StringAppend> {
+ @Override
public StringAppend createMethodOperation(Element element, SimpleMethod simpleMethod) throws MiniLangException {
return new StringAppend(element, simpleMethod);
}
+ @Override
public String getName() {
return "string-append";
}