aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/com/healthmarketscience/jackcess/impl/expr
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2019-02-11 22:26:03 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2019-02-11 22:26:03 +0000
commit831d8c0b1d0996ba63c9e2ef3b73d6a8982a3ad2 (patch)
tree863cb3ae6e4f864ba13f1bd7ab59fdc7302318c9 /src/main/java/com/healthmarketscience/jackcess/impl/expr
parent4d6305152e060fea9e3aab12ec55bc8941d4d23f (diff)
downloadjackcess-831d8c0b1d0996ba63c9e2ef3b73d6a8982a3ad2.tar.gz
jackcess-831d8c0b1d0996ba63c9e2ef3b73d6a8982a3ad2.zip
Add ColumnFormatter utility which can apply Column Format property for display of column values
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1291 f203690c-595d-4dc9-a70b-905162fa7fd2
Diffstat (limited to 'src/main/java/com/healthmarketscience/jackcess/impl/expr')
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java7
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java3
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/expr/FormatUtil.java121
3 files changed, 91 insertions, 40 deletions
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java
index 5a871e4..6182dd4 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java
@@ -29,6 +29,7 @@ import com.healthmarketscience.jackcess.expr.EvalContext;
import com.healthmarketscience.jackcess.expr.EvalException;
import com.healthmarketscience.jackcess.expr.Function;
import com.healthmarketscience.jackcess.expr.FunctionLookup;
+import com.healthmarketscience.jackcess.expr.LocaleContext;
import com.healthmarketscience.jackcess.expr.NumericConfig;
import com.healthmarketscience.jackcess.expr.TemporalConfig;
import com.healthmarketscience.jackcess.expr.Value;
@@ -473,11 +474,11 @@ public class DefaultFunctions
}
});
- private static boolean stringIsNumeric(EvalContext ctx, Value param) {
+ private static boolean stringIsNumeric(LocaleContext ctx, Value param) {
return (maybeGetAsBigDecimal(ctx, param) != null);
}
- static BigDecimal maybeGetAsBigDecimal(EvalContext ctx, Value param) {
+ static BigDecimal maybeGetAsBigDecimal(LocaleContext ctx, Value param) {
try {
return param.getAsBigDecimal(ctx);
} catch(EvalException ignored) {
@@ -490,7 +491,7 @@ public class DefaultFunctions
return (maybeGetAsDateTimeValue(ctx, param) != null);
}
- static Value maybeGetAsDateTimeValue(EvalContext ctx, Value param) {
+ static Value maybeGetAsDateTimeValue(LocaleContext ctx, Value param) {
try {
// see if we can coerce to date/time
return param.getAsDateTimeValue(ctx);
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 39f7050..544c08b 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java
@@ -38,6 +38,7 @@ import com.healthmarketscience.jackcess.expr.ParseException;
import com.healthmarketscience.jackcess.expr.TemporalConfig;
import com.healthmarketscience.jackcess.expr.Value;
import com.healthmarketscience.jackcess.impl.ColumnImpl;
+import org.apache.commons.lang3.StringUtils;
/**
@@ -89,7 +90,7 @@ class ExpressionTokenizer
exprStr = exprStr.trim();
}
- if((exprStr == null) || (exprStr.length() == 0)) {
+ if(StringUtils.isEmpty(exprStr)) {
return null;
}
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/FormatUtil.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/FormatUtil.java
index 14ad3fa..68fce3c 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/FormatUtil.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/FormatUtil.java
@@ -41,6 +41,7 @@ import com.healthmarketscience.jackcess.expr.EvalException;
import com.healthmarketscience.jackcess.expr.NumericConfig;
import com.healthmarketscience.jackcess.expr.TemporalConfig;
import com.healthmarketscience.jackcess.expr.Value;
+import org.apache.commons.lang3.StringUtils;
import static com.healthmarketscience.jackcess.impl.expr.ExpressionTokenizer.ExprBuf;
/**
@@ -114,40 +115,41 @@ public class FormatUtil
private static final Map<String,Fmt> PREDEF_FMTS = new HashMap<String,Fmt>();
static {
- PREDEF_FMTS.put("General Date", args -> ValueSupport.toValue(
+ putPredefFormat("General Date", args -> ValueSupport.toValue(
args.coerceToDateTimeValue().getAsString()));
- PREDEF_FMTS.put("Long Date",
+ putPredefFormat("Long Date",
new PredefDateFmt(TemporalConfig.Type.LONG_DATE));
- PREDEF_FMTS.put("Medium Date",
+ putPredefFormat("Medium Date",
new PredefDateFmt(TemporalConfig.Type.MEDIUM_DATE));
- PREDEF_FMTS.put("Short Date",
+ putPredefFormat("Short Date",
new PredefDateFmt(TemporalConfig.Type.SHORT_DATE));
- PREDEF_FMTS.put("Long Time",
+ putPredefFormat("Long Time",
new PredefDateFmt(TemporalConfig.Type.LONG_TIME));
- PREDEF_FMTS.put("Medium Time",
+ putPredefFormat("Medium Time",
new PredefDateFmt(TemporalConfig.Type.MEDIUM_TIME));
- PREDEF_FMTS.put("Short Time",
+ putPredefFormat("Short Time",
new PredefDateFmt(TemporalConfig.Type.SHORT_TIME));
- PREDEF_FMTS.put("General Number", args -> ValueSupport.toValue(
+ putPredefFormat("General Number", args -> ValueSupport.toValue(
args.coerceToNumberValue().getAsString()));
- PREDEF_FMTS.put("Currency",
+ putPredefFormat("Currency",
new PredefNumberFmt(NumericConfig.Type.CURRENCY));
- PREDEF_FMTS.put("Euro", new PredefNumberFmt(NumericConfig.Type.EURO));
- PREDEF_FMTS.put("Fixed",
+ putPredefFormat("Euro", new PredefNumberFmt(NumericConfig.Type.EURO));
+ putPredefFormat("Fixed",
new PredefNumberFmt(NumericConfig.Type.FIXED));
- PREDEF_FMTS.put("Standard",
+ putPredefFormat("Standard",
new PredefNumberFmt(NumericConfig.Type.STANDARD));
- PREDEF_FMTS.put("Percent",
+ putPredefFormat("Percent",
new PredefNumberFmt(NumericConfig.Type.PERCENT));
- PREDEF_FMTS.put("Scientific", new ScientificPredefNumberFmt());
+ putPredefFormat("Scientific", new ScientificPredefNumberFmt());
- PREDEF_FMTS.put("True/False", new PredefBoolFmt("True", "False"));
- PREDEF_FMTS.put("Yes/No", new PredefBoolFmt("Yes", "No"));
- PREDEF_FMTS.put("On/Off", new PredefBoolFmt("On", "Off"));
+ putPredefFormat("True/False", new PredefBoolFmt("True", "False"));
+ putPredefFormat("Yes/No", new PredefBoolFmt("Yes", "No"));
+ putPredefFormat("On/Off", new PredefBoolFmt("On", "Off"));
}
private static final Fmt NULL_FMT = args -> ValueSupport.EMPTY_STR_VAL;
+ private static final Fmt DUMMY_FMT = args -> args.getNonNullExpr();
private static final char QUOTE_CHAR = '"';
private static final char ESCAPE_CHAR = '\\';
@@ -282,6 +284,15 @@ public class FormatUtil
_firstWeekType = firstWeekType;
}
+ public Args setExpr(Value expr) {
+ _expr = expr;
+ return this;
+ }
+
+ public Value getNonNullExpr() {
+ return (_expr.isNull() ? ValueSupport.EMPTY_STR_VAL : _expr);
+ }
+
public boolean isNullOrEmptyString() {
return(_expr.isNull() ||
// only a string value could ever be an empty string
@@ -385,37 +396,67 @@ public class FormatUtil
public String getAsString() {
return _expr.getAsString(_ctx);
}
+
+ public Value format(Fmt fmt) {
+ Value origExpr = _expr;
+ try {
+ return fmt.format(this);
+ } catch(EvalException ee) {
+ // values which cannot be formatted as the target type are just
+ // returned "as is"
+ return origExpr;
+ }
+ }
}
private FormatUtil() {}
+ /**
+ * Utility for leveraging format support outside of expression evaluation.
+ */
+ public static class StandaloneFormatter
+ {
+ private final Fmt _fmt;
+ private final Args _args;
+
+ private StandaloneFormatter(Fmt fmt, Args args) {
+ _fmt = fmt;
+ _args = args;
+ }
+
+ public Value format(Value expr) {
+ return _args.setExpr(expr).format(_fmt);
+ }
+ }
public static Value format(EvalContext ctx, Value expr, String fmtStr,
int firstDay, int firstWeekType) {
+ Args args = new Args(ctx, expr, firstDay, firstWeekType);
+ return args.format(createFormat(args, fmtStr));
+ }
- try {
- Args args = new Args(ctx, expr, firstDay, firstWeekType);
+ public static StandaloneFormatter createStandaloneFormatter(
+ EvalContext ctx, String fmtStr, int firstDay, int firstWeekType) {
+ Args args = new Args(ctx, null, firstDay, firstWeekType);
+ Fmt fmt = createFormat(args, fmtStr);
+ return new StandaloneFormatter(fmt, args);
+ }
- Fmt predefFmt = PREDEF_FMTS.get(fmtStr);
- if(predefFmt != null) {
- if(args.isNullOrEmptyString()) {
- // predefined formats return empty string for null
- return ValueSupport.EMPTY_STR_VAL;
- }
- return predefFmt.format(args);
- }
+ private static Fmt createFormat(Args args, String fmtStr) {
+ Fmt predefFmt = PREDEF_FMTS.get(fmtStr);
+ if(predefFmt != null) {
+ return predefFmt;
+ }
- // TODO implement caching for custom formats? put into Bindings. use
- // special "cache" prefix to know which caches to clear when evalconfig
- // is altered (could also cache other Format* functions)
+ if(StringUtils.isEmpty(fmtStr)) {
+ return DUMMY_FMT;
+ }
- return parseCustomFormat(fmtStr, args).format(args);
+ // TODO implement caching for custom formats? put into Bindings. use
+ // special "cache" prefix to know which caches to clear when evalconfig
+ // is altered (could also cache other Format* functions)
- } catch(EvalException ee) {
- // values which cannot be formatted as the target type are just
- // returned "as is"
- return expr;
- }
+ return parseCustomFormat(fmtStr, args);
}
private static Fmt parseCustomFormat(String fmtStr, Args args) {
@@ -1178,6 +1219,14 @@ public class FormatUtil
}
}
+ private static void putPredefFormat(String key, Fmt fmt) {
+ // predefined formats return empty string for null
+ Fmt wrapFmt = args -> (args.isNullOrEmptyString() ?
+ ValueSupport.EMPTY_STR_VAL :
+ fmt.format(args));
+ PREDEF_FMTS.put(key, wrapFmt);
+ }
+
private static final class PredefDateFmt implements Fmt
{
private final TemporalConfig.Type _type;