You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2014/03/26 16:23:28 UTC
[2/4] [OLINGO-175,
OLINGO-205] provided (v4) context url and entity reference retrieving
+ it tests
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaderValues.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaderValues.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaderValues.java
deleted file mode 100644
index 37c4698..0000000
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaderValues.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.client.api.communication.header;
-
-/**
- * Constant header values class.
- */
-public class ODataHeaderValues {
-
- /**
- * <code>Prefer</code> header, return content.
- *
- * @see ODataHeaders.HeaderName#prefer
- */
- public static final String preferReturnContent = "return-content";
-
- /**
- * <code>Prefer</code> header, return no content.
- *
- * @see ODataHeaders.HeaderName#prefer
- */
- public static final String preferReturnNoContent = "return-no-content";
-
- /**
- * @see ODataHeaders.HeaderName#dataServiceUrlConventions
- */
- public static final String keyAsSegment = "KeyAsSegment";
-
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataPreferences.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataPreferences.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataPreferences.java
new file mode 100644
index 0000000..6afa950
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataPreferences.java
@@ -0,0 +1,424 @@
+/*
+ * 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.client.api.communication.header;
+
+import java.util.Arrays;
+import java.util.List;
+import org.apache.olingo.commons.api.ODataRuntimeException;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+
+/**
+ * Values of the Prefer header.
+ */
+public class ODataPreferences {
+
+ final ODataServiceVersion serviceVersion;
+
+ public ODataPreferences(final ODataServiceVersion serviceVersion) {
+ this.serviceVersion = serviceVersion;
+ }
+
+ /**
+ * <code>Prefer</code> header, return content.
+ *
+ * @see HeaderName#prefer
+ */
+ public String returnContent() {
+ return PreferenceNames.returnContent.isSupportedBy(serviceVersion).toString();
+ }
+
+ /**
+ * <code>Prefer</code> header, return no content.
+ *
+ * @see HeaderName#prefer
+ */
+ public String returnNoContent() {
+ return PreferenceNames.returnNoContent.isSupportedBy(serviceVersion).toString();
+ }
+
+ /**
+ * @see HeaderName#dataServiceUrlConventions
+ */
+ public String keyAsSegment() {
+ return PreferenceNames.keyAsSegment.isSupportedBy(serviceVersion).toString();
+ }
+
+ /**
+ * The odata.allow-entityreferences preference indicates that the service is allowed to return entity references in
+ * place of entities that have previously been returned, with at least the properties requested, in the same response
+ * (for example, when serializing the expanded results of many-to-many relationships). The service MUST NOT return
+ * entity references in place of requested entities if odata.allow-entityreferences has not been specified in the
+ * request, unless explicitly defined by other rules in this document. The syntax of the odata.allow-entityreferences
+ * preference is specified in [OData-ABNF].
+ * <br />
+ * In the case the service applies the odata.allow-entityreferences preference it MUST include a Preference-Applied
+ * response header containing the odata.allow-entityreferences preference to indicate that entity references MAY be
+ * returned in place of entities that have previously been returned.
+ * <br/><br/>
+ * Supported by OData version 4.0 only.
+ *
+ * @see HeaderName#prefer
+ * @return preference.
+ */
+ public String allowEntityReferences() {
+ return PreferenceNames.allowEntityReferences.isSupportedBy(serviceVersion).toString();
+ }
+
+ /**
+ * For scenarios in which links returned by the service are used by the client to poll for additional information, the
+ * client can specify the odata.callback preference to request that the service notify the client when data is
+ * available.
+ * <br />
+ * The odata.callback preference can be specified:
+ * <ul>
+ * <li>when requesting asynchronous processing of a request with the respond-async preference, or</li>
+ * <li>on a GET request to a delta link.</li>
+ * </ul>
+ * <br />
+ * The odata.callback preference MUST include the parameter url whose value is the URL of a callback endpoint to be
+ * invoked by the OData service when data is available. The syntax of the odata.callback preference is specified in
+ * [OData-ABNF]. For HTTP based callbacks, the OData service executes an HTTP GET request against the specified URL.
+ * <br />
+ * Services that support odata.callback SHOULD support notifying the client through HTTP. Services can advertise
+ * callback support using the Capabilities.CallbackSupport annotation term defined in [OData-VocCap].
+ * <br />
+ * If the service applies the odata.callback preference it MUST include the odata.callback preference in the
+ * Preference-Applied response header.
+ * <br />
+ * When the odata.callback preference is applied to asynchronous requests, the OData service invokes the callback
+ * endpoint once it has finished processing the request. The status monitor resource, returned in the Location header
+ * of the previously returned 202 Accepted response, can then be used to retrieve the results of the asynchronously
+ * executed request.
+ * <br />
+ * When the odata.callback preference is specified on a GET request to a delta link and there are no changes
+ * available, the OData service returns a 202 Accepted response with a Location header specifying the delta link to be
+ * used to check for future updates. The OData service then invokes the specified callback endpoint once new changes
+ * become available.
+ * <br />
+ * Combining respond-async, odata.callback and odata.track-changes preferences on a GET request to a delta-link might
+ * influence the response in a couple of ways.
+ * <ul>
+ * <li>If the service processes the request synchronously, and no updates are available, then the response is the same
+ * as if the respond-async hadn’t been specified and results in a response as described above.</li>
+ * <li>If the service processes the request asynchronously, then it responds with a 202 Accepted response specifying
+ * the URL to the status monitor resource as it would have with any other asynchronous request. Once the service has
+ * finished processing the asynchronous request to the delta link resource, if changes are available it invokes the
+ * specified callback endpoint. If no changes are available, the service SHOULD wait to notify the client until
+ * changes are available. Once notified, the client uses the status monitor resource from the Location header of the
+ * previously returned 202 Accepted response to retrieve the results. In case no updates were available after
+ * processing the initial request, the result will contain no updates and the client can use the delta-link contained
+ * in the result to retrieve the updates that have since become available.</li>
+ * </ul>
+ * <br />
+ * If the consumer specifies the same URL as callback endpoint in multiple requests, the service MAY collate them into
+ * a single notification once additional data is available for any of the requests. However, the consumer MUST be
+ * prepared to deal with receiving up to as many notifications as it requested.
+ * <br /><br />
+ * Example: using a HTTP callback endpoint to receive notification
+ * <br /><br />
+ * Prefer: odata.callback; url="http://myserver/notfication/token/12345"
+ * <br/><br/>
+ * Supported by OData version 4.0 only.
+ *
+ * @see HeaderName#prefer
+ * @return preference.
+ */
+ public String callback(final String url) {
+ return PreferenceNames.callback.isSupportedBy(serviceVersion).toString() + ";url=\"" + url + "\"";
+ }
+
+ /**
+ * The odata.continue-on-error preference on a batch request is used to request that, upon encountering a request
+ * within the batch that returns an error, the service return the error for that request and continue processing
+ * additional requests within the batch. The syntax of the odata.continue-on-error preference is specified in
+ * [OData-ABNF].
+ * <br />
+ * If not specified, upon encountering an error the service MUST return the error within the batch and stop processing
+ * additional requests within the batch.
+ * <br />
+ * A service MAY specify the support for the odata.continue-on-error preference using an annotation with term
+ * Capabilities.BatchContinueOnErrorSupported, see [OData-VocCap].
+ * <br/><br/>
+ * Supported by OData version 4.0 only.
+ *
+ * @see HeaderName#prefer
+ * @return preference.
+ */
+ public String continueOnError() {
+ return PreferenceNames.callback.isSupportedBy(serviceVersion).toString();
+ }
+
+ /**
+ * The odata.include-annotations preference in a request for data or metadata is used to specify the set of
+ * annotations the client requests to be included, where applicable, in the response.
+ * <br/>
+ * The value of the odata.include-annotations preference is a comma-separated list of namespaces or namespace
+ * qualified term names to include or exclude, with "*" representing all. The full syntax of the
+ * odata.include-annotations preference is defined in [OData-ABNF].
+ * <br/>
+ * The most specific identifier always takes precedence. If the same identifier value is requested to both be excluded
+ * and included the behavior is undefined; the service MAY return or omit the specified vocabulary but MUST NOT raise
+ * an exception.
+ * <br/><br/>
+ * Example 1: a Prefer header requesting all annotations within a metadata document to be returned
+ * <br/><br/>
+ * Prefer: odata.include-annotations="*"
+ * <br/><br/>
+ * Example 2: a Prefer header requesting that no annotations are returned
+ * <br/><br/>
+ * Prefer: odata.include-annotations="-*"
+ * <br/><br/>
+ * Example 3: a Prefer header requesting that all annotations defined under the "display" namespace (recursively) be
+ * returned
+ * <br/><br/>
+ * Prefer: odata.include-annotations="display.*"
+ * <br/><br/>
+ * Example 4: a Prefer header requesting that the annotation with the term name subject within the display namespace
+ * be returned if applied
+ * <br/><br/>
+ * Prefer: odata.include-annotations="display.subject"
+ * <br/><br/>
+ * The odata.include-annotations preference is only a hint to the service. The service MAY ignore the preference and
+ * is free to decide whether or not to return annotations not specified in the odata.include-annotations preference.
+ * <br/>
+ * In the case that the client has specified the odata.include-annotations preference in the request, the service
+ * SHOULD include a Preference-Applied response header containing the odata.include-annotations preference to specify
+ * the annotations actually included, where applicable, in the response. This value may differ from the annotations
+ * requested in the Prefer header of the request.
+ * <br/><br/>
+ * Supported by OData version 4.0 only.
+ *
+ * @see HeaderName#prefer
+ * @return preference.
+ */
+ public String includeAnnotations(final String value) {
+ return PreferenceNames.includeAnnotations.isSupportedBy(serviceVersion).toString() + "=" + value;
+ }
+
+ /**
+ * The odata.maxpagesize preference is used to request that each collection within the response contain no more than
+ * the number of items specified as the positive integer value of this preference. The syntax of the odata.maxpagesize
+ * preference is specified in [OData-ABNF].
+ * <br/><br/>
+ * Example: a request for customers and their orders would result in a response containing one collection with
+ * customer entities and for every customer a separate collection with order entities. The client could specify
+ * <br/>
+ * odata.maxpagesize=50
+ * <br/>in order to request that each page of results contain a maximum of 50 customers, each with a maximum of 50
+ * orders.
+ * <br/><br/>
+ * If a collection within the result contains more than the specified odata.maxpagesize, the collection SHOULD be a
+ * partial set of the results with a next link to the next page of results. The client MAY specify a different value
+ * for this preference with every request following a next link.
+ * <br/>
+ * In the example given above, the result page should include a next link for the customer collection, if there are
+ * more than 50 customers, and additional next links for all returned orders collections with more than 50 entities.
+ * <br/>
+ * If the client has specified the odata.maxpagesize preference in the request, and the service limits the number of
+ * items in collections within the response through server-driven paging, the service MAY include a Preference-Applied
+ * response header containing the odata.maxpagesize preference and the maximum page size applied. This value may
+ * differ from the value requested by the client.
+ * <br/><br/>
+ * Supported by OData version 4.0 only.
+ *
+ * @see HeaderName#prefer
+ * @return preference.
+ */
+ public String maxPageSize(final int size) {
+ return PreferenceNames.maxPageSize.isSupportedBy(serviceVersion).toString() + "=" + size;
+ }
+
+ /**
+ * The odata.track-changes preference is used to request that the service return a delta link that can subsequently be
+ * used to obtain changes (deltas) to this result. The syntax of the odata.track-changes preference is specified in
+ * [OData-ABNF].
+ * <br />
+ * For paged results, the preference MUST be specified on the initial request. Services MUST ignore the
+ * odata.track-changes preference if applied to the next link.
+ * <br />
+ * The delta link MUST NOT be returned prior to the final page of results.
+ * <br />
+ * The service includes a Preference-Applied response header in the first page of the response containing the
+ * odata.track-changes preference to signal that changes are being tracked.
+ * <br />
+ * A service MAY specify the support for the odata.track-changes preference using an annotation with term
+ * Capabilities.ChangeTrackingSupport, see [OData-VocCap].
+ * <br/><br/>
+ * Supported by OData version 4.0 only.
+ *
+ * @see HeaderName#prefer
+ * @return preference.
+ */
+ public String trackChanges() {
+ return PreferenceNames.trackChanges.isSupportedBy(serviceVersion).toString();
+ }
+
+ /**
+ * The respond-async preference, as defined in [HTTP-Prefer], allows clients to request that the service process the
+ * request asynchronously.
+ * <br/>
+ * If the client has specified respond-async in the request, the service MAY process the request asynchronously and
+ * return a 202 Accepted response.
+ * <br/>
+ * The respond-async preference MAY be used for batch requests, but the service MUST ignore the respond-async
+ * preference for individual requests within a batch request.
+ * <br/>
+ * In the case that the service applies the respond-async preference it MUST include a Preference-Applied response
+ * header containing the respond-async preference.
+ * <br/>
+ * A service MAY specify the support for the respond-async preference using an annotation with term
+ * Capabilities.AsynchronousRequestsSupported, see [OData-VocCap].
+ * <br/><br/>
+ * Example: a service receiving the following header might choose to respond
+ * <ul>
+ * <li>asynchronously if the synchronous processing of the request will take longer than 10 seconds</li>
+ * <li>synchronously after 5 seconds</li>
+ * <li>asynchronously (ignoring the wait preference)</li>
+ * <li>synchronously after 15 seconds (ignoring respond-async preference and the wait preference)</li>
+ * </ul>
+ * <br/>
+ * Prefer: respond-async, wait=10
+ * <br/><br/>
+ * Supported by OData version 4.0 only.
+ *
+ * @see HeaderName#prefer
+ * @return preference.
+ */
+ public String respondAsync() {
+ return PreferenceNames.respondAsync.isSupportedBy(serviceVersion).toString();
+ }
+
+ /**
+ * The wait preference, as defined in [HTTP-Prefer], is used to establish an upper bound on the length of time, in
+ * seconds, the client is prepared to wait for the service to process the request synchronously once it has been
+ * received.
+ * <br/>
+ * If the respond-async preference is also specified, the client requests that the service respond asynchronously
+ * after the specified length of time.
+ * <br/>
+ * If the respond-async preference has not been specified, the service MAY interpret the wait as a request to timeout
+ * after the specified period of time.
+ * <br/><br/>
+ * Supported by OData version 4.0 only.
+ *
+ * @see HeaderName#prefer
+ * @return preference.
+ */
+ public String wait(final int value) {
+ return PreferenceNames.wait.isSupportedBy(serviceVersion).toString() + "=" + value;
+ }
+
+ /**
+ * The return=representation and return=minimal preferences are defined in [HTTP-Prefer],
+ * <br/>
+ * In OData, return=representation or return=minimal is defined for use with a POST, PUT, or PATCH Data Modification
+ * Request other than to a stream property, or to an Action Request. Specifying a preference of return=representation
+ * or return=minimal in a GET or DELETE request, or any request to a stream property, SHOULD return a 4xx Client
+ * Error.
+ * <br/>
+ * A preference of return=representation or return=minimal is allowed on an individual Data Modification Request or
+ * Action Request within a batch, subject to the same restrictions, but SHOULD return a 4xx Client Error if specified
+ * on the batch request itself.
+ * <br/>
+ * A preference of return=minimal requests that the service invoke the request but does not return content in the
+ * response. The service MAY apply this preference by returning 204 No Content in which case it MAY include a
+ * Preference-Applied response header containing the return=minimal preference.
+ * <br/>
+ * A preference of return=representation requests that the service invokes the request and returns the modified
+ * entity. The service MAY apply this preference by returning the successfully modified resource in the body of the
+ * response, formatted according to the rules specified for the requested format. In this case the service MAY include
+ * a Preference-Applied response header containing the return=representation preference.
+ * <br/><br/>
+ * Supported by OData version 4.0 only.
+ *
+ * @see HeaderName#prefer
+ * @return preference.
+ */
+ public String returnMinimal() {
+ return PreferenceNames.odataReturn.isSupportedBy(serviceVersion).toString() + "=minimal";
+ }
+
+ /**
+ * The return=representation and return=minimal preferences are defined in [HTTP-Prefer],
+ * <br/>
+ * In OData, return=representation or return=minimal is defined for use with a POST, PUT, or PATCH Data Modification
+ * Request other than to a stream property, or to an Action Request. Specifying a preference of return=representation
+ * or return=minimal in a GET or DELETE request, or any request to a stream property, SHOULD return a 4xx Client
+ * Error.
+ * <br/>
+ * A preference of return=representation or return=minimal is allowed on an individual Data Modification Request or
+ * Action Request within a batch, subject to the same restrictions, but SHOULD return a 4xx Client Error if specified
+ * on the batch request itself.
+ * <br/>
+ * A preference of return=minimal requests that the service invoke the request but does not return content in the
+ * response. The service MAY apply this preference by returning 204 No Content in which case it MAY include a
+ * Preference-Applied response header containing the return=minimal preference.
+ * <br/>
+ * A preference of return=representation requests that the service invokes the request and returns the modified
+ * entity. The service MAY apply this preference by returning the successfully modified resource in the body of the
+ * response, formatted according to the rules specified for the requested format. In this case the service MAY include
+ * a Preference-Applied response header containing the return=representation preference.
+ * <br/><br/>
+ * Supported by OData version 4.0 only.
+ *
+ * @see HeaderName#prefer
+ * @return preference.
+ */
+ public String returnRepresentation() {
+ return PreferenceNames.odataReturn.isSupportedBy(serviceVersion).toString() + "=representation";
+ }
+
+ private static enum PreferenceNames {
+
+ returnContent("return-content", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
+ returnNoContent("return-no-content", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
+ keyAsSegment("KeyAsSegment", Arrays.asList(ODataServiceVersion.V30, ODataServiceVersion.V40)),
+ allowEntityReferences("odata.allow-entityreferences", Arrays.asList(ODataServiceVersion.V40)),
+ callback("odata.callback", Arrays.asList(ODataServiceVersion.V40)),
+ continueOnError("odata.continue-on-error", Arrays.asList(ODataServiceVersion.V40)),
+ includeAnnotations("odata.include-annotations", Arrays.asList(ODataServiceVersion.V40)),
+ maxPageSize("odata.maxpagesize", Arrays.asList(ODataServiceVersion.V40)),
+ trackChanges("odata.track-changes", Arrays.asList(ODataServiceVersion.V40)),
+ respondAsync("respond-async", Arrays.asList(ODataServiceVersion.V40)),
+ wait("wait", Arrays.asList(ODataServiceVersion.V40)),
+ odataReturn("return", Arrays.asList(ODataServiceVersion.V40));
+
+ private final String preferenceName;
+
+ private final List<ODataServiceVersion> supportedVersions;
+
+ private PreferenceNames(final String preferenceName, final List<ODataServiceVersion> supportedVersions) {
+ this.preferenceName = preferenceName;
+ this.supportedVersions = supportedVersions;
+ }
+
+ final PreferenceNames isSupportedBy(final ODataServiceVersion serviceVersion) {
+ if (!supportedVersions.contains(serviceVersion)) {
+ throw new ODataRuntimeException("Unsupported header " + this.toString());
+ }
+
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return preferenceName;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataRequest.java
index 8ea098c..e9a2c90 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataRequest.java
@@ -21,16 +21,20 @@ package org.apache.olingo.client.api.communication.request;
import java.io.InputStream;
import java.net.URI;
import java.util.Collection;
+import org.apache.olingo.client.api.communication.header.HeaderName;
import org.apache.olingo.client.api.http.HttpMethod;
/**
* Abstract representation of an OData request. Get instance by using factories.
*
- * @see CUDRequestFactory
- * @see RetrieveRequestFactory
- * @see BatchRequestFactory
- * @see InvokeRequestFactory
- * @see StreamedRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.cud.v4.CUDRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.batch.v4.BatchRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.invoke.v4.InvokeRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.streamed.v4.StreamedRequestFactory
*/
public interface ODataRequest {
@@ -176,6 +180,16 @@ public interface ODataRequest {
ODataRequest addCustomHeader(final String name, final String value);
/**
+ * Adds a custom OData request header. The method fails in case of the header name is not supported by the current
+ * working version.
+ *
+ * @param name header name.
+ * @param value header value.
+ * @return current object
+ */
+ ODataRequest addCustomHeader(final HeaderName name, final String value);
+
+ /**
* Gets byte array representation of the full request header.
*
* @return full request header.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/SegmentType.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/SegmentType.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/SegmentType.java
index a3e5a15..5da7f09 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/SegmentType.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/SegmentType.java
@@ -34,6 +34,7 @@ public enum SegmentType {
NAVIGATION,
DERIVED_ENTITY_TYPE,
VALUE("$value"),
+ COUNT("$count"),
BOUND_OPERATION,
UNBOUND_OPERATION,
METADATA("$metadata"),
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v3/URIBuilder.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v3/URIBuilder.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v3/URIBuilder.java
index 72a0c03..d81edbf 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v3/URIBuilder.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v3/URIBuilder.java
@@ -42,8 +42,7 @@ public interface URIBuilder extends CommonURIBuilder<URIBuilder> {
*
* @param inlineCount value
* @return current URIBuilder instance
- * @see QueryOption#INLINECOUNT
+ * @see org.apache.olingo.client.api.uri.QueryOption#INLINECOUNT
*/
URIBuilder inlineCount(InlineCount inlineCount);
-
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v4/URIBuilder.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v4/URIBuilder.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v4/URIBuilder.java
index 5fc8a1d..7aed3c0 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v4/URIBuilder.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/uri/v4/URIBuilder.java
@@ -18,6 +18,7 @@
*/
package org.apache.olingo.client.api.uri.v4;
+import java.util.Map;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
public interface URIBuilder extends CommonURIBuilder<URIBuilder> {
@@ -65,7 +66,7 @@ public interface URIBuilder extends CommonURIBuilder<URIBuilder> {
*
* @param idValue opaque token.
* @return current URIBuilder instance
- * @see QueryOption#ID
+ * @see org.apache.olingo.client.api.uri.QueryOption#ID
*/
URIBuilder id(String idValue);
@@ -74,7 +75,7 @@ public interface URIBuilder extends CommonURIBuilder<URIBuilder> {
*
* @param value true or false
* @return current URIBuilder instance
- * @see QueryOption#COUNT
+ * @see org.apache.olingo.client.api.uri.QueryOption#COUNT
*/
URIBuilder count(boolean value);
@@ -83,7 +84,19 @@ public interface URIBuilder extends CommonURIBuilder<URIBuilder> {
*
* @param expression search expression
* @return current URIBuilder instance
- * @see QueryOption#SEARCH
+ * @see org.apache.olingo.client.api.uri.QueryOption#SEARCH
*/
URIBuilder search(String expression);
+
+ /**
+ * The set of expanded entities can be refined through the application of expand options, expressed as a
+ * semicolon-separated list of system query options, enclosed in parentheses, see [OData-URL].
+ *
+ * @param expandItem item to be expanded.
+ * @param options System query options. Allowed query options are: $filter, $select, $orderby, $skip, $top, $count,
+ * $search, $expand, and $levels.
+ * @return current URIBuilder instance.
+ * @see org.apache.olingo.client.api.uri.QueryOption#EXPAND
+ */
+ URIBuilder expandWithOptions(String expandItem, Map<String, Object> options);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
index 3e6c1bb..0a8c495 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
@@ -38,14 +38,10 @@ import org.apache.olingo.client.api.v3.Configuration;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.ODataServerErrorException;
import org.apache.olingo.client.api.communication.header.HeaderName;
-import org.apache.olingo.client.api.communication.header.ODataHeaderValues;
import org.apache.olingo.client.api.communication.header.ODataHeaders;
+import org.apache.olingo.client.api.communication.header.ODataPreferences;
import org.apache.olingo.client.api.communication.request.ODataRequest;
import org.apache.olingo.client.api.communication.request.ODataStreamer;
-import org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory;
-import org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory;
-import org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory;
-import org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory;
import org.apache.olingo.client.api.communication.response.ODataResponse;
import org.apache.olingo.commons.api.format.Format;
import org.apache.olingo.client.api.http.HttpClientException;
@@ -66,10 +62,14 @@ import org.slf4j.LoggerFactory;
*
* @param <T> Accepted content-type formats by the request in object.
*
- * @see CUDRequestFactory
- * @see BatchRequestFactory
- * @see InvokeRequestFactory
- * @see StreamedRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.cud.v4.CUDRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.batch.v4.BatchRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.invoke.v4.InvokeRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.streamed.v4.StreamedRequestFactory
*/
public class ODataRequestImpl<T extends Format> implements ODataRequest {
@@ -254,6 +254,15 @@ public class ODataRequestImpl<T extends Format> implements ODataRequest {
* {@inheritDoc}
*/
@Override
+ public ODataRequest addCustomHeader(final HeaderName name, final String value) {
+ odataHeaders.setHeader(name, value);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public String getAccept() {
final String acceptHead = odataHeaders.getHeader(HeaderName.accept);
return StringUtils.isBlank(acceptHead) ? getDefaultFormat().toString(odataClient.getServiceVersion()) : acceptHead;
@@ -384,7 +393,8 @@ public class ODataRequestImpl<T extends Format> implements ODataRequest {
if (odataClient.getServiceVersion() == ODataServiceVersion.V30
&& ((Configuration) odataClient.getConfiguration()).isKeyAsSegment()) {
addCustomHeader(
- HeaderName.dataServiceUrlConventions.toString(), ODataHeaderValues.keyAsSegment);
+ HeaderName.dataServiceUrlConventions.toString(),
+ new ODataPreferences(odataClient.getServiceVersion()).keyAsSegment());
}
// Add all available headers
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java
index 143aed8..8594f90 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java
@@ -57,7 +57,7 @@ public class JSONServiceDocumentDeserializer extends ODataJacksonDeserializer<Ab
setMetadataContext(tree.get(Constants.JSON_CONTEXT).textValue());
}
- for (final Iterator<JsonNode> itor = tree.get(Constants.JSON_VALUE).elements(); itor.hasNext();) {
+ for (final Iterator<JsonNode> itor = tree.get(Constants.VALUE).elements(); itor.hasNext();) {
final JsonNode node = itor.next();
final ServiceDocumentItemImpl item = new ServiceDocumentItemImpl();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
index 44e7ad4..bdc3536 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
@@ -87,21 +87,22 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
}
@Override
- public Feed getFeed(final ODataEntitySet feed, final Class<? extends Feed> reference) {
- final Feed feedResource = ResourceFactory.newFeed(reference);
+ public Feed getFeed(final ODataEntitySet entitySet, final Class<? extends Feed> reference) {
+ final Feed feed = ResourceFactory.newFeed(reference);
- feedResource.setCount(feed.getCount());
+ feed.setContextURL(entitySet.getContextURL());
+ feed.setCount(entitySet.getCount());
- final URI next = feed.getNext();
+ final URI next = entitySet.getNext();
if (next != null) {
- feedResource.setNext(next);
+ feed.setNext(next);
}
- for (ODataEntity entity : feed.getEntities()) {
- feedResource.getEntries().add(getEntry(entity, ResourceFactory.entryClassForFeed(reference)));
+ for (ODataEntity entity : entitySet.getEntities()) {
+ feed.getEntries().add(getEntry(entity, ResourceFactory.entryClassForFeed(reference)));
}
- return feedResource;
+ return feed;
}
@Override
@@ -112,6 +113,9 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
@Override
public Entry getEntry(final ODataEntity entity, final Class<? extends Entry> reference, final boolean setType) {
final Entry entry = ResourceFactory.newEntry(reference);
+
+ entry.setContextURL(entity.getContextURL());
+ entry.setId(entity.getReference());
entry.setType(entity.getName());
// -------------------------------------------------------------
@@ -269,13 +273,15 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
}
final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;
-
+
final URI next = resource.getNext();
final ODataEntitySet entitySet = next == null
? client.getObjectFactory().newEntitySet()
: client.getObjectFactory().newEntitySet(URIUtils.getURI(base, next.toASCIIString()));
+ entitySet.setContextURL(resource.getContextURL());
+
if (resource.getCount() != null) {
entitySet.setCount(resource.getCount());
}
@@ -283,7 +289,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
for (Entry entryResource : resource.getEntries()) {
entitySet.addEntity(getODataEntity(entryResource));
}
-
+
return entitySet;
}
@@ -306,16 +312,19 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
final ODataEntity entity = resource.getSelfLink() == null
? client.getObjectFactory().newEntity(resource.getType())
: client.getObjectFactory().newEntity(resource.getType(),
- URIUtils.getURI(base, resource.getSelfLink().getHref()));
+ URIUtils.getURI(base, resource.getSelfLink().getHref()));
+
+ entity.setContextURL(resource.getContextURL());
+ entity.setReference(resource.getId());
if (StringUtils.isNotBlank(resource.getETag())) {
entity.setETag(resource.getETag());
}
-
+
if (resource.getEditLink() != null) {
entity.setEditLink(URIUtils.getURI(base, resource.getEditLink().getHref()));
}
-
+
for (Link link : resource.getAssociationLinks()) {
entity.addLink(client.getObjectFactory().newAssociationLink(link.getTitle(), base, link.getHref()));
}
@@ -327,16 +336,16 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
if (inlineEntry == null && inlineFeed == null) {
entity.addLink(
client.getObjectFactory().newEntityNavigationLink(link.getTitle(), base, link.getHref()));
- } else if (inlineFeed == null) {
+ } else if (inlineEntry != null) {
entity.addLink(client.getObjectFactory().newInlineEntity(
link.getTitle(), base, link.getHref(),
getODataEntity(inlineEntry,
- inlineEntry.getBaseURI() == null ? base : inlineEntry.getBaseURI())));
+ inlineEntry.getBaseURI() == null ? base : inlineEntry.getBaseURI())));
} else {
entity.addLink(client.getObjectFactory().newInlineEntitySet(
link.getTitle(), base, link.getHref(),
getODataEntitySet(inlineFeed,
- inlineFeed.getBaseURI() == null ? base : inlineFeed.getBaseURI())));
+ inlineFeed.getBaseURI() == null ? base : inlineFeed.getBaseURI())));
}
}
@@ -374,16 +383,16 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
value = client.getPrimitiveValueBuilder().
setText(resource.getValue().asSimple().get()).
setType(resource.getType() == null
- ? null
- : EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
+ ? null
+ : EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
} else if (resource.getValue().isGeospatial()) {
value = client.getGeospatialValueBuilder().
setValue(resource.getValue().asGeospatial().get()).
setType(resource.getType() == null
- || EdmPrimitiveTypeKind.Geography.getFullQualifiedName().toString().equals(resource.getType())
- || EdmPrimitiveTypeKind.Geometry.getFullQualifiedName().toString().equals(resource.getType())
- ? null
- : EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
+ || EdmPrimitiveTypeKind.Geography.getFullQualifiedName().toString().equals(resource.getType())
+ || EdmPrimitiveTypeKind.Geometry.getFullQualifiedName().toString().equals(resource.getType())
+ ? null
+ : EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), resource.getType())).build();
} else if (resource.getValue().isComplex()) {
value = new ODataComplexValue(resource.getType());
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java
index 2beecb3..732789c 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/AbstractURIBuilder.java
@@ -21,6 +21,7 @@ package org.apache.olingo.client.core.uri;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -60,9 +61,7 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
public String getValue() {
return value;
}
-
}
-
protected final List<Segment> segments = new ArrayList<Segment>();
/**
@@ -111,17 +110,11 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
@Override
public UB appendKeySegment(final Map<String, Object> segmentValues) {
- if (segmentValues == null || segmentValues.isEmpty()) {
+ final String key = buildMultiKeySegment(segmentValues, true);
+ if (StringUtils.isEmpty(key)) {
segments.add(new Segment(SegmentType.KEY, noKeysWrapper()));
} else {
- final StringBuilder keyBuilder = new StringBuilder().append('(');
- for (Map.Entry<String, Object> entry : segmentValues.entrySet()) {
- keyBuilder.append(entry.getKey()).append('=').append(URIUtils.escape(entry.getValue()));
- keyBuilder.append(',');
- }
- keyBuilder.deleteCharAt(keyBuilder.length() - 1).append(')');
-
- segments.add(new Segment(SegmentType.KEY, keyBuilder.toString()));
+ segments.add(new Segment(SegmentType.KEY, key));
}
return getThis();
@@ -179,7 +172,14 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
@Override
public UB expand(final String... expandItems) {
- return addQueryOption(QueryOption.EXPAND, StringUtils.join(expandItems, ","));
+ final List<String> values = new ArrayList<String>();
+ if (queryOptions.containsKey(QueryOption.EXPAND.toString())) {
+ values.add(queryOptions.get(QueryOption.EXPAND.toString()));
+ }
+
+ values.addAll(Arrays.asList(expandItems));
+
+ return addQueryOption(QueryOption.EXPAND, StringUtils.join(values, ","));
}
@Override
@@ -199,7 +199,14 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
@Override
public UB select(final String... selectItems) {
- return addQueryOption(QueryOption.SELECT, StringUtils.join(selectItems, ","));
+ final List<String> values = new ArrayList<String>();
+ if (queryOptions.containsKey(QueryOption.SELECT.toString())) {
+ values.add(queryOptions.get(QueryOption.SELECT.toString()));
+ }
+
+ values.addAll(Arrays.asList(selectItems));
+
+ return addQueryOption(QueryOption.SELECT, StringUtils.join(values, ","));
}
@Override
@@ -271,4 +278,19 @@ public abstract class AbstractURIBuilder<UB extends CommonURIBuilder<?>> impleme
return build().toASCIIString();
}
+ protected String buildMultiKeySegment(final Map<String, Object> segmentValues, final boolean escape) {
+ if (segmentValues == null || segmentValues.isEmpty()) {
+ return StringUtils.EMPTY;
+ } else {
+ final StringBuilder keyBuilder = new StringBuilder().append('(');
+ for (Map.Entry<String, Object> entry : segmentValues.entrySet()) {
+ keyBuilder.append(entry.getKey()).append('=').append(
+ escape ? URIUtils.escape(entry.getValue()) : entry.getValue());
+ keyBuilder.append(',');
+ }
+ keyBuilder.deleteCharAt(keyBuilder.length() - 1).append(')');
+
+ return keyBuilder.toString();
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java
index ae4284d..fa66f02 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/uri/v4/URIBuilderImpl.java
@@ -18,6 +18,7 @@
*/
package org.apache.olingo.client.core.uri.v4;
+import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.uri.QueryOption;
import org.apache.olingo.client.api.uri.SegmentType;
@@ -79,11 +80,6 @@ public class URIBuilderImpl extends AbstractURIBuilder<URIBuilder> implements UR
}
@Override
- public URIBuilder count(final boolean value) {
- return addQueryOption(QueryOption.COUNT, Boolean.toString(value));
- }
-
- @Override
public URIBuilder appendAllSegment() {
segments.add(new Segment(SegmentType.ALL, SegmentType.ALL.getValue()));
return getThis();
@@ -99,4 +95,13 @@ public class URIBuilderImpl extends AbstractURIBuilder<URIBuilder> implements UR
return addQueryOption(QueryOption.SEARCH, expression);
}
+ @Override
+ public URIBuilder count(final boolean value) {
+ return addQueryOption(QueryOption.COUNT, Boolean.toString(value));
+ }
+
+ @Override
+ public URIBuilder expandWithOptions(final String expandItem, final Map<String, Object> options) {
+ return expand(expandItem + buildMultiKeySegment(options, false));
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java
index bb12f1a..5a31e2c 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java
@@ -82,8 +82,8 @@ public class ODataClientImpl extends AbstractODataClient implements ODataClient
@Override
public ODataHeaders getVersionHeaders() {
final ODataHeadersImpl odataHeaders = new ODataHeadersImpl();
- odataHeaders.setHeader(HeaderName.maxDataServiceVersion, ODataServiceVersion.V40.toString());
- odataHeaders.setHeader(HeaderName.dataServiceVersion, ODataServiceVersion.V40.toString());
+ odataHeaders.setHeader(HeaderName.odataMaxVersion, ODataServiceVersion.V40.toString());
+ odataHeaders.setHeader(HeaderName.odataVersion, ODataServiceVersion.V40.toString());
return odataHeaders;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityCreateTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityCreateTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityCreateTestITCase.java
index 8146830..1c331e5 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityCreateTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityCreateTestITCase.java
@@ -30,7 +30,7 @@ import java.util.LinkedHashMap;
import java.util.Set;
import org.apache.http.entity.ContentType;
import org.apache.olingo.client.api.communication.header.HeaderName;
-import org.apache.olingo.client.api.communication.header.ODataHeaderValues;
+import org.apache.olingo.client.api.communication.header.ODataPreferences;
import org.apache.olingo.client.api.communication.request.UpdateType;
import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest;
@@ -229,11 +229,11 @@ public class EntityCreateTestITCase extends AbstractTestITCase {
final ODataEntityCreateRequest createReq = client.getCUDRequestFactory().getEntityCreateRequest(
client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Customer").build(), original);
- createReq.setPrefer(ODataHeaderValues.preferReturnNoContent);
+ createReq.setPrefer(new ODataPreferences(client.getServiceVersion()).returnNoContent());
final ODataEntityCreateResponse createRes = createReq.execute();
assertEquals(204, createRes.getStatusCode());
- assertEquals(ODataHeaderValues.preferReturnNoContent,
+ assertEquals(new ODataPreferences(client.getServiceVersion()).returnNoContent(),
createRes.getHeader(HeaderName.preferenceApplied).iterator().next());
try {
@@ -260,7 +260,7 @@ public class EntityCreateTestITCase extends AbstractTestITCase {
client.getCUDRequestFactory().getEntityCreateRequest(uriBuilder.build(), original);
createReq.setFormat(ODataPubFormat.JSON_FULL_METADATA);
createReq.setContentType(ContentType.APPLICATION_ATOM_XML.getMimeType());
- createReq.setPrefer(ODataHeaderValues.preferReturnContent);
+ createReq.setPrefer(new ODataPreferences(client.getServiceVersion()).returnContent());
try {
final ODataEntityCreateResponse createRes = createReq.execute();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityUpdateTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityUpdateTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityUpdateTestITCase.java
index 129f086..8a9f93f 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityUpdateTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityUpdateTestITCase.java
@@ -26,7 +26,7 @@ import java.net.URI;
import java.util.LinkedHashMap;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.header.HeaderName;
-import org.apache.olingo.client.api.communication.header.ODataHeaderValues;
+import org.apache.olingo.client.api.communication.header.ODataPreferences;
import org.apache.olingo.client.api.communication.request.UpdateType;
import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
@@ -210,11 +210,11 @@ public class EntityUpdateTestITCase extends AbstractTestITCase {
@Test
public void updateReturnContent() throws EdmPrimitiveTypeException {
final ODataEntityUpdateRequest req = buildMultiKeyUpdateReq(client.getConfiguration().getDefaultPubFormat());
- req.setPrefer(ODataHeaderValues.preferReturnContent);
+ req.setPrefer(new ODataPreferences(client.getServiceVersion()).returnContent());
final ODataEntityUpdateResponse res = req.execute();
assertEquals(200, res.getStatusCode());
- assertEquals(ODataHeaderValues.preferReturnContent,
+ assertEquals(new ODataPreferences(client.getServiceVersion()).returnContent(),
res.getHeader(HeaderName.preferenceApplied).iterator().next());
assertNotNull(res.getBody());
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyValueTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyValueTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyValueTestITCase.java
index b8dd0a8..3660cad 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyValueTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyValueTestITCase.java
@@ -100,11 +100,11 @@ public class PropertyValueTestITCase extends AbstractTestITCase {
req.setAccept("application/json");
ODataRetrieveResponse<ODataEntity> res = req.execute();
assertEquals(200, res.getStatusCode());
- ODataEntity entitySet = res.getBody();
- assertNotNull(entitySet);
+ ODataEntity entity = res.getBody();
+ assertNotNull(entity);
assertEquals("fi653p3+MklA/LdoBlhWgnMTUUEo8tEgtbMXnF0a3CUNL9BZxXpSRiD9ebTnmNR0zWPjJ"
+ "VIDx4tdmCnq55XrJh+RW9aI/b34wAogK3kcORw=",
- entitySet.getProperties().get(0).getValue().toString());
+ entity.getProperties().get(0).getValue().toString());
}
@Test(expected = ODataClientErrorException.class)
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java
new file mode 100644
index 0000000..a96384f
--- /dev/null
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java
@@ -0,0 +1,280 @@
+/*
+ * 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.client.core.it.v4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
+import org.apache.olingo.client.api.communication.response.ODataRawResponse;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.commons.api.domain.ODataEntity;
+import org.apache.olingo.commons.api.domain.ODataEntitySet;
+import org.apache.olingo.commons.api.domain.ODataInlineEntity;
+import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
+import org.apache.olingo.commons.api.domain.ODataLink;
+import org.apache.olingo.commons.api.domain.ODataProperty;
+import org.apache.olingo.commons.api.format.ODataPubFormat;
+import org.apache.olingo.client.api.uri.CommonURIBuilder;
+import org.apache.olingo.commons.core.op.ResourceFactory;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * This is the unit test class to check entity retrieve operations.
+ */
+public class EntityRetrieveTestITCase extends AbstractTestITCase {
+
+ protected String getServiceRoot() {
+ return testStaticServiceRootURL;
+ }
+
+ private void withInlineEntry(final ODataPubFormat format) {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
+ appendEntitySetSegment("Customers").appendKeySegment(1).expand("Company");
+
+ final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
+ req.setFormat(format);
+
+ final ODataRetrieveResponse<ODataEntity> res = req.execute();
+ final ODataEntity entity = res.getBody();
+
+ assertNotNull(entity);
+ assertEquals("#Microsoft.Test.OData.Services.ODataWCFService.Customer", entity.getName());
+ assertEquals(getServiceRoot() + "/Customers(PersonID=1)", entity.getEditLink().toASCIIString());
+
+ assertEquals(3, entity.getNavigationLinks().size());
+ assertTrue(entity.getAssociationLinks().isEmpty());
+
+ boolean found = false;
+
+ for (ODataLink link : entity.getNavigationLinks()) {
+ if (link instanceof ODataInlineEntity) {
+ final ODataEntity inline = ((ODataInlineEntity) link).getEntity();
+ assertNotNull(inline);
+
+ debugEntry(client.getBinder().getEntry(
+ inline, ResourceFactory.entryClassForFormat(format == ODataPubFormat.ATOM)), "Just read");
+
+ final List<ODataProperty> properties = inline.getProperties();
+ assertEquals(5, properties.size());
+
+ assertTrue(properties.get(0).getName().equals("CompanyID")
+ || properties.get(1).getName().equals("CompanyID")
+ || properties.get(2).getName().equals("CompanyID")
+ || properties.get(3).getName().equals("CompanyID")
+ || properties.get(4).getName().equals("CompanyID"));
+ assertTrue(properties.get(0).getValue().toString().equals("0")
+ || properties.get(1).getValue().toString().equals("0")
+ || properties.get(2).getValue().toString().equals("0")
+ || properties.get(3).getValue().toString().equals("0")
+ || properties.get(4).getValue().toString().equals("0"));
+
+ found = true;
+ }
+ }
+
+ assertTrue(found);
+ }
+
+ @Test
+ public void withInlineEntryFromAtom() {
+ withInlineEntry(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void withInlineEntryFromJSON() {
+ // this needs to be full, otherwise there is no mean to recognize links
+ withInlineEntry(ODataPubFormat.JSON_FULL_METADATA);
+ }
+
+ private void withInlineFeed(final ODataPubFormat format) {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
+ appendEntitySetSegment("Customers").appendKeySegment(1).expand("Orders");
+
+ final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
+ req.setFormat(format);
+
+ final ODataRetrieveResponse<ODataEntity> res = req.execute();
+ final ODataEntity entity = res.getBody();
+ assertNotNull(entity);
+
+ boolean found = false;
+
+ for (ODataLink link : entity.getNavigationLinks()) {
+ if (link instanceof ODataInlineEntitySet) {
+ final ODataEntitySet inline = ((ODataInlineEntitySet) link).getEntitySet();
+ assertNotNull(inline);
+
+ debugFeed(client.getBinder().getFeed(inline, ResourceFactory.feedClassForFormat(
+ format == ODataPubFormat.ATOM)), "Just read");
+
+ found = true;
+ }
+ }
+
+ assertTrue(found);
+ }
+
+ @Test
+ public void withInlineFeedFromAtom() {
+ withInlineFeed(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void withInlineFeedFromJSON() {
+ // this needs to be full, otherwise there is no mean to recognize links
+ withInlineFeed(ODataPubFormat.JSON_FULL_METADATA);
+ }
+
+ private void rawRequest(final ODataPubFormat format) {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
+ appendEntitySetSegment("People").appendKeySegment(5);
+
+ final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
+ req.setFormat(format.toString(client.getServiceVersion()));
+
+ final ODataRawResponse res = req.execute();
+ assertNotNull(res);
+
+ final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
+ assertNull(entitySet);
+
+ final ODataEntity entity = res.getBodyAs(ODataEntity.class);
+ assertTrue(entity.getReference().endsWith("/StaticService/V40/Static.svc/People(5)"));
+ }
+
+ @Test
+ public void rawRequestAsAtom() {
+ rawRequest(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void rawRequestAsJSON() {
+ // this needs to be full, otherwise actions will not be provided
+ rawRequest(ODataPubFormat.JSON_FULL_METADATA);
+ }
+
+ private void multiKey(final ODataPubFormat format) throws EdmPrimitiveTypeException {
+ final LinkedHashMap<String, Object> multiKey = new LinkedHashMap<String, Object>();
+ multiKey.put("ProductID", "6");
+ multiKey.put("ProductDetailID", 1);
+
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
+ appendEntitySetSegment("ProductDetails").appendKeySegment(multiKey);
+
+ final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
+ req.setFormat(format);
+
+ final ODataRetrieveResponse<ODataEntity> res = req.execute();
+ final ODataEntity entity = res.getBody();
+ assertNotNull(entity);
+ assertEquals(Integer.valueOf(1),
+ entity.getProperty("ProductDetailID").getPrimitiveValue().toCastValue(Integer.class));
+ }
+
+ @Test
+ public void multiKeyAsAtom() throws EdmPrimitiveTypeException {
+ multiKey(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void multiKeyAsJSON() throws EdmPrimitiveTypeException {
+ multiKey(ODataPubFormat.JSON_FULL_METADATA);
+ }
+
+ @Test
+ public void checkForETagAsATOM() {
+ checkForETag(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void checkForETagAsJSON() {
+ checkForETag(ODataPubFormat.JSON_FULL_METADATA);
+ }
+
+ private void checkForETag(final ODataPubFormat format) {
+ final CommonURIBuilder<?> uriBuilder =
+ client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Orders").appendKeySegment(8);
+
+ final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
+ req.setFormat(format);
+
+ final ODataRetrieveResponse<ODataEntity> res = req.execute();
+ assertEquals(200, res.getStatusCode());
+
+ final String etag = res.getEtag();
+ assertTrue(StringUtils.isNotBlank(etag));
+
+ final ODataEntity order = res.getBody();
+ assertEquals(etag, order.getETag());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ @Ignore
+ public void issue99() {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Car");
+
+ final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
+ req.setFormat(ODataPubFormat.JSON);
+
+ // this statement should cause an IllegalArgumentException bearing JsonParseException
+ // since we are attempting to parse an EntitySet as if it was an Entity
+ req.execute().getBody();
+ }
+
+ @Test
+ public void retrieveEntityReferenceAsAtom() {
+ retrieveEntityReference(ODataPubFormat.ATOM);
+ }
+
+ @Test
+ @Ignore
+ public void retrieveEntityReferenceAsJSON() {
+ retrieveEntityReference(ODataPubFormat.JSON_FULL_METADATA);
+ }
+
+ private void retrieveEntityReference(final ODataPubFormat format) {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
+ appendEntitySetSegment("Orders").appendKeySegment(8).appendNavigationSegment("CustomerForOrder").
+ appendRefSegment();
+
+ final ODataEntityRequest req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
+ req.setFormat(format);
+
+ final ODataRetrieveResponse<ODataEntity> res = req.execute();
+ assertNotNull(res);
+
+ final ODataEntity entity = res.getBody();
+ assertNotNull(entity);
+ assertTrue(entity.getReference().endsWith("/StaticService/V40/Static.svc/Customers(PersonID=1)"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
index 8455ecd..473e721 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
@@ -104,6 +104,8 @@ public class EntitySetTestITCase extends AbstractTestITCase {
assertNotNull(feed);
+ assertTrue(feed.getContextURL().toASCIIString().endsWith("$metadata#People"));
+
debugFeed(client.getBinder().getFeed(feed, ResourceFactory.feedClassForFormat(
ODataPubFormat.ATOM == format)), "Just retrieved feed");
@@ -151,5 +153,6 @@ public class EntitySetTestITCase extends AbstractTestITCase {
final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
assertNotNull(entitySet);
+ assertTrue(entitySet.getContextURL().toASCIIString().endsWith("$metadata#People"));
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/PropertyValueTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/PropertyValueTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/PropertyValueTestITCase.java
new file mode 100644
index 0000000..3a8b9e9
--- /dev/null
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/PropertyValueTestITCase.java
@@ -0,0 +1,144 @@
+/*
+ * 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.client.core.it.v4;
+
+import static org.junit.Assert.*;
+import java.io.IOException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataValueRequest;
+import org.apache.olingo.commons.api.format.ODataValueFormat;
+import org.apache.olingo.client.api.uri.CommonURIBuilder;
+import org.apache.olingo.commons.api.domain.ODataPrimitiveValue;
+import org.apache.olingo.commons.api.domain.ODataProperty;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.format.ODataPubFormat;
+import org.junit.Test;
+
+public class PropertyValueTestITCase extends AbstractTestITCase {
+
+ @Test
+ public void retrieveIntPropertyValueTest() throws EdmPrimitiveTypeException {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+ appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("PersonID").
+ appendValueSegment();
+ final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
+ req.setFormat(ODataValueFormat.TEXT);
+ assertEquals("5", req.execute().getBody().toString());
+ }
+
+ @Test
+ public void retrieveBooleanPropertyValueTest() throws EdmPrimitiveTypeException {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+ appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("IsRegistered").
+ appendValueSegment();
+ final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
+ req.setFormat(ODataValueFormat.TEXT);
+ assertEquals("true", req.execute().getBody().toString());
+ }
+
+ @Test
+ public void retrieveStringPropertyValueTest() throws EdmPrimitiveTypeException {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+ appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("FirstName").
+ appendValueSegment();
+ final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
+ req.setFormat(ODataValueFormat.TEXT);
+ assertEquals("Peter", req.execute().getBody().toString());
+ }
+
+ @Test
+ public void retrieveDatePropertyValueTest() {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+ appendEntitySetSegment("Orders").appendKeySegment(8).appendPropertySegment("OrderDate").
+ appendValueSegment();
+ final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
+ req.setFormat(ODataValueFormat.TEXT);
+ final ODataPrimitiveValue property = req.execute().getBody();
+ assertEquals("2011-03-04T16:03:57Z", property.toString());
+ }
+
+ @Test
+ public void retrieveDecimalPropertyValueTest() throws EdmPrimitiveTypeException {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+ appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("Height").
+ appendValueSegment();
+ final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
+ req.setFormat(ODataValueFormat.TEXT);
+ final ODataPrimitiveValue property = req.execute().getBody();
+ assertEquals("179", property.toString());
+ }
+
+ @Test
+ public void retrieveBinaryPropertyValueTest() throws IOException {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+ appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("PDC").
+ appendValueSegment();
+ final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
+ req.setFormat(ODataValueFormat.TEXT);
+ final ODataPrimitiveValue property = req.execute().getBody();
+ assertEquals("fi653p3+MklA/LdoBlhWgnMTUUEo8tEgtbMXnF0a3CUNL9BZxXpSRiD9ebTnmNR0zWPjJ"
+ + "VIDx4tdmCnq55XrJh+RW9aI/b34wAogK3kcORw=", property.toString());
+ }
+
+ @Test(expected = ODataClientErrorException.class)
+ public void retrieveBinaryPropertyValueTestWithAtom() throws IOException {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+ appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("PDC").
+ appendValueSegment();
+ final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
+ req.setAccept(ODataPubFormat.ATOM.toString(ODataServiceVersion.V40));
+ req.execute().getBody();
+ }
+
+ @Test(expected = ODataClientErrorException.class)
+ public void retrieveBinaryPropertyValueTestWithXML() throws IOException {
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+ appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("PDC").
+ appendValueSegment();
+ final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
+ req.setAccept(ODataFormat.XML.toString());
+ req.execute().getBody();
+ }
+
+ @Test
+ public void retrieveCollectionPropertyValueTest() {
+ CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+ appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("Numbers");
+ final ODataPropertyRequest req = client.getRetrieveRequestFactory().getPropertyRequest(uriBuilder.build());
+ req.setFormat(ODataFormat.XML);
+ final ODataProperty property = req.execute().getBody();
+ assertTrue(property.getValue().isCollection());
+ assertEquals("555-555-5555", property.getCollectionValue().iterator().next().asPrimitive().toString());
+ }
+
+ @Test
+ public void retrieveNullPropertyValueTest() {
+ CommonURIBuilder<?> uriBuilder = client.getURIBuilder(testStaticServiceRootURL).
+ appendEntitySetSegment("People").appendKeySegment(5).appendPropertySegment("MiddleName").
+ appendValueSegment();
+ final ODataValueRequest req = client.getRetrieveRequestFactory().getValueRequest(uriBuilder.build());
+ req.setFormat(ODataValueFormat.TEXT);
+ final ODataPrimitiveValue property = req.execute().getBody();
+ assertTrue(StringUtils.isBlank(property.toString()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/URIBuilderTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/URIBuilderTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/URIBuilderTest.java
index 1838cf8..98fce0a 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/URIBuilderTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/URIBuilderTest.java
@@ -104,7 +104,7 @@ public class URIBuilderTest extends AbstractTest {
public void unboundAction() throws URISyntaxException {
final URIBuilder uriBuilder = getClient().getURIBuilder(SERVICE_ROOT).
appendOperationCallSegment("ProductsByCategoryId",
- Collections.<String, Object>singletonMap("categoryId", 2));
+ Collections.<String, Object>singletonMap("categoryId", 2));
assertEquals(new org.apache.http.client.utils.URIBuilder(
SERVICE_ROOT + "/ProductsByCategoryId(categoryId=2)").build(), uriBuilder.build());
@@ -128,4 +128,22 @@ public class URIBuilderTest extends AbstractTest {
assertEquals(new org.apache.http.client.utils.URIBuilder(
SERVICE_ROOT + "/Customers/Model/Namespace.VipCustomer(1)").build(), uriBuilder.build());
}
+
+ @Test
+ public void expandMoreThenOnce() throws URISyntaxException {
+ URI uri = getClient().getURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
+ expand("Orders", "Customers").expand("Info").build();
+
+ assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products(5)").
+ addParameter("$expand", "Orders,Customers,Info").build(), uri);
+ }
+
+ @Test
+ public void selectMoreThenOnce() throws URISyntaxException {
+ URI uri = getClient().getURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Customers").appendKeySegment(5).
+ select("Name", "Surname").expand("Info").select("Gender").build();
+
+ assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Customers(5)").
+ addParameter("$select", "Name,Surname,Gender").addParameter("$expand", "Info").build(), uri);
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/URIBuilderTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/URIBuilderTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/URIBuilderTest.java
index 868b363..56ea4f7 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/URIBuilderTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/URIBuilderTest.java
@@ -20,6 +20,7 @@ package org.apache.olingo.client.core.v4;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.LinkedHashMap;
import org.apache.olingo.client.api.v4.ODataClient;
import org.apache.olingo.client.api.uri.v4.URIBuilder;
@@ -39,6 +40,22 @@ public class URIBuilderTest extends AbstractTest {
}
@Test
+ public void expandWithOptions() throws URISyntaxException {
+ URI uri = getClient().getURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
+ expandWithOptions("ProductDetails", new LinkedHashMap<String, Object>() {
+ private static final long serialVersionUID = 3109256773218160485L;
+
+ {
+ put("$expand", "ProductInfo");
+ put("$select", "Price");
+ }
+ }).expand("Orders", "Customers").build();
+
+ assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products(5)").
+ addParameter("$expand", "ProductDetails($expand=ProductInfo,$select=Price),Orders,Customers").build(), uri);
+ }
+
+ @Test
public void count() throws URISyntaxException {
URI uri = getClient().getURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").count().build();
@@ -132,5 +149,4 @@ public class URIBuilderTest extends AbstractTest {
assertEquals(new org.apache.http.client.utils.URIBuilder(
SERVICE_ROOT + "/Products").addParameter("$search", "blue OR green").build(), uriBuilder.build());
}
-
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
index b4c048f..3b5b9cc 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
@@ -72,6 +72,8 @@ public interface Constants {
public static final QName QNAME_ATTR_XML_BASE = new QName(XMLConstants.XML_NS_URI, ATTR_XML_BASE);
+ public static final String CONTEXT = "context";
+
public static final String ATTR_REL = "rel";
public static final String ATTR_TITLE = "title";
@@ -173,7 +175,7 @@ public interface Constants {
public final static String JSON_NULL = "odata.null";
- public final static String JSON_VALUE = "value";
+ public final static String VALUE = "value";
public final static String JSON_URL = "url";
@@ -192,6 +194,12 @@ public interface Constants {
// Atom stuff
public final static String ATOM_ELEM_ENTRY = "entry";
+ public final static String ATOM_ELEM_ENTRY_REF = "ref";
+
+ public final static String ATOM_ELEM_ENTRY_REF_ID = "id";
+
+ public final static QName QNAME_ATOM_ELEM_ENTRY_REF_ID = new QName(ATOM_ELEM_ENTRY_REF_ID);
+
public static final QName QNAME_ATOM_ELEM_ENTRY = new QName(NS_ATOM, ATOM_ELEM_ENTRY);
public final static String ATOM_ELEM_FEED = "feed";
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Entry.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Entry.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Entry.java
index ea73b7d..5ac0dbd 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Entry.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Entry.java
@@ -39,6 +39,21 @@ public interface Entry {
URI getBaseURI();
/**
+ * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
+ * fragment identifying the relevant portion of the metadata document.
+ *
+ * @return context URL.
+ */
+ URI getContextURL();
+
+ /**
+ * Set context URL.
+ *
+ * @param contextURL context URL.
+ */
+ void setContextURL(final URI contextURL);
+
+ /**
* Gets entry type.
*
* @return entry type.
@@ -53,13 +68,20 @@ public interface Entry {
void setType(String type);
/**
- * Gest entry ID.
+ * Gets entry ID.
*
* @return entry ID.
*/
String getId();
/**
+ * Sets entry ID.
+ *
+ * @param id entry ID.
+ */
+ void setId(String id);
+
+ /**
* Gets entry self link.
*
* @return self link.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Feed.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Feed.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Feed.java
index 4e98ac6..45b28d9 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Feed.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Feed.java
@@ -31,6 +31,21 @@ public interface Feed {
URI getBaseURI();
/**
+ * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
+ * fragment identifying the relevant portion of the metadata document.
+ *
+ * @return context URL.
+ */
+ URI getContextURL();
+
+ /**
+ * Set context URL.
+ *
+ * @param contextURL context URL.
+ */
+ void setContextURL(final URI contextURL);
+
+ /**
* Sets number of entries.
*
* @param count number of entries
@@ -71,5 +86,4 @@ public interface Feed {
* @param next next link.
*/
void setNext(URI next);
-
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Property.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Property.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Property.java
index feb8f71..da34c16 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Property.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Property.java
@@ -18,8 +18,18 @@
*/
package org.apache.olingo.commons.api.data;
+import java.net.URI;
+
public interface Property {
+ /**
+ * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
+ * fragment identifying the relevant portion of the metadata document.
+ *
+ * @return context URL.
+ */
+ URI getContextURL();
+
String getName();
void setName(String name);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/428277c2/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/AbstractODataPayload.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/AbstractODataPayload.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/AbstractODataPayload.java
new file mode 100644
index 0000000..9bc177c
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/AbstractODataPayload.java
@@ -0,0 +1,52 @@
+/*
+ * 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.commons.api.domain;
+
+import java.net.URI;
+
+/**
+ * OData entity.
+ */
+public abstract class AbstractODataPayload extends ODataItem {
+
+ private static final long serialVersionUID = -8234709365887433612L;
+
+ /**
+ * Context URL.
+ */
+ private URI contextURL;
+
+ public AbstractODataPayload(final String name) {
+ super(name);
+ }
+
+ /**
+ * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
+ * fragment identifying the relevant portion of the metadata document.
+ *
+ * @return context URL.
+ */
+ public URI getContextURL() {
+ return contextURL;
+ }
+
+ public void setContextURL(final URI contextURL) {
+ this.contextURL = contextURL;
+ }
+}