[OLINGO-801] better enum and alias support in technical service
This commit is contained in:
parent
4134b2e82c
commit
23fb86a870
|
@ -19,6 +19,7 @@
|
||||||
package org.apache.olingo.fit.tecsvc.client;
|
package org.apache.olingo.fit.tecsvc.client;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -41,6 +42,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
|
||||||
private static final String ES_COMP_ALL_PRIM = "ESCompAllPrim";
|
private static final String ES_COMP_ALL_PRIM = "ESCompAllPrim";
|
||||||
private static final String ES_TWO_KEY_NAV = "ESTwoKeyNav";
|
private static final String ES_TWO_KEY_NAV = "ESTwoKeyNav";
|
||||||
private static final String ES_ALL_PRIM = "ESAllPrim";
|
private static final String ES_ALL_PRIM = "ESAllPrim";
|
||||||
|
private static final String ES_MIX_ENUM_DEF_COLL_COMP = "ESMixEnumDefCollComp";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void timeOfDayLiteral() {
|
public void timeOfDayLiteral() {
|
||||||
|
@ -184,6 +186,9 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
|
||||||
clientEntity = result.getBody().getEntities().get(1);
|
clientEntity = result.getBody().getEntities().get(1);
|
||||||
assertShortOrInt(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue());
|
assertShortOrInt(1, clientEntity.getProperty("PropertyInt16").getPrimitiveValue().toValue());
|
||||||
assertEquals("2", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue());
|
assertEquals("2", clientEntity.getProperty("PropertyString").getPrimitiveValue().toValue());
|
||||||
|
|
||||||
|
result = sendRequest(ES_MIX_ENUM_DEF_COLL_COMP, "PropertyEnumString has Namespace1_Alias.ENString'String1'");
|
||||||
|
assertTrue(result.getBody().getEntities().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -994,7 +999,7 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
|
||||||
result = sendRequest(ES_ALL_PRIM, "'Test1' ne 'Test'");
|
result = sendRequest(ES_ALL_PRIM, "'Test1' ne 'Test'");
|
||||||
assertEquals(3, result.getBody().getEntities().size());
|
assertEquals(3, result.getBody().getEntities().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void castException() {
|
public void castException() {
|
||||||
fail("ESAllPrim", "PropertyInt16 eq '1'", HttpStatusCode.BAD_REQUEST);
|
fail("ESAllPrim", "PropertyInt16 eq '1'", HttpStatusCode.BAD_REQUEST);
|
||||||
|
@ -1004,7 +1009,6 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
|
||||||
fail("ESAllPrim", "PropertyInt16 eq duration'PT4S'", HttpStatusCode.BAD_REQUEST);
|
fail("ESAllPrim", "PropertyInt16 eq duration'PT4S'", HttpStatusCode.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void stringFunctionWithoutStringParameters() {
|
public void stringFunctionWithoutStringParameters() {
|
||||||
fail("ESServerSidePaging", "contains(PropertyInt16, 3) eq 'hallo'", HttpStatusCode.BAD_REQUEST);
|
fail("ESServerSidePaging", "contains(PropertyInt16, 3) eq 'hallo'", HttpStatusCode.BAD_REQUEST);
|
||||||
|
|
|
@ -91,15 +91,15 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void countEntityCollection(final ODataRequest request, final ODataResponse response, final UriInfo
|
public void countEntityCollection(final ODataRequest request, final ODataResponse response,
|
||||||
uriInfo) throws ODataApplicationException, ODataLibraryException {
|
final UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException {
|
||||||
validateOptions(uriInfo.asUriInfoResource());
|
validateOptions(uriInfo.asUriInfoResource());
|
||||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo); // including checks
|
getEdmEntitySet(uriInfo); // including checks
|
||||||
final EntityCollection entitySetInitial = readEntityCollection(uriInfo);
|
final EntityCollection entitySetInitial = readEntityCollection(uriInfo);
|
||||||
EntityCollection entitySet = new EntityCollection();
|
EntityCollection entitySet = new EntityCollection();
|
||||||
|
|
||||||
entitySet.getEntities().addAll(entitySetInitial.getEntities());
|
entitySet.getEntities().addAll(entitySetInitial.getEntities());
|
||||||
FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, edmEntitySet);
|
FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, uriInfo, serviceMetadata.getEdm());
|
||||||
response.setContent(odata.createFixedFormatSerializer().count(
|
response.setContent(odata.createFixedFormatSerializer().count(
|
||||||
entitySet.getEntities().size()));
|
entitySet.getEntities().size()));
|
||||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
|
@ -430,7 +430,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
|
|
||||||
final ExpandSystemQueryOptionHandler expandHandler = new ExpandSystemQueryOptionHandler();
|
final ExpandSystemQueryOptionHandler expandHandler = new ExpandSystemQueryOptionHandler();
|
||||||
final Entity entitySerialization = expandHandler.transformEntityGraphToTree(entity, edmEntitySet, expand);
|
final Entity entitySerialization = expandHandler.transformEntityGraphToTree(entity, edmEntitySet, expand);
|
||||||
expandHandler.applyExpandQueryOptions(entitySerialization, edmEntitySet, expand);
|
expandHandler.applyExpandQueryOptions(entitySerialization, edmEntitySet, expand, uriInfo,
|
||||||
|
serviceMetadata.getEdm());
|
||||||
|
|
||||||
final SerializerResult serializerResult = isReference ?
|
final SerializerResult serializerResult = isReference ?
|
||||||
serializeReference(entity, edmEntitySet, requestedFormat) :
|
serializeReference(entity, edmEntitySet, requestedFormat) :
|
||||||
|
@ -480,9 +481,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
entitySet.getEntities().addAll(entitySetInitial.getEntities());
|
entitySet.getEntities().addAll(entitySetInitial.getEntities());
|
||||||
|
|
||||||
// Apply system query options
|
// Apply system query options
|
||||||
FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, edmEntitySet);
|
FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, uriInfo, serviceMetadata.getEdm());
|
||||||
CountHandler.applyCountSystemQueryOption(uriInfo.getCountOption(), entitySet);
|
CountHandler.applyCountSystemQueryOption(uriInfo.getCountOption(), entitySet);
|
||||||
OrderByHandler.applyOrderByOption(uriInfo.getOrderByOption(), entitySet, edmEntitySet);
|
OrderByHandler.applyOrderByOption(uriInfo.getOrderByOption(), entitySet, uriInfo, serviceMetadata.getEdm());
|
||||||
SkipHandler.applySkipSystemQueryHandler(uriInfo.getSkipOption(), entitySet);
|
SkipHandler.applySkipSystemQueryHandler(uriInfo.getSkipOption(), entitySet);
|
||||||
TopHandler.applyTopSystemQueryOption(uriInfo.getTopOption(), entitySet);
|
TopHandler.applyTopSystemQueryOption(uriInfo.getTopOption(), entitySet);
|
||||||
|
|
||||||
|
@ -505,7 +506,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||||
final EntityCollection entitySetSerialization = expandHandler.transformEntitySetGraphToTree(entitySet,
|
final EntityCollection entitySetSerialization = expandHandler.transformEntitySetGraphToTree(entitySet,
|
||||||
edmEntitySet,
|
edmEntitySet,
|
||||||
expand);
|
expand);
|
||||||
expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand);
|
expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand, uriInfo,
|
||||||
|
serviceMetadata.getEdm());
|
||||||
final CountOption countOption = uriInfo.getCountOption();
|
final CountOption countOption = uriInfo.getCountOption();
|
||||||
|
|
||||||
String id;
|
String id;
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.Set;
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.data.EntityCollection;
|
import org.apache.olingo.commons.api.data.EntityCollection;
|
||||||
import org.apache.olingo.commons.api.data.Link;
|
import org.apache.olingo.commons.api.data.Link;
|
||||||
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
||||||
import org.apache.olingo.commons.api.edm.EdmElement;
|
import org.apache.olingo.commons.api.edm.EdmElement;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||||
|
@ -35,6 +36,7 @@ import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
|
||||||
import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
|
import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
|
||||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||||
import org.apache.olingo.server.api.ODataApplicationException;
|
import org.apache.olingo.server.api.ODataApplicationException;
|
||||||
|
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||||
import org.apache.olingo.server.api.uri.UriResource;
|
import org.apache.olingo.server.api.uri.UriResource;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.CountOption;
|
import org.apache.olingo.server.api.uri.queryoption.CountOption;
|
||||||
|
@ -53,29 +55,28 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.options.TopHandler
|
||||||
public class ExpandSystemQueryOptionHandler {
|
public class ExpandSystemQueryOptionHandler {
|
||||||
|
|
||||||
public void applyExpandQueryOptions(final EntityCollection entitySet, final EdmEntitySet edmEntitySet,
|
public void applyExpandQueryOptions(final EntityCollection entitySet, final EdmEntitySet edmEntitySet,
|
||||||
final ExpandOption expandOption) throws ODataApplicationException {
|
final ExpandOption expandOption, final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
|
||||||
if (expandOption == null) {
|
if (expandOption == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Entity entity : entitySet.getEntities()) {
|
for (final Entity entity : entitySet.getEntities()) {
|
||||||
applyExpandOptionToEntity(entity, edmEntitySet, expandOption);
|
applyExpandOptionToEntity(entity, edmEntitySet, expandOption, uriInfo, edm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyExpandQueryOptions(final Entity entity, final EdmEntitySet edmEntitySet,
|
public void applyExpandQueryOptions(final Entity entity, final EdmEntitySet edmEntitySet,
|
||||||
final ExpandOption expandOption)
|
final ExpandOption expandOption, final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
|
||||||
throws ODataApplicationException {
|
|
||||||
if (expandOption == null) {
|
if (expandOption == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyExpandOptionToEntity(entity, edmEntitySet, expandOption);
|
applyExpandOptionToEntity(entity, edmEntitySet, expandOption, uriInfo, edm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyExpandOptionToEntity(final Entity entity, final EdmBindingTarget edmBindingTarget,
|
private void applyExpandOptionToEntity(final Entity entity, final EdmBindingTarget edmBindingTarget,
|
||||||
final ExpandOption expandOption) throws ODataApplicationException {
|
final ExpandOption expandOption, final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
|
||||||
|
|
||||||
final EdmEntityType entityType = edmBindingTarget.getEntityType();
|
final EdmEntityType entityType = edmBindingTarget.getEntityType();
|
||||||
|
|
||||||
for (ExpandItem item : expandOption.getExpandItems()) {
|
for (ExpandItem item : expandOption.getExpandItems()) {
|
||||||
|
@ -103,7 +104,7 @@ public class ExpandSystemQueryOptionHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(EdmNavigationProperty navigationProperty: navigationProperties) {
|
for (EdmNavigationProperty navigationProperty: navigationProperties) {
|
||||||
final String navPropertyName = navigationProperty.getName();
|
final String navPropertyName = navigationProperty.getName();
|
||||||
final EdmBindingTarget targetEdmEntitySet = edmBindingTarget.getRelatedBindingTarget(navPropertyName);
|
final EdmBindingTarget targetEdmEntitySet = edmBindingTarget.getRelatedBindingTarget(navPropertyName);
|
||||||
|
|
||||||
|
@ -116,7 +117,8 @@ public class ExpandSystemQueryOptionHandler {
|
||||||
item.getCountOption(),
|
item.getCountOption(),
|
||||||
item.getSkipOption(),
|
item.getSkipOption(),
|
||||||
item.getTopOption(),
|
item.getTopOption(),
|
||||||
item.getExpandOption());
|
item.getExpandOption(),
|
||||||
|
uriInfo, edm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,11 +127,12 @@ public class ExpandSystemQueryOptionHandler {
|
||||||
private void applyOptionsToEntityCollection(final EntityCollection entitySet,
|
private void applyOptionsToEntityCollection(final EntityCollection entitySet,
|
||||||
final EdmBindingTarget edmBindingTarget,
|
final EdmBindingTarget edmBindingTarget,
|
||||||
final FilterOption filterOption, final OrderByOption orderByOption, final CountOption countOption,
|
final FilterOption filterOption, final OrderByOption orderByOption, final CountOption countOption,
|
||||||
final SkipOption skipOption, final TopOption topOption, final ExpandOption expandOption)
|
final SkipOption skipOption, final TopOption topOption, final ExpandOption expandOption,
|
||||||
|
final UriInfoResource uriInfo, final Edm edm)
|
||||||
throws ODataApplicationException {
|
throws ODataApplicationException {
|
||||||
|
|
||||||
FilterHandler.applyFilterSystemQuery(filterOption, entitySet, edmBindingTarget);
|
FilterHandler.applyFilterSystemQuery(filterOption, entitySet, uriInfo, edm);
|
||||||
OrderByHandler.applyOrderByOption(orderByOption, entitySet, edmBindingTarget);
|
OrderByHandler.applyOrderByOption(orderByOption, entitySet, uriInfo, edm);
|
||||||
CountHandler.applyCountSystemQueryOption(countOption, entitySet);
|
CountHandler.applyCountSystemQueryOption(countOption, entitySet);
|
||||||
SkipHandler.applySkipSystemQueryHandler(skipOption, entitySet);
|
SkipHandler.applySkipSystemQueryHandler(skipOption, entitySet);
|
||||||
TopHandler.applyTopSystemQueryOption(topOption, entitySet);
|
TopHandler.applyTopSystemQueryOption(topOption, entitySet);
|
||||||
|
@ -137,7 +140,7 @@ public class ExpandSystemQueryOptionHandler {
|
||||||
// Apply nested expand system query options to remaining entities
|
// Apply nested expand system query options to remaining entities
|
||||||
if (expandOption != null) {
|
if (expandOption != null) {
|
||||||
for (final Entity entity : entitySet.getEntities()) {
|
for (final Entity entity : entitySet.getEntities()) {
|
||||||
applyExpandOptionToEntity(entity, edmBindingTarget, expandOption);
|
applyExpandOptionToEntity(entity, edmBindingTarget, expandOption, uriInfo, edm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,9 @@ import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.data.Property;
|
import org.apache.olingo.commons.api.data.Property;
|
||||||
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEnumType;
|
import org.apache.olingo.commons.api.edm.EdmEnumType;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||||
import org.apache.olingo.commons.api.edm.EdmType;
|
import org.apache.olingo.commons.api.edm.EdmType;
|
||||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||||
|
@ -48,16 +49,19 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operati
|
||||||
|
|
||||||
public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand> {
|
public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand> {
|
||||||
|
|
||||||
final private Entity entity;
|
private final Entity entity;
|
||||||
|
private final UriInfoResource uriInfo;
|
||||||
|
private final Edm edm;
|
||||||
|
|
||||||
public ExpressionVisitorImpl(final Entity entity, final EdmBindingTarget bindingTarget) {
|
public ExpressionVisitorImpl(final Entity entity, final UriInfoResource uriInfo, final Edm edm) {
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
|
this.uriInfo = uriInfo;
|
||||||
|
this.edm = edm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VisitorOperand visitBinaryOperator(final BinaryOperatorKind operator, final VisitorOperand left,
|
public VisitorOperand visitBinaryOperator(final BinaryOperatorKind operator, final VisitorOperand left,
|
||||||
final VisitorOperand right)
|
final VisitorOperand right) throws ExpressionVisitException, ODataApplicationException {
|
||||||
throws ExpressionVisitException, ODataApplicationException {
|
|
||||||
|
|
||||||
final BinaryOperator binaryOperator = new BinaryOperator(left, right);
|
final BinaryOperator binaryOperator = new BinaryOperator(left, right);
|
||||||
|
|
||||||
|
@ -84,6 +88,9 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
|
||||||
case DIV:
|
case DIV:
|
||||||
case MOD:
|
case MOD:
|
||||||
return binaryOperator.arithmeticOperator(operator);
|
return binaryOperator.arithmeticOperator(operator);
|
||||||
|
case HAS:
|
||||||
|
return binaryOperator.hasOperator();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return throwNotImplemented();
|
return throwNotImplemented();
|
||||||
}
|
}
|
||||||
|
@ -161,15 +168,13 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VisitorOperand visitLambdaExpression(final String lambdaFunction, final String lambdaVariable,
|
public VisitorOperand visitLambdaExpression(final String lambdaFunction, final String lambdaVariable,
|
||||||
final Expression expression)
|
final Expression expression) throws ExpressionVisitException, ODataApplicationException {
|
||||||
throws ExpressionVisitException, ODataApplicationException {
|
|
||||||
|
|
||||||
return throwNotImplemented();
|
return throwNotImplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VisitorOperand visitLiteral(final Literal literal) throws ExpressionVisitException, ODataApplicationException {
|
public VisitorOperand visitLiteral(final Literal literal) throws ExpressionVisitException, ODataApplicationException {
|
||||||
return new UntypedOperand(literal.getText());
|
return new UntypedOperand(literal.getText(), edm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -204,12 +209,12 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VisitorOperand visitAlias(final String aliasName) throws ExpressionVisitException, ODataApplicationException {
|
public VisitorOperand visitAlias(final String aliasName) throws ExpressionVisitException, ODataApplicationException {
|
||||||
return throwNotImplemented();
|
return new UntypedOperand(uriInfo.getValueForAlias(aliasName), edm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VisitorOperand visitTypeLiteral(final EdmType type) throws ExpressionVisitException,
|
public VisitorOperand visitTypeLiteral(final EdmType type)
|
||||||
ODataApplicationException {
|
throws ExpressionVisitException, ODataApplicationException {
|
||||||
return throwNotImplemented();
|
return throwNotImplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,9 +226,18 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VisitorOperand visitEnum(final EdmEnumType type, final List<String> enumValues)
|
public VisitorOperand visitEnum(final EdmEnumType type, final List<String> enumValues)
|
||||||
throws ExpressionVisitException,
|
throws ExpressionVisitException, ODataApplicationException {
|
||||||
ODataApplicationException {
|
Long result = null;
|
||||||
return throwNotImplemented();
|
try {
|
||||||
|
for (final String enumValue : enumValues) {
|
||||||
|
final Long value = type.valueOfString(enumValue, null, null, null, null, null, Long.class);
|
||||||
|
result = result == null ? value : result | value;
|
||||||
|
}
|
||||||
|
} catch (final EdmPrimitiveTypeException e) {
|
||||||
|
throw new ODataApplicationException("Illegal enum value.",
|
||||||
|
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT, e);
|
||||||
|
}
|
||||||
|
return new TypedOperand(result, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private VisitorOperand throwNotImplemented() throws ODataApplicationException {
|
private VisitorOperand throwNotImplemented() throws ODataApplicationException {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand;
|
package org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||||
|
@ -54,36 +55,42 @@ public class TypedOperand extends VisitorOperand {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypedOperand asTypedOperand(final EdmPrimitiveType... asTypes) throws ODataApplicationException {
|
public TypedOperand asTypedOperand(final EdmPrimitiveType asType) throws ODataApplicationException {
|
||||||
if (is(primNull)) {
|
if (is(primNull)) {
|
||||||
return this;
|
return this;
|
||||||
} else if (isNull()) {
|
} else if (isNull()) {
|
||||||
return new TypedOperand(null, asTypes[0]);
|
return new TypedOperand(null, asType);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object newValue = null;
|
Object newValue = null;
|
||||||
for (EdmPrimitiveType asType : asTypes) {
|
// Use BigInteger for arbitrarily large whole numbers.
|
||||||
// Use BigDecimal for unlimited precision
|
if (asType.equals(primSByte) || asType.equals(primByte)
|
||||||
if (asType.equals(primDouble) || asType.equals(primSingle) || asType.equals(primDecimal)) {
|
|| asType.equals(primInt16) || asType.equals(primInt32) || asType.equals(primInt64)) {
|
||||||
|
if (value instanceof BigInteger) {
|
||||||
try {
|
newValue = value;
|
||||||
newValue = new BigDecimal(value.toString());
|
} else if (value instanceof Byte || value instanceof Short
|
||||||
} catch (NumberFormatException e) {
|
|| value instanceof Integer || value instanceof Long) {
|
||||||
// Nothing to do
|
newValue = BigInteger.valueOf(((Number) value).longValue());
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Use type conversion of EdmPrimitive types
|
|
||||||
try {
|
|
||||||
final String literal = getLiteral(value);
|
|
||||||
newValue = tryCast(literal, asType);
|
|
||||||
} catch (EdmPrimitiveTypeException e) {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// Use BigDecimal for unlimited precision.
|
||||||
if (newValue != null) {
|
} else if (asType.equals(primDouble) || asType.equals(primSingle) || asType.equals(primDecimal)) {
|
||||||
return new TypedOperand(newValue, asType);
|
try {
|
||||||
|
newValue = new BigDecimal(value.toString());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// Nothing to do
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Use type conversion of EdmPrimitive types
|
||||||
|
try {
|
||||||
|
final String literal = getLiteral(value);
|
||||||
|
newValue = tryCast(literal, asType);
|
||||||
|
} catch (EdmPrimitiveTypeException e) {
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newValue != null) {
|
||||||
|
return new TypedOperand(newValue, asType);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ODataApplicationException("Cast failed", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
throw new ODataApplicationException("Cast failed", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||||
|
@ -93,11 +100,9 @@ public class TypedOperand extends VisitorOperand {
|
||||||
final TypedOperand other = otherOperand.asTypedOperand();
|
final TypedOperand other = otherOperand.asTypedOperand();
|
||||||
final EdmType oType = other.getType();
|
final EdmType oType = other.getType();
|
||||||
|
|
||||||
// In case of numberic values make sure that the EDM type is equals, check also the java type.
|
// In case of numberic values make sure that the EDM type is equal, check also the java type.
|
||||||
// So it is possible, that there is an conversation even if the same
|
// It is possible that there is an conversion even if the same EdmType is provided.
|
||||||
// EdmType is provided.
|
// For example consider an Edm.Int32 (internal Integer) and an Edm.Int16 (internal Short) value:
|
||||||
// For example consider an Edm16 (internal Integer) and Edm16(internal
|
|
||||||
// Short)
|
|
||||||
// shortInstance.equals(intInstance) will always be false!
|
// shortInstance.equals(intInstance) will always be false!
|
||||||
if (type == oType && value != null && other.getValue() != null
|
if (type == oType && value != null && other.getValue() != null
|
||||||
&& value.getClass() == other.getValue().getClass()) {
|
&& value.getClass() == other.getValue().getClass()) {
|
||||||
|
|
|
@ -20,15 +20,21 @@ package org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operan
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmEnumType;
|
||||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmSchema;
|
||||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||||
import org.apache.olingo.server.api.ODataApplicationException;
|
import org.apache.olingo.server.api.ODataApplicationException;
|
||||||
|
|
||||||
public class UntypedOperand extends VisitorOperand {
|
public class UntypedOperand extends VisitorOperand {
|
||||||
|
|
||||||
public UntypedOperand(final String literal) {
|
private final Edm edm;
|
||||||
|
|
||||||
|
public UntypedOperand(final String literal, final Edm edm) {
|
||||||
super(literal);
|
super(literal);
|
||||||
|
this.edm = edm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -37,22 +43,18 @@ public class UntypedOperand extends VisitorOperand {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypedOperand asTypedOperand(final EdmPrimitiveType... types) throws ODataApplicationException {
|
public TypedOperand asTypedOperand(final EdmPrimitiveType type) throws ODataApplicationException {
|
||||||
final String literal = (String) value;
|
final String literal = (String) value;
|
||||||
Object newValue = null;
|
Object newValue = null;
|
||||||
|
|
||||||
// First try the null literal
|
// First try the null literal.
|
||||||
if ((newValue = tryCast(literal, primNull)) != null) {
|
if ((newValue = tryCast(literal, primNull)) != null) {
|
||||||
return new TypedOperand(newValue, primNull);
|
return new TypedOperand(newValue, primNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Than try the given types
|
// Then try the given type.
|
||||||
for (EdmPrimitiveType type : types) {
|
if ((newValue = tryCast(literal, type)) != null) {
|
||||||
newValue = tryCast(literal, type);
|
return new TypedOperand(newValue, type);
|
||||||
|
|
||||||
if (newValue != null) {
|
|
||||||
return new TypedOperand(newValue, type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ODataApplicationException("Cast failed", HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(),
|
throw new ODataApplicationException("Cast failed", HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(),
|
||||||
|
@ -130,6 +132,17 @@ public class UntypedOperand extends VisitorOperand {
|
||||||
return new TypedOperand(newValue, primDouble);
|
return new TypedOperand(newValue, primDouble);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enum
|
||||||
|
final EdmSchema schema = edm.getSchema(edm.getEntityContainer().getNamespace());
|
||||||
|
final String enumValue = schema.getAlias() != null && literal.startsWith(schema.getAlias()) ?
|
||||||
|
literal.replace(schema.getAlias(), schema.getNamespace()) :
|
||||||
|
literal;
|
||||||
|
for (final EdmEnumType enumType : schema.getEnumTypes()) {
|
||||||
|
if ((newValue = tryCast(enumValue, enumType)) != null) {
|
||||||
|
return new TypedOperand(newValue, enumType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw new ODataApplicationException("Could not determine type for literal " + literal,
|
throw new ODataApplicationException("Could not determine type for literal " + literal,
|
||||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ public abstract class VisitorOperand {
|
||||||
|
|
||||||
public abstract TypedOperand asTypedOperand() throws ODataApplicationException;
|
public abstract TypedOperand asTypedOperand() throws ODataApplicationException;
|
||||||
|
|
||||||
public abstract TypedOperand asTypedOperand(EdmPrimitiveType... types) throws ODataApplicationException;
|
public abstract TypedOperand asTypedOperand(EdmPrimitiveType type) throws ODataApplicationException;
|
||||||
|
|
||||||
public abstract EdmProperty getEdmProperty();
|
public abstract EdmProperty getEdmProperty();
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,15 @@ public class BinaryOperator {
|
||||||
return new TypedOperand(result, primBoolean);
|
return new TypedOperand(result, primBoolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
public VisitorOperand hasOperator() throws ODataApplicationException {
|
||||||
|
final boolean result = isBinaryComparisonNecessary()
|
||||||
|
&& !left.getTypedValue(BigInteger.class).equals(BigInteger.ZERO)
|
||||||
|
&& left.getTypedValue(BigInteger.class).and(BigInteger.valueOf(right.getTypedValue(Number.class).longValue()))
|
||||||
|
.equals(BigInteger.valueOf(right.getTypedValue(Number.class).longValue()));
|
||||||
|
return new TypedOperand(result, primBoolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private boolean binaryComparison(final int... expect) {
|
private boolean binaryComparison(final int... expect) {
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
@ -180,13 +188,14 @@ public class BinaryOperator {
|
||||||
result = left.getTypedValue(BigInteger.class).compareTo(right.getTypedValue(BigInteger.class));
|
result = left.getTypedValue(BigInteger.class).compareTo(right.getTypedValue(BigInteger.class));
|
||||||
} else if (left.isDecimalType()) {
|
} else if (left.isDecimalType()) {
|
||||||
result = left.getTypedValue(BigDecimal.class).compareTo(right.getTypedValue(BigDecimal.class));
|
result = left.getTypedValue(BigDecimal.class).compareTo(right.getTypedValue(BigDecimal.class));
|
||||||
} else if(left.getValue().getClass() == right.getValue().getClass() && left.getValue() instanceof Comparable) {
|
} else if(left.getValue().getClass() == right.getValue().getClass()
|
||||||
result = ((Comparable)left.getValue()).compareTo(right.getValue());
|
&& left.getValue() instanceof Comparable<?>) {
|
||||||
|
result = ((Comparable<Object>) left.getValue()).compareTo(right.getValue());
|
||||||
} else {
|
} else {
|
||||||
result = left.getValue().equals(right.getValue()) ? 0 : 1;
|
result = left.getValue().equals(right.getValue()) ? 0 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int expectedValue : expect) {
|
for (int expectedValue : expect) {
|
||||||
if (expectedValue == result) {
|
if (expectedValue == result) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -23,12 +23,13 @@ import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.data.EntityCollection;
|
import org.apache.olingo.commons.api.data.EntityCollection;
|
||||||
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||||
import org.apache.olingo.server.api.OData;
|
import org.apache.olingo.server.api.OData;
|
||||||
import org.apache.olingo.server.api.ODataApplicationException;
|
import org.apache.olingo.server.api.ODataApplicationException;
|
||||||
|
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.FilterOption;
|
import org.apache.olingo.server.api.uri.queryoption.FilterOption;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
|
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
|
||||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.ExpressionVisitorImpl;
|
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.ExpressionVisitorImpl;
|
||||||
|
@ -37,16 +38,11 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand
|
||||||
|
|
||||||
public class FilterHandler {
|
public class FilterHandler {
|
||||||
|
|
||||||
protected static final OData oData;
|
protected static final EdmPrimitiveType primBoolean =
|
||||||
protected static final EdmPrimitiveType primBoolean;
|
OData.newInstance().createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean);
|
||||||
|
|
||||||
static {
|
|
||||||
oData = OData.newInstance();
|
|
||||||
primBoolean = oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void applyFilterSystemQuery(final FilterOption filterOption, final EntityCollection entitySet,
|
public static void applyFilterSystemQuery(final FilterOption filterOption, final EntityCollection entitySet,
|
||||||
final EdmBindingTarget edmEntitySet) throws ODataApplicationException {
|
final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
|
||||||
|
|
||||||
if (filterOption == null) {
|
if (filterOption == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -57,16 +53,17 @@ public class FilterHandler {
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
final VisitorOperand operand = filterOption.getExpression()
|
final VisitorOperand operand = filterOption.getExpression()
|
||||||
.accept(new ExpressionVisitorImpl(iter.next(), edmEntitySet));
|
.accept(new ExpressionVisitorImpl(iter.next(), uriInfo, edm));
|
||||||
final TypedOperand typedOperand = operand.asTypedOperand();
|
final TypedOperand typedOperand = operand.asTypedOperand();
|
||||||
|
|
||||||
if(typedOperand.is(primBoolean)) {
|
if (typedOperand.is(primBoolean)) {
|
||||||
if(Boolean.FALSE.equals(typedOperand.getTypedValue(Boolean.class))) {
|
if (Boolean.FALSE.equals(typedOperand.getTypedValue(Boolean.class))) {
|
||||||
iter.remove();
|
iter.remove();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new ODataApplicationException("Invalid filter expression. Filter expressions must return a value of "
|
throw new ODataApplicationException(
|
||||||
+ "type Edm.Boolean", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
"Invalid filter expression. Filter expressions must return a value of type Edm.Boolean",
|
||||||
|
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,10 @@ import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.data.Entity;
|
import org.apache.olingo.commons.api.data.Entity;
|
||||||
import org.apache.olingo.commons.api.data.EntityCollection;
|
import org.apache.olingo.commons.api.data.EntityCollection;
|
||||||
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||||
import org.apache.olingo.server.api.ODataApplicationException;
|
import org.apache.olingo.server.api.ODataApplicationException;
|
||||||
|
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.OrderByItem;
|
import org.apache.olingo.server.api.uri.queryoption.OrderByItem;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
|
import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
|
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
|
||||||
|
@ -35,43 +36,43 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand
|
||||||
|
|
||||||
public class OrderByHandler {
|
public class OrderByHandler {
|
||||||
public static void applyOrderByOption(final OrderByOption orderByOption, final EntityCollection entitySet,
|
public static void applyOrderByOption(final OrderByOption orderByOption, final EntityCollection entitySet,
|
||||||
final EdmBindingTarget edmBindingTarget) throws ODataApplicationException {
|
final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
|
||||||
|
|
||||||
if (orderByOption == null) {
|
if (orderByOption == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
applyOrderByOptionInternal(orderByOption, entitySet, edmBindingTarget);
|
applyOrderByOptionInternal(orderByOption, entitySet, uriInfo, edm);
|
||||||
} catch (SystemQueryOptionsRuntimeException e) {
|
} catch (SystemQueryOptionsRuntimeException e) {
|
||||||
if (e.getCause() instanceof ODataApplicationException) {
|
if (e.getCause() instanceof ODataApplicationException) {
|
||||||
// Throw the nested exception, to send the correct HTTP status code in the HTTP response
|
// Throw the nested exception, to send the correct HTTP status code in the HTTP response
|
||||||
throw (ODataApplicationException) e.getCause();
|
throw (ODataApplicationException) e.getCause();
|
||||||
} else {
|
} else {
|
||||||
throw new ODataApplicationException("Exception in orderBy evaluation", HttpStatusCode.INTERNAL_SERVER_ERROR
|
throw new ODataApplicationException("Exception in orderBy evaluation",
|
||||||
.getStatusCode(), Locale.ROOT);
|
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void applyOrderByOptionInternal(final OrderByOption orderByOption, final EntityCollection entitySet,
|
private static void applyOrderByOptionInternal(final OrderByOption orderByOption, final EntityCollection entitySet,
|
||||||
final EdmBindingTarget edmBindingTarget) throws ODataApplicationException {
|
final UriInfoResource uriInfo, final Edm edm) throws ODataApplicationException {
|
||||||
Collections.sort(entitySet.getEntities(), new Comparator<Entity>() {
|
Collections.sort(entitySet.getEntities(), new Comparator<Entity>() {
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings("unchecked")
|
||||||
public int compare(final Entity e1, final Entity e2) {
|
public int compare(final Entity e1, final Entity e2) {
|
||||||
// Evaluate the first order option for both entity
|
// Evaluate the first order option for both entities.
|
||||||
// If and only if the result of the previous order option is equals to 0
|
// If and only if the result of the previous order option is equal to 0
|
||||||
// evaluate the next order option until all options are evaluated or they are not equals
|
// evaluate the next order option until all options are evaluated or they are not equal.
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
for (int i = 0; i < orderByOption.getOrders().size() && result == 0; i++) {
|
for (int i = 0; i < orderByOption.getOrders().size() && result == 0; i++) {
|
||||||
try {
|
try {
|
||||||
final OrderByItem item = orderByOption.getOrders().get(i);
|
final OrderByItem item = orderByOption.getOrders().get(i);
|
||||||
final TypedOperand op1 =
|
final TypedOperand op1 =
|
||||||
item.getExpression().accept(new ExpressionVisitorImpl(e1, edmBindingTarget)).asTypedOperand();
|
item.getExpression().accept(new ExpressionVisitorImpl(e1, uriInfo, edm)).asTypedOperand();
|
||||||
final TypedOperand op2 =
|
final TypedOperand op2 =
|
||||||
item.getExpression().accept(new ExpressionVisitorImpl(e2, edmBindingTarget)).asTypedOperand();
|
item.getExpression().accept(new ExpressionVisitorImpl(e2, uriInfo, edm)).asTypedOperand();
|
||||||
|
|
||||||
if (op1.isNull() || op2.isNull()) {
|
if (op1.isNull() || op2.isNull()) {
|
||||||
if (op1.isNull() && op2.isNull()) {
|
if (op1.isNull() && op2.isNull()) {
|
||||||
|
@ -84,7 +85,7 @@ public class OrderByHandler {
|
||||||
Object o2 = op2.getValue();
|
Object o2 = op2.getValue();
|
||||||
|
|
||||||
if (o1.getClass() == o2.getClass() && o1 instanceof Comparable) {
|
if (o1.getClass() == o2.getClass() && o1 instanceof Comparable) {
|
||||||
result = ((Comparable) o1).compareTo(o2);
|
result = ((Comparable<Object>) o1).compareTo(o2);
|
||||||
} else {
|
} else {
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue