aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/com
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2018-09-29 19:36:51 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2018-09-29 19:36:51 +0000
commita314d6501dd4266ad197847f8879ac0a119ec930 (patch)
tree76606167d0cc6cbdcf96c4cbe9dde378359af864 /src/main/java/com
parent0dea2079f785d3f1b70a2a2263c12b3e511ad94d (diff)
downloadjackcess-a314d6501dd4266ad197847f8879ac0a119ec930.tar.gz
jackcess-a314d6501dd4266ad197847f8879ac0a119ec930.zip
add support for monthname function; implement better string to date/time conversions
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1202 f203690c-595d-4dc9-a70b-905162fa7fd2
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/expr/EvalContext.java15
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/expr/LocaleContext.java41
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java72
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/expr/package-info.java4
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java57
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java202
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java3
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/StringValue.java1
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java8
9 files changed, 285 insertions, 118 deletions
diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/EvalContext.java b/src/main/java/com/healthmarketscience/jackcess/expr/EvalContext.java
index a7e0ecd..c82fe43 100644
--- a/src/main/java/com/healthmarketscience/jackcess/expr/EvalContext.java
+++ b/src/main/java/com/healthmarketscience/jackcess/expr/EvalContext.java
@@ -16,7 +16,6 @@ limitations under the License.
package com.healthmarketscience.jackcess.expr;
-import java.text.SimpleDateFormat;
import javax.script.Bindings;
/**
@@ -26,21 +25,9 @@ import javax.script.Bindings;
*
* @author James Ahlborn
*/
-public interface EvalContext
+public interface EvalContext extends LocaleContext
{
/**
- * @return the currently configured TemporalConfig (from the
- * {@link EvalConfig})
- */
- public TemporalConfig getTemporalConfig();
-
- /**
- * @return an appropriately configured (i.e. TimeZone and other date/time
- * flags) SimpleDateFormat for the given format.
- */
- public SimpleDateFormat createDateFormat(String formatStr);
-
- /**
* @param seed the seed for the random value, following the rules for the
* "Rnd" function
* @return a random value for the given seed following the statefulness
diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/LocaleContext.java b/src/main/java/com/healthmarketscience/jackcess/expr/LocaleContext.java
new file mode 100644
index 0000000..8a9a649
--- /dev/null
+++ b/src/main/java/com/healthmarketscience/jackcess/expr/LocaleContext.java
@@ -0,0 +1,41 @@
+/*
+Copyright (c) 2018 James Ahlborn
+
+Licensed 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 com.healthmarketscience.jackcess.expr;
+
+import java.text.SimpleDateFormat;
+
+/**
+ * LocaleContext encapsulates all shared localization state for expression
+ * parsing and evaluation.
+ *
+ * @author James Ahlborn
+ */
+public interface LocaleContext
+{
+ /**
+ * @return the currently configured TemporalConfig (from the
+ * {@link EvalConfig})
+ */
+ public TemporalConfig getTemporalConfig();
+
+ /**
+ * @return an appropriately configured (i.e. TimeZone and other date/time
+ * flags) SimpleDateFormat for the given format.
+ */
+ public SimpleDateFormat createDateFormat(String formatStr);
+
+}
diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java b/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java
index 2ea1a12..d7061ca 100644
--- a/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java
+++ b/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java
@@ -16,6 +16,9 @@ limitations under the License.
package com.healthmarketscience.jackcess.expr;
+import java.text.DateFormatSymbols;
+import java.util.Locale;
+
/**
* A TemporalConfig encapsulates date/time formatting options for expression
* evaluation. The default {@link #US_TEMPORAL_CONFIG} instance provides US
@@ -33,7 +36,45 @@ public class TemporalConfig
/** default implementation which is configured for the US locale */
public static final TemporalConfig US_TEMPORAL_CONFIG = new TemporalConfig(
- US_DATE_FORMAT, US_TIME_FORMAT_12, US_TIME_FORMAT_24, '/', ':');
+ US_DATE_FORMAT, US_TIME_FORMAT_12, US_TIME_FORMAT_24, '/', ':', Locale.US);
+
+ public enum Type {
+ DATE, TIME, DATE_TIME, TIME_12, TIME_24, DATE_TIME_12, DATE_TIME_24;
+
+ public Type getDefaultType() {
+ switch(this) {
+ case DATE:
+ return DATE;
+ case TIME:
+ case TIME_12:
+ case TIME_24:
+ return TIME;
+ case DATE_TIME:
+ case DATE_TIME_12:
+ case DATE_TIME_24:
+ return DATE_TIME;
+ default:
+ throw new RuntimeException("invalid type " + this);
+ }
+ }
+
+ public Value.Type getValueType() {
+ switch(this) {
+ case DATE:
+ return Value.Type.DATE;
+ case TIME:
+ case TIME_12:
+ case TIME_24:
+ return Value.Type.TIME;
+ case DATE_TIME:
+ case DATE_TIME_12:
+ case DATE_TIME_24:
+ return Value.Type.DATE_TIME;
+ default:
+ throw new RuntimeException("invalid type " + this);
+ }
+ }
+ }
private final String _dateFormat;
private final String _timeFormat12;
@@ -42,6 +83,7 @@ public class TemporalConfig
private final char _timeSeparator;
private final String _dateTimeFormat12;
private final String _dateTimeFormat24;
+ private final DateFormatSymbols _symbols;
/**
* Instantiates a new TemporalConfig with the given configuration. Note
@@ -63,7 +105,7 @@ public class TemporalConfig
*/
public TemporalConfig(String dateFormat, String timeFormat12,
String timeFormat24, char dateSeparator,
- char timeSeparator)
+ char timeSeparator, Locale locale)
{
_dateFormat = dateFormat;
_timeFormat12 = timeFormat12;
@@ -72,6 +114,7 @@ public class TemporalConfig
_timeSeparator = timeSeparator;
_dateTimeFormat12 = _dateFormat + " " + _timeFormat12;
_dateTimeFormat24 = _dateFormat + " " + _timeFormat24;
+ _symbols = DateFormatSymbols.getInstance(locale);
}
public String getDateFormat() {
@@ -113,4 +156,29 @@ public class TemporalConfig
public char getTimeSeparator() {
return _timeSeparator;
}
+
+ public String getDateTimeFormat(Type type) {
+ switch(type) {
+ case DATE:
+ return getDefaultDateFormat();
+ case TIME:
+ return getDefaultTimeFormat();
+ case DATE_TIME:
+ return getDefaultDateTimeFormat();
+ case TIME_12:
+ return getTimeFormat12();
+ case TIME_24:
+ return getTimeFormat24();
+ case DATE_TIME_12:
+ return getDateTimeFormat12();
+ case DATE_TIME_24:
+ return getDateTimeFormat24();
+ default:
+ throw new IllegalArgumentException("unknown date/time type " + type);
+ }
+ }
+
+ public DateFormatSymbols getDateFormatSymbols() {
+ return _symbols;
+ }
}
diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java b/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java
index 416c96e..05c72e6 100644
--- a/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java
+++ b/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java
@@ -138,7 +138,7 @@ limitations under the License.
* <tr class="TableRowColor"><td>Hour</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>Minute</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>Month</td><td>Y</td></tr>
- * <tr class="TableRowColor"><td>MonthName</td><td></td></tr>
+ * <tr class="TableRowColor"><td>MonthName</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>Now</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>Second</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>Time</td><td>Y</td></tr>
@@ -146,7 +146,7 @@ limitations under the License.
* <tr class="TableRowColor"><td>TimeSerial</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>TimeValue</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>Weekday</td><td>Y</td></tr>
- * <tr class="TableRowColor"><td>WeekdayName</td><td></td></tr>
+ * <tr class="TableRowColor"><td>WeekdayName</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>Year</td><td>Y</td></tr>
* </table>
*
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java
index c8ffc0f..b062a05 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java
@@ -26,6 +26,7 @@ import java.util.Date;
import com.healthmarketscience.jackcess.expr.EvalContext;
import com.healthmarketscience.jackcess.expr.EvalException;
import com.healthmarketscience.jackcess.expr.Function;
+import com.healthmarketscience.jackcess.expr.TemporalConfig;
import com.healthmarketscience.jackcess.expr.Value;
import com.healthmarketscience.jackcess.impl.ColumnImpl;
import static com.healthmarketscience.jackcess.impl.expr.DefaultFunctions.*;
@@ -204,6 +205,27 @@ public class DefaultDateFunctions
}
});
+ public static final Function MONTHNAME = registerFunc(new FuncVar("MonthName", 1, 2) {
+ @Override
+ protected Value evalVar(EvalContext ctx, Value[] params) {
+ Value param1 = params[0];
+ if(param1 == null) {
+ return null;
+ }
+ // convert from 1 based to 0 based value
+ int month = param1.getAsLongInt() - 1;
+
+ boolean abbreviate = getOptionalBooleanParam(params, 1);
+
+ DateFormatSymbols syms = ctx.createDateFormat(
+ ctx.getTemporalConfig().getDateFormat()).getDateFormatSymbols();
+ String[] monthNames = (abbreviate ?
+ syms.getShortMonths() : syms.getMonths());
+ // note, the array is 1 based
+ return ValueSupport.toValue(monthNames[month]);
+ }
+ });
+
public static final Function DAY = registerFunc(new Func1NullIsNull("Day") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {
@@ -236,10 +258,7 @@ public class DefaultDateFunctions
}
int weekday = param1.getAsLongInt();
- boolean abbreviate = false;
- if(params.length > 1) {
- abbreviate = params[1].getAsBoolean();
- }
+ boolean abbreviate = getOptionalBooleanParam(params, 1);
int firstDay = getFirstDayParam(params, 2);
@@ -280,14 +299,31 @@ public class DefaultDateFunctions
}
if(type == Value.Type.STRING) {
- // see if we can coerce to date/time
- // FIXME use ExpressionatorTokenizer to detect explicit date/time format
+ // see if we can coerce to date/time or double
+ String valStr = param.getAsString();
+ TemporalConfig.Type valTempType = ExpressionTokenizer.determineDateType(
+ valStr, ctx);
+
+ if(valTempType != null) {
+
+ try {
+ DateFormat parseDf = ExpressionTokenizer.createParseDateFormat(
+ valTempType, ctx);
+ Date dateVal = ExpressionTokenizer.parseComplete(parseDf, valStr);
+ return ValueSupport.toValue(ctx, valTempType.getValueType(),
+ dateVal);
+ } catch(java.text.ParseException pe) {
+ // not a valid date string, not a date/time
+ return null;
+ }
+ }
+ // see if string can be coerced to number
try {
return numberToDateValue(ctx, param.getAsDouble());
} catch(NumberFormatException ignored) {
- // not a number
+ // not a number, not a date/time
return null;
}
}
@@ -358,4 +394,11 @@ public class DefaultDateFunctions
}
return firstDay;
}
+
+ private static boolean getOptionalBooleanParam(Value[] params, int idx) {
+ if(params.length > idx) {
+ return params[idx].getAsBoolean();
+ }
+ return false;
+ }
}
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java
index f14f934..c75fae0 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
+import java.util.EnumMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -32,9 +33,10 @@ import java.util.Set;
import java.util.TimeZone;
import static com.healthmarketscience.jackcess.impl.expr.Expressionator.*;
-import com.healthmarketscience.jackcess.expr.Value;
-import com.healthmarketscience.jackcess.expr.TemporalConfig;
+import com.healthmarketscience.jackcess.expr.LocaleContext;
import com.healthmarketscience.jackcess.expr.ParseException;
+import com.healthmarketscience.jackcess.expr.TemporalConfig;
+import com.healthmarketscience.jackcess.expr.Value;
/**
@@ -290,9 +292,33 @@ class ExpressionTokenizer
private static Token parseDateLiteral(ExprBuf buf)
{
- TemporalConfig cfg = buf.getTemporalConfig();
String dateStr = parseDateLiteralString(buf);
+ TemporalConfig.Type type = determineDateType(
+ dateStr, buf.getContext());
+ if(type == null) {
+ throw new ParseException("Invalid date/time literal " + dateStr +
+ " " + buf);
+ }
+
+ // note that although we may parse in the time "24" format, we will
+ // display as the default time format
+ DateFormat parseDf = buf.getDateTimeFormat(type);
+ DateFormat df = buf.getDateTimeFormat(type.getDefaultType());
+
+ try {
+ return new Token(TokenType.LITERAL, parseComplete(parseDf, dateStr),
+ dateStr, type.getValueType(), df);
+ } catch(java.text.ParseException pe) {
+ throw new ParseException(
+ "Invalid date/time literal " + dateStr + " " + buf, pe);
+ }
+ }
+
+ static TemporalConfig.Type determineDateType(
+ String dateStr, LocaleContext ctx)
+ {
+ TemporalConfig cfg = ctx.getTemporalConfig();
boolean hasDate = (dateStr.indexOf(cfg.getDateSeparator()) >= 0);
boolean hasTime = (dateStr.indexOf(cfg.getTimeSeparator()) >= 0);
boolean hasAmPm = false;
@@ -306,29 +332,65 @@ class ExpressionTokenizer
PM_SUFFIX, 0, AMPM_SUFFIX_LEN)));
}
- DateFormat sdf = null;
- Value.Type valType = null;
- if(hasDate && hasTime) {
- sdf = (hasAmPm ? buf.getDateTimeFormat12() : buf.getDateTimeFormat24());
- valType = Value.Type.DATE_TIME;
- } else if(hasDate) {
- sdf = buf.getDateFormat();
- valType = Value.Type.DATE;
+ if(hasDate) {
+ if(hasTime) {
+ return (hasAmPm ? TemporalConfig.Type.DATE_TIME_12 :
+ TemporalConfig.Type.DATE_TIME_24);
+ }
+ return TemporalConfig.Type.DATE;
} else if(hasTime) {
- sdf = (hasAmPm ? buf.getTimeFormat12() : buf.getTimeFormat24());
- valType = Value.Type.TIME;
- } else {
- throw new ParseException("Invalid date time literal " + dateStr +
- " " + buf);
+ return (hasAmPm ? TemporalConfig.Type.TIME_12 :
+ TemporalConfig.Type.TIME_24);
}
+ return null;
+ }
- try {
- return new Token(TokenType.LITERAL, sdf.parse(dateStr), dateStr, valType,
- sdf);
- } catch(java.text.ParseException pe) {
- throw new ParseException(
- "Invalid date time literal " + dateStr + " " + buf, pe);
+ static DateFormat createParseDateFormat(TemporalConfig.Type type,
+ LocaleContext ctx)
+ {
+ TemporalConfig cfg = ctx.getTemporalConfig();
+ DateFormat df = ctx.createDateFormat(cfg.getDateTimeFormat(type));
+
+ TemporalConfig.Type parseType = null;
+ switch(type) {
+ case TIME:
+ parseType = TemporalConfig.Type.DATE_TIME;
+ break;
+ case TIME_12:
+ parseType = TemporalConfig.Type.DATE_TIME_12;
+ break;
+ case TIME_24:
+ parseType = TemporalConfig.Type.DATE_TIME_24;
+ break;
+ default:
+ }
+
+ if(parseType != null) {
+ // we need to use a special DateFormat impl which handles parsing
+ // separately from formatting
+ String baseDate = getBaseDatePrefix(ctx);
+ DateFormat parseDf = ctx.createDateFormat(
+ cfg.getDateTimeFormat(parseType));
+ df = new TimeFormat(parseDf, df, baseDate);
+ }
+
+ return df;
+ }
+
+ private static String getBaseDatePrefix(LocaleContext ctx) {
+ String dateFmt = ctx.getTemporalConfig().getDateFormat();
+ String baseDate = BASE_DATE;
+ if(!BASE_DATE_FMT.equals(dateFmt)) {
+ try {
+ // need to reformat the base date to the relevant date format
+ DateFormat parseDf = ctx.createDateFormat(BASE_DATE_FMT);
+ DateFormat df = ctx.createDateFormat(dateFmt);
+ baseDate = df.format(parseComplete(parseDf, baseDate));
+ } catch(Exception e) {
+ throw new ParseException("Could not parse base date", e);
+ }
}
+ return baseDate + " ";
}
private static Token maybeParseNumberLiteral(char firstChar, ExprBuf buf) {
@@ -426,17 +488,29 @@ class ExpressionTokenizer
return new AbstractMap.SimpleImmutableEntry<K,V>(a, b);
}
+ static Date parseComplete(DateFormat df, String str)
+ throws java.text.ParseException
+ {
+ // the java parsers will parse "successfully" even if there is leftover
+ // information. we only want to consider a parse operation successful if
+ // it parses the entire string (ignoring surrounding whitespace)
+ str = str.trim();
+ ParsePosition pp = new ParsePosition(0);
+ Object d = df.parse(str, pp);
+ if(pp.getIndex() < str.length()) {
+ throw new java.text.ParseException("Failed parsing '" + str + "'",
+ pp.getIndex());
+ }
+ return (Date)d;
+ }
+
private static final class ExprBuf
{
private final String _str;
private final ParseContext _ctx;
private int _pos;
- private DateFormat _dateFmt;
- private DateFormat _timeFmt12;
- private DateFormat _dateTimeFmt12;
- private DateFormat _timeFmt24;
- private DateFormat _dateTimeFmt24;
- private String _baseDate;
+ private final Map<TemporalConfig.Type,DateFormat> _dateTimeFmts =
+ new EnumMap<TemporalConfig.Type,DateFormat>(TemporalConfig.Type.class);
private final StringBuilder _scratch = new StringBuilder();
private ExprBuf(String str, ParseContext ctx) {
@@ -484,69 +558,17 @@ class ExpressionTokenizer
return _scratch;
}
- public TemporalConfig getTemporalConfig() {
- return _ctx.getTemporalConfig();
+ public ParseContext getContext() {
+ return _ctx;
}
- public DateFormat getDateFormat() {
- if(_dateFmt == null) {
- _dateFmt = _ctx.createDateFormat(getTemporalConfig().getDateFormat());
+ public DateFormat getDateTimeFormat(TemporalConfig.Type type) {
+ DateFormat df = _dateTimeFmts.get(type);
+ if(df == null) {
+ df = createParseDateFormat(type, _ctx);
+ _dateTimeFmts.put(type, df);
}
- return _dateFmt;
- }
-
- public DateFormat getTimeFormat12() {
- if(_timeFmt12 == null) {
- _timeFmt12 = new TimeFormat(
- getDateTimeFormat12(), _ctx.createDateFormat(
- getTemporalConfig().getTimeFormat12()),
- getBaseDate());
- }
- return _timeFmt12;
- }
-
- public DateFormat getDateTimeFormat12() {
- if(_dateTimeFmt12 == null) {
- _dateTimeFmt12 = _ctx.createDateFormat(
- getTemporalConfig().getDateTimeFormat12());
- }
- return _dateTimeFmt12;
- }
-
- public DateFormat getTimeFormat24() {
- if(_timeFmt24 == null) {
- _timeFmt24 = new TimeFormat(
- getDateTimeFormat24(), _ctx.createDateFormat(
- getTemporalConfig().getTimeFormat24()),
- getBaseDate());
- }
- return _timeFmt24;
- }
-
- public DateFormat getDateTimeFormat24() {
- if(_dateTimeFmt24 == null) {
- _dateTimeFmt24 = _ctx.createDateFormat(
- getTemporalConfig().getDateTimeFormat24());
- }
- return _dateTimeFmt24;
- }
-
- private String getBaseDate() {
- if(_baseDate == null) {
- String dateFmt = getTemporalConfig().getDateFormat();
- String baseDate = BASE_DATE;
- if(!BASE_DATE_FMT.equals(dateFmt)) {
- try {
- // need to reformat the base date to the relevant date format
- DateFormat df = _ctx.createDateFormat(BASE_DATE_FMT);
- baseDate = getDateFormat().format(df.parse(baseDate));
- } catch(Exception e) {
- throw new ParseException("Could not parse base date", e);
- }
- }
- _baseDate = baseDate + " ";
- }
- return _baseDate;
+ return df;
}
@Override
@@ -618,6 +640,10 @@ class ExpressionTokenizer
}
}
+ /**
+ * Special date/time format which will parse time-only strings "correctly"
+ * according to how access handles time-only values.
+ */
private static final class TimeFormat extends DateFormat
{
private static final long serialVersionUID = 0L;
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java
index f948d15..d53d6d3 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java
@@ -41,6 +41,7 @@ import com.healthmarketscience.jackcess.expr.Expression;
import com.healthmarketscience.jackcess.expr.Function;
import com.healthmarketscience.jackcess.expr.FunctionLookup;
import com.healthmarketscience.jackcess.expr.Identifier;
+import com.healthmarketscience.jackcess.expr.LocaleContext;
import com.healthmarketscience.jackcess.expr.ParseException;
import com.healthmarketscience.jackcess.expr.TemporalConfig;
import com.healthmarketscience.jackcess.expr.Value;
@@ -65,7 +66,7 @@ public class Expressionator
DEFAULT_VALUE, EXPRESSION, FIELD_VALIDATOR, RECORD_VALIDATOR;
}
- public interface ParseContext {
+ public interface ParseContext extends LocaleContext {
public TemporalConfig getTemporalConfig();
public SimpleDateFormat createDateFormat(String formatStr);
public FunctionLookup getFunctionLookup();
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/StringValue.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/StringValue.java
index 51b9c6a..781faf4 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/StringValue.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/StringValue.java
@@ -90,6 +90,7 @@ public class StringValue extends BaseValue
if(tmpVal.charAt(0) != NUMBER_BASE_PREFIX) {
// parse using standard numeric support
+ // FIXME, this should handle grouping separator, but needs ctx
_num = ValueSupport.normalize(new BigDecimal(tmpVal));
return (BigDecimal)_num;
}
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java
index 279a4f0..b0924f3 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java
@@ -20,7 +20,7 @@ import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.Date;
-import com.healthmarketscience.jackcess.expr.EvalContext;
+import com.healthmarketscience.jackcess.expr.LocaleContext;
import com.healthmarketscience.jackcess.expr.EvalException;
import com.healthmarketscience.jackcess.expr.Value;
import com.healthmarketscience.jackcess.impl.ColumnImpl;
@@ -90,7 +90,7 @@ public class ValueSupport
dd, fmt.getCalendar())), fmt);
}
- public static Value toValue(EvalContext ctx, Value.Type type, Date d) {
+ public static Value toValue(LocaleContext ctx, Value.Type type, Date d) {
return toValue(type, d, getDateFormatForType(ctx, type));
}
@@ -107,7 +107,7 @@ public class ValueSupport
}
}
- static Value toDateValue(EvalContext ctx, Value.Type type, double v,
+ static Value toDateValue(LocaleContext ctx, Value.Type type, double v,
Value param1, Value param2)
{
DateFormat fmt = null;
@@ -124,7 +124,7 @@ public class ValueSupport
return toValue(type, d, fmt);
}
- static DateFormat getDateFormatForType(EvalContext ctx, Value.Type type) {
+ static DateFormat getDateFormatForType(LocaleContext ctx, Value.Type type) {
String fmtStr = null;
switch(type) {
case DATE: