Repository: cxf Updated Branches: refs/heads/2.7.x-fixes 5ee12626b -> 0a54ffd4d
[CXF-5739] Support for SQL Timestamp, applying a patch on behalf of Romain Castan Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/0a54ffd4 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/0a54ffd4 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/0a54ffd4 Branch: refs/heads/2.7.x-fixes Commit: 0a54ffd4d7672c11bbe96fbca182dbb6feb8abd6 Parents: 5ee1262 Author: Sergey Beryozkin <[email protected]> Authored: Thu May 15 14:44:32 2014 +0100 Committer: Sergey Beryozkin <[email protected]> Committed: Thu May 15 16:02:03 2014 +0100 ---------------------------------------------------------------------- .../apache/cxf/jaxrs/utils/InjectionUtils.java | 11 ++--- .../cxf/jaxrs/ext/search/SearchUtils.java | 13 +++-- .../cxf/jaxrs/ext/search/fiql/FiqlParser.java | 51 +++++++++++++++----- .../jpa/AbstractJPATypedQueryVisitor.java | 28 +++++++---- .../jaxrs/ext/search/sql/SQLPrinterVisitor.java | 9 ++-- 5 files changed, 75 insertions(+), 37 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/0a54ffd4/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java index 52fc9ad..f3c8d6c 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java @@ -440,6 +440,7 @@ public final class InjectionUtils { return pClass.cast(result); } + private static <T> T instantiateFromParameterHandler(String value, Class<T> pClass, Annotation[] anns, @@ -452,7 +453,7 @@ public final class InjectionUtils { } } - private static <T> T createFromParameterHandler(String value, + public static <T> T createFromParameterHandler(String value, Class<T> pClass, Annotation[] anns, Message message) { @@ -1253,11 +1254,9 @@ public final class InjectionUtils { } public static Object convertStringToPrimitive(String value, Class<?> cls, Annotation[] anns) { Message m = JAXRSUtils.getCurrentMessage(); - if (m != null) { - ParamConverter<?> pc = ProviderFactory.getInstance(m).createParameterHandler(cls, anns); - if (pc != null) { - return pc.fromString(value); - } + Object obj = createFromParameterHandler(value, cls, anns, m); + if (obj != null) { + return obj; } if (String.class == cls) { return value; http://git-wip-us.apache.org/repos/asf/cxf/blob/0a54ffd4/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java index c6bc2ca..773395e 100644 --- a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java +++ b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java @@ -62,7 +62,7 @@ public final class SearchUtils { if (value.contains("%")) { value = value.replaceAll("%", "\\\\%"); } - if (!value.contains("*")) { + if (!containsWildcard(value)) { return alwaysWildcard ? "%" + value + "%" : value; } else { value = value.replaceAll("\\*", "%"); @@ -81,6 +81,10 @@ public final class SearchUtils { return containsEscapedPercent(value) || value.contains("\\\\") || value.contains("\\_"); } + public static boolean containsWildcard(String value) { + return value.contains("*"); + } + public static boolean containsEscapedPercent(String value) { return value.contains("\\%"); } @@ -107,16 +111,17 @@ public final class SearchUtils { sb.append(" WHERE "); } - public static String conditionTypeToSqlOperator(ConditionType ct, String value) { + public static String conditionTypeToSqlOperator(ConditionType ct, String value, String originalValue) { // TODO : if we have the same column involved, ex a >= 123 and a <=244 then // we may try to use IN or BETWEEN, depending on the values + final boolean wildcardAvailable = SearchUtils.containsWildcard(originalValue); String op; switch (ct) { case EQUALS: - op = containsEscapedPercent(value) || value.contains("%") ? "LIKE" : "="; + op = wildcardAvailable ? "LIKE" : "="; break; case NOT_EQUALS: - op = containsEscapedPercent(value) || value.contains("%") ? "NOT LIKE" : "<>"; + op = wildcardAvailable ? "NOT LIKE" : "<>"; break; case GREATER_THAN: op = ">"; http://git-wip-us.apache.org/repos/asf/cxf/blob/0a54ffd4/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java ---------------------------------------------------------------------- diff --git a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java index e7a08b3..937aba5 100644 --- a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java +++ b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java @@ -17,8 +17,11 @@ * under the License. */ package org.apache.cxf.jaxrs.ext.search.fiql; + +import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.sql.Timestamp; import java.text.DateFormat; import java.text.ParseException; import java.util.ArrayList; @@ -50,6 +53,8 @@ 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.jaxrs.utils.JAXRSUtils; +import org.apache.cxf.message.Message; import org.apache.cxf.message.MessageUtils; @@ -330,7 +335,7 @@ public class FiqlParser<T> implements SearchConditionParser<T> { if (index == -1) { Object castedValue = value; if (Date.class.isAssignableFrom(valueType)) { - castedValue = convertToDate(value); + castedValue = convertToDate(valueType, value); } else { boolean isPrimitive = InjectionUtils.isPrimitive(valueType); boolean isPrimitiveOrEnum = isPrimitive || valueType.isEnum(); @@ -382,7 +387,7 @@ public class FiqlParser<T> implements SearchConditionParser<T> { boolean isPrimitive = !returnCollection && InjectionUtils.isPrimitive(returnType) || returnType.isEnum(); boolean lastTry = names.length == 2 - && (isPrimitive || returnType == Date.class || returnCollection); + && (isPrimitive || Date.class.isAssignableFrom(returnType) || returnCollection); Object valueObject = ownerBean != null ? ownerBean : actualType.isInterface() @@ -395,7 +400,7 @@ public class FiqlParser<T> implements SearchConditionParser<T> { if (lastTry) { if (!returnCollection) { nextObject = isPrimitive ? InjectionUtils.convertStringToPrimitive(value, returnType) - : convertToDate(value); + : convertToDate(returnType, value); } else { CollectionCheck collCheck = getCollectionCheck(originalPropName, true, actualReturnType); if (collCheck == null) { @@ -471,18 +476,20 @@ public class FiqlParser<T> implements SearchConditionParser<T> { } } - private Object convertToDate(String value) throws SearchParseException { + private Object convertToDate(Class<?> valueType, String value) throws SearchParseException { + + Message m = JAXRSUtils.getCurrentMessage(); + Object obj = InjectionUtils.createFromParameterHandler(value, valueType, new Annotation[]{}, m); + if (obj != null) { + return obj; + } + try { - DateFormat df = SearchUtils.getDateFormat(contextProperties); - String dateValue = value; - if (SearchUtils.isTimeZoneSupported(contextProperties, Boolean.FALSE)) { - // zone in XML is "+01:00" in Java is "+0100"; stripping semicolon - int idx = value.lastIndexOf(':'); - if (idx != -1) { - dateValue = value.substring(0, idx) + value.substring(idx + 1); - } + if (Timestamp.class.isAssignableFrom(valueType)) { + return convertToTimestamp(value); + } else { + return convertToDefaultDate(value); } - return df.parse(dateValue); } catch (ParseException e) { // is that duration? try { @@ -497,6 +504,24 @@ public class FiqlParser<T> implements SearchConditionParser<T> { } } + private Timestamp convertToTimestamp(String value) throws ParseException { + Date date = convertToDefaultDate(value); + return new Timestamp(date.getTime()); + } + + private Date convertToDefaultDate(String value) throws ParseException { + DateFormat df = SearchUtils.getDateFormat(contextProperties); + String dateValue = value; + if (SearchUtils.isTimeZoneSupported(contextProperties, Boolean.FALSE)) { + // zone in XML is "+01:00" in Java is "+0100"; stripping semicolon + int idx = value.lastIndexOf(':'); + if (idx != -1) { + dateValue = value.substring(0, idx) + value.substring(idx + 1); + } + } + return df.parse(dateValue); + } + private int getDotIndex(String setter) { return this.conditionClass == SearchBean.class ? -1 : setter.indexOf("."); } http://git-wip-us.apache.org/repos/asf/cxf/blob/0a54ffd4/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java ---------------------------------------------------------------------- diff --git a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java index d084cf3..084cd93 100644 --- a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java +++ b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java @@ -198,11 +198,15 @@ public abstract class AbstractJPATypedQueryVisitor<T, T1, E> break; case EQUALS: if (clazz.equals(String.class)) { - String theValue = SearchUtils.toSqlWildcardString(value.toString(), isWildcardStringMatch()); - if (SearchUtils.containsEscapedPercent(theValue)) { - pred = builder.like((Expression<String>)exp, theValue, '\\'); - } else if (theValue.contains("%")) { - pred = builder.like((Expression<String>)exp, theValue); + final String originalValue = value.toString(); + + String theValue = SearchUtils.toSqlWildcardString(originalValue, isWildcardStringMatch()); + if (SearchUtils.containsWildcard(originalValue)) { + if (SearchUtils.containsEscapedChar(theValue)) { + pred = builder.like((Expression<String>)exp, theValue, '\\'); + } else { + pred = builder.like((Expression<String>)exp, theValue); + } } else { pred = builder.equal(exp, clazz.cast(value)); } @@ -212,11 +216,15 @@ public abstract class AbstractJPATypedQueryVisitor<T, T1, E> break; case NOT_EQUALS: if (clazz.equals(String.class)) { - String theValue = SearchUtils.toSqlWildcardString(value.toString(), isWildcardStringMatch()); - if (SearchUtils.containsEscapedPercent(theValue)) { - pred = builder.notLike((Expression<String>)exp, theValue, '\\'); - } else if (theValue.contains("%")) { - pred = builder.notLike((Expression<String>)exp, theValue); + final String originalValue = value.toString(); + + String theValue = SearchUtils.toSqlWildcardString(originalValue, isWildcardStringMatch()); + if (SearchUtils.containsWildcard(originalValue)) { + if (SearchUtils.containsEscapedChar(theValue)) { + pred = builder.notLike((Expression<String>)exp, theValue, '\\'); + } else { + pred = builder.notLike((Expression<String>)exp, theValue); + } } else { pred = builder.notEqual(exp, clazz.cast(value)); } http://git-wip-us.apache.org/repos/asf/cxf/blob/0a54ffd4/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/sql/SQLPrinterVisitor.java ---------------------------------------------------------------------- diff --git a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/sql/SQLPrinterVisitor.java b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/sql/SQLPrinterVisitor.java index 3f62168..4ce60d8 100644 --- a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/sql/SQLPrinterVisitor.java +++ b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/sql/SQLPrinterVisitor.java @@ -68,10 +68,10 @@ public class SQLPrinterVisitor<T> extends AbstractUntypedSearchConditionVisitor< if (statement != null) { if (statement.getProperty() != null) { String name = getRealPropertyName(statement.getProperty()); - String value = getPropertyValue(name, statement.getValue()); - validatePropertyValue(name, value); + String originalValue = getPropertyValue(name, statement.getValue()); + validatePropertyValue(name, originalValue); - value = SearchUtils.toSqlWildcardString(value, isWildcardStringMatch()); + String value = SearchUtils.toSqlWildcardString(originalValue, isWildcardStringMatch()); value = SearchUtils.duplicateSingleQuoteIfNeeded(value); if (tableAlias != null) { @@ -79,7 +79,8 @@ public class SQLPrinterVisitor<T> extends AbstractUntypedSearchConditionVisitor< } sb.append(name).append(" ").append( - SearchUtils.conditionTypeToSqlOperator(sc.getConditionType(), value)) + SearchUtils.conditionTypeToSqlOperator(sc.getConditionType(), value, + originalValue)) .append(" ").append("'").append(value).append("'"); } } else {
