LUCENE-5207: minor docs and API cleanups

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene5207@1522781 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2013-09-13 05:21:27 +00:00
parent 0603e66d7d
commit b29b3e5f3f
7 changed files with 63 additions and 45 deletions

View File

@ -70,7 +70,7 @@ public abstract class Bindings implements Iterable<String> {
if (vs instanceof ExpressionValueSource) {
Expression expr = ((ExpressionValueSource)vs).expression;
for (String external : expr.externals) {
for (String external : expr.variables) {
if (chain.contains(external)) {
throw new IllegalArgumentException("Recursion Error: Cycle detected originating in (" + external + ")");
}

View File

@ -16,6 +16,7 @@ package org.apache.lucene.expressions;
* limitations under the License.
*/
import org.apache.lucene.expressions.js.JavascriptCompiler; // javadocs
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.search.SortField;
@ -38,32 +39,33 @@ import org.apache.lucene.search.SortField;
* Query query = new TermQuery(new Term("body", "contents"));
* searcher.search(query, null, 10, sort);
* </pre>
* @see JavascriptCompiler#compile
* @lucene.experimental
*/
public abstract class Expression {
/** The original {@link String} expression, before it was compiled */
public final String expression;
/** The original source text */
public final String sourceText;
/** The names of external references found in the expression */
public final String[] externals;
/** Named variables referred to by this expression */
public final String[] variables;
/**
* Creates a new {@code CompiledExpression}.
* Creates a new {@code Expression}.
*
* @param expression The expression that was compiled
* @param externals Names of external references found in the expression
* @param sourceText Source text for the expression: e.g. {@code ln(popularity)}
* @param variables Names of external variables referred to by the expression
*/
public Expression(String expression, String[] externals) {
this.expression = expression;
this.externals = externals;
protected Expression(String sourceText, String[] variables) {
this.sourceText = sourceText;
this.variables = variables;
}
/**
* Evaluates the expression for the given document.
*
* @param document <code>docId</code> of the document to compute a value for
* @param functionValues {@link FunctionValues} for each element of {@link #externals}.
* @param functionValues {@link FunctionValues} for each element of {@link #variables}.
* @return The computed value of the expression for the given document.
*/
public abstract double evaluate(int document, FunctionValues[] functionValues);

View File

@ -47,10 +47,10 @@ final class ExpressionValueSource extends ValueSource {
if (valuesCache == null) {
throw new NullPointerException();
}
FunctionValues[] externalValues = new FunctionValues[expression.externals.length];
FunctionValues[] externalValues = new FunctionValues[expression.variables.length];
for (int i = 0; i < expression.externals.length; ++i) {
String externalName = expression.externals[i];
for (int i = 0; i < expression.variables.length; ++i) {
String externalName = expression.variables[i];
FunctionValues values = valuesCache.get(externalName);
if (values == null) {
source = bindings.getValueSource(externalName);
@ -68,12 +68,12 @@ final class ExpressionValueSource extends ValueSource {
@Override
public SortField getSortField(boolean reverse) {
return new ExpressionSortField(expression.expression, this, reverse);
return new ExpressionSortField(expression.sourceText, this, reverse);
}
@Override
public String description() {
return "ExpressionValueSource(" + expression.expression + ")";
return "ExpressionValueSource(" + expression.sourceText + ")";
}
@Override

View File

@ -43,6 +43,6 @@ class ScoreFunctionValues extends FunctionValues {
@Override
public String toString(int document) {
return "ComputedScorerValues(" + document + ": " + doubleVal(document) + ")";
return "ScoreFunctionValues(" + document + ": " + doubleVal(document) + ")";
}
}

View File

@ -33,7 +33,8 @@ import org.apache.lucene.search.FieldCache.LongParser;
import org.apache.lucene.search.SortField;
/**
* Simple class that binds expression variable names to {@link SortField}s.
* Simple class that binds expression variable names to {@link SortField}s
* or other {@link Expression}s.
*
* @lucene.experimental
*/

View File

@ -23,7 +23,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
@ -91,6 +90,14 @@ import static org.objectweb.asm.Opcodes.V1_7;
/**
* An expression compiler for javascript expressions.
* <p>
* Example:
* <pre class="prettyprint">
* Expression foo = JavascriptCompiler.compile("((0.3*popularity)/10.0)+(0.7*score)");
* </pre>
* <p>
* See the {@link org.apache.lucene.expressions.js package documentation} for
* the supported syntax and functions.
*
* @lucene.experimental
*/
@ -115,8 +122,7 @@ public class JavascriptCompiler {
private static final String COMPILED_EXPRESSION_INTERNAL = Type.getInternalName(Expression.class);
private static final String FUNCTION_VALUES_INTERNAL = Type.getInternalName(FunctionValues.class);
private Loader loader;
private AtomicLong counter = new AtomicLong();
private final Loader loader;
private String className;
private ClassWriter classWriter;
@ -127,17 +133,17 @@ public class JavascriptCompiler {
/**
* Constructs a compiler for expressions.
*/
public JavascriptCompiler() {
this(null);
private JavascriptCompiler() {
loader = new Loader(getClass().getClassLoader());
}
/**
* Constructs a compiler for expressions that will be loaded using the given class loader as the parent.
* @param parent Class loader to load the dynamically compiled expression
*/
public JavascriptCompiler(ClassLoader parent) {
private JavascriptCompiler(ClassLoader parent) {
if (parent == null) {
parent = getClass().getClassLoader();
throw new NullPointerException();
}
loader = new Loader(parent);
}
@ -145,28 +151,43 @@ public class JavascriptCompiler {
/**
* Compiles the given expression.
*
* @param expression The expression to compile
* @param sourceText The expression to compile
* @return A new compiled expression
* @throws ParseException on failure to compile
*/
public static Expression compile(String expression) throws ParseException {
return new JavascriptCompiler().compileExpression(expression);
public static Expression compile(String sourceText) throws ParseException {
return new JavascriptCompiler().compileExpression(sourceText);
}
/**
* Compiles the given expression, specifying the parent classloader.
*
* @param sourceText The expression to compile
* @param parent Parent classloader
* @return A new compiled expression
* @throws ParseException on failure to compile
*/
public static Expression compile(String sourceText, ClassLoader parent) throws ParseException {
return new JavascriptCompiler(parent).compileExpression(sourceText);
}
/**
* Compiles the given expression.
*
* @param expression The expression to compile
* @param sourceText The expression to compile
* @return A new compiled expression
* @throws ParseException on failure to compile
*/
public Expression compileExpression(String expression) throws ParseException {
private Expression compileExpression(String sourceText) throws ParseException {
if (sourceText == null) {
throw new NullPointerException();
}
try {
this.className = "Expr" + Long.toString(counter.incrementAndGet());
this.className = "CompiledExpression";
externalsMap = new HashMap<String, Integer>();
externalsList = new ArrayList<String>();
Tree antlrTree = getAntlrComputedExpressionTree(expression);
Tree antlrTree = getAntlrComputedExpressionTree(sourceText);
beginCompile();
recursiveCompile(antlrTree, ComputedType.DOUBLE);
@ -174,14 +195,8 @@ public class JavascriptCompiler {
Class<? extends Expression> evaluatorClass = loader.define(EXPRESSION_CLASS_PREFIX + className, classWriter.toByteArray());
Constructor<? extends Expression> constructor = evaluatorClass.getConstructor(String.class, String[].class);
return constructor.newInstance(expression, externalsList.toArray(new String[externalsList.size()]));
} catch (InstantiationException exception) {
throw new IllegalStateException("An internal error occurred attempting to compile the expression (" + className + ").", exception);
} catch (IllegalAccessException exception) {
throw new IllegalStateException("An internal error occurred attempting to compile the expression (" + className + ").", exception);
} catch (NoSuchMethodException exception) {
throw new IllegalStateException("An internal error occurred attempting to compile the expression (" + className + ").", exception);
} catch (InvocationTargetException exception) {
return constructor.newInstance(sourceText, externalsList.toArray(new String[externalsList.size()]));
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException exception) {
throw new IllegalStateException("An internal error occurred attempting to compile the expression (" + className + ").", exception);
}
}

View File

@ -22,13 +22,13 @@
<h1>expressions</h1>
<p>
{@link org.apache.lucene.expressions.Expression} - result of compiling an expression, which can
evaluate it for a given document. Each expression can have external variables which evaluate
will retrieve from passed FunctionValues.
evaluate it for a given document. Each expression can have external variables are resolved by
{@code Bindings}.
</p>
<p>
{@link org.apache.lucene.expressions.Bindings} - abstraction for binding external variables
to a way to get a value for those variables for a particular document (ValueSource)
to a way to get a value for those variables for a particular document (ValueSource).
</p>
<p>