diff options
author | James Ahlborn <jtahlborn@yahoo.com> | 2018-09-06 02:11:39 +0000 |
---|---|---|
committer | James Ahlborn <jtahlborn@yahoo.com> | 2018-09-06 02:11:39 +0000 |
commit | 44b3742c6d5075d88e013f3e4177df724cf37fa1 (patch) | |
tree | 767e75834dd61debeb3941c665d4f720baf5ba24 | |
parent | 5dbcd361698afc6da7e88a7186ee459a658fcf6d (diff) | |
download | jackcess-44b3742c6d5075d88e013f3e4177df724cf37fa1.tar.gz jackcess-44b3742c6d5075d88e013f3e4177df724cf37fa1.zip |
add a bunch of javadocs for expr classes
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1191 f203690c-595d-4dc9-a70b-905162fa7fd2
10 files changed, 235 insertions, 23 deletions
diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/EvalConfig.java b/src/main/java/com/healthmarketscience/jackcess/expr/EvalConfig.java index 07ac492..72d3f51 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/EvalConfig.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/EvalConfig.java @@ -17,22 +17,55 @@ limitations under the License. package com.healthmarketscience.jackcess.expr; import javax.script.Bindings; +import com.healthmarketscience.jackcess.Database; /** + * The EvalContext allows for customization of the expression evaluation + * context for a given {@link Database} instance. * * @author James Ahlborn */ public interface EvalConfig { + /** + * @return the currently configured TemporalConfig + */ public TemporalConfig getTemporalConfig(); + /** + * Sets the TemporalConfig for use when evaluating expressions. The default + * date/time formatting is US based, so this may need to be modified when + * interacting with {@link Database} instances from other locales. + */ public void setTemporalConfig(TemporalConfig temporal); + /** + * @return the currently configured FunctionLookup + */ public FunctionLookup getFunctionLookup(); + /** + * Sets the {@link Function} provider to use during expression evaluation. + * The Functions supported by the default FunctionLookup are documented in + * {@link com.healthmarketscience.jackcess#expr}. Custom Functions can be + * implemented and provided to the expression evaluation engine by installing + * a custom FunctionLookup instance (which would presumably wrap and + * delegate to the default FunctionLookup instance for any default + * implementations). + */ public void setFunctionLookup(FunctionLookup lookup); + /** + * @return the currently configured Bindings + */ public Bindings getBindings(); + /** + * Allows for passing custom information into expression evaluation. + * Currently, none of the default implementations make use of the Bindings. + * However, in the future, customization parameters could potentially be + * supported via custom Bindings. Additionally, custom Function instances + * could be passed external information via custom Bindings. + */ public void setBindings(Bindings bindings); } diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/EvalContext.java b/src/main/java/com/healthmarketscience/jackcess/expr/EvalContext.java index f1dbab3..a7e0ecd 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/EvalContext.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/EvalContext.java @@ -20,26 +20,66 @@ import java.text.SimpleDateFormat; import javax.script.Bindings; /** + * EvalContext encapsulates all shared state for expression parsing and + * evaluation. It provides a bridge between the expression execution engine + * and the current Database. * * @author James Ahlborn */ public interface EvalContext { + /** + * @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 + * rules for the "Rnd" function + */ public float getRandom(Integer seed); + /** + * @return the expected type of the result value for the current expression + * evaluation (for "default value" and "calculated" expressions) + */ public Value.Type getResultType(); + /** + * @return the value of the "current" column (for "field validator" + * expressions) + */ public Value getThisColumnValue(); + /** + * @return the value of the entity identified by the given identifier (for + * "calculated" and "row validator" expressions) + */ public Value getIdentifierValue(Identifier identifier); + /** + * @return the currently configured Bindings (from the {@link EvalConfig}) + */ public Bindings getBindings(); + /** + * @return the value of the current key from the currently configured + * {@link Bindings} + */ public Object get(String key); + /** + * Sets the value of the given key to the given value in the currently + * configured {@link Bindings}. + */ public void put(String key, Object value); } diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/Expression.java b/src/main/java/com/healthmarketscience/jackcess/expr/Expression.java index cffd7b9..504d697 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/Expression.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/Expression.java @@ -19,10 +19,8 @@ package com.healthmarketscience.jackcess.expr; import java.util.Collection; /** - * FIXME, doc me and my friend - * * An Expression is an executable handle to an Access expression. While the - * expression framework is implemented as separate from the core database + * expression framework is implemented separately from the core database * functionality, most usage of Expressions will happen indirectly within the * context of normal database operations. Thus, most users will not ever * directly interact with an Expression instance. That said, Expressions may @@ -32,13 +30,38 @@ import java.util.Collection; */ public interface Expression { + + /** + * Evaluates the expression and returns the result. + * + * @param ctx the context within which to evaluate the expression + * + * @return the result of the expression evaluation + */ public Object eval(EvalContext ctx); + /** + * @return a detailed string which indicates how the expression was + * interpreted by the expression evaluation engine. + */ public String toDebugString(); + /** + * @return the original, unparsed expression string. By contrast, the {@link + * Object#toString} result may return a value which has been cleaned + * up with respect to the original expression. + */ public String toRawString(); + /** + * @return {@code true} if this is a constant expression. A constant + * expression will always return the same result when invoked and + * has no side effect. + */ public boolean isConstant(); + /** + * Adds any Identifiers from this expression to the given collection. + */ public void collectIdentifiers(Collection<Identifier> identifiers); } diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/Function.java b/src/main/java/com/healthmarketscience/jackcess/expr/Function.java index 0d94dde..b9bbd78 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/Function.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/Function.java @@ -17,12 +17,31 @@ limitations under the License. package com.healthmarketscience.jackcess.expr; /** + * A Function provides an invokable handle to external functionality to an + * expression. * * @author James Ahlborn */ -public interface Function +public interface Function { + + /** + * @return the name of this function + */ public String getName(); + + /** + * Evaluates this function within the given context with the given + * parameters. + * + * @return the result of the function evaluation + */ public Value eval(EvalContext ctx, Value... params); + + /** + * @return {@code true} if this function is a "pure" function, {@code false} + * otherwise. A pure function will always return the same result + * for a given set of parameters and has no side effects. + */ public boolean isPure(); } diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/FunctionLookup.java b/src/main/java/com/healthmarketscience/jackcess/expr/FunctionLookup.java index 8314c41..3210db9 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/FunctionLookup.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/FunctionLookup.java @@ -17,10 +17,17 @@ limitations under the License. package com.healthmarketscience.jackcess.expr; /** + * A FunctionLookup provides a source for {@link Function} instances used + * during expression evaluation. * * @author James Ahlborn */ public interface FunctionLookup { + /** + * @return the function for the given function name, or {@code null} if none + * exists. Note that Access function names are treated in a case + * insensitive manner. + */ public Function getFunction(String name); } diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/Identifier.java b/src/main/java/com/healthmarketscience/jackcess/expr/Identifier.java index cb402e7..45db1ad 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/Identifier.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/Identifier.java @@ -19,15 +19,23 @@ package com.healthmarketscience.jackcess.expr; import org.apache.commons.lang.ObjectUtils; /** + * identifies a database entity (e.g. the name of a database field). An + * Identify must have an object name, but the collection name and property + * name are optional. * * @author James Ahlborn */ -public class Identifier +public class Identifier { private final String _collectionName; private final String _objectName; private final String _propertyName; + public Identifier(String objectName) + { + this(null, objectName, null); + } + public Identifier(String collectionName, String objectName, String propertyName) { _collectionName = collectionName; @@ -35,17 +43,17 @@ public class Identifier _propertyName = propertyName; } - public String getCollectionName() + public String getCollectionName() { return _collectionName; } - public String getObjectName() + public String getObjectName() { return _objectName; } - public String getPropertyName() + public String getPropertyName() { return _propertyName; } @@ -62,7 +70,7 @@ public class Identifier } Identifier oi = (Identifier)o; - + return (ObjectUtils.equals(_objectName, oi._objectName) && ObjectUtils.equals(_collectionName, oi._collectionName) && ObjectUtils.equals(_propertyName, oi._propertyName)); diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java b/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java index 8059538..2ea1a12 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java @@ -17,6 +17,11 @@ limitations under the License. package com.healthmarketscience.jackcess.expr; /** + * A TemporalConfig encapsulates date/time formatting options for expression + * evaluation. The default {@link #US_TEMPORAL_CONFIG} instance provides US + * specific locale configuration. Databases which have been built for other + * locales can utilize custom implementations of TemporalConfig in order to + * evaluate expressions correctly. * * @author James Ahlborn */ @@ -26,6 +31,7 @@ public class TemporalConfig public static final String US_TIME_FORMAT_12 = "h:mm:ss a"; public static final String US_TIME_FORMAT_24 = "H:mm:ss"; + /** 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, '/', ':'); @@ -37,6 +43,24 @@ public class TemporalConfig private final String _dateTimeFormat12; private final String _dateTimeFormat24; + /** + * Instantiates a new TemporalConfig with the given configuration. Note + * that the date/time format variants will be created by concatenating the + * relevant date and time formats, separated by a single space, e.g. "<date> + * <time>". + * + * @param dateFormat the date (no time) format + * @param timeFormat12 the 12 hour time format + * @param timeFormat24 the 24 hour time format + * @param dateSeparator the primary separator used to separate elements in + * the date format. this is used to identify the + * components of date/time string. + * @param timeSeparator the primary separator used to separate elements in + * the time format (both 12 hour and 24 hour). this is + * used to identify the components of a date/time + * string. This value should differ from the + * dateSeparator. + */ public TemporalConfig(String dateFormat, String timeFormat12, String timeFormat24, char dateSeparator, char timeSeparator) diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/Value.java b/src/main/java/com/healthmarketscience/jackcess/expr/Value.java index 39008f2..210c170 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/Value.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/Value.java @@ -20,11 +20,17 @@ import java.math.BigDecimal; import java.util.Date; /** + * Wrapper for a typed primitive value used within the expression evaluation + * engine. Note that the "Null" value is represented by an actual Value + * instance with the type of {@link Type#NULL}. Also note that all the + * conversion methods will throw an {@link EvalException} if the conversion is + * not supported for the current value. * * @author James Ahlborn */ -public interface Value +public interface Value { + /** the types supported within the expression evaluation engine */ public enum Type { NULL, STRING, DATE, TIME, DATE_TIME, LONG, DOUBLE, BIG_DEC; @@ -60,22 +66,49 @@ public interface Value } } - + /** + * @return the type of this value + */ public Type getType(); + /** + * @return the raw primitive value + */ public Object get(); + /** + * @return {@code true} if this value represents a "Null" value, + * {@code false} otherwise. + */ public boolean isNull(); + /** + * @return this primitive value converted to a boolean + */ public boolean getAsBoolean(); + /** + * @return this primitive value converted to a String + */ public String getAsString(); + /** + * @return this primitive value converted to a Date + */ public Date getAsDateTime(EvalContext ctx); + /** + * @return this primitive value converted (rounded) to an int + */ public Integer getAsLongInt(); + /** + * @return this primitive value converted (rounded) to a double + */ public Double getAsDouble(); + /** + * @return this primitive value converted to a BigDecimal + */ public BigDecimal getAsBigDecimal(); } 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 6e02e88..a6e6ac3 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/package-info.java @@ -19,10 +19,16 @@ limitations under the License. * the 2.2.0 release). This functionality is currently disabled by default * but can be globally enabled via the system property * "com.healthmarketscience.jackcess.enableExpressionEvaluation" or - * selectively enabled on a per database basis using {@link com.healthmarketscience.jackcess.Database#setEvaluateExpressions(Boolean)}. Expressions can be used in a - * number of different places within an Access database. - *<p/> - * When enabled, Jackcess supports the following usage: + * selectively enabled on a per database basis using {@link com.healthmarketscience.jackcess.Database#setEvaluateExpressions(Boolean)}. + * <p/> + * The expression evaluation engine implementation does its best to follow all + * the warts and idiosyncracies of Access expression evaluation (both those + * that are documented as well as those discovered through experimentation). + * These include such things as value conversions, "Null" handling, rounding + * rules, and implicit interpretations of expression in certain contexts. + * <p/> + * Expressions can be used in a number of different places within an Access + * database. When enabled, Jackcess supports the following usage: * <ul> * <li><b>Default Values:</b> When a row is added which has a * {@code null} value for a field which has a default value @@ -48,19 +54,37 @@ limitations under the License. * <h2>Supporting Classes</h2> * <p/> * The classes in this package make up the public api for expression handling - * in Jackcess. They geneerally fall into two categoreies: + * in Jackcess. They generally fall into two categories: * <p/> * <h3>General Use Classes</h3> * <p/> * <ul> + * <li>{@link EvalConfig} allows for customization of the expression + * evaluation context for a given {@link com.healthmarketscience.jackcess.Database} instance.</li> + * <li>{@link TemporalConfig} encapsulates date/time formatting options for + * expression evaluation.</li> + * <li>{@link FunctionLookup} provides a source for {@link Function} instances + * used during expression evaluation.</li> + * <li>{@link EvalException} wrapper exception thrown for failures which occur + * during expression evaluation.</li> + * <li>{@link ParseException} wrapper exception thrown for failures which + * occur during expression parsing.</li> * </ul> * <p/> * <h3>Advanced Use Classes</h3> * <p/> * <ul> + * <li>{@link EvalContext} encapsulates all shared state for expression + * parsing and evaluation.</li> + * <li>{@link Expression} provides an executable handle to an actual + * Access expression.</li> + * <li>{@link Function} provides an invokable handle to external functionality + * to an expression.</li> + * <li>{@link Identifier} identifies a database entity (e.g. the name of a + * database field).</li> + * <li>{@link Value} represents a typed primitive value.</li> * </ul> * <p/> - * <p/> * <h2>Function Support</h2> * <p/> * Jackcess supports many of the standard Access functions. The following diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml index c8d7f6b..cc7f318 100644 --- a/src/site/xdoc/index.xml +++ b/src/site/xdoc/index.xml @@ -19,16 +19,17 @@ for more info. </p> - <subsection name="Expression Evaluation"> + <subsection name="Expression Evaluation (FIXME)"> <p> Have you ever wished that Jackcess could handle field "default - values" (or other expressions)? Wish no longer! The 2.2.0 version - of Jackcess has finally landed a beta version of expression - evaluation. See the <a href="apidocs/com/healthmarketscience/jackcess/expr/package-summary.html#package_description">expr package</a> javadocs for more details. + values" (or other expressins)? Wish no longer! Experimental + support for expression evaluation has finally landed in the 2.2.0 + release. See the <a href="apidocs/com/healthmarketscience/jackcess/expr/package-summary.html#package_description">expression package</a> + javadocs for more details. </p> </subsection> - <subsection name="Brand New License!"> + <subsection name="Brand New License! (2015-04-16)"> <p> Due to the generosity of Health Market Science and the efforts of the <a href="https://tika.apache.org/">Apache Tika project</a>, the @@ -37,7 +38,7 @@ </p> </subsection> - <subsection name="All New: Jackcess 2.0"> + <subsection name="All New: Jackcess 2.0 (2013-08-26)"> <p> <b>New crunchy outside, same yummy filling!</b> </p> |