Author: sergeyb
Date: Sun Oct 21 18:41:23 2012
New Revision: 1400692
URL: http://svn.apache.org/viewvc?rev=1400692&view=rev
Log:
Support for nested properties with mappings at different levels
Added:
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PropertyNotFoundException.java
(with props)
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Name.java
(with props)
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerAddress.java
(with props)
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerName.java
(with props)
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionVisitor.java
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextImpl.java
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Book.java
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/JPATypedQueryVisitorTest.java
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java?rev=1400692&r1=1400691&r2=1400692&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
Sun Oct 21 18:41:23 2012
@@ -1136,6 +1136,12 @@ public final class InjectionUtils {
return PrimitiveUtils.read(value, cls);
} else {
try {
+ Constructor<?> c = cls.getConstructor(new
Class<?>[]{String.class});
+ return c.newInstance(new Object[]{value});
+ } catch (Throwable ex) {
+ // try valueOf
+ }
+ try {
Method m = cls.getMethod("valueOf", new Class[]{String.class});
return cls.cast(m.invoke(null, value));
} catch (Exception ex) {
Modified:
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionVisitor.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionVisitor.java?rev=1400692&r1=1400691&r2=1400692&view=diff
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionVisitor.java
(original)
+++
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionVisitor.java
Sun Oct 21 18:41:23 2012
@@ -18,15 +18,13 @@
*/
package org.apache.cxf.jaxrs.ext.search;
+import java.lang.reflect.Method;
import java.util.Map;
-import java.util.logging.Logger;
-import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
public abstract class AbstractSearchConditionVisitor <T, E> implements
SearchConditionVisitor<T, E> {
-
- private static final Logger LOG =
LogUtils.getL7dLogger(AbstractSearchConditionVisitor.class);
private Map<String, String> fieldMap;
private Map<String, Class<?>> primitiveFieldTypeMap;
@@ -36,25 +34,50 @@ public abstract class AbstractSearchCond
}
protected String getRealPropertyName(String name) {
- if (fieldMap != null && !fieldMap.isEmpty()) {
- if (fieldMap.containsKey(name)) {
- return fieldMap.get(name);
- } else {
- LOG.warning("Unrecognized field alias : " + name);
- }
+ if (fieldMap != null && fieldMap.containsKey(name)) {
+ return fieldMap.get(name);
}
return name;
}
- protected Class<?> getPrimitiveFieldClass(String name, Class<?>
defaultCls) {
+ protected Class<?> getPrimitiveFieldClass(String name, Class<?> valueCls) {
+ return getPrimitiveFieldClass(name, valueCls, null).getCls();
+ }
+
+ protected ClassValue getPrimitiveFieldClass(String name, Class<?>
valueCls, Object value) {
+
+ int index = name.indexOf(".");
+ if (index != -1) {
+ String[] names = name.split("\\.");
+ name = name.substring(index + 1);
+ if (value != null && !InjectionUtils.isPrimitive(valueCls)) {
+ try {
+ String nextPart = names[1];
+ if (nextPart.length() == 1) {
+ nextPart = nextPart.toUpperCase();
+ } else {
+ nextPart = Character.toUpperCase(nextPart.charAt(0)) +
nextPart.substring(1);
+ }
+ Method m = valueCls.getMethod("get" + nextPart, new
Class[]{});
+ value = m.invoke(value, new Object[]{});
+ valueCls = value.getClass();
+
+ } catch (Throwable ex) {
+ throw new RuntimeException();
+ }
+ return getPrimitiveFieldClass(name, valueCls, value);
+ }
+
+ }
+
Class<?> cls = null;
if (primitiveFieldTypeMap != null) {
cls = primitiveFieldTypeMap.get(name);
}
if (cls == null) {
- cls = defaultCls;
+ cls = valueCls;
}
- return cls;
+ return new ClassValue(cls, value);
}
public void setPrimitiveFieldTypeMap(Map<String, Class<?>>
primitiveFieldTypeMap) {
@@ -64,4 +87,26 @@ public abstract class AbstractSearchCond
public SearchConditionVisitor<T, E> visitor() {
return this;
}
+
+ protected class ClassValue {
+ private Class<?> cls;
+ private Object value;
+ public ClassValue(Class<?> cls, Object value) {
+ this.cls = cls;
+ this.value = value;
+
+ }
+ public Class<?> getCls() {
+ return cls;
+ }
+ public void setCls(Class<?> cls) {
+ this.cls = cls;
+ }
+ public Object getValue() {
+ return value;
+ }
+ public void setValue(Object value) {
+ this.value = value;
+ }
+ }
}
Modified:
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java?rev=1400692&r1=1400691&r2=1400692&view=diff
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
(original)
+++
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
Sun Oct 21 18:41:23 2012
@@ -18,10 +18,13 @@
*/
package org.apache.cxf.jaxrs.ext.search;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+
public class PrimitiveSearchCondition<T> implements SearchCondition<T> {
private String propertyName;
@@ -75,17 +78,28 @@ public class PrimitiveSearchCondition<T>
return compare(pojo, cType, propertyValue);
} else {
Object lValue = getValue(propertyName, pojo);
- return lValue == null ? false : compare(lValue, cType,
propertyValue);
+ Object rValue = getPrimitiveValue(propertyName, propertyValue);
+ return lValue == null ? false : compare(lValue, cType, rValue);
}
}
private Object getValue(String getter, T pojo) {
+ String thePropertyName;
+ int index = getter.indexOf(".");
+ if (index != -1) {
+ thePropertyName = getter.substring(0, index).toLowerCase();
+ } else {
+ thePropertyName = getter;
+ }
+
+ Object value;
try {
if (beanspector != null) {
- return beanspector.swap(pojo).getValue(getter);
+ value = beanspector.swap(pojo).getValue(thePropertyName);
} else {
- return ((SearchBean)pojo).get(getter);
+ value = ((SearchBean)pojo).get(getter);
}
+ return getPrimitiveValue(getter, value);
} catch (Throwable e) {
return null;
}
@@ -174,4 +188,30 @@ public class PrimitiveSearchCondition<T>
return lval.equals(rval);
}
}
+
+ protected static Object getPrimitiveValue(String name, Object value) {
+
+ int index = name.indexOf(".");
+ if (index != -1) {
+ String[] names = name.split("\\.");
+ name = name.substring(index + 1);
+ if (value != null &&
!InjectionUtils.isPrimitive(value.getClass())) {
+ try {
+ String nextPart = names[1];
+ if (nextPart.length() == 1) {
+ nextPart = nextPart.toUpperCase();
+ } else {
+ nextPart = Character.toUpperCase(nextPart.charAt(0)) +
nextPart.substring(1);
+ }
+ Method m = value.getClass().getMethod("get" + nextPart,
new Class[]{});
+ value = m.invoke(value, new Object[]{});
+ } catch (Throwable ex) {
+ throw new RuntimeException();
+ }
+ }
+ return getPrimitiveValue(name, value);
+ }
+ return value;
+
+ }
}
Added:
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PropertyNotFoundException.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PropertyNotFoundException.java?rev=1400692&view=auto
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PropertyNotFoundException.java
(added)
+++
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PropertyNotFoundException.java
Sun Oct 21 18:41:23 2012
@@ -0,0 +1,37 @@
+/**
+ * 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;
+
+public class PropertyNotFoundException extends SearchParseException {
+ private static final long serialVersionUID = -3262559013167020058L;
+ private String name;
+ private String value;
+ public PropertyNotFoundException(String name, String value) {
+ this.name = name;
+ this.value = value;
+ }
+ public String getName() {
+ return name;
+ }
+ public String getValue() {
+ return value;
+ }
+
+
+}
Propchange:
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PropertyNotFoundException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/PropertyNotFoundException.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified:
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextImpl.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextImpl.java?rev=1400692&r1=1400691&r2=1400692&view=diff
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextImpl.java
(original)
+++
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextImpl.java
Sun Oct 21 18:41:23 2012
@@ -26,6 +26,7 @@ import java.util.logging.Logger;
import javax.ws.rs.core.MultivaluedMap;
import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
import org.apache.cxf.jaxrs.utils.InjectionUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
@@ -91,11 +92,17 @@ public class SearchContextImpl implement
// we can use this method as a parser factory, ex
// we can get parsers capable of parsing XQuery and other languages
// depending on the properties set by a user
- Map<String, String> props = new LinkedHashMap<String, String>(2);
+ Map<String, String> props = new LinkedHashMap<String, String>(4);
props.put(SearchUtils.DATE_FORMAT_PROPERTY,
(String)message.getContextualProperty(SearchUtils.DATE_FORMAT_PROPERTY));
props.put(SearchUtils.TIMEZONE_SUPPORT_PROPERTY,
(String)message.getContextualProperty(SearchUtils.TIMEZONE_SUPPORT_PROPERTY));
- return new FiqlParser<T>(cls, props);
+ props.put(SearchUtils.LAX_PROPERTY_MATCH,
+
(String)message.getContextualProperty(SearchUtils.LAX_PROPERTY_MATCH));
+
+ Map<String, String> beanProps =
+ CastUtils.cast((Map<?,
?>)message.getContextualProperty(SearchUtils.BEAN_PROPERTY_MAP));
+
+ return new FiqlParser<T>(cls, props, beanProps);
}
}
Modified:
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java?rev=1400692&r1=1400691&r2=1400692&view=diff
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
(original)
+++
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
Sun Oct 21 18:41:23 2012
@@ -28,6 +28,8 @@ public final class SearchUtils {
public static final String DATE_FORMAT_PROPERTY = "search.date-format";
public static final String TIMEZONE_SUPPORT_PROPERTY =
"search.timezone.support";
+ public static final String LAX_PROPERTY_MATCH =
"search.lax.property.match";
+ public static final String BEAN_PROPERTY_MAP = "search.lax.property.match";
private SearchUtils() {
Modified:
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java?rev=1400692&r1=1400691&r2=1400692&view=diff
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
(original)
+++
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
Sun Oct 21 18:41:23 2012
@@ -68,7 +68,7 @@ public class SimpleSearchCondition<T> im
throw new IllegalArgumentException("unsupported condition type: "
+ cType.name());
}
this.condition = condition;
- scts = createConditions(null, cType);
+ scts = createConditions(null, null, cType);
}
@@ -80,7 +80,9 @@ public class SimpleSearchCondition<T> im
* @param getters2operators getters names and operators to be used with
them during comparison
* @param condition template object
*/
- public SimpleSearchCondition(Map<String, ConditionType> getters2operators,
T condition) {
+ public SimpleSearchCondition(Map<String, ConditionType> getters2operators,
+ Map<String, String> realGetters,
+ T condition) {
if (getters2operators == null) {
throw new IllegalArgumentException("getters2operators is null");
}
@@ -98,9 +100,14 @@ public class SimpleSearchCondition<T> im
throw new IllegalArgumentException("unsupported condition
type: " + ct.name());
}
}
- scts = createConditions(getters2operators, null);
+ scts = createConditions(getters2operators, realGetters, null);
}
+ public SimpleSearchCondition(Map<String, ConditionType> getters2operators,
+ T condition) {
+ this(getters2operators, null, condition);
+ }
+
public T getCondition() {
return condition;
}
@@ -126,7 +133,8 @@ public class SimpleSearchCondition<T> im
}
}
- private List<SearchCondition<T>> createConditions(Map<String,
ConditionType> getters2operators,
+ private List<SearchCondition<T>> createConditions(Map<String,
ConditionType> getters2operators,
+ Map<String, String>
realGetters,
ConditionType
sharedType) {
if (isBuiltIn(condition)) {
return Collections.singletonList(
@@ -148,7 +156,10 @@ public class SimpleSearchCondition<T> im
if (rval == null) {
continue;
}
- list.add(new PrimitiveSearchCondition<T>(getter, rval, ct,
condition));
+ String realGetter = realGetters != null &&
realGetters.containsKey(getter)
+ ? realGetters.get(getter) : getter;
+
+ list.add(new PrimitiveSearchCondition<T>(realGetter, rval, ct,
condition));
}
if (list.isEmpty()) {
Modified:
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java?rev=1400692&r1=1400691&r2=1400692&view=diff
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java
(original)
+++
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParser.java
Sun Oct 21 18:41:23 2012
@@ -17,13 +17,13 @@
* under the License.
*/
package org.apache.cxf.jaxrs.ext.search.fiql;
+import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
@@ -36,6 +36,7 @@ import org.apache.cxf.jaxrs.ext.search.A
import org.apache.cxf.jaxrs.ext.search.Beanspector;
import org.apache.cxf.jaxrs.ext.search.ConditionType;
import org.apache.cxf.jaxrs.ext.search.OrSearchCondition;
+import org.apache.cxf.jaxrs.ext.search.PropertyNotFoundException;
import org.apache.cxf.jaxrs.ext.search.SearchBean;
import org.apache.cxf.jaxrs.ext.search.SearchCondition;
import org.apache.cxf.jaxrs.ext.search.SearchConditionParser;
@@ -43,6 +44,7 @@ import org.apache.cxf.jaxrs.ext.search.S
import org.apache.cxf.jaxrs.ext.search.SearchUtils;
import org.apache.cxf.jaxrs.ext.search.SimpleSearchCondition;
import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.message.MessageUtils;
/**
@@ -66,7 +68,7 @@ public class FiqlParser<T> implements Se
public static final String NEQ = "!=";
public static final String DEFAULT_DATE_FORMAT =
"yyyy-MM-dd'T'HH:mm:ss.SSSZ";
-
+
private static final Pattern COMPARATORS_PATTERN;
private static final Map<String, ConditionType> OPERATORS_MAP;
@@ -88,7 +90,8 @@ public class FiqlParser<T> implements Se
private Beanspector<T> beanspector;
private Class<T> conditionClass;
- private Map<String, String> properties;
+ private Map<String, String> contextProperties;
+ private Map<String, String> beanPropertiesMap;
/**
* Creates FIQL parser.
*
@@ -107,12 +110,27 @@ public class FiqlParser<T> implements Se
* @param contextProperties
*/
public FiqlParser(Class<T> tclass, Map<String, String> contextProperties) {
+ this(tclass, contextProperties, null);
+ }
+
+ /**
+ * Creates FIQL parser.
+ *
+ * @param tclass - class of T used to create condition objects in built
syntax tree. Class T must have
+ * accessible no-arg constructor and complementary setters to
these used in FIQL expressions.
+ * @param contextProperties
+ */
+ public FiqlParser(Class<T> tclass,
+ Map<String, String> contextProperties,
+ Map<String, String> beanProperties) {
beanspector = SearchBean.class.isAssignableFrom(tclass)
? null : new Beanspector<T>(tclass);
conditionClass = tclass;
- properties = contextProperties;
+ this.contextProperties = contextProperties == null
+ ? Collections.<String, String>emptyMap() : contextProperties;
+ this.beanPropertiesMap = beanProperties;
}
-
+
/**
* Parses expression and builds search filter. Names used in FIQL
expression are names of getters/setters
* in type T.
@@ -203,7 +221,9 @@ public class FiqlParser<T> implements Se
} else {
node = parseComparison(subex);
}
- ands.add(node);
+ if (node != null) {
+ ands.add(node);
+ }
}
to = from;
if (ands.getSubnodes().size() == 1) {
@@ -228,56 +248,141 @@ public class FiqlParser<T> implements Se
if ("".equals(value)) {
throw new SearchParseException("Not a comparison expression: "
+ expr);
}
- Object castedValue = parseDatatype(name, value);
- return new Comparison(name, operator, castedValue);
+
+ String beanPropertyName = beanPropertiesMap == null ? null :
beanPropertiesMap.get(name);
+ if (beanPropertyName != null) {
+ name = beanPropertyName;
+ }
+
+ Object castedValue = parseType(name, value);
+ if (castedValue != null) {
+ return new Comparison(name, operator, castedValue);
+ } else if
(MessageUtils.isTrue(contextProperties.get(SearchUtils.LAX_PROPERTY_MATCH))) {
+ return null;
+ } else {
+ throw new PropertyNotFoundException(name, value);
+ }
} else {
throw new SearchParseException("Not a comparison expression: " +
expr);
}
}
- private Object parseDatatype(String setter, String value) throws
SearchParseException {
- Object castedValue = value;
- Class<?> valueType;
+
+ private Object parseType(String setter, String value) throws
SearchParseException {
+ String name = getSetter(setter);
+
try {
- valueType = beanspector != null ?
beanspector.getAccessorType(setter) : String.class;
+ Class<?> valueType =
+ beanspector != null ? beanspector.getAccessorType(name) :
String.class;
+ return parseType(null, null, setter, valueType, value);
} catch (Exception e) {
- throw new SearchParseException(e);
+ return null;
}
- if (Date.class.isAssignableFrom(valueType)) {
- try {
- DateFormat df = SearchUtils.getDateFormat(properties,
DEFAULT_DATE_FORMAT);
- String dateValue = value;
- if (SearchUtils.isTimeZoneSupported(properties, Boolean.TRUE))
{
- // 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);
- }
- }
- castedValue = df.parse(dateValue);
- } catch (ParseException e) {
- // is that duration?
+
+ }
+
+ private Object parseType(Object ownerBean, Object lastCastedValue, String
setter,
+ Class<?> valueType, String value) throws
SearchParseException {
+ int index = setter.indexOf(".");
+ if (index == -1) {
+ Object castedValue = value;
+ if (Date.class.isAssignableFrom(valueType)) {
+ castedValue = convertToDate(value);
+ } else {
try {
- Date now = new Date();
-
DatatypeFactory.newInstance().newDuration(value).addTo(now);
- castedValue = now;
- } catch (DatatypeConfigurationException e1) {
- throw new SearchParseException(e1);
- } catch (IllegalArgumentException e1) {
- throw new SearchParseException("Can parse " + value + "
neither as date nor duration", e);
+ castedValue =
InjectionUtils.convertStringToPrimitive(value, valueType);
+ } catch (Exception e) {
+ boolean throwEx = true;
+ if (!valueType.isPrimitive()) {
+ try {
+ Method setterM = valueType.getMethod("set" +
getMethodNameSuffix(setter),
+ new
Class[]{String.class});
+ setterM.invoke(ownerBean, new Object[]{value});
+ castedValue = lastCastedValue;
+ throwEx = false;
+ } catch (Throwable ex) {
+ // continue
+ }
+ }
+ if (throwEx) {
+ throw new SearchParseException("Cannot convert String
value \"" + value
+ + "\" to a value of class " +
valueType.getName(), e);
+ }
}
}
+ return castedValue;
} else {
+ String[] names = setter.split("\\.");
try {
- castedValue = InjectionUtils.convertStringToPrimitive(value,
valueType);
- } catch (Exception e) {
+ String nextPart = getMethodNameSuffix(names[1]);
+ Method getterM = valueType.getMethod("get" + nextPart, new
Class[]{});
+ Class<?> returnType = getterM.getReturnType();
+ boolean lastTry = names.length == 2
+ && (InjectionUtils.isPrimitive(returnType) || returnType
== Date.class);
+
+ Object valueObject = lastTry && ownerBean != null ? ownerBean
: valueType.newInstance();
+ Object nextObject = lastTry ?
InjectionUtils.convertStringToPrimitive(value, returnType)
+ : returnType.newInstance();
+ Method setterM = valueType.getMethod("set" + nextPart, new
Class[]{getterM.getReturnType()});
+ setterM.invoke(valueObject, new Object[]{nextObject});
+
+ lastCastedValue = lastCastedValue == null ? valueObject :
lastCastedValue;
+ if (lastTry) {
+ return lastCastedValue;
+ }
+
+ return parseType(nextObject, lastCastedValue,
setter.substring(index + 1),
+ nextObject.getClass(), value);
+ } catch (Throwable e) {
throw new SearchParseException("Cannot convert String value
\"" + value
- + "\" to a value of class " +
valueType.getName(), e);
+ + "\" to a value of class " +
valueType.getName(), e);
}
}
- return castedValue;
}
-
+
+ private Object convertToDate(String value) throws SearchParseException {
+ try {
+ DateFormat df = SearchUtils.getDateFormat(contextProperties,
DEFAULT_DATE_FORMAT);
+ String dateValue = value;
+ if (SearchUtils.isTimeZoneSupported(contextProperties,
Boolean.TRUE)) {
+ // 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);
+ } catch (ParseException e) {
+ // is that duration?
+ try {
+ Date now = new Date();
+ DatatypeFactory.newInstance().newDuration(value).addTo(now);
+ return now;
+ } catch (DatatypeConfigurationException e1) {
+ throw new SearchParseException(e1);
+ } catch (IllegalArgumentException e1) {
+ throw new SearchParseException("Can parse " + value + "
neither as date nor duration", e);
+ }
+ }
+ }
+
+ private String getSetter(String setter) {
+ int index = setter.indexOf(".");
+ if (index != -1) {
+ return setter.substring(0, index).toLowerCase();
+ } else {
+ return setter;
+ }
+ }
+
+ private String getMethodNameSuffix(String name) {
+ if (name.length() == 1) {
+ return name.toUpperCase();
+ } else {
+ return Character.toUpperCase(name.charAt(0)) + name.substring(1);
+ }
+ }
+
// node of abstract syntax tree
private interface ASTNode<T> {
SearchCondition<T> build() throws SearchParseException;
@@ -314,38 +419,16 @@ public class FiqlParser<T> implements Se
}
public SearchCondition<T> build() throws SearchParseException {
- boolean hasSubtree = false;
+ List<SearchCondition<T>> scNodes = new
ArrayList<SearchCondition<T>>();
for (ASTNode<T> node : subnodes) {
- if (node instanceof FiqlParser.SubExpression) {
- hasSubtree = true;
- break;
- }
+ scNodes.add(node.build());
}
- if (!hasSubtree && AND.equals(operator) && beanspector != null) {
- try {
- // Optimization: single SimpleSearchCondition for 'AND'
conditions
- Map<String, ConditionType> map = new LinkedHashMap<String,
ConditionType>();
- beanspector.instantiate();
- for (ASTNode<T> node : subnodes) {
- FiqlParser<T>.Comparison comp = (Comparison)node;
- map.put(comp.getName(),
OPERATORS_MAP.get(comp.getOperator()));
- beanspector.setValue(comp.getName(), comp.getValue());
- }
- return new SimpleSearchCondition<T>(map,
beanspector.getBean());
- } catch (Throwable e) {
- throw new RuntimeException(e);
- }
+ if (OR.equals(operator)) {
+ return new OrSearchCondition<T>(scNodes);
} else {
- List<SearchCondition<T>> scNodes = new
ArrayList<SearchCondition<T>>();
- for (ASTNode<T> node : subnodes) {
- scNodes.add(node.build());
- }
- if (OR.equals(operator)) {
- return new OrSearchCondition<T>(scNodes);
- } else {
- return new AndSearchCondition<T>(scNodes);
- }
+ return new AndSearchCondition<T>(scNodes);
}
+
}
}
@@ -360,31 +443,21 @@ public class FiqlParser<T> implements Se
this.value = value;
}
- public String getName() {
- return name;
- }
-
- public String getOperator() {
- return operator;
- }
-
- public Object getValue() {
- return value;
- }
-
@Override
public String toString() {
return name + " " + operator + " " + value + " (" +
value.getClass().getSimpleName() + ")";
}
public SearchCondition<T> build() throws SearchParseException {
- T cond = createTemplate(name, value);
+ String templateName = getSetter(name);
+ T cond = createTemplate(templateName, value);
ConditionType ct = OPERATORS_MAP.get(operator);
if (isPrimitive(cond)) {
return new SimpleSearchCondition<T>(ct, cond);
} else {
- return new
SimpleSearchCondition<T>(Collections.singletonMap(name, ct),
+ return new
SimpleSearchCondition<T>(Collections.singletonMap(templateName, ct),
+
Collections.singletonMap(templateName, name),
cond);
}
}
Modified:
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java?rev=1400692&r1=1400691&r2=1400692&view=diff
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java
(original)
+++
cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/jpa/AbstractJPATypedQueryVisitor.java
Sun Oct 21 18:41:23 2012
@@ -106,9 +106,10 @@ public abstract class AbstractJPATypedQu
private Predicate buildPredicate(ConditionType ct, String name, Object
value) {
name = super.getRealPropertyName(name);
- Class<? extends Comparable> clazz = (Class<? extends Comparable>)
- getPrimitiveFieldClass(name, value.getClass());
+ ClassValue cv = getPrimitiveFieldClass(name, value.getClass(), value);
+ Class<? extends Comparable> clazz = (Class<? extends
Comparable>)cv.getCls();
+ value = cv.getValue();
Path<?> path = getPath(root, name);
@@ -119,7 +120,7 @@ public abstract class AbstractJPATypedQu
break;
case EQUALS:
if (clazz.equals(String.class)) {
- String theValue = (String)value;
+ String theValue = value.toString();
if (theValue.contains("*")) {
theValue = ((String)value).replaceAll("\\*", "");
}
Modified:
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Book.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Book.java?rev=1400692&r1=1400691&r2=1400692&view=diff
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Book.java
(original)
+++
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Book.java
Sun Oct 21 18:41:23 2012
@@ -18,6 +18,7 @@
*/
package org.apache.cxf.jaxrs.ext.search.jpa;
+import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -25,8 +26,9 @@ import javax.persistence.Id;
public class Book {
@Id
private int id;
- private String name;
-
+ private String title;
+ private OwnerAddress address;
+ private OwnerName ownerName;
public int getId() {
return id;
@@ -36,11 +38,28 @@ public class Book {
this.id = id;
}
- public String getName() {
- return name;
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String name) {
+ this.title = name;
+ }
+
+ @Embedded
+ public OwnerAddress getAddress() {
+ return address;
+ }
+
+ public void setAddress(OwnerAddress address) {
+ this.address = address;
+ }
+
+ public OwnerName getOwnerName() {
+ return ownerName;
}
- public void setName(String name) {
- this.name = name;
+ public void setOwnerName(OwnerName ownerName) {
+ this.ownerName = ownerName;
}
}
Modified:
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/JPATypedQueryVisitorTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/JPATypedQueryVisitorTest.java?rev=1400692&r1=1400691&r2=1400692&view=diff
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/JPATypedQueryVisitorTest.java
(original)
+++
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/JPATypedQueryVisitorTest.java
Sun Oct 21 18:41:23 2012
@@ -20,7 +20,10 @@ package org.apache.cxf.jaxrs.ext.search.
import java.sql.Connection;
import java.sql.DriverManager;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
@@ -60,17 +63,23 @@ public class JPATypedQueryVisitorTest ex
em.getTransaction().begin();
Book b1 = new Book();
b1.setId(9);
- b1.setName("num9");
+ b1.setTitle("num9");
+ b1.setAddress(new OwnerAddress("Street1"));
+ b1.setOwnerName(new OwnerName(new Name("Fred")));
em.persist(b1);
assertTrue(em.contains(b1));
Book b2 = new Book();
b2.setId(10);
- b2.setName("num10");
+ b2.setTitle("num10");
+ b2.setAddress(new OwnerAddress("Street2"));
+ b2.setOwnerName(new OwnerName(new Name("Barry")));
em.persist(b2);
assertTrue(em.contains(b2));
Book b3 = new Book();
b3.setId(11);
- b3.setName("num11");
+ b3.setTitle("num11");
+ b3.setAddress(new OwnerAddress("Street3"));
+ b3.setOwnerName(new OwnerName(new Name("Bill")));
em.persist(b3);
assertTrue(em.contains(b3));
@@ -116,14 +125,14 @@ public class JPATypedQueryVisitorTest ex
@Test
public void testAndQuery() throws Exception {
- List<Book> books = queryBooks("id==10;name==num10");
+ List<Book> books = queryBooks("id==10;title==num10");
assertEquals(1, books.size());
- assertTrue(10 == books.get(0).getId() &&
"num10".equals(books.get(0).getName()));
+ assertTrue(10 == books.get(0).getId() &&
"num10".equals(books.get(0).getTitle()));
}
@Test
public void testAndQueryNoMatch() throws Exception {
- List<Book> books = queryBooks("id==10;name==num9");
+ List<Book> books = queryBooks("id==10;title==num9");
assertEquals(0, books.size());
}
@@ -135,8 +144,83 @@ public class JPATypedQueryVisitorTest ex
}
@Test
+ public void testEqualsAddressQuery() throws Exception {
+ List<Book> books = queryBooks("address==Street1",
+ Collections.singletonMap("address", "address.street"));
+ assertEquals(1, books.size());
+ Book book = books.get(0);
+ assertTrue(9 == book.getId());
+ assertEquals("Street1", book.getAddress().getStreet());
+ }
+
+ @Test
+ public void testIsMet() throws Exception {
+ SearchCondition<Book> filter =
+ new FiqlParser<Book>(Book.class,
+ null,
+ Collections.singletonMap("address",
"address.street")).parse("address==Street1");
+
+ Book b = new Book();
+ b.setAddress(new OwnerAddress("Street1"));
+ assertTrue(filter.isMet(b));
+
+ b.setAddress(new OwnerAddress("Street2"));
+ assertFalse(filter.isMet(b));
+ }
+
+ @Test
+ public void testEqualsAddressQuery2() throws Exception {
+ List<Book> books = queryBooks("street==Street1",
+ null,
+ Collections.singletonMap("street", "address.street"));
+ assertEquals(1, books.size());
+ Book book = books.get(0);
+ assertTrue(9 == book.getId());
+ assertEquals("Street1", book.getAddress().getStreet());
+ }
+
+ @Test
+ public void testEqualsAddressQuery3() throws Exception {
+ Map<String, String> beanPropertiesMap = new HashMap<String, String>();
+ beanPropertiesMap.put("street", "address.street");
+ beanPropertiesMap.put("housenum", "address.houseNumber");
+ List<Book> books =
+ queryBooks("street==Street2;housenum=lt=5", null,
beanPropertiesMap);
+ assertEquals(1, books.size());
+ Book book = books.get(0);
+ assertTrue(10 == book.getId());
+ assertEquals("Street2", book.getAddress().getStreet());
+
+ }
+
+ @Test
+ public void testEqualsOwnerNameQuery() throws Exception {
+ List<Book> books = queryBooks("ownerName.name.name==Fred");
+ assertEquals(1, books.size());
+ Book book = books.get(0);
+ assertEquals("Fred", book.getOwnerName().getName().getName());
+ }
+
+ @Test
+ public void testEqualsOwnerNameQuery2() throws Exception {
+ List<Book> books = queryBooks("ownerName.name==Fred");
+ assertEquals(1, books.size());
+ Book book = books.get(0);
+ assertEquals("Fred", book.getOwnerName().getName().getName());
+ }
+
+ @Test
+ public void testEqualsOwnerNameQuery3() throws Exception {
+ List<Book> books = queryBooks("ownerName==Fred", null,
+ Collections.singletonMap("ownerName", "ownerName.name.name"));
+ assertEquals(1, books.size());
+ Book book = books.get(0);
+ assertEquals("Fred", book.getOwnerName().getName().getName());
+ }
+
+ @Test
public void testEqualsWildcard() throws Exception {
- List<Book> books = queryBooks("name==num1*");
+ List<Book> books = queryBooks("title==num1*");
assertEquals(2, books.size());
assertTrue(10 == books.get(0).getId() && 11 == books.get(1).getId()
|| 11 == books.get(0).getId() && 10 == books.get(1).getId());
@@ -174,8 +258,23 @@ public class JPATypedQueryVisitorTest ex
}
private List<Book> queryBooks(String expression) throws Exception {
- SearchCondition<Book> filter = new
FiqlParser<Book>(Book.class).parse(expression);
- SearchConditionVisitor<Book, TypedQuery<Book>> jpa = new
JPATypedQueryVisitor<Book>(em, Book.class);
+ return queryBooks(expression, null);
+ }
+
+ private List<Book> queryBooks(String expression,
+ Map<String, String> visitorProps) throws
Exception {
+ return queryBooks(expression, visitorProps, null);
+ }
+
+ private List<Book> queryBooks(String expression,
+ Map<String, String> visitorProps,
+ Map<String, String> parserBinProps) throws
Exception {
+ SearchCondition<Book> filter =
+ new FiqlParser<Book>(Book.class,
+ visitorProps,
+ parserBinProps).parse(expression);
+ SearchConditionVisitor<Book, TypedQuery<Book>> jpa =
+ new JPATypedQueryVisitor<Book>(em, Book.class, visitorProps);
filter.accept(jpa);
TypedQuery<Book> query = jpa.getQuery();
return query.getResultList();
Added:
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Name.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Name.java?rev=1400692&view=auto
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Name.java
(added)
+++
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Name.java
Sun Oct 21 18:41:23 2012
@@ -0,0 +1,45 @@
+/**
+ * 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.jpa;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+
+@Embeddable
+public class Name {
+
+ private String name;
+
+ public Name() {
+
+ }
+ Name(String name) {
+ this.name = name;
+ }
+
+ @Column(name = "thename")
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
Propchange:
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Name.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/Name.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerAddress.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerAddress.java?rev=1400692&view=auto
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerAddress.java
(added)
+++
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerAddress.java
Sun Oct 21 18:41:23 2012
@@ -0,0 +1,53 @@
+/**
+ * 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.jpa;
+
+import javax.persistence.Embeddable;
+
+@Embeddable
+public class OwnerAddress {
+
+ private String street;
+ private int houseNumber;
+
+
+ public OwnerAddress() {
+
+ }
+
+ public OwnerAddress(String street) {
+ this.street = street;
+ }
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ public int getHouseNumber() {
+ return houseNumber;
+ }
+
+ public void setHouseNumber(int houseNumber) {
+ this.houseNumber = houseNumber;
+ }
+}
Propchange:
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerAddress.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerAddress.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerName.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerName.java?rev=1400692&view=auto
==============================================================================
---
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerName.java
(added)
+++
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerName.java
Sun Oct 21 18:41:23 2012
@@ -0,0 +1,45 @@
+/**
+ * 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.jpa;
+
+import javax.persistence.Embeddable;
+import javax.persistence.Embedded;
+
+@Embeddable
+public class OwnerName {
+
+ private Name name;
+
+ public OwnerName() {
+
+ }
+
+ public OwnerName(Name name) {
+ this.name = name;
+ }
+
+ @Embedded
+ public Name getName() {
+ return name;
+ }
+
+ public void setName(Name name) {
+ this.name = name;
+ }
+}
Propchange:
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerName.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/jpa/OwnerName.java
------------------------------------------------------------------------------
svn:keywords = Rev Date