Author: jleroux
Date: Tue Jan 29 04:55:45 2008 New Revision: 616292 URL: http://svn.apache.org/viewvc?rev=616292&view=rev Log: A patch from Adrian Crum from an issue initiated by Fabien Carrion "To permit to calculate on a DATE object in minilang" (https://issues.apache.org/jira/browse/OFBIZ-1249) - OFBIZ-1249 I have added the XSD part please check it. Added: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetCalendar.java (with props) Modified: ofbiz/trunk/framework/minilang/dtd/simple-methods.xsd ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/SimpleMethod.java ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodContext.java Modified: ofbiz/trunk/framework/minilang/dtd/simple-methods.xsd URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/dtd/simple-methods.xsd?rev=616292&r1=616291&r2=616292&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/dtd/simple-methods.xsd (original) +++ ofbiz/trunk/framework/minilang/dtd/simple-methods.xsd Tue Jan 29 04:55:45 2008 @@ -1514,7 +1514,7 @@ put in the field. You can also specify a default value in the case that the - value evaluates to an empty string or the from field is + value evaluates to an empty string or the from-field is null or empty. Then the default-value will be used. Again you can use the flexible string expander here, the @@ -1554,7 +1554,7 @@ <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. + 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> @@ -4940,6 +4940,179 @@ </xs:annotation> </xs:attribute> </xs:attributeGroup> + <xs:element name="set-calendar" substitutionGroup="OtherOperations"> + <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. + + 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. + + You must specify at least one adjuster between years, months, days, hours, minutes, seconds, millis + (in these cases it must be an integer value optionally precedeed by + or -), period-align-start and period-align-end. + + You may specify a locale or a time-zone else the respective default request value is used. + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:attributeGroup name="attlist.set"> + <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:integer" name="years"> + <xs:annotation> + <xs:documentation> + Add (optionally using +) or subtract (using -) a number of year(s) + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:integer" name="months"> + <xs:annotation> + <xs:documentation> + Add (optionally using +) or subtract (using -) a number of month(s) + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:integer" name="days"> + <xs:annotation> + <xs:documentation> + Add (optionally using +) or subtract (using -) a number of days(s) + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:integer" name="hours"> + <xs:annotation> + <xs:documentation> + Add (optionally using +) or subtract (using -) a number of hour(s) + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:integer" name="minutes"> + <xs:annotation> + <xs:documentation> + Add (optionally using +) or subtract (using -) a number of minute(s) + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:integer" name="seconds"> + <xs:annotation> + <xs:documentation> + Add (optionally using +) or subtract (using -) a number of second(s) + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:integer" name="millis"> + <xs:annotation> + <xs:documentation> + Add (optionally using +) or subtract (using -) a number of milli-second(s) + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute type="xs:string" 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 type="xs:string" 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/org/ofbiz/minilang/SimpleMethod.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/SimpleMethod.java?rev=616292&r1=616291&r2=616292&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/SimpleMethod.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/SimpleMethod.java Tue Jan 29 04:55:45 2008 @@ -770,6 +770,8 @@ } else if ("set".equals(nodeName)) { methodOperations.add(new org.ofbiz.minilang.method.envops.SetOperation(curOperElem, simpleMethod)); + } else if ("set-calendar".equals(nodeName)) { + methodOperations.add(new org.ofbiz.minilang.method.envops.SetCalendar(curOperElem, simpleMethod)); } else if ("env-to-env".equals(nodeName)) { MethodOperation mop = new org.ofbiz.minilang.method.envops.EnvToEnv(curOperElem, simpleMethod); methodOperations.add(mop); Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodContext.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodContext.java?rev=616292&r1=616291&r2=616292&view=diff ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodContext.java (original) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodContext.java Tue Jan 29 04:55:45 2008 @@ -22,6 +22,7 @@ import java.util.Iterator; import java.util.Locale; import java.util.Map; +import java.util.TimeZone; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -46,9 +47,10 @@ protected int methodType; - protected Map env = new HashMap(); + protected Map<String, Object> env = new HashMap<String, Object>(); protected Map parameters; protected Locale locale; + protected TimeZone timeZone; protected ClassLoader loader; protected LocalDispatcher dispatcher; protected GenericDelegator delegator; @@ -58,7 +60,7 @@ protected HttpServletRequest request = null; protected HttpServletResponse response = null; - protected Map results = null; + protected Map<String, Object> results = null; protected DispatchContext ctx; public MethodContext(HttpServletRequest request, HttpServletResponse response, ClassLoader loader) { @@ -68,6 +70,7 @@ this.request = request; this.response = response; this.locale = UtilHttp.getLocale(request); + this.timeZone = UtilHttp.getTimeZone(request); this.dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); this.delegator = (GenericDelegator) request.getAttribute("delegator"); this.security = (Security) request.getAttribute("security"); @@ -87,10 +90,11 @@ this.parameters = context; this.loader = loader; this.locale = (Locale) context.get("locale"); + this.timeZone = (TimeZone) context.get("timeZone"); this.dispatcher = ctx.getDispatcher(); this.delegator = ctx.getDelegator(); this.security = ctx.getSecurity(); - this.results = new HashMap(); + this.results = new HashMap<String, Object>(); this.userLogin = (GenericValue) context.get("userLogin"); if (this.loader == null) { @@ -112,6 +116,7 @@ this.parameters = context; this.loader = loader; this.locale = (Locale) context.get("locale"); + this.timeZone = (TimeZone) context.get("timeZone"); this.dispatcher = (LocalDispatcher) context.get("dispatcher"); this.delegator = (GenericDelegator) context.get("delegator"); this.security = (Security) context.get("security"); @@ -121,6 +126,7 @@ this.request = (HttpServletRequest) context.get("request"); this.response = (HttpServletResponse) context.get("response"); if (this.locale == null) this.locale = UtilHttp.getLocale(request); + if (this.timeZone == null) this.timeZone = UtilHttp.getTimeZone(request); //make sure the delegator and other objects are in place, getting from // request if necessary; assumes this came through the ControlServlet @@ -132,7 +138,7 @@ if (this.userLogin == null) this.userLogin = (GenericValue) this.request.getSession().getAttribute("userLogin"); } } else if (methodType == MethodContext.SERVICE) { - this.results = new HashMap(); + this.results = new HashMap<String, Object>(); } if (this.loader == null) { @@ -247,6 +253,10 @@ public Locale getLocale() { return this.locale; + } + + public TimeZone getTimeZone() { + return this.timeZone; } public LocalDispatcher getDispatcher() { Added: 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=616292&view=auto ============================================================================== --- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetCalendar.java (added) +++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetCalendar.java Tue Jan 29 04:55:45 2008 @@ -0,0 +1,203 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.minilang.method.envops; + +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; + +import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.ObjectType; +import org.ofbiz.base.util.UtilDateTime; +import org.ofbiz.base.util.string.FlexibleStringExpander; +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; + +/** + * Adjust a Timestamp by a specified time. + */ +public class SetCalendar extends MethodOperation { + public static final String module = SetCalendar.class.getName(); + + protected ContextAccessor field; + protected ContextAccessor fromField; + protected FlexibleStringExpander valueExdr; + protected FlexibleStringExpander defaultExdr; + protected FlexibleStringExpander yearsExdr; + protected FlexibleStringExpander monthsExdr; + protected FlexibleStringExpander daysExdr; + protected FlexibleStringExpander hoursExdr; + protected FlexibleStringExpander minutesExdr; + protected FlexibleStringExpander secondsExdr; + protected FlexibleStringExpander millisExdr; + protected FlexibleStringExpander periodAlignStart; + protected FlexibleStringExpander periodAlignEnd; + protected FlexibleStringExpander localeExdr; + protected FlexibleStringExpander timeZoneExdr; + protected boolean setIfNull; // default to false + protected boolean setIfEmpty; // default to true + + public SetCalendar(Element element, SimpleMethod simpleMethod) { + super(element, simpleMethod); + this.field = new ContextAccessor(element.getAttribute("field")); + this.fromField = new ContextAccessor(element.getAttribute("from-field")); + this.valueExdr = new FlexibleStringExpander(element.getAttribute("value")); + this.defaultExdr = new FlexibleStringExpander(element.getAttribute("default-value")); + this.yearsExdr = new FlexibleStringExpander(element.getAttribute("years")); + this.monthsExdr = new FlexibleStringExpander(element.getAttribute("months")); + this.daysExdr = new FlexibleStringExpander(element.getAttribute("days")); + this.hoursExdr = new FlexibleStringExpander(element.getAttribute("hours")); + this.minutesExdr = new FlexibleStringExpander(element.getAttribute("minutes")); + this.secondsExdr = new FlexibleStringExpander(element.getAttribute("seconds")); + this.millisExdr = new FlexibleStringExpander(element.getAttribute("millis")); + this.periodAlignStart = new FlexibleStringExpander(element.getAttribute("period-align-start")); + this.periodAlignEnd = new FlexibleStringExpander(element.getAttribute("period-align-end")); + this.localeExdr = new FlexibleStringExpander(element.getAttribute("locale")); + this.timeZoneExdr = new FlexibleStringExpander(element.getAttribute("time-zone")); + // default to false, anything but true is false + 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"); + } + if (this.yearsExdr.isEmpty() && this.monthsExdr.isEmpty() && + this.daysExdr.isEmpty() && this.hoursExdr.isEmpty() && this.minutesExdr.isEmpty() && + this.secondsExdr.isEmpty() && this.millisExdr.isEmpty() && + this.periodAlignStart.isEmpty() && this.periodAlignEnd.isEmpty()) { + throw new IllegalArgumentException("At least one adjuster must be specified"); + } + } + + public boolean exec(MethodContext methodContext) { + 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 (!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; + 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 (locale == null) { + locale = methodContext.getLocale(); + } + if (timeZone == null) { + timeZone = methodContext.getTimeZone(); + } + fromStamp = (Timestamp) ObjectType.simpleTypeConvert(newValue, "Timestamp", UtilDateTime.DATE_TIME_FORMAT, timeZone, locale, true); + } catch (Exception e) { + // Catching all exceptions - even potential ClassCastException + if (Debug.verboseOn()) Debug.logVerbose("Error converting attributes to objects: " + e.getMessage(), module); + return true; + } + + // Convert Strings to ints + int years = Integer.parseInt("0" + methodContext.expandString(this.yearsExdr)); + int months = Integer.parseInt("0" + methodContext.expandString(this.monthsExdr)); + int days = Integer.parseInt("0" + methodContext.expandString(this.daysExdr)); + int hours = Integer.parseInt("0" + methodContext.expandString(this.hoursExdr)); + int minutes = Integer.parseInt("0" + methodContext.expandString(this.minutesExdr)); + int seconds = Integer.parseInt("0" + methodContext.expandString(this.secondsExdr)); + int millis = Integer.parseInt("0" + methodContext.expandString(this.millisExdr)); + + // Adjust calendar + Calendar cal = UtilDateTime.toCalendar(fromStamp, timeZone, locale); + cal.add(Calendar.MILLISECOND, millis); + cal.add(Calendar.SECOND, seconds); + cal.add(Calendar.MINUTE, minutes); + cal.add(Calendar.HOUR, hours); + cal.add(Calendar.DAY_OF_MONTH, days); + 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); + if ("day".equals(period)) { + toStamp = UtilDateTime.getDayStart(toStamp, 0, timeZone, locale); + } else if ("week".equals(period)) { + toStamp = UtilDateTime.getWeekStart(toStamp, 0, timeZone, locale); + } else if ("month".equals(period)) { + toStamp = UtilDateTime.getMonthStart(toStamp, 0, timeZone, locale); + } else if ("year".equals(period)) { + toStamp = UtilDateTime.getYearStart(toStamp, 0, timeZone, locale); + } + } else if (!periodAlignEnd.isEmpty()) { + String period = methodContext.expandString(periodAlignEnd); + if ("day".equals(period)) { + toStamp = UtilDateTime.getDayEnd(toStamp, timeZone, locale); + } else if ("week".equals(period)) { + toStamp = UtilDateTime.getWeekEnd(toStamp, timeZone, locale); + } else if ("month".equals(period)) { + toStamp = UtilDateTime.getMonthEnd(toStamp, timeZone, locale); + } else if ("year".equals(period)) { + toStamp = UtilDateTime.getYearEnd(toStamp, timeZone, locale); + } + } + + if (Debug.verboseOn()) + Debug.logVerbose("In screen setting calendar [" + this.field.toString(), module); + this.field.put(methodContext, toStamp); + return true; + } + + 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()) + + "\"/>"; + } + public String expandedString(MethodContext methodContext) { + // TODO: something more than a stub/dummy + return this.rawString(); + } +} Propchange: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetCalendar.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetCalendar.java ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/envops/SetCalendar.java ------------------------------------------------------------------------------ svn:mime-type = text/plain |
Free forum by Nabble | Edit this page |