You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2015/11/24 09:21:26 UTC
olingo-odata4 git commit: [OLINGO-568] improved search in technical
service
Repository: olingo-odata4
Updated Branches:
refs/heads/master 69ef9f519 -> 8674a1f29
[OLINGO-568] improved search in technical service
Signed-off-by: Christian Amend <ch...@sap.com>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/8674a1f2
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/8674a1f2
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/8674a1f2
Branch: refs/heads/master
Commit: 8674a1f29919a9f2fe472cf4aa892344bb65e73f
Parents: 69ef9f5
Author: Klaus Straubinger <kl...@sap.com>
Authored: Fri Nov 20 16:43:25 2015 +0100
Committer: Christian Amend <ch...@sap.com>
Committed: Tue Nov 24 09:21:02 2015 +0100
----------------------------------------------------------------------
.../tecsvc/client/SystemQueryOptionITCase.java | 48 +++++-----
.../processor/TechnicalEntityProcessor.java | 7 +-
.../TechnicalPrimitiveComplexProcessor.java | 5 +-
.../queryoptions/options/SearchHandler.java | 97 +++++++++++++-------
4 files changed, 94 insertions(+), 63 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8674a1f2/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java
index b330038..7ffa8a9 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java
@@ -19,10 +19,11 @@
package org.apache.olingo.fit.tecsvc.client;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.net.URI;
-import java.util.List;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
@@ -83,7 +84,7 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
for (int i = 0; i < 5; i++) {
ClientEntity entity = response.getBody().getEntities().get(i);
- assertEquals(new Integer(i + 1).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
+ assertShortOrInt(i + 1, entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
}
}
@@ -102,7 +103,7 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
for (int i = 0; i < 10; i++) {
ClientEntity entity = response.getBody().getEntities().get(i);
- assertEquals(new Integer(i + 6).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
+ assertShortOrInt(i + 6, entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
}
}
@@ -118,7 +119,7 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
ODataRetrieveResponse<ClientEntitySet> response = request.execute();
saveCookieHeader(response);
- assertEquals(0, response.getBody().getEntities().size());
+ assertTrue(response.getBody().getEntities().isEmpty());
}
@Test
@@ -132,15 +133,16 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
ODataRetrieveResponse<ClientEntitySet> response = request.execute();
saveCookieHeader(response);
- assertEquals(0, response.getBody().getEntities().size());
+ assertTrue(response.getBody().getEntities().isEmpty());
}
@Test
- public void filterWithTopSkipOrderByAndServerSidePaging() {
+ public void searchAndFilterWithTopSkipOrderByAndServerSidePaging() {
ODataEntitySetRequest<ClientEntitySet> request = getClient().getRetrieveRequestFactory()
.getEntitySetRequest(getClient().newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(ES_SERVER_SIDE_PAGING)
- .filter("PropertyInt16 le 105") // 1, 2, ... , 105
+ .search("\"Number:\" AND NOT \"106\"") // 1, 2, ..., 105, 107, ...
+ .filter("PropertyInt16 le 106") // 1, 2, ..., 105
.orderBy("PropertyInt16 desc") // 105, 104, ..., 2, 1
.count(true) // 105
.skip(3) // 102, 101, ..., 2, 1
@@ -155,14 +157,14 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
int id = 102;
- // Check first 10 entities
+ // Check first 10 entities.
for (int i = 0; i < 10; i++) {
ClientEntity entity = response.getBody().getEntities().get(i);
- assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
+ assertShortOrInt(id, entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
id--;
}
- // Get 3 * 10 = 30 Entities and check the key
+ // Get 3 * 10 = 30 Entities and check the key.
for (int j = 0; j < 3; j++) {
request = getClient().getRetrieveRequestFactory().getEntitySetRequest(response.getBody().getNext());
setCookieHeader(request);
@@ -172,12 +174,12 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
assertEquals(10, response.getBody().getEntities().size());
for (int i = 0; i < 10; i++) {
ClientEntity entity = response.getBody().getEntities().get(i);
- assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
+ assertShortOrInt(id, entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
id--;
}
}
- // Get the last 3 items
+ // Get the last 3 items.
request = getClient().getRetrieveRequestFactory().getEntitySetRequest(response.getBody().getNext());
setCookieHeader(request);
response = request.execute();
@@ -186,12 +188,12 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
assertEquals(3, response.getBody().getEntities().size());
for (int i = 0; i < 3; i++) {
ClientEntity entity = response.getBody().getEntities().get(i);
- assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
+ assertShortOrInt(id, entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
id--;
}
// Make sure that the body no not contain a next link
- assertEquals(null, response.getBody().getNext());
+ assertNull(response.getBody().getNext());
}
@Test
@@ -299,7 +301,7 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), e.getStatusLine().getStatusCode());
}
}
-
+
@Test
public void basicSearch() {
ODataEntitySetRequest<ClientEntitySet> request = getClient().getRetrieveRequestFactory()
@@ -308,9 +310,9 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
.search("Second")
.build());
setCookieHeader(request);
- ODataRetrieveResponse<ClientEntitySet> response = request.execute();
- List<ClientEntity> entities = response.getBody().getEntities();
- assertEquals(1, entities.size());
+ final ODataRetrieveResponse<ClientEntitySet> response = request.execute();
+ saveCookieHeader(response);
+ assertEquals(1, response.getBody().getEntities().size());
}
@Test
@@ -321,9 +323,9 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
.search("Second AND positive")
.build());
setCookieHeader(request);
- ODataRetrieveResponse<ClientEntitySet> response = request.execute();
- List<ClientEntity> entities = response.getBody().getEntities();
- assertEquals(0, entities.size());
+ final ODataRetrieveResponse<ClientEntitySet> response = request.execute();
+ saveCookieHeader(response);
+ assertTrue(response.getBody().getEntities().isEmpty());
}
@Test
@@ -335,7 +337,7 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
.build());
setCookieHeader(request);
ODataRetrieveResponse<ClientEntitySet> response = request.execute();
- List<ClientEntity> entities = response.getBody().getEntities();
- assertEquals(2, entities.size());
+ saveCookieHeader(response);
+ assertEquals(2, response.getBody().getEntities().size());
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8674a1f2/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index 923bf29..6d7c41e 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -471,23 +471,22 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
edmEntitySet.getEntityType();
EntityCollection entitySetInitial = readEntityCollection(uriInfo);
-
if (entitySetInitial == null) {
entitySetInitial = new EntityCollection();
}
// Modifying the original entitySet means modifying the "database", so we have to make a shallow
- // copy of the entity set (new EntitySet, but exactly the same data)
+ // copy of the entity set (new EntitySet, but exactly the same data).
EntityCollection entitySet = new EntityCollection();
entitySet.getEntities().addAll(entitySetInitial.getEntities());
- // Apply system query options
+ // Apply system query options.
+ SearchHandler.applySearchSystemQueryOption(uriInfo.getSearchOption(), entitySet);
FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, uriInfo, serviceMetadata.getEdm());
CountHandler.applyCountSystemQueryOption(uriInfo.getCountOption(), entitySet);
OrderByHandler.applyOrderByOption(uriInfo.getOrderByOption(), entitySet, uriInfo, serviceMetadata.getEdm());
SkipHandler.applySkipSystemQueryHandler(uriInfo.getSkipOption(), entitySet);
TopHandler.applyTopSystemQueryOption(uriInfo.getTopOption(), entitySet);
- SearchHandler.applySearchSystemQueryOption(uriInfo.getSearchOption(), entitySet);
final Integer pageSize = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getMaxPageSize();
final Integer serverPageSize = ServerSidePagingHandler.applyServerSidePaging(uriInfo.getSkipTokenOption(),
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8674a1f2/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
index 87fbf00..f97b7eb 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
@@ -47,8 +47,8 @@ import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer;
-import org.apache.olingo.server.api.prefer.PreferencesApplied;
import org.apache.olingo.server.api.prefer.Preferences.Return;
+import org.apache.olingo.server.api.prefer.PreferencesApplied;
import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.ComplexProcessor;
import org.apache.olingo.server.api.processor.CountComplexCollectionProcessor;
@@ -226,6 +226,9 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
((UriResourceFunction) resourceParts.get(0)).getParameters(), resource), path) :
getPropertyData(entity, path);
+ // TODO: implement filter on collection properties (on a shallow copy of the values)
+ // FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), property, uriInfo, serviceMetadata.getEdm());
+
if (property == null && representationType != RepresentationType.COUNT) {
if (representationType == RepresentationType.VALUE) {
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8674a1f2/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SearchHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SearchHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SearchHandler.java
index ccc1658..78b6a3b 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SearchHandler.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SearchHandler.java
@@ -18,6 +18,13 @@
*/
package org.apache.olingo.server.tecsvc.processor.queryoptions.options;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.Locale;
+
+import javax.xml.bind.DatatypeConverter;
+
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Property;
@@ -29,64 +36,83 @@ import org.apache.olingo.server.api.uri.queryoption.search.SearchBinaryOperatorK
import org.apache.olingo.server.api.uri.queryoption.search.SearchExpression;
import org.apache.olingo.server.api.uri.queryoption.search.SearchTerm;
-import javax.xml.bind.DatatypeConverter;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.ListIterator;
-import java.util.Locale;
-
public class SearchHandler {
- private static SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
- public static void applySearchSystemQueryOption(final SearchOption searchOption, final EntityCollection entitySet)
+ public static void applySearchSystemQueryOption(final SearchOption searchOption, EntityCollection entitySet)
throws ODataApplicationException {
-
if (searchOption != null) {
SearchExpression se = searchOption.getSearchExpression();
Iterator<Entity> it = entitySet.getEntities().iterator();
- while(it.hasNext()) {
+ while (it.hasNext()) {
boolean keep = false;
Entity entity = it.next();
ListIterator<Property> properties = entity.getProperties().listIterator();
- while(properties.hasNext() && !keep) {
+ while (properties.hasNext() && !keep) {
keep = isTrue(se, properties.next());
}
- if(!keep) {
+ if (!keep) {
it.remove();
}
}
}
}
- private static boolean isTrue(SearchTerm term, Property property) {
- if(property.isPrimitive() && !property.isNull()) {
- String propertyString = asString(property);
- return propertyString != null && propertyString.contains(term.getSearchTerm());
+ private static boolean isTrue(final SearchTerm term, final Property property) {
+ if (property.isNull()) {
+ return false;
+ } else if (property.isPrimitive()) {
+ if (property.isCollection()) {
+ for (final Object primitive : property.asCollection()) {
+ final String propertyString = asString(primitive);
+ if (propertyString != null && propertyString.contains(term.getSearchTerm())) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ final String propertyString = asString(property.asPrimitive());
+ return propertyString != null && propertyString.contains(term.getSearchTerm());
+ }
+ } else if (property.isComplex()) {
+ if (property.isCollection()) {
+ for (final Object member : property.asCollection()) {
+ if (isTrue(term, (Property) member)) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ for (final Property innerProperty : property.asComplex().getValue()) {
+ if (isTrue(term, innerProperty)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ } else {
+ return false;
}
- return false;
}
- private static String asString(Property property) {
- // TODO: mibo(151117): improve 'string' conversion
- Object primitive = property.asPrimitive();
- if(primitive instanceof Calendar) {
- return SIMPLE_DATE_FORMAT.format(((Calendar) primitive).getTime());
- } else if(primitive instanceof Date) {
- return SIMPLE_DATE_FORMAT.format((Date) primitive);
- } else if(primitive instanceof byte[]) {
+ private static String asString(final Object primitive) {
+ // TODO: improve 'string' conversion; maybe consider only String properties
+ if (primitive instanceof String) {
+ return (String) primitive;
+ } else if (primitive instanceof Calendar) {
+ return DatatypeConverter.printDateTime((Calendar) primitive);
+ } else if (primitive instanceof byte[]) {
return DatatypeConverter.printBase64Binary((byte[]) primitive);
+ } else {
+ return primitive.toString();
}
- return primitive.toString();
}
- private static boolean isTrue(SearchBinary binary, Property property) throws ODataApplicationException {
+ private static boolean isTrue(final SearchBinary binary, final Property property) throws ODataApplicationException {
SearchExpression left = binary.getLeftOperand();
SearchExpression right = binary.getRightOperand();
- if(binary.getOperator() == SearchBinaryOperatorKind.AND) {
+ if (binary.getOperator() == SearchBinaryOperatorKind.AND) {
return isTrue(left, property) && isTrue(right, property);
- } else if(binary.getOperator() == SearchBinaryOperatorKind.OR) {
+ } else if (binary.getOperator() == SearchBinaryOperatorKind.OR) {
return isTrue(left, property) || isTrue(right, property);
} else {
throw new ODataApplicationException("Found unknown SearchBinaryOperatorKind: " + binary.getOperator(),
@@ -94,12 +120,13 @@ public class SearchHandler {
}
}
- private static boolean isTrue(SearchExpression searchExpression, Property property) throws ODataApplicationException {
- if(searchExpression.isSearchBinary()) {
+ private static boolean isTrue(final SearchExpression searchExpression, final Property property)
+ throws ODataApplicationException {
+ if (searchExpression.isSearchBinary()) {
return isTrue(searchExpression.asSearchBinary(), property);
- } else if(searchExpression.isSearchTerm()) {
+ } else if (searchExpression.isSearchTerm()) {
return isTrue(searchExpression.asSearchTerm(), property);
- } else if(searchExpression.isSearchUnary()) {
+ } else if (searchExpression.isSearchUnary()) {
return !isTrue(searchExpression.asSearchUnary().getOperand(), property);
}
throw new ODataApplicationException("Found unknown SearchExpression: " + searchExpression,