From f1695104fa8df6d9b484ef94d13eac16bcb3cf36 Mon Sep 17 00:00:00 2001 From: Dennis Gove Date: Tue, 13 Jun 2017 09:06:00 -0400 Subject: [PATCH] SOLR-10882: LengthEvaluator now supports collections of any type --- .../client/solrj/io/eval/LengthEvaluator.java | 23 +++- .../io/stream/eval/LengthEvaluatorTest.java | 119 ++++++++++++++++++ 2 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/LengthEvaluatorTest.java diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LengthEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LengthEvaluator.java index da55ee49316..b070fe8e621 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LengthEvaluator.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LengthEvaluator.java @@ -17,7 +17,8 @@ package org.apache.solr.client.solrj.io.eval; import java.io.IOException; -import java.util.List; +import java.util.Collection; +import java.util.Locale; import org.apache.solr.client.solrj.io.Tuple; import org.apache.solr.client.solrj.io.stream.expr.Explanation; @@ -33,12 +34,26 @@ public class LengthEvaluator extends ComplexEvaluator implements Expressible { public LengthEvaluator(StreamExpression expression, StreamFactory factory) throws IOException { super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } } public Number evaluate(Tuple tuple) throws IOException { - StreamEvaluator colEval1 = subEvaluators.get(0); - List numbers = (List)colEval1.evaluate(tuple); - return numbers.size(); + + Object result = subEvaluators.get(0).evaluate(tuple); + + if(null == result){ + throw new IOException(String.format(Locale.ROOT, "Unable to find %s(...) because the value is null", constructingFactory.getFunctionName(getClass()))); + } + + if(result instanceof Collection){ + // Cause other evaluators expect Long instead of Integer + return new Long(((Collection)result).size()); + } + + throw new IOException(String.format(Locale.ROOT, "Unable to find %s(...) because the value is not a collection, instead a %s was found", constructingFactory.getFunctionName(getClass()), result.getClass().getSimpleName())); } @Override diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/LengthEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/LengthEvaluatorTest.java new file mode 100644 index 00000000000..4b137b55054 --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/LengthEvaluatorTest.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.solr.client.solrj.io.stream.eval; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.LengthEvaluator; +import org.apache.solr.client.solrj.io.eval.SequenceEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class LengthEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public LengthEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("length", LengthEvaluator.class) + .withFunctionName("sequence", SequenceEvaluator.class); + values = new HashMap(); + } + + @Test + public void lengthField() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("length(a)"); + Object result; + + values.clear(); + values.put("a", new ArrayList(){{ add(1); add(2); add(4); }}); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(3L, result); + + values.clear(); + values.put("a", new ArrayList(){{ add("a"); add("b"); }}); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(2L, result); + + values.clear(); + values.put("a", new ArrayList(){{ }}); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(0L, result); + } + + @Test + public void lengthEvaluator() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("length(sequence(3,4,10))"); + Object result; + + values.clear(); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(3L, result); + } + + @Test(expected = IOException.class) + public void lengthValueNotCollection() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("length(a)"); + + values.clear(); + values.put("a", "foo"); + evaluator.evaluate(new Tuple(values)); + } + + @Test(expected = IOException.class) + public void lengthNoField() throws Exception{ + factory.constructEvaluator("length()"); + } + + @Test(expected = IOException.class) + public void lengthTwoFields() throws Exception{ + factory.constructEvaluator("length(a,b)"); + } + + @Test(expected = IOException.class) + public void lengthNoValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("length(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test(expected = IOException.class) + public void lengthNullValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("length(a)"); + + values.clear(); + values.put("a", null); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } +}