From fdeff8480b3b57f72a42659c30369b6d7a1a9299 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Fri, 18 Nov 2016 00:03:34 +0000 Subject: [PATCH] reorg of expression classes git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/exprs@1058 f203690c-595d-4dc9-a70b-905162fa7fd2 --- .../jackcess/expr/Expression.java | 30 +++++++++++++++ .../jackcess/expr/Function.java | 27 ++++++++++++++ .../jackcess/expr/RowContext.java | 29 +++++++++++++++ .../{util/Expression.java => expr/Value.java} | 35 +++--------------- .../{util => impl/expr}/BuiltinOperators.java | 37 ++++++++++--------- .../{util => impl/expr}/DefaultFunctions.java | 7 +++- .../expr}/ExpressionTokenizer.java | 24 ++++++------ .../{util => impl/expr}/Expressionator.java | 23 +++++++----- .../expr}/ExpressionatorTest.java | 4 +- 9 files changed, 145 insertions(+), 71 deletions(-) create mode 100644 src/main/java/com/healthmarketscience/jackcess/expr/Expression.java create mode 100644 src/main/java/com/healthmarketscience/jackcess/expr/Function.java create mode 100644 src/main/java/com/healthmarketscience/jackcess/expr/RowContext.java rename src/main/java/com/healthmarketscience/jackcess/{util/Expression.java => expr/Value.java} (58%) rename src/main/java/com/healthmarketscience/jackcess/{util => impl/expr}/BuiltinOperators.java (90%) rename src/main/java/com/healthmarketscience/jackcess/{util => impl/expr}/DefaultFunctions.java (93%) rename src/main/java/com/healthmarketscience/jackcess/{util => impl/expr}/ExpressionTokenizer.java (96%) rename src/main/java/com/healthmarketscience/jackcess/{util => impl/expr}/Expressionator.java (98%) rename src/test/java/com/healthmarketscience/jackcess/{util => impl/expr}/ExpressionatorTest.java (97%) diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/Expression.java b/src/main/java/com/healthmarketscience/jackcess/expr/Expression.java new file mode 100644 index 0000000..c5accc5 --- /dev/null +++ b/src/main/java/com/healthmarketscience/jackcess/expr/Expression.java @@ -0,0 +1,30 @@ +/* +Copyright (c) 2016 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; + +/** + * + * @author James Ahlborn + */ +public interface Expression +{ + public Object evalDefault(); + + public Boolean evalCondition(RowContext ctx); + + public String toDebugString(); +} diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/Function.java b/src/main/java/com/healthmarketscience/jackcess/expr/Function.java new file mode 100644 index 0000000..9b250b3 --- /dev/null +++ b/src/main/java/com/healthmarketscience/jackcess/expr/Function.java @@ -0,0 +1,27 @@ +/* +Copyright (c) 2016 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; + +/** + * + * @author James Ahlborn + */ +public interface Function +{ + public String getName(); + public Value eval(Value... params); +} diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/RowContext.java b/src/main/java/com/healthmarketscience/jackcess/expr/RowContext.java new file mode 100644 index 0000000..cc60f4d --- /dev/null +++ b/src/main/java/com/healthmarketscience/jackcess/expr/RowContext.java @@ -0,0 +1,29 @@ +/* +Copyright (c) 2016 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; + +/** + * + * @author James Ahlborn + */ +public interface RowContext +{ + public Value getThisColumnValue(); + + public Value getRowValue(String collectionName, String objName, + String colName); +} diff --git a/src/main/java/com/healthmarketscience/jackcess/util/Expression.java b/src/main/java/com/healthmarketscience/jackcess/expr/Value.java similarity index 58% rename from src/main/java/com/healthmarketscience/jackcess/util/Expression.java rename to src/main/java/com/healthmarketscience/jackcess/expr/Value.java index f2bb462..5c1d13f 100644 --- a/src/main/java/com/healthmarketscience/jackcess/util/Expression.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/Value.java @@ -14,23 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -package com.healthmarketscience.jackcess.util; +package com.healthmarketscience.jackcess.expr; /** * * @author James Ahlborn */ -public interface Expression +public interface Value { - public interface RowContext - { - public Value getThisColumnValue(); - - public Value getRowValue(String collectionName, String objName, - String colName); - } - - public enum ValueType + public enum Type { NULL, BOOLEAN, STRING, DATE, TIME, DATE_TIME, LONG, DOUBLE, BIG_INT, BIG_DEC; @@ -42,27 +34,12 @@ public interface Expression return inRange(DATE, DATE_TIME); } - private boolean inRange(ValueType start, ValueType end) { + private boolean inRange(Type start, Type end) { return ((start.ordinal() <= ordinal()) && (ordinal() <= end.ordinal())); } } - public interface Value - { - public ValueType getType(); - public Object get(); - } - - public interface Function - { - public String getName(); - public Value eval(Value... params); - } - - - public Object evalDefault(); - - public Boolean evalCondition(RowContext ctx); - public String toDebugString(); + public Type getType(); + public Object get(); } diff --git a/src/main/java/com/healthmarketscience/jackcess/util/BuiltinOperators.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/BuiltinOperators.java similarity index 90% rename from src/main/java/com/healthmarketscience/jackcess/util/BuiltinOperators.java rename to src/main/java/com/healthmarketscience/jackcess/impl/expr/BuiltinOperators.java index cb7eb6c..aa58b97 100644 --- a/src/main/java/com/healthmarketscience/jackcess/util/BuiltinOperators.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/BuiltinOperators.java @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package com.healthmarketscience.jackcess.util; +package com.healthmarketscience.jackcess.impl.expr; import java.io.IOException; import java.math.BigDecimal; @@ -25,7 +25,10 @@ import java.util.regex.Pattern; import com.healthmarketscience.jackcess.RuntimeIOException; import com.healthmarketscience.jackcess.impl.ColumnImpl; -import com.healthmarketscience.jackcess.util.Expression.*; +import com.healthmarketscience.jackcess.expr.Expression; +import com.healthmarketscience.jackcess.expr.Value; +import com.healthmarketscience.jackcess.expr.Function; +import com.healthmarketscience.jackcess.expr.RowContext; /** @@ -36,23 +39,23 @@ public class BuiltinOperators { public static final Value NULL_VAL = - new SimpleValue(ValueType.NULL, null); + new SimpleValue(Value.Type.NULL, null); public static final Value TRUE_VAL = - new SimpleValue(ValueType.BOOLEAN, Boolean.TRUE); + new SimpleValue(Value.Type.BOOLEAN, Boolean.TRUE); public static final Value FALSE_VAL = - new SimpleValue(ValueType.BOOLEAN, Boolean.FALSE); + new SimpleValue(Value.Type.BOOLEAN, Boolean.FALSE); public static class SimpleValue implements Value { - private final ValueType _type; + private final Value.Type _type; private final Object _val; - public SimpleValue(ValueType type, Object val) { + public SimpleValue(Value.Type type, Object val) { _type = type; _val = val; } - public ValueType getType() { + public Value.Type getType() { return _type; } @@ -277,11 +280,11 @@ public class BuiltinOperators } public static Value isNull(Value param1) { - return toValue(param1.getType() == ValueType.NULL); + return toValue(param1.getType() == Value.Type.NULL); } public static Value isNotNull(Value param1) { - return toValue(param1.getType() == ValueType.NULL); + return toValue(param1.getType() == Value.Type.NULL); } public static Value like(Value param1, Pattern pattern) { @@ -340,7 +343,7 @@ public class BuiltinOperators } private static boolean paramIsNull(Value param1) { - return (param1.getType() == ValueType.NULL); + return (param1.getType() == Value.Type.NULL); } protected static CharSequence paramToString(Object param) { @@ -410,24 +413,24 @@ public class BuiltinOperators if(obj instanceof Date) { // any way to figure out whether it's a date/time/dateTime? - return new SimpleValue(ValueType.DATE_TIME, obj); + return new SimpleValue(Value.Type.DATE_TIME, obj); } if(obj instanceof Number) { if((obj instanceof Double) || (obj instanceof Float)) { - return new SimpleValue(ValueType.DOUBLE, obj); + return new SimpleValue(Value.Type.DOUBLE, obj); } if(obj instanceof BigDecimal) { - return new SimpleValue(ValueType.BIG_DEC, obj); + return new SimpleValue(Value.Type.BIG_DEC, obj); } if(obj instanceof BigInteger) { - return new SimpleValue(ValueType.BIG_INT, obj); + return new SimpleValue(Value.Type.BIG_INT, obj); } - return new SimpleValue(ValueType.LONG, obj); + return new SimpleValue(Value.Type.LONG, obj); } try { - return new SimpleValue(ValueType.STRING, + return new SimpleValue(Value.Type.STRING, ColumnImpl.toCharSequence(obj).toString()); } catch(IOException e) { throw new RuntimeIOException(e); diff --git a/src/main/java/com/healthmarketscience/jackcess/util/DefaultFunctions.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java similarity index 93% rename from src/main/java/com/healthmarketscience/jackcess/util/DefaultFunctions.java rename to src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java index 3c9c292..7031f0e 100644 --- a/src/main/java/com/healthmarketscience/jackcess/util/DefaultFunctions.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java @@ -14,13 +14,16 @@ See the License for the specific language governing permissions and limitations under the License. */ -package com.healthmarketscience.jackcess.util; +package com.healthmarketscience.jackcess.impl.expr; import java.util.HashMap; import java.util.Map; -import com.healthmarketscience.jackcess.util.Expression.*; +import com.healthmarketscience.jackcess.expr.Expression; +import com.healthmarketscience.jackcess.expr.Value; +import com.healthmarketscience.jackcess.expr.Function; +import com.healthmarketscience.jackcess.expr.RowContext; /** * diff --git a/src/main/java/com/healthmarketscience/jackcess/util/ExpressionTokenizer.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java similarity index 96% rename from src/main/java/com/healthmarketscience/jackcess/util/ExpressionTokenizer.java rename to src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java index 192a62d..40418f4 100644 --- a/src/main/java/com/healthmarketscience/jackcess/util/ExpressionTokenizer.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package com.healthmarketscience.jackcess.util; +package com.healthmarketscience.jackcess.impl.expr; import java.math.BigDecimal; import java.text.ParseException; @@ -27,8 +27,8 @@ import java.util.List; import java.util.Map; import java.util.Set; -import static com.healthmarketscience.jackcess.util.Expressionator.*; -import com.healthmarketscience.jackcess.util.Expression.ValueType; +import static com.healthmarketscience.jackcess.impl.expr.Expressionator.*; +import com.healthmarketscience.jackcess.expr.Value; /** @@ -153,7 +153,7 @@ class ExpressionTokenizer switch(c) { case QUOTED_STR_CHAR: tokens.add(new Token(TokenType.LITERAL, null, parseQuotedString(buf), - ValueType.STRING)); + Value.Type.STRING)); break; case DATE_LIT_QUOTE_CHAR: tokens.add(parseDateLiteralString(buf, context)); @@ -316,16 +316,16 @@ class ExpressionTokenizer boolean hasTime = (dateStr.indexOf(':') >= 0); SimpleDateFormat sdf = null; - ValueType valType = null; + Value.Type valType = null; if(hasDate && hasTime) { sdf = buf.getDateTimeFormat(context); - valType = ValueType.DATE_TIME; + valType = Value.Type.DATE_TIME; } else if(hasDate) { sdf = buf.getDateFormat(context); - valType = ValueType.DATE; + valType = Value.Type.DATE; } else if(hasTime) { sdf = buf.getTimeFormat(context); - valType = ValueType.TIME; + valType = Value.Type.TIME; } else { throw new IllegalArgumentException("Invalid date time literal " + dateStr + " " + buf); @@ -375,7 +375,7 @@ class ExpressionTokenizer // what number type to use here? BigDecimal num = new BigDecimal(numStr); foundNum = true; - return new Token(TokenType.LITERAL, num, numStr, ValueType.BIG_DEC); + return new Token(TokenType.LITERAL, num, numStr, Value.Type.BIG_DEC); } catch(NumberFormatException ne) { throw new IllegalArgumentException( "Invalid number literal " + numStr + " " + buf, ne); @@ -492,7 +492,7 @@ class ExpressionTokenizer private final TokenType _type; private final Object _val; private final String _valStr; - private final ValueType _valType; + private final Value.Type _valType; private Token(TokenType type, String val) { this(type, val, val); @@ -502,7 +502,7 @@ class ExpressionTokenizer this(type, val, valStr, null); } - private Token(TokenType type, Object val, String valStr, ValueType valType) { + private Token(TokenType type, Object val, String valStr, Value.Type valType) { _type = type; _val = ((val != null) ? val : valStr); _valStr = valStr; @@ -521,7 +521,7 @@ class ExpressionTokenizer return _valStr; } - public ValueType getValueType() { + public Value.Type getValueType() { return _valType; } diff --git a/src/main/java/com/healthmarketscience/jackcess/util/Expressionator.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java similarity index 98% rename from src/main/java/com/healthmarketscience/jackcess/util/Expressionator.java rename to src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java index 286ab8b..625358e 100644 --- a/src/main/java/com/healthmarketscience/jackcess/util/Expressionator.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package com.healthmarketscience.jackcess.util; +package com.healthmarketscience.jackcess.impl.expr; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -31,9 +31,12 @@ import java.util.Set; import java.util.regex.Pattern; import com.healthmarketscience.jackcess.DatabaseBuilder; -import static com.healthmarketscience.jackcess.util.ExpressionTokenizer.Token; -import static com.healthmarketscience.jackcess.util.ExpressionTokenizer.TokenType; -import com.healthmarketscience.jackcess.util.Expression.*; +import com.healthmarketscience.jackcess.expr.Expression; +import com.healthmarketscience.jackcess.expr.Value; +import com.healthmarketscience.jackcess.expr.Function; +import com.healthmarketscience.jackcess.expr.RowContext; +import com.healthmarketscience.jackcess.impl.expr.ExpressionTokenizer.TokenType; +import com.healthmarketscience.jackcess.impl.expr.ExpressionTokenizer.Token; /** * @@ -1258,7 +1261,7 @@ public class Expressionator return _val; } - public ValueType getType() { + public Value.Type getType() { return getDelegate().getType(); } @@ -1273,7 +1276,7 @@ public class Expressionator public Object evalDefault() { Value val = eval(null); - if(val.getType() == ValueType.NULL) { + if(val.getType() == Value.Type.NULL) { return null; } @@ -1285,11 +1288,11 @@ public class Expressionator public Boolean evalCondition(RowContext ctx) { Value val = eval(ctx); - if(val.getType() == ValueType.NULL) { + if(val.getType() == Value.Type.NULL) { return null; } - if(val.getType() != ValueType.BOOLEAN) { + if(val.getType() != Value.Type.BOOLEAN) { // a single value as a conditional expression seems to act like an // implicit "=" // FIXME, what about row validators? @@ -1408,7 +1411,7 @@ public class Expressionator { private final Value _val; - private ELiteralValue(ValueType valType, Object value) { + private ELiteralValue(Value.Type valType, Object value) { _val = new BuiltinOperators.SimpleValue(valType, value); } @@ -1419,7 +1422,7 @@ public class Expressionator @Override protected void toExprString(StringBuilder sb, boolean isDebug) { - if(_val.getType() == ValueType.STRING) { + if(_val.getType() == Value.Type.STRING) { literalStrToString((String)_val.get(), sb); } else if(_val.getType().isTemporal()) { // // FIXME Date,Time,DateTime formatting? diff --git a/src/test/java/com/healthmarketscience/jackcess/util/ExpressionatorTest.java b/src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java similarity index 97% rename from src/test/java/com/healthmarketscience/jackcess/util/ExpressionatorTest.java rename to src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java index 8da921f..c7d2edc 100644 --- a/src/test/java/com/healthmarketscience/jackcess/util/ExpressionatorTest.java +++ b/src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java @@ -14,10 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -package com.healthmarketscience.jackcess.util; +package com.healthmarketscience.jackcess.impl.expr; import junit.framework.TestCase; +import com.healthmarketscience.jackcess.expr.Expression; + /** * * @author James Ahlborn -- 2.39.5