From a5285b8655c0b89373e2f65d6dc0b63ce8f28123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 7 Mar 2014 18:05:10 +0100 Subject: [PATCH] [OLINGO-194] Merging V3 URIBuilder / FilterFactory + adding skeletons for V4 --- .../olingo/odata4/client/api/ODataClient.java | 9 +- .../client/api/domain/ODataDuration.java | 1 - .../client/api/domain/ODataTimestamp.java | 189 +++++++------ .../odata4/client/api/uri/QueryOption.java | 87 ++++++ .../odata4/client/api/uri/URIBuilder.java | 261 ++++++++++++++++++ .../client/api/uri/filter/FilterArg.java | 30 ++ .../client/api/uri/filter/FilterFactory.java | 59 ++++ .../client/api/uri/filter/URIFilter.java | 32 +++ .../odata4/client/core/ODataV3Client.java | 25 +- .../odata4/client/core/ODataV4Client.java | 24 +- .../client/core/uri/AbstractURIBuilder.java | 242 ++++++++++++++++ .../odata4/client/core/uri/V3URIBuilder.java | 39 +++ .../odata4/client/core/uri/V4URIBuilder.java | 39 +++ .../uri/filter/AbstractComparingFilter.java | 45 +++ .../uri/filter/AbstractFilterFactory.java | 110 ++++++++ .../client/core/uri/filter/AndFilter.java | 42 +++ .../client/core/uri/filter/EqFilter.java | 33 +++ .../core/uri/filter/FilterArgFactory.java | 155 +++++++++++ .../core/uri/filter/FilterFunction.java | 48 ++++ .../client/core/uri/filter/FilterLiteral.java | 41 +++ .../client/core/uri/filter/FilterOp.java | 45 +++ .../core/uri/filter/FilterProperty.java | 40 +++ .../client/core/uri/filter/GeFilter.java | 33 +++ .../client/core/uri/filter/GtFilter.java | 33 +++ .../client/core/uri/filter/LeFilter.java | 33 +++ .../client/core/uri/filter/LtFilter.java | 33 +++ .../client/core/uri/filter/MatchFilter.java | 36 +++ .../client/core/uri/filter/NeFilter.java | 33 +++ .../client/core/uri/filter/NotFilter.java | 35 +++ .../client/core/uri/filter/OrFilter.java | 42 +++ .../core/uri/filter/V3FilterFactory.java | 25 ++ .../core/uri/filter/V4FilterFactory.java | 25 ++ .../client/core/v3/FilterFactoryTest.java | 136 +++++++++ .../odata4/client/core/v3/URIBuilderTest.java | 89 ++++++ 34 files changed, 2028 insertions(+), 121 deletions(-) create mode 100644 odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/QueryOption.java create mode 100644 odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/URIBuilder.java create mode 100644 odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/FilterArg.java create mode 100644 odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/FilterFactory.java create mode 100644 odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/URIFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/AbstractURIBuilder.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/V3URIBuilder.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/V4URIBuilder.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AbstractComparingFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AbstractFilterFactory.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AndFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/EqFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterArgFactory.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterFunction.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterLiteral.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterOp.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterProperty.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/GeFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/GtFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/LeFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/LtFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/MatchFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/NeFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/NotFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/OrFilter.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/V3FilterFactory.java create mode 100644 odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/V4FilterFactory.java create mode 100644 odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/FilterFactoryTest.java create mode 100644 odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/URIBuilderTest.java diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataClient.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataClient.java index b101a8dca..ea786448e 100644 --- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataClient.java +++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/ODataClient.java @@ -22,6 +22,8 @@ import org.apache.olingo.odata4.client.api.op.ODataBinder; import org.apache.olingo.odata4.client.api.op.ODataDeserializer; import org.apache.olingo.odata4.client.api.op.ODataReader; import org.apache.olingo.odata4.client.api.op.ODataSerializer; +import org.apache.olingo.odata4.client.api.uri.URIBuilder; +import org.apache.olingo.odata4.client.api.uri.filter.FilterFactory; import org.apache.olingo.odata4.commons.api.edm.constants.ODataServiceVersion; public interface ODataClient { @@ -31,10 +33,11 @@ public interface ODataClient { //ODataHeaders getVersionHeaders(); Configuration getConfiguration(); -// URIBuilder getURIBuilder(String serviceRoot); -// FilterFactory getFilterFactory(); + URIBuilder getURIBuilder(String serviceRoot); + + FilterFactory getFilterFactory(); + ODataSerializer getSerializer(); -// ODataDeserializer getDeserializer(); diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataDuration.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataDuration.java index ba6ff17f0..5a8a108c1 100644 --- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataDuration.java +++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataDuration.java @@ -28,7 +28,6 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; /** * Helper class for handling time (as duration) primitive values. * - * @see com.msopentech.odatajclient.engine.data.metadata.edm.EdmSimpleType#TIME * @see Duration */ public final class ODataDuration implements Serializable { diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataTimestamp.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataTimestamp.java index b2a4077bd..32ef10e35 100644 --- a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataTimestamp.java +++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/domain/ODataTimestamp.java @@ -28,114 +28,111 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; /** * Helper class for handling datetime and datetime-offset primitive values. - * - * @see com.msopentech.odatajclient.engine.data.metadata.edm.EdmSimpleType#DATE_TIME - * @see com.msopentech.odatajclient.engine.data.metadata.edm.EdmSimpleType#DATE_TIME_OFFSET */ public final class ODataTimestamp implements Serializable { - private static final long serialVersionUID = 4053990618660356004L; + private static final long serialVersionUID = 4053990618660356004L; - private final SimpleDateFormat sdf; + private final SimpleDateFormat sdf; - private final Timestamp timestamp; + private final Timestamp timestamp; - private String timezone; + private String timezone; - private final boolean offset; + private final boolean offset; - public static ODataTimestamp getInstance(final EdmSimpleType type, final Timestamp timestamp) { - return new ODataTimestamp(new SimpleDateFormat(type.pattern()), - new Date(timestamp.getTime()), timestamp.getNanos(), type == EdmSimpleType.DateTimeOffset); - } + public static ODataTimestamp getInstance(final EdmSimpleType type, final Timestamp timestamp) { + return new ODataTimestamp(new SimpleDateFormat(type.pattern()), + new Date(timestamp.getTime()), timestamp.getNanos(), type == EdmSimpleType.DateTimeOffset); + } - public static ODataTimestamp parse(final EdmSimpleType type, final String input) { - final ODataTimestamp instance; + public static ODataTimestamp parse(final EdmSimpleType type, final String input) { + final ODataTimestamp instance; - final String[] dateParts = input.split("\\."); - final SimpleDateFormat sdf = new SimpleDateFormat(type.pattern()); - final boolean isOffset = type == EdmSimpleType.DateTimeOffset; + final String[] dateParts = input.split("\\."); + final SimpleDateFormat sdf = new SimpleDateFormat(type.pattern()); + final boolean isOffset = type == EdmSimpleType.DateTimeOffset; - try { - final Date date = sdf.parse(dateParts[0]); - if (dateParts.length > 1) { - int idx = dateParts[1].indexOf('+'); - if (idx == -1) { - idx = dateParts[1].indexOf('-'); - } - if (idx == -1) { - instance = new ODataTimestamp(sdf, date, Integer.parseInt(dateParts[1]), isOffset); - } else { - instance = new ODataTimestamp(sdf, date, - Integer.parseInt(dateParts[1].substring(0, idx)), dateParts[1].substring(idx), isOffset); - } - } else { - instance = new ODataTimestamp(sdf, date, isOffset); - } - } catch (Exception e) { - throw new IllegalArgumentException("Cannot parse " + type.pattern(), e); + try { + final Date date = sdf.parse(dateParts[0]); + if (dateParts.length > 1) { + int idx = dateParts[1].indexOf('+'); + if (idx == -1) { + idx = dateParts[1].indexOf('-'); } - - return instance; - } - - private ODataTimestamp(final SimpleDateFormat sdf, final Date date, final boolean offset) { - this.sdf = sdf; - this.timestamp = new Timestamp(date.getTime()); - this.offset = offset; - } - - private ODataTimestamp(final SimpleDateFormat sdf, final Date date, final int nanos, final boolean offset) { - this(sdf, date, offset); - this.timestamp.setNanos(nanos); - } - - private ODataTimestamp( - final SimpleDateFormat sdf, final Date date, final int nanos, final String timezone, final boolean offset) { - this(sdf, date, nanos, offset); - this.timezone = timezone; - } - - public Timestamp getTimestamp() { - return timestamp; - } - - public String getTimezone() { - return timezone; - } - - public boolean isOffset() { - return offset; - } - - /** - * {@inheritDoc } - */ - @Override - public boolean equals(final Object obj) { - return EqualsBuilder.reflectionEquals(this, obj, "sdf"); - } - - /** - * {@inheritDoc } - */ - @Override - public int hashCode() { - return HashCodeBuilder.reflectionHashCode(this, "sdf"); - } - - /** - * {@inheritDoc } - */ - @Override - public String toString() { - final StringBuilder formatted = new StringBuilder().append(sdf.format(timestamp)); - if (timestamp.getNanos() > 0) { - formatted.append('.').append(String.valueOf(timestamp.getNanos())); + if (idx == -1) { + instance = new ODataTimestamp(sdf, date, Integer.parseInt(dateParts[1]), isOffset); + } else { + instance = new ODataTimestamp(sdf, date, + Integer.parseInt(dateParts[1].substring(0, idx)), dateParts[1].substring(idx), isOffset); } - if (StringUtils.isNotBlank(timezone)) { - formatted.append(timezone); - } - return formatted.toString(); + } else { + instance = new ODataTimestamp(sdf, date, isOffset); + } + } catch (Exception e) { + throw new IllegalArgumentException("Cannot parse " + type.pattern(), e); } + + return instance; + } + + private ODataTimestamp(final SimpleDateFormat sdf, final Date date, final boolean offset) { + this.sdf = sdf; + this.timestamp = new Timestamp(date.getTime()); + this.offset = offset; + } + + private ODataTimestamp(final SimpleDateFormat sdf, final Date date, final int nanos, final boolean offset) { + this(sdf, date, offset); + this.timestamp.setNanos(nanos); + } + + private ODataTimestamp( + final SimpleDateFormat sdf, final Date date, final int nanos, final String timezone, final boolean offset) { + this(sdf, date, nanos, offset); + this.timezone = timezone; + } + + public Timestamp getTimestamp() { + return timestamp; + } + + public String getTimezone() { + return timezone; + } + + public boolean isOffset() { + return offset; + } + + /** + * {@inheritDoc } + */ + @Override + public boolean equals(final Object obj) { + return EqualsBuilder.reflectionEquals(this, obj, "sdf"); + } + + /** + * {@inheritDoc } + */ + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this, "sdf"); + } + + /** + * {@inheritDoc } + */ + @Override + public String toString() { + final StringBuilder formatted = new StringBuilder().append(sdf.format(timestamp)); + if (timestamp.getNanos() > 0) { + formatted.append('.').append(String.valueOf(timestamp.getNanos())); + } + if (StringUtils.isNotBlank(timezone)) { + formatted.append(timezone); + } + return formatted.toString(); + } } diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/QueryOption.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/QueryOption.java new file mode 100644 index 000000000..067fec52c --- /dev/null +++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/QueryOption.java @@ -0,0 +1,87 @@ +/* + * 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.odata4.client.api.uri; + +/** + * Query options. + */ +public enum QueryOption { + + /** + * This option indicates entities associated with the EntityType instance or EntitySet, identified by the resource + * path section of the URI, and MUST be represented inline in the data service's response. + */ + EXPAND("expand"), + /** + * This option specifies the media type acceptable in a response. If present, this value SHOULD take precedence over + * value(s) specified in an Accept request header. + */ + FORMAT("format"), + /** + * This option is used to specify that a subset of the properties of the entities identified by the path of the + * request URI and $expand query option SHOULD be returned in the response from the data service. + */ + SELECT("select"), + /** + * This option specifies the sort properties and sort direction (ascending or descending) that the data service MUST + * use to order the entities in the EntitySet, identified by the resource path section of the URI. + */ + ORDERBY("orderby"), + /** + * This option specifies a positive integer N that is the maximum number of entities in the EntitySet, identified by + * the resource path section of the URI, that the data service MUST return. + */ + TOP("top"), + /** + * This option specifies a positive integer N that represents the number of entities, counted from the first entity in + * the EntitySet and ordered as specified by the $orderby option, that the data service should skip when returning the + * entities in the EntitySet, which is identified by the resource path section of the URI. The data service SHOULD + * return all subsequent entities, starting from the one in position N+1. + */ + SKIP("skip"), + /** + * This query option applies only to the OData 2.0 protocol to the AtomPub protocol. The value of a $skiptoken query + * option is an opaque token which identifies an index into the collection of entities identified by the URI + * containing the $skiptoken parameter. + */ + SKIPTOKEN("skiptoken"), + /** + * This option specifies a predicate used to filter the elements from the EntitySet identified by the resource path + * section of the URI. + */ + FILTER("filter"), + /** + * For a value of "allpages", this option indicates that the response to the request MUST include the count of the + * number of entities in the EntitySet, identified by the resource path section of the URI after all $filter system + * query options have been applied. For a value of "none", this option indicates that the response to the request MUST + * NOT include the count value. + */ + INLINECOUNT("inlinecount"); + + final String option; + + QueryOption(final String option) { + this.option = option; + } + + @Override + public String toString() { + return option; + } +} diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/URIBuilder.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/URIBuilder.java new file mode 100644 index 000000000..b3104ff88 --- /dev/null +++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/URIBuilder.java @@ -0,0 +1,261 @@ +/* + * 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.odata4.client.api.uri; + +import org.apache.olingo.odata4.client.api.uri.filter.URIFilter; +import java.io.Serializable; +import java.net.URI; +import java.util.Map; + +/** + * OData URI builder. + */ +public interface URIBuilder extends Serializable { + + public static class Segment { + + private final SegmentType type; + + private final String value; + + public Segment(final SegmentType type, final String value) { + this.type = type; + this.value = value; + } + + public SegmentType getType() { + return type; + } + + public String getValue() { + return value; + } + + } + + /** + * Adds the specified query option to the URI. + * + * @param option query option. + * @param value query option value. + * @return current ODataURIBuilder object. + */ + URIBuilder addQueryOption(QueryOption option, String value); + + /** + * Adds the specified (custom) query option to the URI. + * + * @param option query option. + * @param value query option value. + * @return current ODataURIBuilder object. + */ + URIBuilder addQueryOption(String option, String value); + + /** + * Append EntitySet segment to the URI. + * + * @param segmentValue segment value. + * @return current ODataURIBuilder object. + */ + URIBuilder appendEntitySetSegment(String segmentValue); + + /** + * Append EntityType segment to the URI. + * + * @param segmentValue segment value. + * @return current ODataURIBuilder object. + */ + URIBuilder appendEntityTypeSegment(String segmentValue); + + /** + * Append key segment to the URI. + * + * @param val segment value. + * @return current ODataURIBuilder object. + */ + URIBuilder appendKeySegment(Object val); + + /** + * Append key segment to the URI, for multiple keys. + * + * @param segmentValues segment values. + * @return current ODataURIBuilder object. + */ + URIBuilder appendKeySegment(Map segmentValues); + + /** + * Append navigation link segment to the URI. + * + * @param segmentValue segment value. + * @return current ODataURIBuilder object. + */ + URIBuilder appendNavigationLinkSegment(String segmentValue); + + /** + * Append structural segment to the URI. + * + * @param segmentValue segment value. + * @return current ODataURIBuilder object. + */ + URIBuilder appendStructuralSegment(String segmentValue); + + URIBuilder appendLinksSegment(String segmentValue); + + /** + * Append value segment to the URI. + * + * @return current ODataURIBuilder object. + */ + URIBuilder appendValueSegment(); + + /** + * Append count segment to the URI. + * + * @return current ODataURIBuilder object. + */ + URIBuilder appendCountSegment(); + + /** + * Append function import segment to the URI. + * + * @param segmentValue segment value. + * @return current ODataURIBuilder object. + */ + URIBuilder appendFunctionImportSegment(String segmentValue); + + /** + * Append metadata segment to the URI. + * + * @return current ODataURIBuilder object. + */ + URIBuilder appendMetadataSegment(); + + /** + * Append batch segment to the URI. + * + * @return current ODataURIBuilder object. + */ + URIBuilder appendBatchSegment(); + + /** + * Adds expand query option. + * + * @param entityName entity object to be in-line expanded. + * @return current ODataURIBuilder object. + * @see QueryOption#EXPAND + */ + URIBuilder expand(String entityName); + + /** + * Adds format query option. + * + * @param format media type acceptable in a response. + * @return current ODataURIBuilder object. + * @see QueryOption#FORMAT + */ + URIBuilder format(String format); + + /** + * Adds filter for filter query option. + * + * @param filter filter instance (to be obtained via ODataFilterFactory): note that build() method + * will be immediately invoked. + * @return current ODataURIBuilder object. + * @see QueryOption#FILTER + * @see ODataFilter + * @see FilterFactory + */ + URIBuilder filter(URIFilter filter); + + /** + * Adds filter query option. + * + * @param filter filter string. + * @return current ODataURIBuilder object. + * @see QueryOption#FILTER + */ + URIBuilder filter(String filter); + + /** + * Adds select query option. + * + * @param select select query option value. + * @return current ODataURIBuilder object. + * @see QueryOption#SELECT + */ + URIBuilder select(String select); + + /** + * Adds orderby query option. + * + * @param order order string. + * @return current ODataURIBuilder object. + * @see QueryOption#ORDERBY + */ + URIBuilder orderBy(String order); + + /** + * Adds top query option. + * + * @param top maximum number of entities to be returned. + * @return current ODataURIBuilder object. + * @see QueryOption#TOP + */ + URIBuilder top(int top); + + /** + * Adds skip query option. + * + * @param skip number of entities to be skipped into the response. + * @return current ODataURIBuilder object. + * @see QueryOption#SKIP + */ + URIBuilder skip(int skip); + + /** + * Adds skiptoken query option. + * + * @param skipToken opaque token. + * @return current ODataURIBuilder object. + * @see QueryOption#SKIPTOKEN + */ + URIBuilder skipToken(String skipToken); + + /** + * Adds inlinecount query option. + * + * @return current ODataURIBuilder object. + * @see QueryOption#INLINECOUNT + */ + URIBuilder inlineCount(); + + /** + * Build OData URI. + * + * @return OData URI. + */ + URI build(); + + /** + * ${@inheritDoc } + */ + @Override + String toString(); + +} diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/FilterArg.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/FilterArg.java new file mode 100644 index 000000000..453a26474 --- /dev/null +++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/FilterArg.java @@ -0,0 +1,30 @@ +/* + * 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.odata4.client.api.uri.filter; + +/** + * Interface for any available filter argument. + */ +public interface FilterArg { + + /** + * @return String representation of this filter argument. + */ + String build(); +} diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/FilterFactory.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/FilterFactory.java new file mode 100644 index 000000000..cf1260c8b --- /dev/null +++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/FilterFactory.java @@ -0,0 +1,59 @@ +/* + * 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.odata4.client.api.uri.filter; + +import java.io.Serializable; + +/** + * OData filter factory. + */ +public interface FilterFactory extends Serializable { + + URIFilter match(FilterArg arg); + + URIFilter eq(String key, Object value); + + URIFilter eq(FilterArg left, FilterArg right); + + URIFilter ne(String key, Object value); + + URIFilter ne(FilterArg left, FilterArg right); + + URIFilter gt(String key, Object value); + + URIFilter gt(FilterArg left, FilterArg right); + + URIFilter ge(String key, Object value); + + URIFilter ge(FilterArg left, FilterArg right); + + URIFilter lt(String key, Object value); + + URIFilter lt(FilterArg left, FilterArg right); + + URIFilter le(String key, Object value); + + URIFilter le(FilterArg left, FilterArg right); + + URIFilter and(URIFilter left, URIFilter right); + + URIFilter or(URIFilter left, URIFilter right); + + URIFilter not(URIFilter filter); +} diff --git a/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/URIFilter.java b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/URIFilter.java new file mode 100644 index 000000000..41c3410d4 --- /dev/null +++ b/odata4-lib/odata4-client-api/src/main/java/org/apache/olingo/odata4/client/api/uri/filter/URIFilter.java @@ -0,0 +1,32 @@ +/* + * 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.odata4.client.api.uri.filter; + +/** + * Interface for any available filter; obtain instances via FilterFactory. + * + * @see FilterFactory + */ +public interface URIFilter { + + /** + * @return String representation of this filter. + */ + String build(); +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV3Client.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV3Client.java index 77b961742..15cc2d267 100644 --- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV3Client.java +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV3Client.java @@ -22,6 +22,8 @@ import org.apache.olingo.odata4.client.core.op.impl.v3.ODataBinderImpl; import org.apache.olingo.odata4.client.core.op.impl.v3.ODataDeserializerImpl; import org.apache.olingo.odata4.client.core.op.impl.v3.ODataReaderImpl; import org.apache.olingo.odata4.client.core.op.impl.v3.ODataSerializerImpl; +import org.apache.olingo.odata4.client.core.uri.V3URIBuilder; +import org.apache.olingo.odata4.client.core.uri.filter.V3FilterFactory; import org.apache.olingo.odata4.commons.api.edm.constants.ODataServiceVersion; public class ODataV3Client extends AbstractODataClient { @@ -30,7 +32,8 @@ public class ODataV3Client extends AbstractODataClient { private final V3Configuration configuration = new V3Configuration(); -// private final V3FilterFactory filterFactory = new V3FilterFactory(); + private final V3FilterFactory filterFactory = new V3FilterFactory(); + private final ODataDeserializerImpl deserializer = new ODataDeserializerImpl(this); private final ODataSerializerImpl serializer = new ODataSerializerImpl(this); @@ -69,16 +72,16 @@ public class ODataV3Client extends AbstractODataClient { return configuration; } -// @Override -// public V3URIBuilder getURIBuilder(final String serviceRoot) { -// return new V3URIBuilder(configuration, serviceRoot); -// } -// -// @Override -// public V3FilterFactory getFilterFactory() { -// return filterFactory; -// } -// + @Override + public V3URIBuilder getURIBuilder(final String serviceRoot) { + return new V3URIBuilder(configuration, serviceRoot); + } + + @Override + public V3FilterFactory getFilterFactory() { + return filterFactory; + } + @Override public ODataDeserializerImpl getDeserializer() { return deserializer; diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV4Client.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV4Client.java index 06195d8b6..35e4809c3 100644 --- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV4Client.java +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/ODataV4Client.java @@ -22,6 +22,8 @@ import org.apache.olingo.odata4.client.core.op.impl.v4.ODataBinderImpl; import org.apache.olingo.odata4.client.core.op.impl.v4.ODataDeserializerImpl; import org.apache.olingo.odata4.client.core.op.impl.v4.ODataReaderImpl; import org.apache.olingo.odata4.client.core.op.impl.v4.ODataSerializerImpl; +import org.apache.olingo.odata4.client.core.uri.V4URIBuilder; +import org.apache.olingo.odata4.client.core.uri.filter.V4FilterFactory; import org.apache.olingo.odata4.commons.api.edm.constants.ODataServiceVersion; public class ODataV4Client extends AbstractODataClient { @@ -30,7 +32,8 @@ public class ODataV4Client extends AbstractODataClient { private final V4Configuration configuration = new V4Configuration(); -// private final V4FilterFactory filterFactory = new V4FilterFactory(); + private final V4FilterFactory filterFactory = new V4FilterFactory(); + private final ODataDeserializerImpl deserializer = new ODataDeserializerImpl(this); private final ODataSerializerImpl serializer = new ODataSerializerImpl(this); @@ -69,15 +72,16 @@ public class ODataV4Client extends AbstractODataClient { return configuration; } -// @Override -// public URIBuilder getURIBuilder(final String serviceRoot) { -// return new V4URIBuilder(configuration, serviceRoot); -// } -// -// @Override -// public V4FilterFactory getFilterFactory() { -// return filterFactory; -// } + @Override + public V4URIBuilder getURIBuilder(final String serviceRoot) { + return new V4URIBuilder(configuration, serviceRoot); + } + + @Override + public V4FilterFactory getFilterFactory() { + return filterFactory; + } + @Override public ODataDeserializerImpl getDeserializer() { return deserializer; diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/AbstractURIBuilder.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/AbstractURIBuilder.java new file mode 100644 index 000000000..79a092c51 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/AbstractURIBuilder.java @@ -0,0 +1,242 @@ +/* + * 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.odata4.client.core.uri; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import org.apache.olingo.odata4.client.api.Configuration; +import org.apache.olingo.odata4.client.api.uri.QueryOption; +import org.apache.olingo.odata4.client.api.uri.SegmentType; +import org.apache.olingo.odata4.client.api.uri.URIBuilder; +import org.apache.olingo.odata4.client.api.uri.filter.URIFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractURIBuilder implements URIBuilder { + + private static final long serialVersionUID = -3267515371720408124L; + + /** + * Logger. + */ + protected static final Logger LOG = LoggerFactory.getLogger(URIBuilder.class); + + protected final List segments; + + /** + * Case-insensitive map of query options. + */ + protected final Map queryOptions = new TreeMap(String.CASE_INSENSITIVE_ORDER); + + /** + * Constructor. + * + * @param serviceRoot absolute URL (schema, host and port included) representing the location of the root of the data + * service. + */ + protected AbstractURIBuilder(final String serviceRoot) { + segments = new ArrayList(); + segments.add(new URIBuilder.Segment(SegmentType.SERVICEROOT, serviceRoot)); + } + + protected abstract Configuration getConfiguration(); + + @Override + public URIBuilder addQueryOption(final QueryOption option, final String value) { + return addQueryOption(option.toString(), value); + } + + @Override + public URIBuilder addQueryOption(final String option, final String value) { + queryOptions.put(option, value); + return this; + } + + @Override + public URIBuilder appendEntitySetSegment(final String segmentValue) { + segments.add(new URIBuilder.Segment(SegmentType.ENTITYSET, segmentValue)); + return this; + } + + @Override + public URIBuilder appendEntityTypeSegment(final String segmentValue) { + segments.add(new URIBuilder.Segment(SegmentType.ENTITYTYPE, segmentValue)); + return this; + } + + @Override + public URIBuilder appendKeySegment(final Object val) { + final String segValue = URIUtils.escape(val); + + segments.add(getConfiguration().isKeyAsSegment() + ? new URIBuilder.Segment(SegmentType.KEY_AS_SEGMENT, segValue) + : new URIBuilder.Segment(SegmentType.KEY, "(" + segValue + ")")); + return this; + } + + @Override + public URIBuilder appendKeySegment(final Map segmentValues) { + if (!getConfiguration().isKeyAsSegment()) { + final StringBuilder keyBuilder = new StringBuilder().append('('); + for (Map.Entry entry : segmentValues.entrySet()) { + keyBuilder.append(entry.getKey()).append('=').append(URIUtils.escape(entry.getValue())); + keyBuilder.append(','); + } + keyBuilder.deleteCharAt(keyBuilder.length() - 1).append(')'); + + segments.add(new URIBuilder.Segment(SegmentType.KEY, keyBuilder.toString())); + } + + return this; + } + + @Override + public URIBuilder appendNavigationLinkSegment(final String segmentValue) { + segments.add(new URIBuilder.Segment(SegmentType.NAVIGATION, segmentValue)); + return this; + } + + @Override + public URIBuilder appendStructuralSegment(final String segmentValue) { + segments.add(new URIBuilder.Segment(SegmentType.STRUCTURAL, segmentValue)); + return this; + } + + @Override + public URIBuilder appendLinksSegment(final String segmentValue) { + segments.add(new URIBuilder.Segment(SegmentType.LINKS, SegmentType.LINKS.getValue())); + segments.add(new URIBuilder.Segment(SegmentType.ENTITYTYPE, segmentValue)); + return this; + } + + @Override + public URIBuilder appendValueSegment() { + segments.add(new URIBuilder.Segment(SegmentType.VALUE, SegmentType.VALUE.getValue())); + return this; + } + + @Override + public URIBuilder appendCountSegment() { + segments.add(new URIBuilder.Segment(SegmentType.COUNT, SegmentType.COUNT.getValue())); + return this; + } + + @Override + public URIBuilder appendFunctionImportSegment(final String segmentValue) { + segments.add(new URIBuilder.Segment(SegmentType.FUNCTIONIMPORT, segmentValue)); + return this; + } + + @Override + public URIBuilder appendMetadataSegment() { + segments.add(new URIBuilder.Segment(SegmentType.METADATA, SegmentType.METADATA.getValue())); + return this; + } + + @Override + public URIBuilder appendBatchSegment() { + segments.add(new URIBuilder.Segment(SegmentType.BATCH, SegmentType.BATCH.getValue())); + return this; + } + + @Override + public URIBuilder expand(final String entityName) { + return addQueryOption(QueryOption.EXPAND, entityName); + } + + @Override + public URIBuilder format(final String format) { + return addQueryOption(QueryOption.FORMAT, format); + } + + @Override + public URIBuilder filter(final URIFilter filter) { + return addQueryOption(QueryOption.FILTER, filter.build()); + } + + @Override + public URIBuilder filter(final String filter) { + return addQueryOption(QueryOption.FILTER, filter); + } + + @Override + public URIBuilder select(final String select) { + return addQueryOption(QueryOption.SELECT, select); + } + + @Override + public URIBuilder orderBy(final String order) { + return addQueryOption(QueryOption.ORDERBY, order); + } + + @Override + public URIBuilder top(final int top) { + return addQueryOption(QueryOption.TOP, String.valueOf(top)); + } + + @Override + public URIBuilder skip(final int skip) { + return addQueryOption(QueryOption.SKIP, String.valueOf(skip)); + } + + @Override + public URIBuilder skipToken(final String skipToken) { + return addQueryOption(QueryOption.SKIPTOKEN, skipToken); + } + + @Override + public URIBuilder inlineCount() { + return addQueryOption(QueryOption.INLINECOUNT, "allpages"); + } + + @Override + public URI build() { + final StringBuilder segmentsBuilder = new StringBuilder(); + for (URIBuilder.Segment seg : segments) { + if (segmentsBuilder.length() > 0 && seg.getType() != SegmentType.KEY) { + segmentsBuilder.append('/'); + } + + segmentsBuilder.append(seg.getValue()); + } + + try { + final org.apache.http.client.utils.URIBuilder builder + = new org.apache.http.client.utils.URIBuilder(segmentsBuilder.toString()); + + for (Map.Entry option : queryOptions.entrySet()) { + builder.addParameter("$" + option.getKey(), option.getValue()); + } + + return builder.build().normalize(); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Could not build valid URI", e); + } + } + + @Override + public String toString() { + return build().toASCIIString(); + } + +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/V3URIBuilder.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/V3URIBuilder.java new file mode 100644 index 000000000..fc4526ce9 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/V3URIBuilder.java @@ -0,0 +1,39 @@ +/* + * 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.odata4.client.core.uri; + +import org.apache.olingo.odata4.client.core.V3Configuration; + +public class V3URIBuilder extends AbstractURIBuilder { + + private static final long serialVersionUID = -3506851722447870532L; + + private final V3Configuration configuration; + + public V3URIBuilder(final V3Configuration configuration, final String serviceRoot) { + super(serviceRoot); + this.configuration = configuration; + } + + @Override + protected V3Configuration getConfiguration() { + return configuration; + } + +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/V4URIBuilder.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/V4URIBuilder.java new file mode 100644 index 000000000..b26f25b98 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/V4URIBuilder.java @@ -0,0 +1,39 @@ +/* + * 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.odata4.client.core.uri; + +import org.apache.olingo.odata4.client.core.V4Configuration; + +public class V4URIBuilder extends AbstractURIBuilder { + + private static final long serialVersionUID = -3506851722447870532L; + + private final V4Configuration configuration; + + public V4URIBuilder(final V4Configuration configuration, final String serviceRoot) { + super(serviceRoot); + this.configuration = configuration; + } + + @Override + protected V4Configuration getConfiguration() { + return configuration; + } + +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AbstractComparingFilter.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AbstractComparingFilter.java new file mode 100644 index 000000000..c76de474a --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AbstractComparingFilter.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.URIFilter; +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; + +abstract class AbstractComparingFilter implements URIFilter { + + private final FilterArg left; + + private final FilterArg right; + + AbstractComparingFilter(final FilterArg left, final FilterArg right) { + this.left = left; + this.right = right; + } + + protected abstract String getOp(); + + @Override + public String build() { + return new StringBuilder(). + append('(').append(left.build()). + append(' ').append(getOp()).append(' '). + append(right.build()).append(')'). + toString(); + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AbstractFilterFactory.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AbstractFilterFactory.java new file mode 100644 index 000000000..fa78672aa --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AbstractFilterFactory.java @@ -0,0 +1,110 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.URIFilter; +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; +import org.apache.olingo.odata4.client.api.uri.filter.FilterFactory; + +public abstract class AbstractFilterFactory implements FilterFactory { + + private static final long serialVersionUID = -6141317149802621836L; + + protected static final String NULL = "null"; + + @Override + public URIFilter match(final FilterArg arg) { + return new MatchFilter(arg); + } + + @Override + public URIFilter eq(final String key, final Object value) { + return new EqFilter(FilterArgFactory.property(key), FilterArgFactory.literal(value)); + } + + @Override + public URIFilter eq(final FilterArg left, final FilterArg right) { + return new EqFilter(left, right); + } + + @Override + public URIFilter ne(final String key, final Object value) { + return new NeFilter(FilterArgFactory.property(key), FilterArgFactory.literal(value)); + } + + @Override + public URIFilter ne(final FilterArg left, final FilterArg right) { + return new NeFilter(left, right); + } + + @Override + public URIFilter gt(final String key, final Object value) { + return new GtFilter(FilterArgFactory.property(key), FilterArgFactory.literal(value)); + } + + @Override + public URIFilter gt(final FilterArg left, final FilterArg right) { + return new GtFilter(left, right); + } + + @Override + public URIFilter ge(final String key, final Object value) { + return new GeFilter(FilterArgFactory.property(key), FilterArgFactory.literal(value)); + } + + @Override + public URIFilter ge(final FilterArg left, final FilterArg right) { + return new GeFilter(left, right); + } + + @Override + public URIFilter lt(final String key, final Object value) { + return new LtFilter(FilterArgFactory.property(key), FilterArgFactory.literal(value)); + } + + @Override + public URIFilter lt(final FilterArg left, final FilterArg right) { + return new LtFilter(left, right); + } + + @Override + public URIFilter le(final String key, final Object value) { + return new LeFilter(FilterArgFactory.property(key), FilterArgFactory.literal(value)); + } + + @Override + public URIFilter le(final FilterArg left, final FilterArg right) { + return new LeFilter(left, right); + } + + @Override + public URIFilter and(final URIFilter left, final URIFilter right) { + return new AndFilter(left, right); + } + + @Override + public URIFilter or(final URIFilter left, final URIFilter right) { + return new OrFilter(left, right); + } + + @Override + public URIFilter not(final URIFilter filter) { + return new NotFilter(filter); + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AndFilter.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AndFilter.java new file mode 100644 index 000000000..c9068a39f --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/AndFilter.java @@ -0,0 +1,42 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.URIFilter; + +public class AndFilter implements URIFilter { + + private final URIFilter left; + + private final URIFilter right; + + public AndFilter(final URIFilter left, final URIFilter right) { + this.left = left; + this.right = right; + } + + @Override + public String build() { + return new StringBuilder(). + append('(').append(left.build()). + append(" and "). + append(right.build()).append(')'). + toString(); + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/EqFilter.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/EqFilter.java new file mode 100644 index 000000000..01bfd0395 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/EqFilter.java @@ -0,0 +1,33 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; + +public class EqFilter extends AbstractComparingFilter { + + EqFilter(final FilterArg left, final FilterArg right) { + super(left, right); + } + + @Override + protected String getOp() { + return "eq"; + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterArgFactory.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterArgFactory.java new file mode 100644 index 000000000..619e3cfda --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterArgFactory.java @@ -0,0 +1,155 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; + +/** + * OData filter arguments factory. + */ +public final class FilterArgFactory { + + private FilterArgFactory() { + // Empty private constructor for static utility classes + } + + public static FilterArg property(final String propertyPath) { + return new FilterProperty(propertyPath); + } + + public static FilterArg literal(final Object value) { + return new FilterLiteral(value); + } + + public static FilterArg add(final FilterArg first, final FilterArg second) { + return new FilterOp("add", first, second); + } + + public static FilterArg sub(final FilterArg first, final FilterArg second) { + return new FilterOp("add", first, second); + } + + public static FilterArg mul(final FilterArg first, final FilterArg second) { + return new FilterOp("mul", first, second); + } + + public static FilterArg div(final FilterArg first, final FilterArg second) { + return new FilterOp("div", first, second); + } + + public static FilterArg mod(final FilterArg first, final FilterArg second) { + return new FilterOp("mod", first, second); + } + + public static FilterArg substringof(final FilterArg first, final FilterArg second) { + return new FilterFunction("substringof", first, second); + } + + public static FilterArg endswith(final FilterArg first, final FilterArg second) { + return new FilterFunction("endswith", first, second); + } + + public static FilterArg startswith(final FilterArg first, final FilterArg second) { + return new FilterFunction("startswith", first, second); + } + + public static FilterArg length(final FilterArg param) { + return new FilterFunction("length", param); + } + + public static FilterArg indexof(final FilterArg first, final FilterArg second) { + return new FilterFunction("indexof", first, second); + } + + public static FilterArg replace( + final FilterArg first, final FilterArg second, final FilterArg third) { + + return new FilterFunction("replace", first, second, third); + } + + public static FilterArg substring(final FilterArg arg, final FilterArg pos) { + return new FilterFunction("substring", arg, pos); + } + + public static FilterArg substring( + final FilterArg arg, final FilterArg pos, final FilterArg length) { + + return new FilterFunction("substring", arg, pos, length); + } + + public static FilterArg tolower(final FilterArg param) { + return new FilterFunction("tolower", param); + } + + public static FilterArg toupper(final FilterArg param) { + return new FilterFunction("toupper", param); + } + + public static FilterArg trim(final FilterArg param) { + return new FilterFunction("trim", param); + } + + public static FilterArg concat(final FilterArg first, final FilterArg second) { + return new FilterFunction("concat", first, second); + } + + public static FilterArg day(final FilterArg param) { + return new FilterFunction("day", param); + } + + public static FilterArg hour(final FilterArg param) { + return new FilterFunction("hour", param); + } + + public static FilterArg minute(final FilterArg param) { + return new FilterFunction("minute", param); + } + + public static FilterArg month(final FilterArg param) { + return new FilterFunction("month", param); + } + + public static FilterArg second(final FilterArg param) { + return new FilterFunction("second", param); + } + + public static FilterArg year(final FilterArg param) { + return new FilterFunction("year", param); + } + + public static FilterArg round(final FilterArg param) { + return new FilterFunction("round", param); + } + + public static FilterArg floor(final FilterArg param) { + return new FilterFunction("floor", param); + } + + public static FilterArg ceiling(final FilterArg param) { + return new FilterFunction("ceiling", param); + } + + public static FilterArg isof(final FilterArg param) { + return new FilterFunction("isof", param); + } + + public static FilterArg isof(final FilterArg first, final FilterArg second) { + return new FilterFunction("isof", first, second); + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterFunction.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterFunction.java new file mode 100644 index 000000000..bd54ade96 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterFunction.java @@ -0,0 +1,48 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; +import org.apache.commons.lang3.StringUtils; + +public class FilterFunction implements FilterArg { + + private final String function; + + private final FilterArg[] params; + + FilterFunction(final String function, final FilterArg... params) { + this.function = function; + this.params = params; + } + + @Override + public String build() { + final String[] strParams = new String[params.length]; + for (int i = 0; i < params.length; i++) { + strParams[i] = params[i].build(); + } + + return new StringBuilder(function). + append('('). + append(StringUtils.join(strParams, ',')). + append(')'). + toString(); + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterLiteral.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterLiteral.java new file mode 100644 index 000000000..578c3e363 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterLiteral.java @@ -0,0 +1,41 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; +import org.apache.olingo.odata4.client.core.uri.URIUtils; + +/** + * Filter value literals; obtain instances via FilterArgFactory. + * + * @see FilterArgFactory + */ +public class FilterLiteral implements FilterArg { + + private final Object value; + + FilterLiteral(final Object value) { + this.value = value; + } + + @Override + public String build() { + return URIUtils.escape(value); + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterOp.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterOp.java new file mode 100644 index 000000000..a59fd7b25 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterOp.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; + +public class FilterOp implements FilterArg { + + private final String op; + + private final FilterArg first; + + private final FilterArg second; + + FilterOp(final String op, final FilterArg first, final FilterArg second) { + this.op = op; + this.first = first; + this.second = second; + } + + @Override + public String build() { + return new StringBuilder(). + append('(').append(first.build()). + append(' ').append(op).append(' '). + append(second.build()).append(')'). + toString(); + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterProperty.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterProperty.java new file mode 100644 index 000000000..e467a44ef --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/FilterProperty.java @@ -0,0 +1,40 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; + +/** + * Filter property path; obtain instances via FilterArgFactory. + * + * @see FilterArgFactory + */ +public class FilterProperty implements FilterArg { + + private final String propertyPath; + + FilterProperty(final String value) { + this.propertyPath = value; + } + + @Override + public String build() { + return propertyPath; + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/GeFilter.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/GeFilter.java new file mode 100644 index 000000000..77024d985 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/GeFilter.java @@ -0,0 +1,33 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; + +public class GeFilter extends AbstractComparingFilter { + + GeFilter(final FilterArg left, final FilterArg right) { + super(left, right); + } + + @Override + protected String getOp() { + return "ge"; + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/GtFilter.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/GtFilter.java new file mode 100644 index 000000000..9f1d1884e --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/GtFilter.java @@ -0,0 +1,33 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; + +public class GtFilter extends AbstractComparingFilter { + + GtFilter(final FilterArg left, final FilterArg right) { + super(left, right); + } + + @Override + protected String getOp() { + return "gt"; + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/LeFilter.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/LeFilter.java new file mode 100644 index 000000000..122ef1bd3 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/LeFilter.java @@ -0,0 +1,33 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; + +public class LeFilter extends AbstractComparingFilter { + + LeFilter(final FilterArg left, final FilterArg right) { + super(left, right); + } + + @Override + protected String getOp() { + return "le"; + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/LtFilter.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/LtFilter.java new file mode 100644 index 000000000..5cbde0d61 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/LtFilter.java @@ -0,0 +1,33 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; + +public class LtFilter extends AbstractComparingFilter { + + LtFilter(final FilterArg left, final FilterArg right) { + super(left, right); + } + + @Override + protected String getOp() { + return "lt"; + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/MatchFilter.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/MatchFilter.java new file mode 100644 index 000000000..ae352ad8b --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/MatchFilter.java @@ -0,0 +1,36 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.URIFilter; +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; + +public class MatchFilter implements URIFilter { + + private final FilterArg arg; + + MatchFilter(final FilterArg arg) { + this.arg = arg; + } + + @Override + public String build() { + return arg.build(); + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/NeFilter.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/NeFilter.java new file mode 100644 index 000000000..cba18ec54 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/NeFilter.java @@ -0,0 +1,33 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.FilterArg; + +public class NeFilter extends AbstractComparingFilter { + + NeFilter(final FilterArg left, final FilterArg right) { + super(left, right); + } + + @Override + protected String getOp() { + return "ne"; + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/NotFilter.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/NotFilter.java new file mode 100644 index 000000000..8aed7bb2e --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/NotFilter.java @@ -0,0 +1,35 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.URIFilter; + +public class NotFilter implements URIFilter { + + private final URIFilter filter; + + public NotFilter(final URIFilter left) { + this.filter = left; + } + + @Override + public String build() { + return new StringBuilder("not (").append(filter.build()).append(')').toString(); + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/OrFilter.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/OrFilter.java new file mode 100644 index 000000000..648fa2756 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/OrFilter.java @@ -0,0 +1,42 @@ +/* + * 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.odata4.client.core.uri.filter; + +import org.apache.olingo.odata4.client.api.uri.filter.URIFilter; + +public class OrFilter implements URIFilter { + + private final URIFilter left; + + private final URIFilter right; + + public OrFilter(final URIFilter left, final URIFilter right) { + this.left = left; + this.right = right; + } + + @Override + public String build() { + return new StringBuilder(). + append('(').append(left.build()). + append(" or "). + append(right.build()).append(')'). + toString(); + } +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/V3FilterFactory.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/V3FilterFactory.java new file mode 100644 index 000000000..4cabe41da --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/V3FilterFactory.java @@ -0,0 +1,25 @@ +/* + * 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.odata4.client.core.uri.filter; + +public class V3FilterFactory extends AbstractFilterFactory { + + private static final long serialVersionUID = 1092594961118334631L; + +} diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/V4FilterFactory.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/V4FilterFactory.java new file mode 100644 index 000000000..09c0dd5ca --- /dev/null +++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/uri/filter/V4FilterFactory.java @@ -0,0 +1,25 @@ +/* + * 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.odata4.client.core.uri.filter; + +public class V4FilterFactory extends AbstractFilterFactory { + + private static final long serialVersionUID = -5358934829490623191L; + +} diff --git a/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/FilterFactoryTest.java b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/FilterFactoryTest.java new file mode 100644 index 000000000..fd4002030 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/FilterFactoryTest.java @@ -0,0 +1,136 @@ +/* + * 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.odata4.client.core.v3; + +import static org.junit.Assert.assertEquals; + +import org.apache.olingo.odata4.client.api.ODataClient; +import org.apache.olingo.odata4.client.api.uri.filter.URIFilter; +import org.apache.olingo.odata4.client.core.AbstractTest; +import org.apache.olingo.odata4.client.core.uri.filter.FilterArgFactory; +import org.junit.Test; + +public class FilterFactoryTest extends AbstractTest { + + @Override + protected ODataClient getClient() { + return v3Client; + } + + @Test + public void simple() { + final URIFilter filter = getClient().getFilterFactory().lt("VIN", 16); + assertEquals("(VIN lt 16)", filter.build()); + } + + @Test + public void and() { + final URIFilter filter = getClient().getFilterFactory().and( + getClient().getFilterFactory().lt("VIN", 16), + getClient().getFilterFactory().gt("VIN", 12)); + + assertEquals("((VIN lt 16) and (VIN gt 12))", filter.build()); + } + + @Test + public void not() { + final URIFilter filter = getClient().getFilterFactory().not( + getClient().getFilterFactory().or( + getClient().getFilterFactory().ge("VIN", 16), + getClient().getFilterFactory().le("VIN", 12))); + + assertEquals("not (((VIN ge 16) or (VIN le 12)))", filter.build()); + } + + @Test + public void operator() { + URIFilter filter = getClient().getFilterFactory().eq( + FilterArgFactory.add(FilterArgFactory.property("VIN"), FilterArgFactory.literal(1)), + FilterArgFactory.literal(16)); + + assertEquals("((VIN add 1) eq 16)", filter.build()); + + filter = getClient().getFilterFactory().eq( + FilterArgFactory.add(FilterArgFactory.literal(1), FilterArgFactory.property("VIN")), + FilterArgFactory.literal(16)); + + assertEquals("((1 add VIN) eq 16)", filter.build()); + + filter = getClient().getFilterFactory().eq( + FilterArgFactory.literal(16), + FilterArgFactory.add(FilterArgFactory.literal(1), FilterArgFactory.property("VIN"))); + + assertEquals("(16 eq (1 add VIN))", filter.build()); + } + + @Test + public void function() { + final URIFilter filter = getClient().getFilterFactory().match( + FilterArgFactory.startswith(FilterArgFactory.property("Description"), FilterArgFactory.literal("cen"))); + + assertEquals("startswith(Description,'cen')", filter.build()); + } + + @Test + public void composed() { + final URIFilter filter = getClient().getFilterFactory().gt( + FilterArgFactory.length(FilterArgFactory.property("Description")), + FilterArgFactory.add(FilterArgFactory.property("VIN"), FilterArgFactory.literal(10))); + + assertEquals("(length(Description) gt (VIN add 10))", filter.build()); + } + + @Test + public void propertyPath() { + URIFilter filter = getClient().getFilterFactory().eq( + FilterArgFactory.indexof( + FilterArgFactory.property("PrimaryContactInfo/HomePhone/PhoneNumber"), + FilterArgFactory.literal("ODataJClient")), + FilterArgFactory.literal(1)); + + assertEquals("(indexof(PrimaryContactInfo/HomePhone/PhoneNumber,'ODataJClient') eq 1)", filter.build()); + + filter = getClient().getFilterFactory().ne( + FilterArgFactory.indexof( + FilterArgFactory.property("PrimaryContactInfo/HomePhone/PhoneNumber"), + FilterArgFactory.literal("lccvussrv")), + FilterArgFactory.literal(-1)); + + assertEquals("(indexof(PrimaryContactInfo/HomePhone/PhoneNumber,'lccvussrv') ne -1)", filter.build()); + } + + @Test + public void datetime() { + final URIFilter filter = getClient().getFilterFactory().eq( + FilterArgFactory.month(FilterArgFactory.property("PurchaseDate")), + FilterArgFactory.literal(12)); + + assertEquals("(month(PurchaseDate) eq 12)", filter.build()); + } + + @Test + public void isof() { + final URIFilter filter = getClient().getFilterFactory().match( + FilterArgFactory.isof( + FilterArgFactory.literal("Microsoft.Test.OData.Services.AstoriaDefaultService.SpecialEmployee"))); + + assertEquals("isof('Microsoft.Test.OData.Services.AstoriaDefaultService.SpecialEmployee')", filter.build()); + } + +} diff --git a/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/URIBuilderTest.java b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/URIBuilderTest.java new file mode 100644 index 000000000..0b2afb0d7 --- /dev/null +++ b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/URIBuilderTest.java @@ -0,0 +1,89 @@ +/* + * 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.odata4.client.core.v3; + +import static org.junit.Assert.assertEquals; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; +import org.apache.olingo.odata4.client.api.ODataClient; +import org.apache.olingo.odata4.client.api.uri.URIBuilder; +import org.apache.olingo.odata4.client.core.AbstractTest; +import org.junit.Test; + +public class URIBuilderTest extends AbstractTest { + + private static final String BASE_URI = "http://host/service"; + + @Override + protected ODataClient getClient() { + return v3Client; + } + + @Test + public void metadata() throws URISyntaxException { + final URI uri = getClient().getURIBuilder(BASE_URI).appendMetadataSegment().build(); + + assertEquals(new org.apache.http.client.utils.URIBuilder(BASE_URI + "/$metadata").build(), uri); + } + + @Test + public void entity() throws URISyntaxException { + final URI uri = getClient().getURIBuilder(BASE_URI).appendEntitySetSegment("AnEntitySet"). + appendKeySegment(11).build(); + + assertEquals(new org.apache.http.client.utils.URIBuilder(BASE_URI + "/AnEntitySet(11)").build(), uri); + + final Map multiKey = new HashMap(); + multiKey.put("OrderId", -10); + multiKey.put("ProductId", -10); + URIBuilder uriBuilder = getClient().getURIBuilder(BASE_URI). + appendEntityTypeSegment("OrderLine").appendKeySegment(multiKey). + appendStructuralSegment("Quantity"). + appendValueSegment(); + + assertEquals(new org.apache.http.client.utils.URIBuilder( + BASE_URI + "/OrderLine(OrderId=-10,ProductId=-10)/Quantity/$value").build(), uriBuilder.build()); + + uriBuilder = getClient().getURIBuilder(BASE_URI). + appendEntityTypeSegment("Customer").appendKeySegment(-10).select("CustomerId,Name,Orders").expand("Orders"); + assertEquals(new org.apache.http.client.utils.URIBuilder( + BASE_URI + "/Customer(-10)").addParameter("$expand", "Orders"). + addParameter("$select", "CustomerId,Name,Orders").build(), + uriBuilder.build()); + + uriBuilder = getClient().getURIBuilder(BASE_URI). + appendNavigationLinkSegment("Customer").appendKeySegment(-10).appendLinksSegment("Orders"); + assertEquals(new org.apache.http.client.utils.URIBuilder(BASE_URI + "/Customer(-10)/$links/Orders").build(), + uriBuilder.build()); + } + + @Test + public void filter() throws URISyntaxException { + final URIBuilder uriBuilder = getClient().getURIBuilder(BASE_URI).appendEntitySetSegment("AnEntitySet"). + filter(getClient().getFilterFactory().lt("VIN", 16)); + + assertEquals(new org.apache.http.client.utils.URIBuilder(BASE_URI + "/AnEntitySet"). + addParameter("$filter", "(VIN lt 16)").build(), + uriBuilder.build()); + } + +}