[OLINGO-1368]OData V4: Support In Operator in filters

This commit is contained in:
ramya vasanth 2019-06-17 14:23:36 +05:30
parent 0c7460a2a2
commit aca474ff64
29 changed files with 589 additions and 77 deletions

View File

@ -41,7 +41,7 @@ public class MetadataTestITCase extends AbstractTestITCase {
final Edm edm = client.getRetrieveRequestFactory().
getMetadataRequest(testVocabulariesServiceRootURL).execute().getBody();
assertNotNull(edm);
final EdmTerm isLanguageDependent = edm.getTerm(new FullQualifiedName("Core", "IsLanguageDependent"));
assertNotNull(isLanguageDependent);
assertTrue(isLanguageDependent.getAppliesTo().contains(TargetType.Property));

View File

@ -142,7 +142,7 @@ public final class AsyncSupportITCase extends AbstractParamTecSvcITCase {
.getEntitySetRequest(uri).execute();
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
ClientEntitySet responseBody = response.getBody();
assertEquals(3, responseBody.getEntities().size());
assertEquals(4, responseBody.getEntities().size());
checkEntityAvailableWith(responseBody, "PropertyInt16", 32767);
// first async request
@ -174,7 +174,7 @@ public final class AsyncSupportITCase extends AbstractParamTecSvcITCase {
ResWrap<EntityCollection> firWrap = client.getDeserializer(getContentType())
.toEntitySet(firstResponse.getRawResponse());
EntityCollection firstResponseEntitySet = firWrap.getPayload();
assertEquals(3, firstResponseEntitySet.getEntities().size());
assertEquals(4, firstResponseEntitySet.getEntities().size());
Entity firstResponseEntity = firstResponseEntitySet.getEntities().get(0);
assertShortOrInt(32767, firstResponseEntity.getProperty("PropertyInt16").asPrimitive());
assertEquals("First Resource - positive values", firstResponseEntity.getProperty("PropertyString").asPrimitive());

View File

@ -294,7 +294,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
assertNotNull(res);
final ResWrap<ClientEntitySet> entitySet = res.getBodyAs(ClientEntitySet.class);
assertEquals(3, entitySet.getPayload().getEntities().size());
assertEquals(4, entitySet.getPayload().getEntities().size());
}
@Test
@ -1303,7 +1303,6 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
getFactory().newPrimitiveValueBuilder().buildInt64(null)));
entity.getProperties().add(getFactory().newPrimitiveProperty(PROPERTY_DECIMAL,
getFactory().newPrimitiveValueBuilder().buildDecimal(null)));
final ODataEntityUpdateRequest<ClientEntity> requestUpdate = getEdmEnabledClient().getCUDRequestFactory()
.getEntityUpdateRequest(uri, UpdateType.PATCH, entity);
requestUpdate.setContentType(CONTENT_TYPE_JSON_IEEE754_COMPATIBLE);
@ -1456,7 +1455,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
final List<ClientEntity> entities = response.getBody().getEntities();
assertEquals(3, entities.size());
assertEquals(4, entities.size());
ClientEntity entity = entities.get(0);
assertEquals(-32768, entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
@ -1469,6 +1468,11 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
assertEquals(BigDecimal.valueOf(0), entity.getProperty(PROPERTY_DECIMAL).getPrimitiveValue().toValue());
entity = entities.get(2);
assertEquals(10, entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals(0L, entity.getProperty(PROPERTY_INT64).getPrimitiveValue().toValue());
assertEquals(BigDecimal.valueOf(0), entity.getProperty(PROPERTY_DECIMAL).getPrimitiveValue().toValue());
entity = entities.get(3);
assertEquals(32767, entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals(Long.MAX_VALUE, entity.getProperty(PROPERTY_INT64).getPrimitiveValue().toValue());
assertEquals(BigDecimal.valueOf(34), entity.getProperty(PROPERTY_DECIMAL).getPrimitiveValue().toValue());

View File

@ -96,7 +96,7 @@ public class BoundOperationITCase extends AbstractParamTecSvcITCase {
final List<ClientEntity> entities = entitySet.getEntities();
assertNotNull(entities);
assertEquals(3, entities.size());
assertEquals(4, entities.size());
ClientEntity entity = entities.get(0);
assertNotNull(entity);

View File

@ -68,7 +68,7 @@ public class EntityReferencesITCase extends AbstractParamTecSvcITCase {
.appendRefSegment()
.orderBy(PROPERTY_INT16).build();
sendRequest(uri, 3, "ESAllPrim(-32768)", "ESAllPrim(0)", "ESAllPrim(32767)");
sendRequest(uri, 4, "ESAllPrim(-32768)", "ESAllPrim(0)", "ESAllPrim(10)", "ESAllPrim(32767)");
}
@Test
@ -78,7 +78,7 @@ public class EntityReferencesITCase extends AbstractParamTecSvcITCase {
.appendRefSegment()
.orderBy(PROPERTY_INT16 + DESCENDING).build();
sendRequest(uri, 3, "ESAllPrim(32767)", "ESAllPrim(0)", "ESAllPrim(-32768)");
sendRequest(uri, 4, "ESAllPrim(32767)", "ESAllPrim(10)", "ESAllPrim(0)", "ESAllPrim(-32768)");
}
@Test
@ -122,7 +122,7 @@ public class EntityReferencesITCase extends AbstractParamTecSvcITCase {
.getEntitySetRequest(uri)
.execute();
assertEquals(Integer.valueOf(3), response.getBody().getCount());
assertEquals(Integer.valueOf(4), response.getBody().getCount());
}
@Test
@ -132,7 +132,7 @@ public class EntityReferencesITCase extends AbstractParamTecSvcITCase {
.appendRefSegment()
.orderBy(PROPERTY_INT16).skip(2).build();
sendRequest(uri, 1, "ESAllPrim(32767)");
sendRequest(uri, 2, "ESAllPrim(10)", "ESAllPrim(32767)");
}
@Test

View File

@ -88,7 +88,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
@Test
public void booleanLiteral() {
ODataRetrieveResponse<ClientEntitySet> response = sendRequest(ES_ALL_PRIM, "PropertyBoolean eq false");
assertEquals(2, response.getBody().getEntities().size());
assertEquals(3, response.getBody().getEntities().size());
ClientEntity clientEntity = response.getBody().getEntities().get(0);
assertShortOrInt(-32768, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue());
@ -256,18 +256,18 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
// One representative of "stringFuntion" "residue class"
ODataRetrieveResponse<ClientEntitySet> result =
sendRequest(ES_ALL_PRIM, "endswith(PropertyString,null) eq null"); // null eq null => true
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
// One representative of "stringifiedValueFunction" "residue class"
result = sendRequest(ES_ALL_PRIM, "substring(PropertyString,null) eq null"); // null eq null => true
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
// Substring
result = sendRequest(ES_ALL_PRIM, "hour(null) eq null"); // null eq null => true
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
result = sendRequest(ES_ALL_PRIM, "substring(PropertyString,0,null) eq null"); // null eq null => true
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
}
@Test
@ -283,7 +283,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
// -1 should be treated as 0, Same values substring(PropertyString, 0, 0) returns the empty String
response = sendRequest(ES_ALL_PRIM, "substring(PropertyString,0,-1) eq ''");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
}
@Test
@ -340,10 +340,10 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
assertEquals(3, result.getBody().getEntities().size());
result = sendRequest(ES_ALL_PRIM, "PropertyDouble ge -179000");
assertEquals(2, result.getBody().getEntities().size());
assertEquals(3, result.getBody().getEntities().size());
result = sendRequest(ES_ALL_PRIM, "PropertyDouble gt -179000");
assertEquals(1, result.getBody().getEntities().size());
assertEquals(2, result.getBody().getEntities().size());
result = sendRequest(ES_ALL_PRIM, "PropertyDouble lt -179000");
assertEquals(1, result.getBody().getEntities().size());
@ -507,7 +507,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
@Test
public void monthFunctionDateTimeOffset() {
ODataRetrieveResponse<ClientEntitySet> result = sendRequest(ES_ALL_PRIM, "month(PropertyDateTimeOffset) eq 12");
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
ClientEntity clientEntity = result.getBody().getEntities().get(0);
assertShortOrInt(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue());
@ -531,7 +531,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
@Test
public void dayFunctionDateTimeOffset() {
ODataRetrieveResponse<ClientEntitySet> result = sendRequest(ES_ALL_PRIM, "day(PropertyDateTimeOffset) eq 3");
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
ClientEntity clientEntity = result.getBody().getEntities().get(0);
assertShortOrInt(32767, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue());
@ -628,7 +628,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
public void fractionalsecondsDateOfTime() {
ODataRetrieveResponse<ClientEntitySet> response =
sendRequest(ES_ALL_PRIM, "fractionalseconds(PropertyTimeOfDay) eq 0");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
}
@Test
@ -636,22 +636,22 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
ODataRetrieveResponse<ClientEntitySet> response;
response = sendRequest(ES_ALL_PRIM, "year(null) eq null");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
response = sendRequest(ES_ALL_PRIM, "month(null) eq null");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
response = sendRequest(ES_ALL_PRIM, "day(null) eq null");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
response = sendRequest(ES_ALL_PRIM, "hour(null) eq null");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
response = sendRequest(ES_ALL_PRIM, "minute(null) eq null");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
response = sendRequest(ES_ALL_PRIM, "second(null) eq null");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
}
@Test
@ -794,7 +794,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
public void numericPromotionToInt64() {
ODataRetrieveResponse<ClientEntitySet> result =
sendRequest(ES_ALL_PRIM, "PropertyInt64 eq 0");
assertEquals(1, result.getBody().getEntities().size());
assertEquals(2, result.getBody().getEntities().size());
ClientEntity clientEntity = result.getBody().getEntities().get(0);
assertShortOrInt(0, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue());
@ -805,7 +805,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
double value = Float.MAX_VALUE + 1;
ODataRetrieveResponse<ClientEntitySet> result =
sendRequest(ES_ALL_PRIM, "PropertyInt64 lt " + value);
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
}
@Test
@ -879,7 +879,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
public void dateSubDate() {
ODataRetrieveResponse<ClientEntitySet> response =
sendRequest(ES_ALL_PRIM, "PropertyDuration eq 2012-12-04 sub 2012-12-04");
assertEquals(1, response.getBody().getEntities().size());
assertEquals(2, response.getBody().getEntities().size());
final ClientEntity clientEntity = response.getBody().getEntities().get(0);
assertShortOrInt(0, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue());
@ -889,7 +889,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
public void dateTimeOffsetSubDateTimeOffset() {
ODataRetrieveResponse<ClientEntitySet> response =
sendRequest(ES_ALL_PRIM, "PropertyDuration eq 2005-12-03T00:00:00Z sub 2005-12-03T00:00:00Z");
assertEquals(1, response.getBody().getEntities().size());
assertEquals(2, response.getBody().getEntities().size());
final ClientEntity clientEntity = response.getBody().getEntities().get(0);
assertShortOrInt(0, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue());
@ -1008,28 +1008,28 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
public void comparisonOnStringOperands() {
// If check if the expression is true => All entry are returned
ODataRetrieveResponse<ClientEntitySet> result = sendRequest(ES_ALL_PRIM, "'Tes' lt 'Test'");
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
result = sendRequest(ES_ALL_PRIM, "'Test' le 'Test'");
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
result = sendRequest(ES_ALL_PRIM, "'Test1' le 'Test'");
assertEquals(0, result.getBody().getEntities().size());
result = sendRequest(ES_ALL_PRIM, "'Test1' gt 'Test'");
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
result = sendRequest(ES_ALL_PRIM, "'Tes' gt 'Test'");
assertEquals(0, result.getBody().getEntities().size());
result = sendRequest(ES_ALL_PRIM, "'Test' ge 'Test'");
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
result = sendRequest(ES_ALL_PRIM, "'Test' eq 'Test'");
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
result = sendRequest(ES_ALL_PRIM, "'Test1' ne 'Test'");
assertEquals(3, result.getBody().getEntities().size());
assertEquals(4, result.getBody().getEntities().size());
}
@Test

View File

@ -42,22 +42,25 @@ public class OrderBySystemQueryITCase extends AbstractParamTecSvcITCase {
ODataRetrieveResponse<ClientEntitySet> response = null;
response = sendRequest(ES_ALL_PRIM, "PropertyDate");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
ClientEntity clientEntity = response.getBody().getEntities().get(0);
assertEquals("0", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
clientEntity = response.getBody().getEntities().get(1);
assertEquals("10", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
clientEntity = response.getBody().getEntities().get(2);
assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
clientEntity = response.getBody().getEntities().get(2);
clientEntity = response.getBody().getEntities().get(3);
assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
}
@Test
public void simpleOrderByDescending() {
ODataRetrieveResponse<ClientEntitySet> response = sendRequest(ES_ALL_PRIM, "PropertyDate desc");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
ClientEntity clientEntity = response.getBody().getEntities().get(0);
assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
@ -72,7 +75,7 @@ public class OrderBySystemQueryITCase extends AbstractParamTecSvcITCase {
@Test
public void multipleOrderBy() {
final ODataRetrieveResponse<ClientEntitySet> response = sendRequest(ES_ALL_PRIM, "PropertyByte,PropertyInt16");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
ClientEntity clientEntity = response.getBody().getEntities().get(0);
assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
@ -81,6 +84,9 @@ public class OrderBySystemQueryITCase extends AbstractParamTecSvcITCase {
assertEquals("0", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
clientEntity = response.getBody().getEntities().get(2);
assertEquals("10", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
clientEntity = response.getBody().getEntities().get(3);
assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
}
@ -88,15 +94,18 @@ public class OrderBySystemQueryITCase extends AbstractParamTecSvcITCase {
public void multipleOrderByDescending() {
final ODataRetrieveResponse<ClientEntitySet> response =
sendRequest(ES_ALL_PRIM, "PropertyByte,PropertyInt16 desc");
assertEquals(3, response.getBody().getEntities().size());
assertEquals(4, response.getBody().getEntities().size());
ClientEntity clientEntity = response.getBody().getEntities().get(0);
assertEquals("10", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
clientEntity = response.getBody().getEntities().get(1);
assertEquals("0", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
clientEntity = response.getBody().getEntities().get(1);
clientEntity = response.getBody().getEntities().get(2);
assertEquals("-32768", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
clientEntity = response.getBody().getEntities().get(2);
clientEntity = response.getBody().getEntities().get(3);
assertEquals("32767", ((ClientValuable) clientEntity.getProperty("PropertyInt16")).getValue().toString());
}

View File

@ -50,8 +50,8 @@ public class SystemQueryOptionITCase extends AbstractParamTecSvcITCase {
ODataRetrieveResponse<ClientEntitySet> response = request.execute();
saveCookieHeader(response);
assertEquals(Integer.valueOf(3), response.getBody().getCount());
assertEquals(3, response.getBody().getEntities().size());
assertEquals(Integer.valueOf(4), response.getBody().getCount());
assertEquals(4, response.getBody().getEntities().size());
}
@Test

View File

@ -0,0 +1,109 @@
/*
* 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.olingo.fit.tecsvc.http;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.fit.AbstractBaseTestITCase;
import org.apache.olingo.fit.tecsvc.TecSvcConst;
import org.junit.Test;
public class InOperatorITCase extends AbstractBaseTestITCase {
private static final String SERVICE_URI = TecSvcConst.BASE_URI + "/";
@Override
protected ODataClient getClient() {
return null;
}
@Test
public void querySimple() throws Exception {
URL url = new URL(SERVICE_URI + "ESAllPrim?$filter=PropertyString%20in%20("
+ "%27Second%20Resource%20-%20negative%20values%27,%27xyz%27)");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=minimal");
connection.connect();
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
final String content = IOUtils.toString(connection.getInputStream());
assertTrue(content.contains("\"value\":[{\"PropertyInt16\":-32768,"
+ "\"PropertyString\":\"Second Resource - negative values\","
+ "\"PropertyBoolean\":false,\"PropertyByte\":0,\"PropertySByte\":-128,"
+ "\"PropertyInt32\":-2147483648,\"PropertyInt64\":-9223372036854775808,"
+ "\"PropertySingle\":-1.79E8,\"PropertyDouble\":-179000.0,\"PropertyDecimal\":-34,"
+ "\"PropertyBinary\":\"ASNFZ4mrze8=\",\"PropertyDate\":\"2015-11-05\","
+ "\"PropertyDateTimeOffset\":\"2005-12-03T07:17:08Z\",\"PropertyDuration\":\"PT9S\","
+ "\"PropertyGuid\":\"76543201-23ab-cdef-0123-456789dddfff\","
+ "\"PropertyTimeOfDay\":\"23:49:14\"}]"));
}
@Test
public void queryInOperatorWithFunction() throws Exception {
URL url = new URL(SERVICE_URI + "ESAllPrim?$filter=PropertyString%20in%20olingo.odata.test1.UFCRTCollString()");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=minimal");
connection.connect();
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
final String content = IOUtils.toString(connection.getInputStream());
assertTrue(content.contains("\"value\":[{\"PropertyInt16\":10,"
+ "\"PropertyString\":\"Employee1@company.example\","
+ "\"PropertyBoolean\":false,\"PropertyByte\":0,\"PropertySByte\":0,"
+ "\"PropertyInt32\":0,\"PropertyInt64\":0,\"PropertySingle\":0.0,"
+ "\"PropertyDouble\":0.0,\"PropertyDecimal\":0,\"PropertyBinary\":\"\","
+ "\"PropertyDate\":\"1970-01-01\","
+ "\"PropertyDateTimeOffset\":\"2005-12-03T00:00:00Z\","
+ "\"PropertyDuration\":\"PT0S\","
+ "\"PropertyGuid\":\"76543201-23ab-cdef-0123-456789cccddd\","
+ "\"PropertyTimeOfDay\":\"00:01:01\"}]"));
}
@Test
public void queryInOperatorOnNavProperty() throws Exception {
URL url = new URL(SERVICE_URI + "ESKeyNav?$filter=PropertyCompTwoPrim/"
+ "PropertyInt16%20in%20NavPropertyETKeyNavOne/CollPropertyInt16");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(HttpMethod.GET.name());
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=minimal");
connection.connect();
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
final String content = IOUtils.toString(connection.getInputStream());
assertTrue(content.contains("\"value\":[]"));
}
}

View File

@ -293,7 +293,8 @@ public class EdmProviderImpl extends AbstractEdm {
try {
if (null != provider.getAliasInfos()) {
for (CsdlAliasInfo aliasInfo : provider.getAliasInfos()) {
if (aliasInfo.getNamespace().equalsIgnoreCase(namespace)) {
if (null != aliasInfo.getNamespace() &&
aliasInfo.getNamespace().equalsIgnoreCase(namespace)) {
return aliasInfo.getAlias();
}
}

View File

@ -18,6 +18,8 @@
*/
package org.apache.olingo.server.api.uri.queryoption.expression;
import java.util.List;
/**
* Represents a binary expression node in the expression tree
* <br>
@ -41,5 +43,11 @@ public interface Binary extends Expression {
* @return Expression sub tree of the right operand
*/
public Expression getRightOperand();
/**
*
* @return list of expressions of the right operand
*/
public List<Expression> getExpressions();
}

View File

@ -28,6 +28,11 @@ public enum BinaryOperatorKind {
* OData has operator used for OData enumerations
*/
HAS("has"),
/**
* In operator
*/
IN("in"),
/**
* Multiplication operator

View File

@ -132,5 +132,17 @@ public interface ExpressionVisitor<T> {
* @throws ODataApplicationException Thrown by the application
*/
T visitEnum(EdmEnumType type, List<String> enumValues) throws ExpressionVisitException, ODataApplicationException;
/**
* Called for each traversed {@link Binary} expression
* @param operator Operator kind
* @param left Application return value of left sub tree
* @param right Application return value of right sub tree
* @return Application return value of type T
* @throws ExpressionVisitException Thrown if an exception while traversing occured
* @throws ODataApplicationException Thrown by the application
*/
T visitBinaryOperator(BinaryOperatorKind operator, T left, List<T> right)
throws ExpressionVisitException, ODataApplicationException;
}

View File

@ -330,6 +330,7 @@ public class ExpressionJsonVisitor implements ExpressionVisitor<JsonNode> {
case NE:
case AND:
case OR:
case IN:
return BOOLEAN_NAME;
}
return UNKNOWN_NAME;
@ -343,4 +344,19 @@ public class ExpressionJsonVisitor implements ExpressionVisitor<JsonNode> {
final EdmType type = segment instanceof UriResourcePartTyped ? ((UriResourcePartTyped) segment).getType() : null;
return type == null ? UNKNOWN_NAME : type.getFullQualifiedName().getFullQualifiedNameAsString();
}
@Override
public JsonNode visitBinaryOperator(BinaryOperatorKind operator, JsonNode left, List<JsonNode> right)
throws ExpressionVisitException, ODataApplicationException {
ObjectNode result = nodeFactory.objectNode()
.put(NODE_TYPE_NAME, BINARY_NAME)
.put(OPERATOR_NAME, operator.toString())
.put(TYPE_NAME, getType(operator));
result.set(LEFT_NODE_NAME, left);
ArrayNode jsonExprs = result.putArray(RIGHT_NODE_NAME);
for (final JsonNode exp : right) {
jsonExprs.add(exp);
}
return result;
}
}

View File

@ -332,9 +332,64 @@ public class ExpressionParser {
final Expression right = createEnumExpression(tokenizer.getText());
return new BinaryImpl(left, BinaryOperatorKind.HAS, right,
odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean));
} else {
return left;
} else if (tokenizer.next(TokenKind.InOperator)) {
EdmType leftExprType = getType(left);
EdmPrimitiveTypeKind kinds = EdmPrimitiveTypeKind.valueOfFQN(leftExprType.getFullQualifiedName());
if (tokenizer.next(TokenKind.OPEN)) {
ParserHelper.bws(tokenizer);
List<Expression> expressionList = parseInExpr();
checkInExpressionTypes(expressionList, kinds);
return new BinaryImpl(left, BinaryOperatorKind.IN, expressionList,
odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean));
} else {
ParserHelper.bws(tokenizer);
final Expression right = parseExpression();
checkType(right, kinds);
return new BinaryImpl(left, BinaryOperatorKind.IN, right,
odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean));
}
}
return left;
}
/**
* @param expressionList
* @param kinds
* @throws UriParserException
* @throws UriParserSemanticException
*/
private void checkInExpressionTypes(List<Expression> expressionList, EdmPrimitiveTypeKind kinds)
throws UriParserException, UriParserSemanticException {
for (Expression expr : expressionList) {
EdmType inExprType = getType(expr);
if (!isType(inExprType, kinds)) {
throw new UriParserSemanticException("Incompatible types.",
UriParserSemanticException.MessageKeys.TYPES_NOT_COMPATIBLE,
inExprType == null ? "" : inExprType.getFullQualifiedName().getFullQualifiedNameAsString(),
kinds.getFullQualifiedName().getFullQualifiedNameAsString());
}
}
}
/**
* @param expressionList
* @throws UriParserException
* @throws UriValidationException
*/
private List<Expression> parseInExpr() throws UriParserException, UriValidationException {
List<Expression> expressionList = new ArrayList<Expression>();
while(!tokenizer.next(TokenKind.CLOSE)) {
Expression expression = parseExpression();
expressionList.add(expression);
ParserHelper.bws(tokenizer);
if (tokenizer.next(TokenKind.COMMA)) {
ParserHelper.bws(tokenizer);
expression = parseExpression();
expressionList.add(expression);
ParserHelper.bws(tokenizer);
}
}
return expressionList;
}
private Expression parseExprValue() throws UriParserException, UriValidationException {

View File

@ -126,6 +126,7 @@ public class UriTokenizer {
LessThanOperator,
LessThanOrEqualsOperator,
HasOperator,
InOperator,
AddOperator,
SubOperator,
MulOperator,
@ -508,6 +509,9 @@ public class UriTokenizer {
case HasOperator:
found = nextBinaryOperator("has");
break;
case InOperator:
found = nextBinaryOperator("in");
break;
case AddOperator:
found = nextBinaryOperator("add");
break;

View File

@ -18,6 +18,9 @@
*/
package org.apache.olingo.server.core.uri.queryoption.expression;
import java.util.ArrayList;
import java.util.List;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.queryoption.expression.Binary;
@ -32,6 +35,7 @@ public class BinaryImpl implements Binary {
private final BinaryOperatorKind operator;
private final Expression right;
private final EdmType type;
private final List<Expression> expressions;
public BinaryImpl(final Expression left, final BinaryOperatorKind operator, final Expression right,
final EdmType type) {
@ -39,6 +43,16 @@ public class BinaryImpl implements Binary {
this.operator = operator;
this.right = right;
this.type = type;
this.expressions = null;
}
public BinaryImpl(final Expression left, final BinaryOperatorKind operator, final List<Expression> right,
final EdmType type) {
this.left = left;
this.operator = operator;
this.right = null;
this.type = type;
this.expressions = right;
}
@Override
@ -63,12 +77,26 @@ public class BinaryImpl implements Binary {
@Override
public <T> T accept(final ExpressionVisitor<T> visitor) throws ExpressionVisitException, ODataApplicationException {
T localLeft = this.left.accept(visitor);
T localRight = this.right.accept(visitor);
return visitor.visitBinaryOperator(operator, localLeft, localRight);
if (this.right != null) {
T localRight = this.right.accept(visitor);
return visitor.visitBinaryOperator(operator, localLeft, localRight);
} else if (this.expressions != null) {
List<T> expressions = new ArrayList<T>();
for (final Expression expression : this.expressions) {
expressions.add(expression.accept(visitor));
}
return visitor.visitBinaryOperator(operator, localLeft, expressions);
}
return null;
}
@Override
public String toString() {
return "{" + left + " " + operator.name() + " " + right + '}';
return "{" + left + " " + operator.name() + " " + (null != right ? right : expressions) + '}';
}
@Override
public List<Expression> getExpressions() {
return expressions;
}
}

View File

@ -392,10 +392,23 @@ public class ExpressionParserTest {
Mockito.when(mockedEdm.getEntityContainer()).thenReturn(container);
UriTokenizer tokenizer = new UriTokenizer("a eq \'abc\'");
final Expression expression = new ExpressionParser(mockedEdm, odata).parse(tokenizer,
Expression expression = new ExpressionParser(mockedEdm, odata).parse(tokenizer,
entityType, null, null);
assertNotNull(expression);
assertEquals("{[a] EQ \'abc\'}", expression.toString());
tokenizer = new UriTokenizer("a in (\'abc\', \'xyz\')");
expression = new ExpressionParser(mockedEdm, odata).parse(tokenizer,
entityType, null, null);
assertNotNull(expression);
assertEquals("{[a] IN [\'abc\', \'xyz\']}", expression.toString());
try {
tokenizer = new UriTokenizer("a in (\'abc\', 10)");
expression = new ExpressionParser(mockedEdm, odata).parse(tokenizer,
entityType, null, null);
} catch (UriParserSemanticException e) {
assertEquals("Incompatible types.", e.getMessage());
}
}
/**
@ -519,10 +532,16 @@ public class ExpressionParserTest {
Mockito.when(mockedEdm.getEntityContainer()).thenReturn(container);
UriTokenizer tokenizer = new UriTokenizer("comp/prop eq \'abc\'");
final Expression expression = new ExpressionParser(mockedEdm, odata).parse(tokenizer,
Expression expression = new ExpressionParser(mockedEdm, odata).parse(tokenizer,
entityType, null, null);
assertNotNull(expression);
assertEquals("{[comp, prop] EQ \'abc\'}", expression.toString());
tokenizer = new UriTokenizer("comp/prop in (\'abc\','xyz')");
expression = new ExpressionParser(mockedEdm, odata).parse(tokenizer,
entityType, null, null);
assertNotNull(expression);
assertEquals("{[comp, prop] IN [\'abc\', \'xyz\']}", expression.toString());
}
/**

View File

@ -1149,6 +1149,25 @@ public class DataCreator {
.addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(0)))
.addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789cccddd")))
.addProperty(createPrimitive("PropertyTimeOfDay", getTime(0, 1, 1))));
entityCollection.getEntities().add(new Entity()
.addProperty(createPrimitive("PropertyInt16", (short) 10))
.addProperty(createPrimitive("PropertyString", "Employee1@company.example"))
.addProperty(createPrimitive("PropertyBoolean", false))
.addProperty(createPrimitive("PropertyByte", (short) 0))
.addProperty(createPrimitive("PropertySByte", 0))
.addProperty(createPrimitive("PropertyInt32", 0))
.addProperty(createPrimitive("PropertyInt64", 0L))
.addProperty(createPrimitive("PropertySingle", (float) 0))
.addProperty(createPrimitive("PropertyDouble", 0D))
.addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(0)))
.addProperty(createPrimitive("PropertyBinary", new byte[] {}))
.addProperty(createPrimitive("PropertyDate", getDate(1970, 1, 1)))
.addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 0, 0, 0)))
.addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(0)))
.addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789cccddd")))
.addProperty(createPrimitive("PropertyTimeOfDay", getTime(0, 1, 1))));
setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETAllPrim));
createEntityId(edm, odata, "ESAllPrim", entityCollection);

View File

@ -24,11 +24,13 @@ import java.util.Locale;
import org.apache.olingo.commons.api.data.ComplexValue;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEnumType;
import org.apache.olingo.commons.api.edm.EdmFunction;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
@ -43,6 +45,7 @@ import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceFunction;
import org.apache.olingo.server.api.uri.UriResourceLambdaAny;
import org.apache.olingo.server.api.uri.UriResourceLambdaVariable;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.api.uri.queryoption.expression.Binary;
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
@ -112,6 +115,8 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
return binaryOperator.arithmeticOperator(operator);
case HAS:
return binaryOperator.hasOperator();
case IN:
return binaryOperator.inOperator();
default:
return throwNotImplemented();
@ -278,6 +283,25 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
}
return new TypedOperand(currentProperty == null ? null : currentProperty.getValue(),
currentEdmProperty.getType(), currentEdmProperty);
} else if (initialPart instanceof UriResourceNavigation) {
EdmNavigationProperty currentEdmNavProperty = ((UriResourceNavigation) initialPart).getProperty();
EdmProperty currentEdmProperty = null;
Link link = entity.getNavigationLink(currentEdmNavProperty.getName());
Entity inlineEntity = link != null ? link.getInlineEntity() : null;
Property currentProperty = null;
for (int i = 1; i < uriResourceParts.size(); i++) {
currentEdmProperty = ((UriResourceProperty) uriResourceParts.get(i)).getProperty();
if (null != inlineEntity) {
for (Property property : inlineEntity.getProperties()) {
if (property.getName().equalsIgnoreCase(currentEdmProperty.getName())) {
currentProperty = property;
break;
}
}
}
}
return new TypedOperand(currentProperty != null ? currentProperty.getValue() : null,
currentEdmProperty.getType(), currentEdmProperty);
} else {
return throwNotImplemented();
}
@ -324,4 +348,15 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
throw new ODataApplicationException("Not implemented", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),
Locale.ROOT);
}
@Override
public VisitorOperand visitBinaryOperator(BinaryOperatorKind operator, VisitorOperand left,
List<VisitorOperand> right) throws ExpressionVisitException, ODataApplicationException {
BinaryOperator binaryOperator = new BinaryOperator(left, right);
switch (operator) {
case IN : return binaryOperator.inOperator();
default:
return throwNotImplemented();
}
}
}

View File

@ -20,7 +20,9 @@ package org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operan
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
@ -55,11 +57,62 @@ public class TypedOperand extends VisitorOperand {
return value.getClass() == getDefaultType((EdmPrimitiveType) type) ?
this :
asTypedOperand((EdmPrimitiveType) type);
} else if (type instanceof EdmPrimitiveType && value instanceof Collection) {
return value.getClass() == getDefaultType((EdmPrimitiveType) type) ?
this :
asTypedOperandForCollection((EdmPrimitiveType) type);
} else {
throw new ODataApplicationException("A single primitive-type instance is expected.",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
}
}
@SuppressWarnings("unchecked")
@Override
public TypedOperand asTypedOperandForCollection(final EdmPrimitiveType asType) throws ODataApplicationException {
if (is(primNull)) {
return this;
} else if (isNull()) {
return new TypedOperand(null, asType);
}
List<Object> newValue = new ArrayList<Object>();
List<Object> list = (List<Object>) value;
for (Object val : list) {
// Use BigInteger for arbitrarily large whole numbers.
if (asType.equals(primSByte) || asType.equals(primByte)
|| asType.equals(primInt16) || asType.equals(primInt32) || asType.equals(primInt64)) {
if (val instanceof BigInteger) {
newValue.add(val);
} else if (val instanceof Byte || val instanceof Short
|| val instanceof Integer || val instanceof Long) {
newValue.add(BigInteger.valueOf(((Number) val).longValue()));
}
// Use BigDecimal for unlimited precision.
} else if (asType.equals(primDouble) || asType.equals(primSingle) || asType.equals(primDecimal)) {
try {
newValue.add(new BigDecimal(val.toString()));
} catch (NumberFormatException e) {
throw new ODataApplicationException("Format exception",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT, e.getCause());
}
} else {
// Use type conversion of EdmPrimitive types
try {
final String literal = getLiteral(val);
newValue.add(tryCast(literal, asType));
} catch (EdmPrimitiveTypeException e) {
throw new ODataApplicationException("Cast Failed",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT, e.getCause());
}
}
}
if (!newValue.isEmpty()) {
return new TypedOperand(newValue, asType);
}
throw new ODataApplicationException("Cast failed", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
}
@Override
public TypedOperand asTypedOperand(final EdmPrimitiveType asType) throws ODataApplicationException {
@ -67,7 +120,7 @@ public class TypedOperand extends VisitorOperand {
return this;
} else if (isNull()) {
return new TypedOperand(null, asType);
}
}
Object newValue = null;
// Use BigInteger for arbitrarily large whole numbers.
@ -119,19 +172,20 @@ public class TypedOperand extends VisitorOperand {
}
if (type.equals(primDouble) || oType.equals(primDouble)) {
return asTypedOperand(primDouble);
return (value instanceof ArrayList) ? asTypedOperandForCollection(primDouble) : asTypedOperand(primDouble);
} else if (type.equals(primSingle) || oType.equals(primSingle)) {
return asTypedOperand(primSingle);
return (value instanceof ArrayList) ? asTypedOperandForCollection(primSingle) : asTypedOperand(primSingle);
} else if (type.equals(primDecimal) || oType.equals(primDecimal)) {
return asTypedOperand(primDecimal);
return (value instanceof ArrayList) ? asTypedOperandForCollection(primDecimal) : asTypedOperand(primDecimal);
} else if (type.equals(primInt64) || oType.equals(primInt64)) {
return asTypedOperand(primInt64);
return (value instanceof ArrayList) ? asTypedOperandForCollection(primInt64) : asTypedOperand(primInt64);
} else if (type.equals(primInt32) || oType.equals(primInt32)) {
return asTypedOperand(primInt32);
return (value instanceof ArrayList) ? asTypedOperandForCollection(primInt32) : asTypedOperand(primInt32);
} else if (type.equals(primInt16) || oType.equals(primInt16)) {
return asTypedOperand(primInt16);
return (value instanceof ArrayList) ? asTypedOperandForCollection(primInt16) : asTypedOperand(primInt16);
} else {
return asTypedOperand((EdmPrimitiveType) type);
return (value instanceof ArrayList) ? asTypedOperandForCollection((EdmPrimitiveType) type) :
asTypedOperand((EdmPrimitiveType) type);
}
}
@ -142,6 +196,16 @@ public class TypedOperand extends VisitorOperand {
public <T> T getTypedValue(final Class<T> clazz) {
return clazz.cast(value);
}
public <T> List<T> getTypedValueList(final Class<T> clazz) {
List<Object> list = (List<Object>) value;
List<Object> newList = new ArrayList<Object>();
for (Object obj : list) {
newList.add(clazz.cast(obj));
}
return (List<T>) newList;
}
public boolean isNull() {
return is(primNull) || value == null;

View File

@ -18,6 +18,8 @@
*/
package org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
@ -54,6 +56,31 @@ public class UntypedOperand extends VisitorOperand {
throw new ODataApplicationException("Cast failed", HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(),
Locale.ROOT);
}
@SuppressWarnings( "unchecked")
@Override
public TypedOperand asTypedOperandForCollection(EdmPrimitiveType type) throws ODataApplicationException {
List<Object> newValue = new ArrayList<Object>();
List<Object> list = (List<Object>) value;
for (Object val : list) {
final String literal = (String) val;
// First try the null literal.
if (null != tryCast(literal, primNull)) {
newValue.add(tryCast(literal, primNull));
type = primNull;
}
// Then try the given type.
if (null != tryCast(literal, type)) {
newValue.add(tryCast(literal, type));
}
}
if (!newValue.isEmpty()) {
return new TypedOperand(newValue, type);
}
throw new ODataApplicationException("Cast failed", HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(),
Locale.ROOT);
}
public TypedOperand determineType() throws ODataApplicationException {
final String literal = (String) value;

View File

@ -86,6 +86,8 @@ public abstract class VisitorOperand {
public abstract TypedOperand asTypedOperand() throws ODataApplicationException;
public abstract TypedOperand asTypedOperand(EdmPrimitiveType type) throws ODataApplicationException;
public abstract TypedOperand asTypedOperandForCollection(EdmPrimitiveType type) throws ODataApplicationException;
public abstract EdmProperty getEdmProperty();

View File

@ -21,9 +21,12 @@ package org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operat
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmType;
@ -84,8 +87,9 @@ public class BinaryOperator {
primDouble = oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Double);
}
private TypedOperand right;
private TypedOperand right = null;
private TypedOperand left;
private List<TypedOperand> rightValues = null;
public BinaryOperator(final VisitorOperand leftOperand, final VisitorOperand rightOperand)
throws ODataApplicationException {
@ -96,6 +100,15 @@ public class BinaryOperator {
right = right.castToCommonType(left);
}
public BinaryOperator(final VisitorOperand leftOperand, final List<VisitorOperand> rightOperand)
throws ODataApplicationException {
rightValues = new ArrayList<TypedOperand>();
left = leftOperand.asTypedOperand();
for (VisitorOperand right : rightOperand) {
rightValues.add(right.asTypedOperand());
}
}
public VisitorOperand andOperator() throws ODataApplicationException {
Boolean result = null;
if (left.is(primBoolean) && right.is(primBoolean)) {
@ -353,4 +366,36 @@ public class BinaryOperator {
Locale.ROOT);
}
}
@SuppressWarnings("unchecked")
public VisitorOperand inOperator() throws ODataApplicationException {
if (null != rightValues) {
for (TypedOperand rightOperand : rightValues) {
if (rightOperand.getTypedValue(String.class).equals(left.getTypedValue(String.class))) {
return new TypedOperand(true, primBoolean);
}
}
} else {
if (right.getValue() instanceof String) {
String value = (String) right.getValue();
value = value.substring(value.indexOf("[") + 1, value.indexOf("]"));
String values[] = value.split(",");
for (String val : values) {
if (val.equals(left.getValue())) {
return new TypedOperand(true, primBoolean);
}
}
} else if (right.getValue() instanceof ArrayList && left.isIntegerType()) {
List<BigInteger> list = (List<BigInteger>) right.getTypedValue(ArrayList.class);
for (BigInteger val : list) {
if (val == left.getTypedValue(BigInteger.class)) {
return new TypedOperand(true, primBoolean);
}
}
} else if (right.getValue() == null && left.isNull()) {
return new TypedOperand(true, primBoolean);
}
}
return new TypedOperand(false, primBoolean);
}
}

View File

@ -90,7 +90,7 @@ public class DataProviderTest {
final DataProvider data = new DataProvider(oData, edm);
EntityCollection outSet = data.readAll(esAllPrim);
Assert.assertEquals(3, outSet.getEntities().size());
Assert.assertEquals(4, outSet.getEntities().size());
Entity first = outSet.getEntities().get(0);
Assert.assertEquals(16, first.getProperties().size());

View File

@ -486,7 +486,7 @@ public class ODataJsonSerializerTest {
while ((index = resultString.indexOf("PropertyInt16\":", ++index)) > 0) {
count++;
}
Assert.assertEquals(3, count);
Assert.assertEquals(4, count);
}
@Test
@ -1938,7 +1938,7 @@ public class ODataJsonSerializerTest {
Assert.assertEquals("{\"@odata.context\":\"../$metadata#Collection($ref)\","
+ "\"value\":[{\"@odata.id\":\"ESAllPrim(32767)\"},"
+ "{\"@odata.id\":\"ESAllPrim(-32768)\"},"
+ "{\"@odata.id\":\"ESAllPrim(0)\"}]}",
+ "{\"@odata.id\":\"ESAllPrim(0)\"},{\"@odata.id\":\"ESAllPrim(10)\"}]}",
resultString);
}
@ -2129,7 +2129,7 @@ public class ODataJsonSerializerTest {
Assert.assertThat(resultString, CoreMatchers.startsWith("{"
+ "\"@odata.context\":\"$metadata#ESAllPrim\","
+ "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\","
+ "\"@odata.count\":\"3\",\"value\":["));
+ "\"@odata.count\":\"4\",\"value\":["));
Assert.assertThat(resultString, CoreMatchers.endsWith("],"
+ "\"@odata.nextLink\":\"/next\"}"));
@ -2138,7 +2138,7 @@ public class ODataJsonSerializerTest {
while ((index = resultString.indexOf("PropertyInt16\":", ++index)) > 0) {
count++;
}
Assert.assertEquals(3, count);
Assert.assertEquals(4, count);
}
@Test
@ -2158,7 +2158,7 @@ public class ODataJsonSerializerTest {
Assert.assertThat(resultString, CoreMatchers.startsWith("{"
+ "\"@odata.context\":\"../$metadata#Collection($ref)\","
+ "\"@odata.count\":\"3\",\"value\":["));
+ "\"@odata.count\":\"4\",\"value\":["));
Assert.assertThat(resultString, CoreMatchers.endsWith("],"
+ "\"@odata.nextLink\":\"/next\"}"));
@ -2167,7 +2167,7 @@ public class ODataJsonSerializerTest {
while ((index = resultString.indexOf("ESAllPrim(", ++index)) > 0) {
count++;
}
Assert.assertEquals(3, count);
Assert.assertEquals(4, count);
}
@Test

View File

@ -482,7 +482,7 @@ public class ODataJsonSerializerv01Test {
while ((index = resultString.indexOf("PropertyInt16\":", ++index)) > 0) {
count++;
}
Assert.assertEquals(3, count);
Assert.assertEquals(4, count);
}
@Test
@ -1943,7 +1943,7 @@ public class ODataJsonSerializerv01Test {
Assert.assertEquals("{\"@context\":\"../$metadata#Collection($ref)\","
+ "\"value\":[{\"@id\":\"ESAllPrim(32767)\"},"
+ "{\"@id\":\"ESAllPrim(-32768)\"},"
+ "{\"@id\":\"ESAllPrim(0)\"}]}",
+ "{\"@id\":\"ESAllPrim(0)\"},{\"@id\":\"ESAllPrim(10)\"}]}",
resultString);
}
@ -2134,7 +2134,7 @@ public class ODataJsonSerializerv01Test {
Assert.assertThat(resultString, CoreMatchers.startsWith("{"
+ "\"@context\":\"$metadata#ESAllPrim\","
+ "\"@metadataEtag\":\"W/\\\"metadataETag\\\"\","
+ "\"@count\":\"3\",\"value\":["));
+ "\"@count\":\"4\",\"value\":["));
Assert.assertThat(resultString, CoreMatchers.endsWith("],"
+ "\"@nextLink\":\"/next\"}"));
@ -2143,7 +2143,7 @@ public class ODataJsonSerializerv01Test {
while ((index = resultString.indexOf("PropertyInt16\":", ++index)) > 0) {
count++;
}
Assert.assertEquals(3, count);
Assert.assertEquals(4, count);
}
@Test
@ -2163,7 +2163,7 @@ public class ODataJsonSerializerv01Test {
Assert.assertThat(resultString, CoreMatchers.startsWith("{"
+ "\"@context\":\"../$metadata#Collection($ref)\","
+ "\"@count\":\"3\",\"value\":["));
+ "\"@count\":\"4\",\"value\":["));
Assert.assertThat(resultString, CoreMatchers.endsWith("],"
+ "\"@nextLink\":\"/next\"}"));
@ -2172,7 +2172,7 @@ public class ODataJsonSerializerv01Test {
while ((index = resultString.indexOf("ESAllPrim(", ++index)) > 0) {
count++;
}
Assert.assertEquals(3, count);
Assert.assertEquals(4, count);
}
@Test

View File

@ -322,6 +322,49 @@ public class ODataXmlSerializerTest {
+ "title=\"olingo.odata.test1.BAETAllPrimRT\" "
+ "target=\"ESAllPrim(0)/olingo.odata.test1.BAETAllPrimRT\" />\n" +
" </a:entry>\n" +
"<a:entry>\n" +
"<a:id>ESAllPrim(10)</a:id>\n" +
"<a:title/>\n" +
"<a:summary/>\n" +
"<a:updated>"+ UPDATED_FORMAT.format(new Date(currentTimeMillis)) +"</a:updated>\n" +
"<a:author>\n" +
"<a:name/>\n" +
"</a:author>\n" +
"<a:link rel=\"edit\" href=\"ESAllPrim(10)\"/>\n" +
"<a:link rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimOne\" "
+ "type=\"application/atom+xml;type=feed\" title=\"NavPropertyETTwoPrimOne\" "
+ "href=\"ESAllPrim(10)/NavPropertyETTwoPrimOne\"/>\n" +
"<a:link rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimMany\" "
+ "type=\"application/atom+xml;type=feed\" title=\"NavPropertyETTwoPrimMany\" "
+ "href=\"ESAllPrim(10)/NavPropertyETTwoPrimMany\"/>\n" +
"<a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" "
+ "term=\"#olingo.odata.test1.ETAllPrim\"/>\n" +
"<a:content type=\"application/xml\">\n" +
"<m:properties>\n" +
"<d:PropertyInt16 m:type=\"Int16\">10</d:PropertyInt16>\n" +
"<d:PropertyString>Employee1@company.example</d:PropertyString>\n" +
"<d:PropertyBoolean m:type=\"Boolean\">false</d:PropertyBoolean>\n" +
"<d:PropertyByte m:type=\"Byte\">0</d:PropertyByte>\n" +
"<d:PropertySByte m:type=\"SByte\">0</d:PropertySByte>\n" +
"<d:PropertyInt32 m:type=\"Int32\">0</d:PropertyInt32>\n" +
"<d:PropertyInt64 m:type=\"Int64\">0</d:PropertyInt64>\n" +
"<d:PropertySingle m:type=\"Single\">0.0</d:PropertySingle>\n" +
"<d:PropertyDouble m:type=\"Double\">0.0</d:PropertyDouble>\n" +
"<d:PropertyDecimal m:type=\"Decimal\">0</d:PropertyDecimal>\n" +
"<d:PropertyBinary m:type=\"Binary\"/>\n" +
"<d:PropertyDate m:type=\"Date\">1970-01-01</d:PropertyDate>\n" +
"<d:PropertyDateTimeOffset m:type=\"DateTimeOffset\">"
+ "2005-12-03T00:00:00Z</d:PropertyDateTimeOffset>\n" +
"<d:PropertyDuration m:type=\"Duration\">PT0S</d:PropertyDuration>\n"+
"<d:PropertyGuid m:type=\"Guid\">"
+ "76543201-23ab-cdef-0123-456789cccddd</d:PropertyGuid>\n" +
"<d:PropertyTimeOfDay m:type=\"TimeOfDay\">00:01:01</d:PropertyTimeOfDay>\n" +
"</m:properties>\n" +
"</a:content>\n" +
"<m:action metadata=\"#olingo.odata.test1.BAETAllPrimRT\" "
+ "title=\"olingo.odata.test1.BAETAllPrimRT\" "
+ "target=\"ESAllPrim(10)/olingo.odata.test1.BAETAllPrimRT\"/>\n" +
"</a:entry>\n" +
"</a:feed>";
checkXMLEqual(expected, resultString);
}
@ -2834,6 +2877,7 @@ public class ODataXmlSerializerTest {
" <m:ref id=\"ESAllPrim(32767)\" />\n" +
" <m:ref id=\"ESAllPrim(-32768)\" />\n" +
" <m:ref id=\"ESAllPrim(0)\" />\n" +
" <m:ref id=\"ESAllPrim(10)\" />\n" +
"</a:feed>";
checkXMLEqual(expected, resultString);
}

View File

@ -150,4 +150,10 @@ public class FilterTreeToText implements ExpressionVisitor<String> {
return "<" + type.getFullQualifiedName().getFullQualifiedNameAsString() + "<" + tmp + ">>";
}
@Override
public String visitBinaryOperator(BinaryOperatorKind operator, String left, List<String> right)
throws ExpressionVisitException, ODataApplicationException {
return "<" + left + " " + operator.toString() + " " + right.toString() + ">";
}
}