Skip to content
Permalink
Browse files
[CXF-5430]: Added initial support for OData 2.0 query language. Cover…
…ed Lucene SearchBean test cases

git-svn-id: https://svn.apache.org/repos/asf/cxf/trunk@1568790 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
Andriy Redko committed Feb 16, 2014
1 parent de6c14b commit 14a29e1f411ff362f8899d3e9276d8239faf33cd
Show file tree
Hide file tree
Showing 5 changed files with 401 additions and 144 deletions.
@@ -23,6 +23,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -34,6 +35,7 @@
* Bean introspection utility.
*/
public class Beanspector<T> {
private final Map< Class< ? >, Class< ? > > primitiveWrappers = getPrimitiveWrappers();

private Class<T> tclass;
private T tobj;
@@ -105,7 +107,8 @@ public TypeInfo getAccessorTypeInfo(String getterOrSetterName) throws Exception
setters.keySet(), getters.keySet());
throw new IntrospectionException(msg);
}
return new TypeInfo(m.getReturnType(), m.getGenericReturnType());
return new TypeInfo(m.getReturnType(), m.getGenericReturnType(),
primitiveToWrapper(m.getReturnType()));
}

public Beanspector<T> swap(T newobject) throws Exception {
@@ -169,6 +172,25 @@ public Object getValue(Method getter) throws Throwable {
}
}

private Map< Class< ? >, Class< ? > > getPrimitiveWrappers() {
final Map< Class< ? >, Class< ? > > wrappers = new HashMap< Class< ? >, Class< ? > >();

wrappers.put(boolean.class, Boolean.class);
wrappers.put(byte.class, Byte.class);
wrappers.put(char.class, Character.class);
wrappers.put(short.class, Short.class);
wrappers.put(int.class, Integer.class);
wrappers.put(long.class, Long.class);
wrappers.put(double.class, Double.class);
wrappers.put(float.class, Float.class);

return wrappers;
}

private Class< ? > primitiveToWrapper(final Class< ? > cls) {
return cls.isPrimitive() ? primitiveWrappers.get(cls) : cls;
}

private boolean isGetter(Method m) {
return m.getParameterTypes().length == 0
&& (m.getName().startsWith("get") || m.getName().startsWith("is"));
@@ -195,18 +217,29 @@ private boolean isSetter(Method m) {

public static class TypeInfo {
private Class<?> cls;
// The wrapper class in case cls is a primitive class (byte, long, ...)
private Class<?> wrapper;
private Type genericType;
private CollectionCheckInfo checkInfo;

public TypeInfo(Class<?> cls, Type genericType) {
this(cls, genericType, cls);
}

public TypeInfo(Class<?> cls, Type genericType, Class<?> wrapper) {
this.cls = cls;
this.genericType = genericType;
this.wrapper = wrapper;
}

public Class<?> getTypeClass() {
return cls;
}

public Class<?> getWrappedTypeClass() {
return wrapper;
}

public Type getGenericType() {
return genericType;
}
@@ -162,7 +162,7 @@ public Object visitBinary(BinaryExpression binaryExpression, BinaryOperator oper

Object typedValue = null;
// If property type and value type are compatible, just use them
if (property.typeInfo.getTypeClass().isAssignableFrom(value.typeClass)) {
if (property.typeInfo.getWrappedTypeClass().isAssignableFrom(value.typeClass)) {
typedValue = value.value;
} else { // Property type and value type are not compatible and convert / cast are required
typedValue = parseType(property.propertyName, null, null, property.propertyName,
@@ -0,0 +1,165 @@
/**
* 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.cxf.jaxrs.ext.search.lucene;

import java.util.Collections;

import org.apache.cxf.jaxrs.ext.search.SearchBean;
import org.apache.cxf.jaxrs.ext.search.SearchCondition;
import org.apache.cxf.jaxrs.ext.search.SearchConditionParser;
import org.apache.cxf.jaxrs.ext.search.SearchConditionVisitor;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;

public abstract class AbstractLuceneQueryVisitorTest extends Assert {

private DirectoryReader ireader;
private IndexSearcher isearcher;
private Directory directory;
private Analyzer analyzer;

@Before
public void setUp() throws Exception {
analyzer = new StandardAnalyzer(Version.LUCENE_40);
directory = new RAMDirectory();
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_40, analyzer);
IndexWriter iwriter = new IndexWriter(directory, config);

Document doc = new Document();
doc.add(new Field("contents", "name=text", TextField.TYPE_STORED));

IntField intField = new IntField("intfield", 4, Field.Store.YES);
doc.add(intField);
iwriter.addDocument(doc);

iwriter.close();
ireader = DirectoryReader.open(directory);
isearcher = new IndexSearcher(ireader);
}

@After
public void tearDown() throws Exception {
ireader.close();
directory.close();
}


protected abstract SearchConditionParser<SearchBean> getParser();

protected void doTestTextContentMatch(String expression) throws Exception {

Query query = createTermQuery("contents", expression);
doTestTextContentMatchWithQuery(query);

}

protected void doTestNoMatch(Query query) throws Exception {
ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs;
assertEquals(0, hits.length);
}

protected void doTestTextContentMatchWithQuery(Query query) throws Exception {
ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs;
assertEquals(1, hits.length);
// Iterate through the results:
for (int i = 0; i < hits.length; i++) {
Document hitDoc = isearcher.doc(hits[i].doc);
assertEquals("name=text", hitDoc.get("contents"));
}

}

protected void doTestIntContentMatch(String expression) throws Exception {

Query query = createTermQuery("intfield", expression);
doTestIntContentMatchWithQuery(query);

}

protected void doTestIntContentMatchWithQuery(Query query) throws Exception {

ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs;
assertEquals(1, hits.length);
// Iterate through the results:
for (int i = 0; i < hits.length; i++) {
Document hitDoc = isearcher.doc(hits[i].doc);
IndexableField field = hitDoc.getField("intfield");
assertEquals(4, field.numericValue().intValue());
}

}

protected Query createTermQuery(String expression) throws Exception {
SearchCondition<SearchBean> filter = getParser().parse(expression);
SearchConditionVisitor<SearchBean, Query> lucene = new LuceneQueryVisitor<SearchBean>();
lucene.visit(filter);
return lucene.getQuery();
}

protected Query createTermQueryWithFieldClass(String expression, Class<?> cls) throws Exception {
SearchCondition<SearchBean> filter = getParser().parse(expression);
LuceneQueryVisitor<SearchBean> lucene = new LuceneQueryVisitor<SearchBean>();
lucene.setPrimitiveFieldTypeMap(Collections.<String, Class<?>>singletonMap("intfield", cls));
lucene.visit(filter);
return lucene.getQuery();
}

protected Query createTermQuery(String fieldName, String expression) throws Exception {
SearchCondition<SearchBean> filter = getParser().parse(expression);
LuceneQueryVisitor<SearchBean> lucene =
new LuceneQueryVisitor<SearchBean>("ct", fieldName);
lucene.visit(filter);
return lucene.getQuery();
}

protected Query createTermQueryWithFieldClass(String fieldName, String expression, Class<?> cls)
throws Exception {
SearchCondition<SearchBean> filter = getParser().parse(expression);
LuceneQueryVisitor<SearchBean> lucene =
new LuceneQueryVisitor<SearchBean>("ct", fieldName);
lucene.setPrimitiveFieldTypeMap(Collections.<String, Class<?>>singletonMap(fieldName, cls));
lucene.visit(filter);
return lucene.getQuery();
}

protected Query createPhraseQuery(String fieldName, String expression) throws Exception {
SearchCondition<SearchBean> filter = getParser().parse(expression);
LuceneQueryVisitor<SearchBean> lucene =
new LuceneQueryVisitor<SearchBean>(fieldName);
lucene.visit(filter);
return lucene.getQuery();
}
}

0 comments on commit 14a29e1

Please sign in to comment.