You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2012/12/27 14:38:58 UTC
svn commit: r1426199 - in /cxf/branches/2.6.x-fixes: ./
rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/
rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/collections/
rt/rs/extensions/search/src/main/java/org/...
Author: sergeyb
Date: Thu Dec 27 13:38:58 2012
New Revision: 1426199
URL: http://svn.apache.org/viewvc?rev=1426199&view=rev
Log:
Merged revisions 1426184 via svnmerge from
https://svn.apache.org/repos/asf/cxf/trunk
........
r1426184 | sergeyb | 2012-12-27 12:55:03 +0000 (Thu, 27 Dec 2012) | 1 line
Updating FIQL parser to recognize collection checks, starting from count
........
Added:
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/collections/
- copied from r1426184, cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/collections/
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/collections/CollectionCheck.java
- copied unchanged from r1426184, cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/collections/CollectionCheck.java
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/collections/CollectionCheckCondition.java
- copied unchanged from r1426184, cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/collections/CollectionCheckCondition.java
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/collections/CollectionCheckInfo.java
- copied unchanged from r1426184, cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/collections/CollectionCheckInfo.java
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/collections/CollectionCheckStatement.java
- copied unchanged from r1426184, cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/collections/CollectionCheckStatement.java
Modified:
cxf/branches/2.6.x-fixes/ (props changed)
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/Beanspector.java
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/visitor/AbstractSearchConditionVisitor.java
cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/JPATypedQueryVisitorTest.java
Propchange: cxf/branches/2.6.x-fixes/
------------------------------------------------------------------------------
Merged /cxf/trunk:r1426184
Propchange: cxf/branches/2.6.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified: cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/Beanspector.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/Beanspector.java?rev=1426199&r1=1426198&r2=1426199&view=diff
==============================================================================
--- cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/Beanspector.java (original)
+++ cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/Beanspector.java Thu Dec 27 13:38:58 2012
@@ -28,6 +28,8 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
+import org.apache.cxf.jaxrs.ext.search.collections.CollectionCheckInfo;
+
/**
* Bean introspection utility.
*/
@@ -194,6 +196,7 @@ public class Beanspector<T> {
public static class TypeInfo {
private Class<?> cls;
private Type genericType;
+ private CollectionCheckInfo checkInfo;
public TypeInfo(Class<?> cls, Type genericType) {
this.cls = cls;
@@ -207,5 +210,13 @@ public class Beanspector<T> {
public Type getGenericType() {
return genericType;
}
+
+ public CollectionCheckInfo getCollectionCheckInfo() {
+ return checkInfo;
+ }
+
+ public void setCollectionCheckInfo(CollectionCheckInfo info) {
+ this.checkInfo = info;
+ }
}
}
Modified: cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java?rev=1426199&r1=1426198&r2=1426199&view=diff
==============================================================================
--- cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java (original)
+++ cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java Thu Dec 27 13:38:58 2012
@@ -76,6 +76,18 @@ public class PrimitiveSearchCondition<T>
return cType;
}
+ protected String getPropertyName() {
+ return propertyName;
+ }
+
+ protected Object getPropertyValue() {
+ return propertyValue;
+ }
+
+ protected Type getPropertyType() {
+ return propertyType;
+ }
+
public List<SearchCondition<T>> getSearchConditions() {
return null;
}
Modified: cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java?rev=1426199&r1=1426198&r2=1426199&view=diff
==============================================================================
--- cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java (original)
+++ cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java Thu Dec 27 13:38:58 2012
@@ -29,6 +29,8 @@ import java.util.Map;
import java.util.Set;
import org.apache.cxf.jaxrs.ext.search.Beanspector.TypeInfo;
+import org.apache.cxf.jaxrs.ext.search.collections.CollectionCheckCondition;
+import org.apache.cxf.jaxrs.ext.search.collections.CollectionCheckInfo;
/**
* Simple search condition comparing primitive objects or complex object by its getters. For details see
@@ -163,11 +165,16 @@ public class SimpleSearchCondition<T> im
}
String realGetter = realGetters != null && realGetters.containsKey(getter)
? realGetters.get(getter) : getter;
-
- Type genType = propertyTypeInfo != null && propertyTypeInfo.containsKey(getter)
- ? propertyTypeInfo.get(getter).getGenericType() : rval.getClass();
- list.add(new PrimitiveSearchCondition<T>(realGetter, rval, genType, ct, condition));
+ TypeInfo tInfo = propertyTypeInfo != null ? propertyTypeInfo.get(getter) : null;
+ Type genType = tInfo != null ? tInfo.getGenericType() : rval.getClass();
+ CollectionCheckInfo checkInfo = tInfo != null ? tInfo.getCollectionCheckInfo() : null;
+
+ PrimitiveSearchCondition<T> pc = checkInfo == null
+ ? new PrimitiveSearchCondition<T>(realGetter, rval, genType, ct, condition)
+ : new CollectionCheckCondition<T>(realGetter, rval, genType, ct, condition, checkInfo);
+
+ list.add(pc);
}
if (list.isEmpty()) {
Modified: cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java?rev=1426199&r1=1426198&r2=1426199&view=diff
==============================================================================
--- cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java (original)
+++ cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java Thu Dec 27 13:38:58 2012
@@ -45,6 +45,8 @@ import org.apache.cxf.jaxrs.ext.search.S
import org.apache.cxf.jaxrs.ext.search.SearchParseException;
import org.apache.cxf.jaxrs.ext.search.SearchUtils;
import org.apache.cxf.jaxrs.ext.search.SimpleSearchCondition;
+import org.apache.cxf.jaxrs.ext.search.collections.CollectionCheck;
+import org.apache.cxf.jaxrs.ext.search.collections.CollectionCheckInfo;
import org.apache.cxf.jaxrs.utils.InjectionUtils;
import org.apache.cxf.message.MessageUtils;
@@ -70,6 +72,10 @@ public class FiqlParser<T> implements Se
public static final String NEQ = "!=";
public static final Map<ConditionType, String> CONDITION_MAP;
+
+ public static final String EXTENSION_COUNT = "count";
+
+ private static final String EXTENSION_COUNT_OPEN = EXTENSION_COUNT + "(";
private static final Map<String, ConditionType> OPERATORS_MAP;
private static final Pattern COMPARATORS_PATTERN;
@@ -253,19 +259,20 @@ public class FiqlParser<T> implements Se
private Comparison parseComparison(String expr) throws SearchParseException {
Matcher m = COMPARATORS_PATTERN.matcher(expr);
if (m.find()) {
- String name = expr.substring(0, m.start(1));
+ String propertyName = expr.substring(0, m.start(1));
String operator = m.group(1);
String value = expr.substring(m.end(1));
if ("".equals(value)) {
throw new SearchParseException("Not a comparison expression: " + expr);
}
+ String name = unwrapSetter(propertyName);
String beanPropertyName = beanPropertiesMap == null ? null : beanPropertiesMap.get(name);
if (beanPropertyName != null) {
name = beanPropertyName;
}
- TypeInfoObject castedValue = parseType(name, value);
+ TypeInfoObject castedValue = parseType(propertyName, name, value);
if (castedValue != null) {
return new Comparison(name, operator, castedValue);
} else if (MessageUtils.isTrue(contextProperties.get(SearchUtils.LAX_PROPERTY_MATCH))) {
@@ -279,14 +286,14 @@ public class FiqlParser<T> implements Se
}
- private TypeInfoObject parseType(String setter, String value) throws SearchParseException {
+ private TypeInfoObject parseType(String originalName, String setter, String value) throws SearchParseException {
String name = getSetter(setter);
try {
TypeInfo typeInfo =
beanspector != null ? beanspector.getAccessorTypeInfo(name)
: new TypeInfo(String.class, String.class);
- Object object = parseType(null, null, setter, typeInfo, value);
+ Object object = parseType(originalName, null, null, setter, typeInfo, value);
return new TypeInfoObject(object, typeInfo);
} catch (Exception e) {
return null;
@@ -294,8 +301,12 @@ public class FiqlParser<T> implements Se
}
- private Object parseType(Object ownerBean, Object lastCastedValue, String setter,
- TypeInfo typeInfo, String value) throws SearchParseException {
+ private Object parseType(String originalPropName,
+ Object ownerBean,
+ Object lastCastedValue,
+ String setter,
+ TypeInfo typeInfo,
+ String value) throws SearchParseException {
Class<?> valueType = typeInfo.getTypeClass();
boolean isCollection = InjectionUtils.isSupportedCollectionOrArray(valueType);
Class<?> actualType = isCollection ? InjectionUtils.getActualType(typeInfo.getGenericType()) : valueType;
@@ -306,11 +317,19 @@ public class FiqlParser<T> implements Se
if (Date.class.isAssignableFrom(valueType)) {
castedValue = convertToDate(value);
} else {
- if (ownerBean == null || InjectionUtils.isPrimitive(valueType) || valueType.isEnum()) {
+ boolean isPrimitive = InjectionUtils.isPrimitive(valueType);
+ boolean isPrimitiveOrEnum = isPrimitive || valueType.isEnum();
+ if (ownerBean == null || isPrimitiveOrEnum) {
try {
- castedValue = InjectionUtils.convertStringToPrimitive(value, actualType);
- if (isCollection) {
+ CollectionCheck collCheck = getCollectionCheck(originalPropName, isCollection, actualType);
+ if (collCheck == null) {
+ castedValue = InjectionUtils.convertStringToPrimitive(value, actualType);
+ }
+ if (collCheck == null && isCollection) {
castedValue = getCollectionSingleton(valueType, castedValue);
+ } else if (isCollection) {
+ typeInfo.setCollectionCheckInfo(new CollectionCheckInfo(collCheck, castedValue));
+ castedValue = getEmptyCollection(valueType);
}
} catch (Exception e) {
throw new SearchParseException("Cannot convert String value \"" + value
@@ -342,6 +361,8 @@ public class FiqlParser<T> implements Se
Method getterM = actualType.getMethod("get" + nextPart, new Class[]{});
Class<?> returnType = getterM.getReturnType();
boolean returnCollection = InjectionUtils.isSupportedCollectionOrArray(returnType);
+ Class<?> actualReturnType = !returnCollection ? returnType
+ : InjectionUtils.getActualType(getterM.getGenericReturnType());
boolean isPrimitive = InjectionUtils.isPrimitive(returnType) || returnType.isEnum();
boolean lastTry = names.length == 2
@@ -355,7 +376,13 @@ public class FiqlParser<T> implements Se
nextObject = isPrimitive ? InjectionUtils.convertStringToPrimitive(value, returnType)
: convertToDate(value);
} else {
- nextObject = getCollectionSingleton(valueType, value);
+ CollectionCheck collCheck = getCollectionCheck(originalPropName, true, actualReturnType);
+ if (collCheck == null) {
+ nextObject = getCollectionSingleton(valueType, value);
+ } else {
+ typeInfo.setCollectionCheckInfo(new CollectionCheckInfo(collCheck, value));
+ nextObject = getEmptyCollection(valueType);
+ }
}
} else {
nextObject = returnType.newInstance();
@@ -370,8 +397,12 @@ public class FiqlParser<T> implements Se
}
TypeInfo nextTypeInfo = new TypeInfo(nextObject.getClass(), getterM.getGenericReturnType());
- return parseType(nextObject, lastCastedValue, setter.substring(index + 1),
- nextTypeInfo, value);
+ return parseType(originalPropName,
+ nextObject,
+ lastCastedValue,
+ setter.substring(index + 1),
+ nextTypeInfo,
+ value);
} catch (Throwable e) {
throw new SearchParseException("Cannot convert String value \"" + value
+ "\" to a value of class " + valueType.getName(), e);
@@ -379,6 +410,19 @@ public class FiqlParser<T> implements Se
}
}
+ private CollectionCheck getCollectionCheck(String propName, boolean isCollection, Class<?> actualCls) {
+ if (isCollection) {
+ if (InjectionUtils.isPrimitive(actualCls)) {
+ if (propName.startsWith(EXTENSION_COUNT_OPEN)) {
+ return CollectionCheck.SIZE;
+ }
+ } else {
+ return CollectionCheck.SIZE;
+ }
+ }
+ return null;
+ }
+
private Object getCollectionSingleton(Class<?> collectionCls, Object value) {
if (Set.class.isAssignableFrom(collectionCls)) {
return Collections.singleton(value);
@@ -387,6 +431,14 @@ public class FiqlParser<T> implements Se
}
}
+ private Object getEmptyCollection(Class<?> collectionCls) {
+ if (Set.class.isAssignableFrom(collectionCls)) {
+ return Collections.emptySet();
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
private Object convertToDate(String value) throws SearchParseException {
try {
DateFormat df = SearchUtils.getDateFormat(contextProperties);
@@ -422,6 +474,14 @@ public class FiqlParser<T> implements Se
}
}
+ private String unwrapSetter(String setter) {
+ if (setter.startsWith(EXTENSION_COUNT_OPEN) && setter.endsWith(")")) {
+ return setter.substring(EXTENSION_COUNT_OPEN.length(), setter.length() - 1);
+ } else {
+ return setter;
+ }
+ }
+
private String getMethodNameSuffix(String name) {
if (name.length() == 1) {
return name.toUpperCase();
Modified: cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java?rev=1426199&r1=1426198&r2=1426199&view=diff
==============================================================================
--- cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java (original)
+++ cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java Thu Dec 27 13:38:58 2012
@@ -18,8 +18,8 @@
*/
package org.apache.cxf.jaxrs.ext.search.jpa;
-import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -30,6 +30,7 @@ import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
@@ -39,6 +40,7 @@ import org.apache.cxf.jaxrs.ext.search.C
import org.apache.cxf.jaxrs.ext.search.OrSearchCondition;
import org.apache.cxf.jaxrs.ext.search.PrimitiveStatement;
import org.apache.cxf.jaxrs.ext.search.SearchCondition;
+import org.apache.cxf.jaxrs.ext.search.collections.CollectionCheckInfo;
import org.apache.cxf.jaxrs.ext.search.visitor.AbstractSearchConditionVisitor;
public abstract class AbstractJPATypedQueryVisitor<T, T1, E>
@@ -116,14 +118,8 @@ public abstract class AbstractJPATypedQu
root = cq.from(tClass);
predStack.push(new ArrayList<Predicate>());
}
- PrimitiveStatement statement = sc.getStatement();
- if (statement != null) {
- if (statement.getProperty() != null) {
- predStack.peek().add(buildPredicate(sc.getConditionType(),
- statement.getProperty(),
- statement.getValue(),
- statement.getValueType()));
- }
+ if (sc.getStatement() != null) {
+ predStack.peek().add(buildPredicate(sc.getStatement()));
} else {
predStack.push(new ArrayList<Predicate>());
for (SearchCondition<T> condition : sc.getSearchConditions()) {
@@ -166,21 +162,34 @@ public abstract class AbstractJPATypedQu
return cq;
}
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private Predicate buildPredicate(ConditionType ct, String name, Object value, Type valueType) {
-
+ private Predicate buildPredicate(PrimitiveStatement ps) {
+ String name = ps.getProperty();
name = super.getRealPropertyName(name);
- ClassValue cv = getPrimitiveFieldClass(name, value.getClass(), valueType, value);
+ ClassValue cv = getPrimitiveFieldClass(ps,
+ name,
+ ps.getValue().getClass(),
+ ps.getValueType(),
+ ps.getValue());
+ CollectionCheckInfo collInfo = cv.getCollectionCheckInfo();
+ Path<?> path = getPath(root, name, cv, collInfo);
- Class<? extends Comparable> clazz = (Class<? extends Comparable>)cv.getCls();
- value = cv.getValue();
+ Predicate pred = collInfo == null
+ ? doBuildPredicate(ps.getCondition(), path, cv.getCls(), cv.getValue())
+ : doBuildCollectionPredicate(ps.getCondition(), path, collInfo);
- Path<?> path = getPath(root, name, cv);
+ return pred;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private Predicate doBuildPredicate(ConditionType ct, Path<?> path, Class<?> valueClazz, Object value) {
+
+ Class<? extends Comparable> clazz = (Class<? extends Comparable>)valueClazz;
+ Expression<? extends Comparable> exp = path.as(clazz);
Predicate pred = null;
switch (ct) {
case GREATER_THAN:
- pred = builder.greaterThan(path.as(clazz), clazz.cast(value));
+ pred = builder.greaterThan(exp, clazz.cast(value));
break;
case EQUALS:
if (clazz.equals(String.class)) {
@@ -188,47 +197,77 @@ public abstract class AbstractJPATypedQu
if (theValue.contains("*")) {
theValue = ((String)value).replaceAll("\\*", "");
}
- pred = builder.like(path.as(String.class), "%" + theValue + "%");
+ pred = builder.like((Expression<String>)exp, "%" + theValue + "%");
} else {
- pred = builder.equal(path.as(clazz), clazz.cast(value));
+ pred = builder.equal(exp, clazz.cast(value));
}
break;
case NOT_EQUALS:
- pred = builder.notEqual(path.as(clazz),
- clazz.cast(value));
+ pred = builder.notEqual(exp, clazz.cast(value));
break;
case LESS_THAN:
- pred = builder.lessThan(path.as(clazz),
- clazz.cast(value));
+ pred = builder.lessThan(exp, clazz.cast(value));
break;
case LESS_OR_EQUALS:
- pred = builder.lessThanOrEqualTo(path.as(clazz),
- clazz.cast(value));
+ pred = builder.lessThanOrEqualTo(exp, clazz.cast(value));
break;
case GREATER_OR_EQUALS:
- pred = builder.greaterThanOrEqualTo(path.as(clazz),
- clazz.cast(value));
+ pred = builder.greaterThanOrEqualTo(exp, clazz.cast(value));
break;
default:
break;
}
return pred;
}
-
- private Path<?> getPath(Path<?> element, String name, ClassValue cv) {
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private Predicate doBuildCollectionPredicate(ConditionType ct, Path<?> path, CollectionCheckInfo collInfo) {
+ Predicate pred = null;
+
+ Expression<Integer> exp = builder.size((Expression<? extends Collection>)path);
+ Integer value = Integer.valueOf(collInfo.getCollectionCheckValue().toString());
+
+ switch (ct) {
+ case GREATER_THAN:
+ pred = builder.greaterThan(exp, value);
+ break;
+ case EQUALS:
+ pred = builder.equal(exp, value);
+ break;
+ case NOT_EQUALS:
+ pred = builder.notEqual(exp, value);
+ break;
+ case LESS_THAN:
+ pred = builder.lessThan(exp, value);
+ break;
+ case LESS_OR_EQUALS:
+ pred = builder.lessThanOrEqualTo(exp, value);
+ break;
+ case GREATER_OR_EQUALS:
+ pred = builder.greaterThanOrEqualTo(exp, value);
+ break;
+ default:
+ break;
+ }
+ return pred;
+ }
+
+ private Path<?> getPath(Path<?> element, String name, ClassValue cv, CollectionCheckInfo collSize) {
if (name.contains(".")) {
String pre = name.substring(0, name.indexOf('.'));
String post = name.substring(name.indexOf('.') + 1);
- return getPath(getNextPath(element, pre, cv),
+ return getPath(getNextPath(element, pre, cv, null),
post,
- cv);
+ cv,
+ collSize);
} else {
- return getNextPath(element, name, cv);
+ return getNextPath(element, name, cv, collSize);
}
}
- private Path<?> getNextPath(Path<?> element, String name, ClassValue cv) {
- if ((cv.isCollection(name) || isJoinProperty(name)) && (element == root || element instanceof Join)) {
+ private Path<?> getNextPath(Path<?> element, String name, ClassValue cv, CollectionCheckInfo collSize) {
+ if (collSize == null
+ && (cv.isCollection(name) || isJoinProperty(name)) && (element == root || element instanceof Join)) {
return element == root ? root.join(name) : ((Join<?, ?>)element).join(name);
} else {
return element.get(name);
Modified: cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/visitor/AbstractSearchConditionVisitor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/visitor/AbstractSearchConditionVisitor.java?rev=1426199&r1=1426198&r2=1426199&view=diff
==============================================================================
--- cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/visitor/AbstractSearchConditionVisitor.java (original)
+++ cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/visitor/AbstractSearchConditionVisitor.java Thu Dec 27 13:38:58 2012
@@ -25,7 +25,10 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import org.apache.cxf.jaxrs.ext.search.PrimitiveStatement;
import org.apache.cxf.jaxrs.ext.search.SearchConditionVisitor;
+import org.apache.cxf.jaxrs.ext.search.collections.CollectionCheckInfo;
+import org.apache.cxf.jaxrs.ext.search.collections.CollectionCheckStatement;
import org.apache.cxf.jaxrs.utils.InjectionUtils;
@@ -50,23 +53,26 @@ public abstract class AbstractSearchCond
}
protected ClassValue getPrimitiveFieldClass(String name, Class<?> valueCls, Object value) {
- return getPrimitiveFieldClass(name, valueCls, valueCls, value);
+ return getPrimitiveFieldClass(null, name, valueCls, valueCls, value);
}
- protected ClassValue getPrimitiveFieldClass(String name, Class<?> valueCls, Type type, Object value) {
- return doGetPrimitiveFieldClass(name, valueCls, type, value, new HashSet<String>());
+ protected ClassValue getPrimitiveFieldClass(PrimitiveStatement ps, String name, Class<?> valueCls,
+ Type type, Object value) {
+ return doGetPrimitiveFieldClass(ps, name, valueCls, type, value, new HashSet<String>());
}
@SuppressWarnings("rawtypes")
- private ClassValue doGetPrimitiveFieldClass(String name, Class<?> valueCls, Type type, Object value,
+ private ClassValue doGetPrimitiveFieldClass(PrimitiveStatement ps,
+ String name, Class<?> valueCls, Type type, Object value,
Set<String> set) {
boolean isCollection = InjectionUtils.isSupportedCollectionOrArray(valueCls);
-
+ Class<?> actualCls = isCollection ? InjectionUtils.getActualType(type) : valueCls;
+ CollectionCheckInfo collInfo = null;
int index = name.indexOf(".");
if (index != -1) {
String[] names = name.split("\\.");
name = name.substring(index + 1);
- if (value != null && !InjectionUtils.isPrimitive(valueCls)) {
+ if (value != null && !InjectionUtils.isPrimitive(actualCls)) {
try {
String nextPart = names[1];
if (nextPart.length() == 1) {
@@ -74,8 +80,7 @@ public abstract class AbstractSearchCond
} else {
nextPart = Character.toUpperCase(nextPart.charAt(0)) + nextPart.substring(1);
}
- Class<?> actualCls = isCollection
- ? InjectionUtils.getActualType(type) : valueCls;
+
Method m = actualCls.getMethod("get" + nextPart, new Class[]{});
if (isCollection) {
value = ((Collection)value).iterator().next();
@@ -87,12 +92,16 @@ public abstract class AbstractSearchCond
} catch (Throwable ex) {
throw new RuntimeException();
}
- return doGetPrimitiveFieldClass(name, valueCls, type, value, set);
+ return doGetPrimitiveFieldClass(ps, name, valueCls, type, value, set);
}
} else if (isCollection) {
set.add(name);
- value = ((Collection)value).iterator().next();
- valueCls = value.getClass();
+ Collection coll = (Collection)value;
+ value = coll.isEmpty() ? null : coll.iterator().next();
+ valueCls = actualCls;
+ if (ps instanceof CollectionCheckStatement) {
+ collInfo = ((CollectionCheckStatement)ps).getCollectionCheckInfo();
+ }
}
Class<?> cls = null;
@@ -102,7 +111,7 @@ public abstract class AbstractSearchCond
if (cls == null) {
cls = valueCls;
}
- return new ClassValue(cls, value, set);
+ return new ClassValue(cls, value, collInfo, set);
}
public void setPrimitiveFieldTypeMap(Map<String, Class<?>> primitiveFieldTypeMap) {
@@ -116,10 +125,16 @@ public abstract class AbstractSearchCond
protected class ClassValue {
private Class<?> cls;
private Object value;
+ private CollectionCheckInfo collInfo;
+
private Set<String> collectionProps;
- public ClassValue(Class<?> cls, Object value, Set<String> collectionProps) {
+ public ClassValue(Class<?> cls,
+ Object value,
+ CollectionCheckInfo collInfo,
+ Set<String> collectionProps) {
this.cls = cls;
this.value = value;
+ this.collInfo = collInfo;
this.collectionProps = collectionProps;
}
public Class<?> getCls() {
@@ -135,6 +150,10 @@ public abstract class AbstractSearchCond
this.value = value;
}
+ public CollectionCheckInfo getCollectionCheckInfo() {
+ return collInfo;
+ }
+
public boolean isCollection(String name) {
return collectionProps != null && collectionProps.contains(name);
}
Modified: cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/JPATypedQueryVisitorTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/JPATypedQueryVisitorTest.java?rev=1426199&r1=1426198&r2=1426199&view=diff
==============================================================================
--- cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/JPATypedQueryVisitorTest.java (original)
+++ cxf/branches/2.6.x-fixes/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/JPATypedQueryVisitorTest.java Thu Dec 27 13:38:58 2012
@@ -199,6 +199,62 @@ public class JPATypedQueryVisitorTest ex
}
@Test
+ public void testQueryElementCollection() throws Exception {
+ List<Book> books =
+ queryBooks("authors==John");
+ assertEquals(2, books.size());
+ }
+
+ @Test
+ public void testNumberOfReviews() throws Exception {
+ List<Book> books =
+ queryBooks("reviews=gt=0");
+ assertEquals(3, books.size());
+ }
+
+ @Test
+ public void testNumberOfReviews2() throws Exception {
+ List<Book> books =
+ queryBooks("reviews=gt=3");
+ assertEquals(0, books.size());
+ }
+
+ @Test
+ public void testNumberOfReviewAuthors() throws Exception {
+ List<Book> books =
+ queryBooks("count(reviews.authors)=gt=0");
+ assertEquals(3, books.size());
+ }
+
+ @Test
+ public void testNumberOfReviewAuthors2() throws Exception {
+ List<Book> books =
+ queryBooks("count(reviews.authors)=gt=3");
+ assertEquals(0, books.size());
+ }
+
+ @Test
+ public void testNumberOfAuthors() throws Exception {
+ List<Book> books =
+ queryBooks("count(authors)=gt=0");
+ assertEquals(3, books.size());
+ }
+
+ @Test
+ public void testNumberOfAuthors2() throws Exception {
+ List<Book> books =
+ queryBooks("count(authors)=gt=3");
+ assertEquals(0, books.size());
+ }
+
+ @Test
+ public void testQueryCollectionSize2() throws Exception {
+ List<Book> books =
+ queryBooks("reviews.authors=gt=0");
+ assertEquals(3, books.size());
+ }
+
+ @Test
public void testAndQueryCollection() throws Exception {
List<Book> books =
queryBooks("id==10;authors==John;reviews.review==good;reviews.authors==Ted");